测试文章

同步资产信息到Jumpserver

Jumpserver开发文档:

  • 创建API Keyimage.png

阿里云API文档:

具体代码:

  • 添加本地IDC机房服务器白名单,避免同步阿里云删除本地机房服务器资产
  • 同步比较Jumpserver创建的重复资产
  • 实时同步线上资产到Jumpserver
  • 同步操作发送结果到钉钉消息
  1#!/usr/bin/env python3
  2#coding=utf-8
  3#Author:cuijianzhe
  4
  5import json
  6import requests
  7import time
  8from httpsig.requests_auth import HTTPSignatureAuth
  9
 10from aliyunsdkcore.client import AcsClient
 11from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest
 12
 13from collections import Counter
 14
 15#新建jumpserver
 16KEY_ID = 'keyid'
 17SECRET = 'secret'
 18Jumpserver_url = 'http://172.16.16.250'
 19#aliyun参数
 20aliyun_ip_list = []
 21aliyun_name_list = []
 22JumpIP_list = []
 23JumpID_list = []
 24
 25class aliyun_ecs():
 26    def __init__(self):
 27        self._client = AcsClient('<accessKeyId>', '<accessSecret>', 'cn-beijing')
 28
 29    def page_num(self):
 30        request = DescribeInstancesRequest()
 31        request.set_accept_format('json')
 32        response = json.loads(self._client.do_action_with_exception(request))
 33        _ecs_num = response.get('TotalCount')//100 + 2
 34        return _ecs_num
 35
 36    def assets_list(self):
 37        request = DescribeInstancesRequest()
 38        request.set_accept_format('json')
 39        request.set_PageSize(100)
 40        for num in range(1,self.page_num()):
 41            request.set_PageNumber(num)
 42            response = json.loads(self._client.do_action_with_exception(request))
 43            instances_list = response.get('Instances').get('Instance')
 44            for info in instances_list:
 45                assetsName = info.get('InstanceName')
 46                aliyun_name_list.append(assetsName)
 47                assetsIp = ''.join(info.get('VpcAttributes').get('PrivateIpAddress').get('IpAddress'))
 48                aliyun_ip_list.append(assetsIp)
 49
 50class new_Jumpserver():
 51    def __init__(self,ip,hostname,id,node,host=Jumpserver_url,keyid=KEY_ID,secret=SECRET):
 52        self.host = host
 53        self.keyid = keyid
 54        self.secret = secret
 55        self.ip = ip
 56        self.hostname = hostname
 57        self.id = id
 58        self.node = node
 59    def _auth(self):
 60        signature_headers = ['(request-target)', 'accept', 'date', 'host']
 61        auth = HTTPSignatureAuth(key_id=self.keyid, secret=self.secret,
 62                                 algorithm='hmac-sha256',
 63                                 headers=signature_headers)
 64        return auth
 65    def _headers(self):
 66        headers = {
 67            'Accept': 'application/json',
 68            'Date': str(time.strftime("%a %b %d %H:%M:%S %Y", time.localtime()))
 69        }
 70        return headers
 71
 72    def get_assets(self):
 73        url = self.host + '/api/v1/assets/assets/'
 74        req = requests.get(url, auth=self._auth(), headers=self._headers())
 75        return json.loads(req.content)
 76    def get_nodes(self):
 77        url = self.host + '/api/v1/assets/nodes/'
 78        req = requests.get(url,auth=self._auth(),headers=self._headers())
 79        return json.loads(req.content)
 80    def create_assets(self):
 81        url = self.host + '/api/v1/assets/assets/'
 82        data = {
 83            'hostname': self.hostname,
 84            'ip': self.ip,
 85            'platform':'Linux',
 86            'nodes': self.node,
 87            "admin_user_display": "limi_admin",
 88            "protocols": ["ssh/5203"],
 89            "created_by": "Administrator",
 90            "admin_user": self.get_assets()[0].get('admin_user'),
 91            "is_active": 'true',
 92        }
 93        req = requests.post(url,auth=self._auth(),headers=self._headers(),data=data)
 94        return json.loads(req.content)
 95
 96    def delete_assets(self):
 97        # /assets/nodes/{id}/
 98        url = Jumpserver_url + '/api/v1/assets/assets/{}/'.format(self.id)
 99        req = requests.delete(url, auth=self._auth(), headers=self._headers())
