Skip to content

Python で CML2 上のリンク情報を取得する

過去、以下のメモを書きました。

上記のコードを流用し、Python からラボのリンク情報を取得するサンプルコードをメモしておきます。 今回は Python 3.9.6 でテストしました。

サンプルコード

  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
import http.client
import json
import ssl

address = "10.0.0.1"
username = "admin"
password = "password"

longest_names = {'Lab': len('Lab'), 'Link': len('Link'), 'Node-A': len('Node-A'), 'Interface-A': len(
    'Interface-A'), 'Node-B': len('Node-B'), 'Interface-B': len('Interface-B')}


def main():
    results = {}
    conn = http.client.HTTPSConnection(
        address, context=ssl._create_unverified_context())
    token = authenticate(conn, username, password)
    labs = get_labs(conn, token)
    for lab in labs:
        check_longest_name(lab, 'Lab')
        results[lab] = []
        data = get_topology(conn, token, lab)
        for link in data['links']:
            link_id = link['id']
            interface_a = get_interface(data, link['interface_a'])
            interface_b = get_interface(data, link['interface_b'])
            check_longest_name(link_id, 'Link')
            check_longest_name(interface_a[0], 'Node-A')
            check_longest_name(interface_a[1], 'Interface-A')
            check_longest_name(interface_b[0], 'Node-B')
            check_longest_name(interface_b[1], 'Interface-B')
            results[lab].append(
                (lab, link_id, interface_a[0], interface_a[1], interface_b[0], interface_b[1]))
    for key in results.keys():
        template = '{0:' + str(longest_names["Lab"]) + '} ' \
                   '{1:' + str(longest_names["Link"]) + '} ' \
                   '{2:' + str(longest_names["Node-A"]) + '} ' \
                   '{3:' + str(longest_names["Interface-A"]) + '} ' \
                   '{4:' + str(longest_names["Node-B"]) + '} ' \
                   '{5:' + str(longest_names["Interface-B"]) + '}'
        print(template.format('Lab', 'Link', 'Node-A',
              'Interface-A', 'Node-B', 'Interface-B'))
        print(template.format('-' * longest_names['Lab'],
                              '-' * longest_names['Link'],
                              '-' * longest_names['Node-A'],
                              '-' * longest_names['Interface-A'],
                              '-' * longest_names['Node-B'],
                              '-' * longest_names['Interface-B']))
        for result in sorted(results[key]):
            print(template.format(*result))
        print('')


def authenticate(conn, username, password):
    payload = json.dumps({
        "username": username,
        "password": password
    })
    headers = {
        'Content-Type': 'application/json'
    }
    conn.request("POST", "/api/v0/authenticate", payload, headers)
    res = conn.getresponse()
    data = res.read()
    return data.decode("utf-8").replace('"', '')


def check_longest_name(item, value):
    if len(item) > longest_names[value]:
        longest_names[value] = len(item)


def get_interface(data, id):
    for interface in data['interfaces']:
        if interface['id'] == id:
            for node in data['nodes']:
                if node['id'] == interface['node']:
                    return node['data']['label'], interface['data']['label']


def get_labs(conn, token):
    payload = ''
    headers = {
        'Authorization': 'Bearer ' + token
    }
    conn.request("GET", "/api/v0/labs", payload, headers)
    res = conn.getresponse()
    data = res.read()
    return json.loads(data.decode("utf-8"))


def get_topology(conn, token, lab):
    payload = ''
    headers = {
        'Authorization': 'Bearer ' + token
    }
    conn.request("GET", "/api/v0/labs/" + lab + "/topology", payload, headers)
    res = conn.getresponse()
    data = res.read()
    return json.loads(data.decode("utf-8"))


if __name__ == "__main__":
    main()

実行例

起動していないラボはリンク情報が取得出来ないようです。

1
2
3
4
5
6
7
8
9
# python links.py
Lab    Link Node-A Interface-A        Node-B Interface-B
------ ---- ------ ------------------ ------ ------------------

Lab    Link Node-A Interface-A        Node-B Interface-B
------ ---- ------ ------------------ ------ ------------------
abc123 l0   iosv-0 GigabitEthernet0/0 iosv-1 GigabitEthernet0/0
abc123 l1   iosv-1 GigabitEthernet0/1 iosv-2 GigabitEthernet0/0
abc123 l2   iosv-2 GigabitEthernet0/1 iosv-0 GigabitEthernet0/1