Chào mọi người,
Trong xu hướng quản trị hạ tầng hiện đại, việc sử dụng REST API thay cho giao diện Web/CLI truyền thống đang ngày càng phổ biến. Hôm nay mình muốn chia sẻ lại trải nghiệm và đoạn code thực hành khi làm bài lab tương tác với Meraki Dashboard API trên hệ thống Cisco DevNet. Bài lab này là một bước khởi động cực tốt cho những ai đang muốn dấn thân vào mảng DevOps và tự động hóa mạng.
1. Luồng truy xuất dữ liệu của Meraki API
Để lấy được thông tin chi tiết của một thiết bị (ví dụ: SSID của Access Point), chúng ta không thể gọi API trực tiếp đến thiết bị đó ngay từ đầu. Meraki Dashboard API thiết kế cấu trúc dữ liệu theo dạng phân tầng. Luồng truy xuất dữ liệu bắt buộc phải đi theo trình tự:
Organization ID -> Network ID -> Device Serial -> Device Info
Bạn phải lấy được ID của lớp ngoài cùng rồi mới dùng nó làm tham số để gọi API lấy thông tin lớp bên trong.
2. Xử lý xác thực (Authentication)
Điểm quan trọng nhất khi giao tiếp với Meraki API là phương thức xác thực. Yêu cầu hệ thống bắt buộc phải đính kèm một API Key (do DevNet Sandbox cung cấp) vào bên trong Header với tên gọi X-Cisco-Meraki-API-Key.
Ghi chú nhỏ: Khi dùng Postman để test thử, các bạn nhớ cấu hình API Key này ở tab Authorization (chọn type là API Key và đẩy vào Header) thay vì nhập thẳng vào tab Headers. Việc nhập thẳng vào tab Headers đôi khi bị Postman ghi đè do tính năng Inherit auth, dẫn đến lỗi HTTP 401.
3. Hiện thực hóa bằng Script Python
Sau khi nắm được luồng dữ liệu, mình tiến hành viết một script Python nhỏ sử dụng thư viện requests. Mình có tạo một menu CLI đơn giản để tiện gọi các hàm tương ứng với các tầng dữ liệu.
Đây là source code đầy đủ mình dùng trong lab:
4. Thảo luận & Hướng phát triển
Script trên giải quyết tốt yêu cầu của bài lab. Tuy nhiên, nếu áp dụng vào thực tế sản xuất (production), chúng ta sẽ cần cải tiến thêm một số điểm:
Trong xu hướng quản trị hạ tầng hiện đại, việc sử dụng REST API thay cho giao diện Web/CLI truyền thống đang ngày càng phổ biến. Hôm nay mình muốn chia sẻ lại trải nghiệm và đoạn code thực hành khi làm bài lab tương tác với Meraki Dashboard API trên hệ thống Cisco DevNet. Bài lab này là một bước khởi động cực tốt cho những ai đang muốn dấn thân vào mảng DevOps và tự động hóa mạng.
1. Luồng truy xuất dữ liệu của Meraki API
Để lấy được thông tin chi tiết của một thiết bị (ví dụ: SSID của Access Point), chúng ta không thể gọi API trực tiếp đến thiết bị đó ngay từ đầu. Meraki Dashboard API thiết kế cấu trúc dữ liệu theo dạng phân tầng. Luồng truy xuất dữ liệu bắt buộc phải đi theo trình tự:
Organization ID -> Network ID -> Device Serial -> Device Info
Bạn phải lấy được ID của lớp ngoài cùng rồi mới dùng nó làm tham số để gọi API lấy thông tin lớp bên trong.
2. Xử lý xác thực (Authentication)
Điểm quan trọng nhất khi giao tiếp với Meraki API là phương thức xác thực. Yêu cầu hệ thống bắt buộc phải đính kèm một API Key (do DevNet Sandbox cung cấp) vào bên trong Header với tên gọi X-Cisco-Meraki-API-Key.
Ghi chú nhỏ: Khi dùng Postman để test thử, các bạn nhớ cấu hình API Key này ở tab Authorization (chọn type là API Key và đẩy vào Header) thay vì nhập thẳng vào tab Headers. Việc nhập thẳng vào tab Headers đôi khi bị Postman ghi đè do tính năng Inherit auth, dẫn đến lỗi HTTP 401.
3. Hiện thực hóa bằng Script Python
Sau khi nắm được luồng dữ liệu, mình tiến hành viết một script Python nhỏ sử dụng thư viện requests. Mình có tạo một menu CLI đơn giản để tiện gọi các hàm tương ứng với các tầng dữ liệu.
Đây là source code đầy đủ mình dùng trong lab:
Code:
import json
import os
import requests
baseURL = "https://api.meraki.com/api/v1"
api_key = "86c2a20fbb15195555f20dbdae40e7ded2f05c1d"
def get_org():
url_org = baseURL + "/organizations"
headers = {
"X-Cisco-Meraki-API-Key": api_key,
"Content-Type": "application/json",
}
send_request = requests.get(url_org, headers=headers, verify=False)
data = send_request.json()
print(json.dumps(data, indent=4))
id_org = data[0]["id"]
return id_org
def get_network():
org_id = get_org()
url_org = baseURL + "/organizations/" + str(org_id) + "/networks"
headers = {
"X-Cisco-Meraki-API-Key": api_key,
"Content-Type": "application/json",
}
send_request = requests.get(url_org, headers=headers, verify=False)
data = send_request.json()
print(json.dumps(data, indent=4))
networkID = data[0]["id"]
return networkID
def get_devices():
network_id = get_network()
url_device = baseURL + "/networks/" + str(network_id) + "/devices"
headers = {
"X-Cisco-Meraki-API-Key": api_key,
"Content-Type": "application/json",
}
send_request = requests.get(url_device, headers=headers, verify=False)
data = send_request.json()
print(json.dumps(data, indent=4))
serialId = data[0]["serial"]
print(serialId)
return serialId
def get_SSID_info():
network_id = get_network()
device_serial = get_devices()
url_ssid_device = baseURL + "/networks/" + str(network_id) + "/devices/" + str(device_serial)
headers = {
"X-Cisco-Meraki-API-Key": api_key,
"Content-Type": "application/json",
}
send_request = requests.get(url_ssid_device, headers=headers, verify=False)
data = send_request.json()
print(json.dumps(data, indent=4))
return data
def main():
while True:
print("\n=== Chọn chức năng Meraki ===")
print("1. get_org")
print("2. get_network")
print("3. get_devices")
print("4. get_SSID_info")
print("0. Thoát")
choice = input("Nhập lựa chọn: ").strip()
if choice == "0":
print("Thoát chương trình.")
break
functions = {
"1": get_org,
"2": get_network,
"3": get_devices,
"4": get_SSID_info,
}
if choice not in functions:
print("Lựa chọn không hợp lệ. Vui lòng chọn 0-4.")
continue
try:
functions[choice]()
except Exception as e:
print(f"Lỗi khi chạy {functions[choice].__name__}: {e}")
if __name__ == "__main__":
main() zz0.cqbzb3wzwsqzz
Script trên giải quyết tốt yêu cầu của bài lab. Tuy nhiên, nếu áp dụng vào thực tế sản xuất (production), chúng ta sẽ cần cải tiến thêm một số điểm:
- Quản lý API Key: Hiện tại key đang được hardcode. Thực tế nên dùng thư viện os (như đã import) để đọc từ biến môi trường (Environment Variables).
- Tối ưu Headers: Khai báo một dictionary headers dùng chung ở ngoài thay vì lặp lại trong từng hàm.
- Tối ưu lời gọi API: Các hàm hiện tại đang gọi lồng nhau liên tục. Ví dụ hàm get_SSID_info gọi get_devices, mà get_devices lại gọi get_network, rồi get_network lại gọi get_org. Điều này khiến API bị gọi đi gọi lại nhiều lần không cần thiết.