100        return req.content.decode('utf-8')
101
102def send_msg(text):
103    headers = {'Content-Type': 'application/json;charset=utf-8'}
104    api_url = "https://oapi.dingtalk.com/robot/send?access_token=access_token"
105    json_text= {
106        "actionCard": {
107            "title": "Jumpserver同步资产通知",
108            "text":
109             text,
110            "hideAvatar": "0",
111            "btnOrientation": "0",
112            "btns": [
113                {
114                    "title": "Jumpserver链接",
115                    "actionURL": "http://opt-jumpserver.jumpserver.com"
116                },
117            ]
118        },
119        "msgtype": "actionCard"
120    }
121    Text = requests.post(api_url,data=json.dumps(json_text),headers=headers).json()
122    return Text
123
124if __name__ == '__main__':
125    #服务器白名单
126    white_list_ip = ['192.168.51.200','192.168.51.201','192.168.51.202','192.168.51.203','192.168.51.204','192.168.51.205','192.168.51.206',
127                     '192.168.51.207','192.168.51.208','192.168.51.209','192.168.51.210','192.168.51.211','192.168.51.212','192.168.51.213',
128                     '192.168.51.214','172.20.9.234']
129    #ali全部资产写入列表
130#    for num in range(1,10):
131#        all_assets = aliyun_ecs(int(num))
132#        aliyun_list = all_assets.assets_list()
133    aliyun_ecs().assets_list()
134    aliassets_dict = dict(list(zip(aliyun_ip_list,aliyun_name_list))) #将aliyun资产ip和命名合并成字典
135    #jumpserver全部资产
136    Jump_assetsInfo = new_Jumpserver(ip=None,hostname=None,id=None,node=None)
137    for var in Jump_assetsInfo.get_assets():
138        JumpIP_list.append(var.get('ip'))
139        JumpID_list.append(var.get('id'))
140    jumpserver_dict = dict(list(zip(JumpIP_list,JumpID_list))) #将Jumpserver资产合并成子字典
141  
142    '''
143    Jumpserver node节点归属
144    '''
145    Jump_nodeInfo = new_Jumpserver(ip=None, hostname=None, id=None, node=None)
146    node_list = []
147    node_dict = {}
148    for node_info in Jump_nodeInfo.get_nodes():
149        node_list.append(node_info.get('value'))
150        node_dict[node_info.get('value')] = node_info.get('id')
151    if 'Jumpserver资产同步' not  in node_list:
152        node_id = node_dict['Default']
153    else:
154        node_id = node_dict['Jumpserver资产同步']
155    '''
156    # 检查Jumpserver是否存在重复资产
157    '''
158  
159    dup = dict(Counter(JumpIP_list))
160    dup_set = [key for key,value in dup.items()if value > 1]
161    if dup_set:
162        message = '**Jumpserver中存在重复资产信息列表**:' + '\n\n' + str(dup_set)
163        send_msg(message)
164        with open('/alidata/jumpserver/rsync_assets/log', 'a', encoding='utf-8') as dup_assets:
165            dup_assets.write(message +'\n')
166    if len(aliyun_ip_list) > 400:  #检查是否有阿里云获取到的值,有则执行下一步
167        #ali云和Jumpserver资产对比,如果jumpserver有而阿里云以及本地机房没有则删除Jumpserver资产
168        delete_ip_list = [ip for ip in JumpIP_list if ip not in aliyun_ip_list+white_list_ip]
169        if len(delete_ip_list) > 0:
170            delete_msg = '**Jumpserver删除资产通知**:' + '\n\n' + \
171                         '**当前时间**:' + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + '\n\n' + \
172                         '**删除ip列表**:' + str(delete_ip_list)
173            for ip in delete_ip_list:
174                del_assets = new_Jumpserver(id=jumpserver_dict[ip],ip=None,hostname=None,node=None)
175                del_assets.delete_assets()
176            with open('/alidata/jumpserver/rsync_assets/log','a',encoding='utf-8') as f:
177                f.write(delete_msg + '\n')
178            send_msg(delete_msg)
179
180        #列表推导式--> 同步阿里云资产到Jumpserver
181        add_ip_list = [ip for ip in aliyun_ip_list if ip not in JumpIP_list]
182        if len(add_ip_list) > 0:
183            add_msg = '**Jumpserver添加资产通知**:' + '\n\n' + \
184                      '**当前时间**:' + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + '\n\n' + \
185                      '**添加ip列表**:' + str(add_ip_list)
186            for ip in add_ip_list:
187                add_assets = new_Jumpserver(ip=ip, hostname=aliassets_dict[ip] + '-' + ip,id=None,node=node_id)
188                add_assets.create_assets()
189            with open('/alidata/jumpserver/rsync_assets/log','a',encoding='utf-8') as f:
190                f.write(add_msg + '\n')
191            send_msg(add_msg)

