• Python调用Jumpserver的Api接口增删改查


    引言

    Jumpserver是一款强大的堡垒机系统,可以有效管理和控制企业内部服务器的访问权限,提高网络安全性。本文将介绍如何使用Python编程语言,结合Jumpserver提供的API接口,实现对跳板机的管理和操作。

    1、什么是Jumpserver?

    Jumpserver是一种堡垒机系统,它提供了一种安全且集中的方式来管理和控制用户对服务器的访问权限。Jumpserver可以帮助企业实现统一认证、审计日志记录、权限管理等功能,从而提高网络安全性。

    2、Jumpserver提供的API接口

    Jumpserver提供了一组强大的API接口,可以实现对跳板机的管理和操作。这些API包括获取服务器列表、认证访问权限、执行命令和文件传输等功能,可以通过HTTP请求进行调用。

    目前使用的版本:v3.6.2
    不同步的版本,API 接口有变化

    https://docs.jumpserver.org/zh/v3/dev/rest_api/
    在这里插入图片描述

    在这里插入图片描述

    3、Python中的HTTP请求库

    在Python中,我们可以使用第三方的HTTP请求库,如requests库或http.client库,来发送HTTP请求并获取响应。这些库提供了简洁的接口,方便我们与Jumpserver的API进行交互。

    requests库:
    requests是一个功能强大、简单易用的第三方HTTP请求库,广泛应用于Python开发中。它提供了简洁的API,使得发送HTTP请求变得非常简单。使用requests库,我们可以发送各种类型的HTTP请求(GET、POST、PUT等),设置请求头、请求参数、请求体等,并能够获得服务器响应的状态码、内容等信息。

    示例代码:

    import requests
    
    # 发送GET请求并获取响应
    response = requests.get('https://api.example.com/users')
    
    # 获取响应内容
    content = response.text
    
    # 获取响应状态码
    status_code = response.status_code
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    4、使用Python调用Jumpserver API进行认证

    在使用Jumpserver的API之前,我们需要先进行认证。通常,Jumpserver会提供一个登录接口,我们可以使用用户名和密码进行登录,并获取到访问令牌(Access Token)。在后续的API请求中,我们需要将该访问令牌作为认证凭证。
    https://docs.jumpserver.org/zh/v3/dev/rest_api/#12
    在这里插入图片描述
    推荐使用:Access Key方式 或者 Private Token
    在这里插入图片描述
    在这里插入图片描述

    docker exec -it jms_core /bin/bash
    cd /opt/jumpserver/apps
    python manage.py shell
    from users.models import User
    u = User.objects.get(username='admin')
    u.create_private_token()
    已经存在 private_token,可以直接获取即可
    u.private_token
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    此处我才用双层验证方式

    
    KeyID = '77e76d19-141c-xxx-8d2b-xxxx'
    SecretID = 'a04817bc-0bb1-439f-baa2-xxxx'
    gmt_form = '%a, %d %b %Y %H:%M:%S GMT'
    ptivate_token = 'xxxxxxxxxx'
    
    headers = {
        'accept': 'application/json',
        'Content-Type': 'application/json',
        # 'X-CSRFToken': 'eoLo2AVcQK5X1JQ392JHCzjZ8wPCWZJFJao5O9ObH8zQwtiPhGBzaOnNKjaENShf',
        "Authorization": 'Token ' + ptivate_token,
        'X-JMS-ORG': '00000000-0000-0000-0000-000000000002',
        'Date': datetime.datetime.utcnow().strftime(gmt_form)
    }
    
    
    # 认证
    def get_auth(KeyID, SecretID):
        """
        认证
        :param KeyID:  The key ID
        :param SecretID:    The secret ID
        :return:
        """
        signature_headers = ['(request-target)', 'accept', 'date']
        auth = HTTPSignatureAuth(key_id=KeyID, secret=SecretID, algorithm='hmac-sha256', headers=signature_headers)
        return auth
    
    
    auth = get_auth(KeyID, SecretID)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    5、Jumpserver接口自动调用

    获取所有用户

    # 获取所有用户
    def get_user_all():
       """
       获取所有用户
       :return:
       """
       url = jms_url + '/api/v1/users/users/'
       response = requests.get(url, auth=auth, headers=headers)
       user_list = json.loads(response.text)
       count = 0
       for i in user_list:
           count += 1
           print(i)
       print(count)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这里插入图片描述
    获取监控指标

    # 获取监控指标
    def get_prometheus_metric():
        """
        获取监控指标
        :return:
        """
        url = jms_url + "/api/v1/prometheus/metrics/"
        response = requests.get(url, headers=headers, auth=auth)
        print(response.text)
        return response.text
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    获取所有资产节点

    # 获取所有资产节点
    def get_node_all():
        """
        获取所有资产节点
        :return:
        """
        url = jms_url + "/api/v1/assets/nodes/"
        response = requests.get(url, headers=headers, auth=auth)
        node_list = json.loads(response.text)
        count = 0
        for i in node_list:
            count += 1
            print(i)
        print(count)
        return response.json()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    查看当前token(即admin)的所有资产

    def get_asset_all():
        """
        查看当前token(即admin)的所有资产
        :return:
        """
        url = jms_url + "/api/v1/assets/assets/"
        response = requests.get(url, headers=headers, auth=auth)
        node_list = json.loads(response.text)
        count = 0
        for i in node_list:
            count += 1
            print(i)
        print(count)
        return response.json()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    创建资产节点

    def assets_nodes_create(node_name):
        """
        创建资产节点
        :param node_name:
        :return:
        """
        node_data = {
            "value": node_name
        }
        url = jms_url + "/api/v1/assets/nodes/"
        node_info = get_node_info(node_name)
        if node_info:  # 根据node_name去查询,如果查到了说明已经有了。
            print("{name}已存在, id: {id}".format(name=node_name, id=node_info[0]["id"]))
        else:
            data = json.dumps(node_data)
            resp = requests.post(url, headers=headers, data=data)
            return resp.json()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    根据ip获取资产信息

    def get_assets_list_by_ip(ip):
        """
        根据ip获取资产信息
        :param ip:
        :return:
        """
        url = jms_url + "/api/v1/assets/assets/"
        response = requests.get(url, headers=headers, params={
            "ip": ip
        })
        print(response.json())
        return response.json()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    查看资产节点信息

    def get_node_info(node_name):
        """
        查看资产节点信息
        :param node_name:   节点名称
        :return:
        """
        url = jms_url + "/api/v1/assets/nodes/"
        response = requests.get(url, auth=auth, headers=headers, params={
            "value": node_name
        })
        print(response.text)
        return response.json()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    创建资产机器

    
    # 创建资产机器
    def asset_create(ip, hostname, node_id, comment):
        """
        创建资产机器
        :param ip:  ip地址
        :param hostname:   主机名
        :param node_id:   节点id
        :return:    返回创建的资产信息
        """
        asset_Data = {
            "name": hostname,
            "address": ip,
            "platform": "1",
            "protocols": [{
    
                "name": "ssh",
                "port": 22
            }],
            "is_active": True,
            "nodes": [node_id],
            "comment": comment,
            "accounts": [{
                # 账号模板id
                "template": "60b11033-a6e1-467d-8388-68a0e64134ff",
            }]
        }
        url = jms_url + "/api/v1/assets/hosts/"
        print(url)
        data = json.dumps(asset_Data)
        print(data)
        response = requests.post(url, auth=auth, headers=headers, data=data)
        print(response.text)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    运行创建服务器资产

    
    # 运行创建服务器资产
    def run_create_assets(node_name, project_name, ip, comment):
        """
        运行创建服务器资产
        :param node_name:  节点名称
        :param project_name:  机器名称
        :param ip:  ip地址
        :param comment:  备注
        :return:
        """
        # 节点id,无节点时创建节点
        node_info = get_node_info(node_name)
    
        # 如果len(node_info) == 0 说明没有节点,需要创建节点
        if len(node_info) == 0:
            # 创建节点
            node_id = assets_nodes_create(node_name)
            print(node_id)
        else:
            # 获取节点id
            node_id = node_info[0]["id"]
            print(node_id)
        # 管理用户 id
        hostname = "{ip}_{project_name}".format(ip=ip, project_name=project_name)
        # 查IP,创建资产
        ip_info = get_assets_list_by_ip(ip)
        if ip_info:
            print("%s 已存在,nodes: %s" % (ip_info[0]["address"], ip_info[0]["nodes"]))
        else:
            asset_create(ip, hostname, node_id, comment)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    获取组织信息

    
    def get_org_info():
        """
        获取组织信息
        :return:
        """
        url = jms_url + "/api/v1/orgs/orgs/"
        response = requests.get(url, headers=headers)
        org_list = response.text
        print(org_list)
        for i in org_list.split("id"):
            print(i)
    
        return response.json()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    6、完整代码

    # -*- coding: utf-8 -*-
    # @Time    : 2023/8/29 14:21
    # @Author  : 南宫乘风
    # @Email   : 1794748404@qq.com
    # @File    : jms_add.py
    # @Software: PyCharm
    
    
    import requests, datetime, json
    from httpsig.requests_auth import HTTPSignatureAuth
    
    KeyID = '77e76d19-141c-4545--xxx'
    SecretID = 'a04817bc-0bb1-439f-baa2-xxxx'
    gmt_form = '%a, %d %b %Y %H:%M:%S GMT'
    ptivate_token = 'xxxxx'
    
    headers = {
        'accept': 'application/json',
        'Content-Type': 'application/json',
        # 'X-CSRFToken': 'eoLo2AVcQK5X1JQ392JHCzjZ8wPCWZJFJao5O9ObH8zQwtiPhGBzaOnNKjaENShf',
        "Authorization": 'Token ' + ptivate_token,
        'X-JMS-ORG': '00000000-0000-0000-0000-000000000002',
        'Date': datetime.datetime.utcnow().strftime(gmt_form)
    }
    
    
    # 认证
    def get_auth(KeyID, SecretID):
        """
        认证
        :param KeyID:  The key ID
        :param SecretID:    The secret ID
        :return:
        """
        signature_headers = ['(request-target)', 'accept', 'date']
        auth = HTTPSignatureAuth(key_id=KeyID, secret=SecretID, algorithm='hmac-sha256', headers=signature_headers)
        return auth
    
    
    auth = get_auth(KeyID, SecretID)
    
    
    # 获取所有用户
    def get_user_all():
        """
        获取所有用户
        :return:
        """
        url = jms_url + '/api/v1/users/users/'
        response = requests.get(url, auth=auth, headers=headers)
        user_list = json.loads(response.text)
        count = 0
        for i in user_list:
            count += 1
            print(i)
        print(count)
    
    
    # 获取监控指标
    def get_prometheus_metric():
        """
        获取监控指标
        :return:
        """
        url = jms_url + "/api/v1/prometheus/metrics/"
        response = requests.get(url, headers=headers, auth=auth)
        print(response.text)
        return response.text
    
    
    # 获取所有资产节点
    def get_node_all():
        """
        获取所有资产节点
        :return:
        """
        url = jms_url + "/api/v1/assets/nodes/"
        response = requests.get(url, headers=headers, auth=auth)
        node_list = json.loads(response.text)
        count = 0
        for i in node_list:
            count += 1
            print(i)
        print(count)
        return response.json()
    
    
    # 查看当前token(即admin)的所有资产
    def get_asset_all():
        """
        查看当前token(即admin)的所有资产
        :return:
        """
        url = jms_url + "/api/v1/assets/assets/"
        response = requests.get(url, headers=headers, auth=auth)
        node_list = json.loads(response.text)
        count = 0
        for i in node_list:
            count += 1
            print(i)
        print(count)
        return response.json()
    
    
    ###################################################################################################
    # 创建资产节点
    def assets_nodes_create(node_name):
        """
        创建资产节点
        :param node_name:
        :return:
        """
        node_data = {
            "value": node_name
        }
        url = jms_url + "/api/v1/assets/nodes/"
        node_info = get_node_info(node_name)
        if node_info:  # 根据node_name去查询,如果查到了说明已经有了。
            print("{name}已存在, id: {id}".format(name=node_name, id=node_info[0]["id"]))
        else:
            data = json.dumps(node_data)
            resp = requests.post(url, headers=headers, data=data)
            return resp.json()
    
    
    #
    def get_assets_list_by_ip(ip):
        """
        根据ip获取资产信息
        :param ip:
        :return:
        """
        url = jms_url + "/api/v1/assets/assets/"
        response = requests.get(url, headers=headers, params={
            "ip": ip
        })
        print(response.json())
        return response.json()
    
    
    # 查看资产节点信息
    def get_node_info(node_name):
        """
        查看资产节点信息
        :param node_name:   节点名称
        :return:
        """
        url = jms_url + "/api/v1/assets/nodes/"
        response = requests.get(url, auth=auth, headers=headers, params={
            "value": node_name
        })
        print(response.text)
        return response.json()
    
    
    # 创建资产机器
    def asset_create(ip, hostname, node_id, comment):
        """
        创建资产机器
        :param ip:  ip地址
        :param hostname:   主机名
        :param node_id:   节点id
        :return:    返回创建的资产信息
        """
        asset_Data = {
            "name": hostname,
            "address": ip,
            "platform": "1",
            "protocols": [{
    
                "name": "ssh",
                "port": 22
            }],
            "is_active": True,
            "nodes": [node_id],
            "comment": comment,
            "accounts": [{
                # 账号模板id
                "template": "60b11033-a6e1-467d-8388-68a0e64134ff",
            }]
        }
        url = jms_url + "/api/v1/assets/hosts/"
        print(url)
        data = json.dumps(asset_Data)
        print(data)
        response = requests.post(url, auth=auth, headers=headers, data=data)
        print(response.text)
    
    
    # 运行创建服务器资产
    def run_create_assets(node_name, project_name, ip, comment):
        """
        运行创建服务器资产
        :param node_name:  节点名称
        :param project_name:  机器名称
        :param ip:  ip地址
        :param comment:  备注
        :return:
        """
        # 节点id,无节点时创建节点
        node_info = get_node_info(node_name)
    
        # 如果len(node_info) == 0 说明没有节点,需要创建节点
        if len(node_info) == 0:
            # 创建节点
            node_id = assets_nodes_create(node_name)
            print(node_id)
        else:
            # 获取节点id
            node_id = node_info[0]["id"]
            print(node_id)
        # 管理用户 id
        hostname = "{ip}_{project_name}".format(ip=ip, project_name=project_name)
        # 查IP,创建资产
        ip_info = get_assets_list_by_ip(ip)
        if ip_info:
            print("%s 已存在,nodes: %s" % (ip_info[0]["address"], ip_info[0]["nodes"]))
        else:
            asset_create(ip, hostname, node_id, comment)
    
    
    def get_org_info():
        """
        获取组织信息
        :return:
        """
        url = jms_url + "/api/v1/orgs/orgs/"
        response = requests.get(url, headers=headers)
        org_list = response.text
        print(org_list)
        for i in org_list.split("id"):
            print(i)
    
        return response.json()
    
    
    if __name__ == '__main__':
        jms_url = 'https://jms.xxx.top'
        username = 'admin'
        password = 'xxxxxx'
    
        # 获取token
        # token = get_token(jms_url, username, password)
    
        # 创建资产节点
        # assets_nodes_create("k8s")
    
        # 根据ip获取资产信息
        # get_assets_list_by_ip("192.168.11.10")
    
        # 查看资产节点信息
        # get_node_info("k8s")
    
        # 创建资产调用
        # node_id = ["e8641c37-93e3-450e-aaf8-64d5baa69753"]
        # get_node_info("k8s")
        # asset_create(ip, hostname, node_id)
    
        # 运行创建服务器资产
        # run_create_assets("test", "风控", "192.168.11.10", "测试")
    
        # 获取组织信息
        # get_org_info()
    
        # 获取所有用户
        get_user_all()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267

    在这里插入图片描述

  • 相关阅读:
    【Linux】进度条和git命令行
    TapTap自动获得游戏的MD5码
    竞赛 题目:基于深度学习的人脸表情识别 - 卷积神经网络 竞赛项目 代码
    mini-imagenet数据集下载-阿里云网盘不限速下载
    数据结构之栈和队列
    「随笔」前端面试 | 2022年前端面试基础必备
    2.Tornado的优势
    Linux设置开机自启动的方式
    Java反射学习笔记--使用示例
    大厂 Java 面经!阿里高工不小心把今年秋招面试题泄露了出来。
  • 原文地址:https://blog.csdn.net/heian_99/article/details/132688272