Cấu hình thiết bị mạng bằng Python: SSH hay API

Khi chúng ta muốn tự động hoá các tác vụ vận hành cho hệ thống mạng, điều đầu tiên nghĩ đến sẽ là sử dụng Python để code. Nhưng cụ thể code như thế nào thì trong bài viết này chúng ta sẽ làm rõ nhé.

Với Python, chúng ta có 2 cách tiếp cận để có thể tương tác và cấu hình các thiết bị mạng :

  • SSH vào thiết bị, và từ đó gửi lệnh
  • Tương tác thông qua API

*Lưu ý : bài viết này không hướng dẫn chi tiết cách thực hiện, Kai chỉ phân tích sự khác nhau giữa 2 cách tiếp cận này mà thôi.

Dùng Python để SSH vào thiết bị

Với cách tiếp cận dùng Python để SSH vào thiết bị, thao tác khá giống với cách con người chúng ta thường làm, chỉ khác là bây giờ máy sẽ làm thay chúng ta.

Các bước cụ thể như sau :

  • Cấu hình SSH trên thiết bị
  • Trên code Python, kết nối SSH vào thiết bị
  • Gửi lệnh đến thiết bị
  • Thiết bị phản hồi output dưới dạng text

Điểm đáng chú ý ở đây, đó là output mà thiết bị gửi về là dưới dạng text, và nếu chúng ta muốn bóc tách một thông số nào đó để sử dụng cho các tác vụ tiếp theo, chúng ta phải xử lý output text này để lấy được thông số chúng ta cần.

Ví dụ như bên dưới là đoạn code SSH và output của lệnh show vlan

from netmiko import ConnectHandler

DEVICE = {
    'host' : '10.10.30.48',
    'device_type' : 'aruba_aoscx',
    'username' : 'admin',
    'password' : '',
    'secret' : ''
}

connection = ConnectHandler(**DEVICE)
output = connection.send_command('show vlan')
print(output)

Output của đoạn code trên

------------------------------------------------------------------------------------------------------------------
VLAN  Name                              Status  Reason                  Type        Interfaces
------------------------------------------------------------------------------------------------------------------
1     DEFAULT_VLAN_1                    up      ok                      default     1/1/1-1/1/5,1/1/7-1/1/16
31    VLAN31                            up      ok                      static      1/1/13-1/1/14
60    VLAN60                            up      ok                      static      1/1/6,1/1/13-1/1/14
70    VLAN70                            up      ok                      static      1/1/13-1/1/14

Tiếp theo, để lấy được danh sách các VLAN, chúng ta cần thêm 1 đoạn code nữa để xử lý output này

connection = ConnectHandler(**DEVICE)
output = connection.send_command('show vlan')

vlans = []

lines = output.split('\n')
lines = lines[4:]
for line in lines:
    line = re.sub(r"\s{2,}", " ", line)
    vlan_id = line.split(' ')[0]
    vlans.append(vlan_id)

print(vlans)

Sau khi xử lý, danh sách các vlan sẽ được lưu trong biến vlans dưới dạng array

Output sẽ như sau :

['1', '31', '60', '70']

Và tương tự, mỗi câu lệnh sẽ xuất ra kiểu output khác nhau, và chúng ta sẽ phải xử lý chuỗi cho mỗi output đó để lấy được thông số chúng ta cần.

Các bạn có thể thử :

  • Lấy địa chỉ IP của một interface
  • Lấy trạng thái up/down của một interface

Tương tác với thiết bị thông qua API

Với cách tiếp cận này, thay vì SSH vào thiết bị, chúng ta sẽ làm một hành động được gọi là \”call API\” hay \”gọi API\”.

Các bước để gọi API như sau :

  • Bật tính năng API trên thiết bị
  • Lấy URL của API cần gọi, vì mỗi API sẽ có một URL khác nhau
  • Thực hiện gọi API
  • Thiết bị phản hồi output, thường là dưới dạng JSON

Dưới đây là đoạn code lấy danh sách VLAN của thiết bị :

import requests
import urllib3
import json

urllib3.disable_warnings()

base_url = "https://10.10.30.48/rest/v10.11"

#Login 
url = base_url + '/login'
data = {
    'username' : 'admin',
    'password' : ''
}

response = requests.post(url, data, verify=False)
cookie = response.cookies

#Get VLAN List
url = 'https://10.10.30.48/rest/v10.11/system/vlans'

response = requests.get(url, cookies=cookie, verify=False)
vlans = response.json()
[print(vlan) for vlan in vlans]


#Logout
url = base_url + '/logout'
response = requests.post(url, verify=False)
cookie = response.cookies

Trong đó, biến url chính là URL của API chứa thông tin VLAN. Khi chúng ta gọi đến API này, thiết bị sẽ trả về danh sách các VLAN trên thiết bị, và output sẽ ở dạng JSON như sau :

{
    '1': '/rest/v10.11/system/vlans/1', 
    '31': '/rest/v10.11/system/vlans/31', 
    '60': '/rest/v10.11/system/vlans/60', 
    '70': '/rest/v10.11/system/vlans/70'
}

Điều giá trị ở đây, đó là output dạng JSON, đây là dạng dữ liệu có tổ chức. Do đó, chúng ta không cần phải xử lý chuỗi, chúng ta chỉ cần truy xuất thông tin mà chúng ta cần.

Ví dụ, để lấy danh sách vlan, chúng ta chỉ cần in chúng ra :

[print(vlan) for vlan in vlans]

Và đây là kết quả sau khi chạy code

1
31
60
70

Dưới đây là một ví dụ khác để xem trạng thái up/down của interface 1/1/14

url = 'https://10.10.30.48/rest/v10.11/system/interfaces/1%2F1%2F14'
response = requests.get(url, cookies=cookie, verify=False)
link_state = response.json()['link_state']
print(link_state)

Output

up

Tổng kết

Qua các ví dụ trên, các bạn có thể thấy sử dụng API để tương tác với thiết bị sẽ giúp code tinh gọn hơn nhiều, do dữ liệu đã được chuẩn hoá. Khi nhận được output, chúng ta chỉ việc truy xuất đúng phần dữ liệu chúng ta cần. Tuy nhiên, không phải thiết bị nào cũng hỗ trợ API, do đó, các tiếp cận này chỉ dùng được ở một số thiết bị hỗ trợ API. Với các tác vụ cần lấy thông tin trạng thái, số liệu từ output thì API là lựa chọn tuyệt vời.

Dùng Python SSH là cách tiếp cận phổ biến hơn, do hầu hết các thiết bị đều hỗ trợ SSH. Tuy nhiên, chúng ta phải tốn khá nhiều công sức để xử lý output khi cần. Với các tác vụ không cần xử lý quá nhiều output, ví dụ như tự động backup cấu hình, thì cách tiếp cận này lại tỏ ra hiệu quả hơn.

Scroll to Top