人机交互同步添加的资产

  1#!/usr/bin/env python3
  2#coding=utf-8
  3import json
  4import requests
  5import time
  6from httpsig.requests_auth import HTTPSignatureAuth
  7
  8from aliyunsdkcore.client import AcsClient
  9from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest
 10
 11#新建jumpserver
 12KEY_ID = 'keyid'
 13SECRET = 'secret'
 14Jumpserver_url = 'http://172.16.16.250'
 15#aliyun参数
 16aliyun_ip_list = []
 17aliyun_name_list = []
 18JumpIP_list = []
 19JumpID_list = []
 20class aliyun_ecs():
 21    def __init__(self):
 22        self._client = AcsClient('<accessKeyId>', '<accessSecret>', 'cn-beijing')
 23
 24    def page_num(self):
 25        request = DescribeInstancesRequest()
 26        request.set_accept_format('json')
 27        response = json.loads(self._client.do_action_with_exception(request))
 28        _ecs_num = response.get('TotalCount')//100 + 2
 29        return _ecs_num
 30
 31    def assets_list(self):
 32        request = DescribeInstancesRequest()
 33        request.set_accept_format('json')
 34        request.set_PageSize(100)
 35        for num in range(1,self.page_num()):
 36            request.set_PageNumber(num)
 37            response = json.loads(self._client.do_action_with_exception(request))
 38            instances_list = response.get('Instances').get('Instance')
 39            for info in instances_list:
 40                assetsName = info.get('InstanceName')
 41                aliyun_name_list.append(assetsName)
 42                assetsIp = ''.join(info.get('VpcAttributes').get('PrivateIpAddress').get('IpAddress'))
 43                aliyun_ip_list.append(assetsIp)
 44        return aliyun_ip_list, aliyun_name_list
 45
 46class new_Jumpserver():
 47    def __init__(self,ip,hostname,id,node,host=Jumpserver_url,keyid=KEY_ID,secret=SECRET):
 48        self.host = host
 49        self.keyid = keyid
 50        self.secret = secret
 51        self.ip = ip
 52        self.hostname = hostname
 53        self.id = id
 54        self.node = node
 55    def _auth(self):
 56        signature_headers = ['(request-target)', 'accept', 'date', 'host']
 57        auth = HTTPSignatureAuth(key_id=self.keyid, secret=self.secret,
 58                                 algorithm='hmac-sha256',
 59                                 headers=signature_headers)
 60        return auth
 61    def _headers(self):
 62        headers = {
 63            'Accept': 'application/json',
 64            'Date': str(time.strftime("%a %b %d %H:%M:%S %Y", time.localtime()))
 65        }
 66        return headers
 67
 68    def get_assets(self):
 69        url = self.host + '/api/v1/assets/assets/'
 70        req = requests.get(url, auth=self._auth(), headers=self._headers())
 71        return json.loads(req.content)
 72    def get_nodes(self):
 73        url = self.host + '/api/v1/assets/nodes/'
 74        req = requests.get(url,auth=self._auth(),headers=self._headers())
 75        return json.loads(req.content)
 76    def create_assets(self):
 77        url = self.host + '/api/v1/assets/assets/'
 78        data = {
 79            'hostname': self.hostname,
 80            'ip': self.ip,
 81            'platform':'Linux',
 82            'nodes': self.node,
 83            "admin_user_display": "limi_admin",
 84            "protocols": ["ssh/5203"],
 85            "created_by": "Administrator",
 86            "admin_user": self.get_assets()[0].get('admin_user'),
 87            "is_active": 'true',
 88        }
 89        req = requests.post(url,auth=self._auth(),headers=self._headers(),data=data)
 90        return json.loads(req.content)
 91
 92
 93
 94def send_msg(text):
 95    headers = {'Content-Type': 'application/json;charset=utf-8'}
 96    api_url = "https://oapi.dingtalk.com/robot/send?access_token=access_token"
 97    json_text= {
 98        "actionCard": {
 99            "title": "Jumpserver同步资产通知",
100            "text":
101             text,
102            "hideAvatar": "0",
103            "btnOrientation": "0",
104            "btns": [
105                {
106                    "title": "Jumpserver链接",
107                    "actionURL": "http://opt-jumpserver.jumpserver.com"
108                },
109            ]
110        },
111        "msgtype": "actionCard"
112    }
113    Text = requests.post(api_url,data=json.dumps(json_text),headers=headers).json()
114    return Text
115
116if __name__ == '__main__':
117
118    #ali全部资产写入列表
119    aliyun_ecs().assets_list()
120    aliassets_dict = dict(list(zip(aliyun_ip_list,aliyun_name_list))) #将aliyun资产ip和命名合并成字典
121    #jumpserver全部资产
122    Jump_assetsInfo = new_Jumpserver(ip=None,hostname=None,id=None,node=None)
123    node_list = []
124    node_dict = {}
125    for node_info in Jump_assetsInfo.get_nodes():
126        node_list.append(node_info.get('value'))
127        node_dict[node_info.get('value')] = node_info.get('id')
128    for num,char in enumerate(node_list):
129        print(num,char)
130    node_num = int(input('请按照以上node节点名称输入相应的序号:'))
131    node_id = node_dict['%s' % node_list[node_num]]
132    for var in Jump_assetsInfo.get_assets():
133        JumpIP_list.append(var.get('ip'))
134        JumpID_list.append(var.get('id'))
135    jumpserver_dict = dict(list(zip(JumpIP_list,JumpID_list))) #将Jumpserver资产合并成子字典
136    if len(aliyun_ip_list) > 400:  #检查是否有阿里云获取到的值,有则执行下一步
137        # 列表推导式--> 同步阿里云资产到Jumpserver
138        add_ip_list = [ip for ip in aliyun_ip_list if ip not in JumpIP_list]
139        if len(add_ip_list) > 0:
140            add_msg = '**Jumpserver添加资产通知**:' + '\n\n' + \
141                      '**当前时间**:' + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + '\n\n' + \
142                      '**添加ip列表**:' + str(add_ip_list)
143            for ip in add_ip_list:
144                add_assets = new_Jumpserver(ip=ip, hostname=aliassets_dict[ip] + '-' + ip,id=None,node=node_id)
145                add_assets.create_assets()
146            with open('./Jumpserver同步阿里云资产_log','a',encoding='utf-8') as f:
147                f.write(add_msg + '\n')
148            send_msg(add_msg)

效果图:
image.png

    评论
    5 评论
    2021-07-02 15:33 回复»

    xcvzxvzcxvzxc

    2020-12-24 13:47 回复»

    doge 加班

    2020-12-23 15:46 回复»

    嚯~ 好玩

    • 光速为什么恒定不变呢?
    • 活着的意义是什么? 回忆还是对未来的期待?

    无聊, 不想写代码

    1. 随手一个回复
    2. 哇咔咔

    2020-12-22 10:14 回复»

    要上班啊doge 我也想出去丸

    2020-12-22 09:10 回复»

    得上班

avatar

取消