Bài 90b: Thực hành REST API — Lấy ticket và đọc danh sách thiết bị từ Network Controller bằng Python trên Packet Tracer
Sơ đồ lab Bài 90b · ⬇️ Tải sơ đồ (SVG) · 🔍 Mở cỡ lớn
💡 Liên hệ thực tế
Sếp cần danh sách toàn bộ thiết bị mạng kèm địa chỉ quản trị, mỗi sáng. Với 5 thiết bị, bạn SSH vào từng cái là xong. Với 500 thiết bị, bạn cần một controller đã biết hết thiết bị trong mạng, và một đoạn script hỏi controller qua REST API.
Packet Tracer có sẵn một Network Controller rút gọn, mô phỏng cách các controller như Cisco Catalyst Center (DNA Center) hay APIC-EM làm việc. Trong bài này bạn cho controller khám phá mạng, rồi dùng Python trên một PC để xin ticket (token) và lấy danh sách thiết bị, host dưới dạng JSON.
Quy tắc ghi nhớ: gọi REST API = phương thức HTTP (GET/POST/PUT/DELETE) + URL + header + (body JSON). Muốn gọi API của controller, trước tiên POST tài khoản để lấy ticket, sau đó gửi ticket trong header X-Auth-Token ở mọi lời gọi tiếp theo.
🎯 Mục tiêu bài lab
- Khởi tạo Network Controller, khai báo tài khoản đăng nhập thiết bị và chạy discovery.
- Gọi API
POST /api/v1/ticketđể lấy ticket. - Gọi
GET /api/v1/network-device,/network-device/count,/hostkèm ticket. - Đọc cấu trúc JSON trả về; nhận biết mã trạng thái HTTP.
📋 Bảng địa chỉ và đấu nối
| Thiết bị | Interface | Địa chỉ IP | Gateway | Ghi chú |
|---|---|---|---|---|
| R1 | G0/0 | 192.168.1.1/24 | — | Thiết bị được quản lý |
| G0/1 | 192.168.2.1/24 | — | LAN người dùng | |
| SW1 | VLAN 1 | 192.168.1.2/24 | 192.168.1.1 | Thiết bị được quản lý |
| NC | GigabitEthernet0 | 192.168.1.10/24 | 192.168.1.1 | Network Controller (mục End Devices) |
| PC-DEV | NIC | 192.168.1.20/24 | 192.168.1.1 | Mở web GUI của NC và chạy Python |
| PC2 | NIC | 192.168.2.10/24 | 192.168.2.1 | Host để controller phát hiện |
| Tài khoản | Dùng cho | Giá trị |
|---|---|---|
| Quản trị NC | Đăng nhập web GUI và xin ticket API | admin / Vne@2026 |
| CLI trên R1, SW1 | NC đăng nhập vào thiết bị khi discovery | netadmin / Net@2026, enable secret class |
| Từ | Cổng | Đến | Cổng | Cáp |
|---|---|---|---|---|
| R1 | G0/0 | SW1 | Gi0/1 | Copper Straight-Through |
| SW1 | Fa0/1, Fa0/2 | NC, PC-DEV | GigabitEthernet0, FastEthernet0 | Copper Straight-Through |
| R1 | G0/1 | PC2 | FastEthernet0 | Copper Cross-Over |
⚙️ Các bước thực hiện
⚠️ Network Controller trong Packet Tracer là bản mô phỏng rút gọn. Tên menu và một số trường JSON có thể khác nhẹ giữa các phiên bản — hãy dựa vào những gì phiên bản của bạn hiển thị. Bài viết theo Packet Tracer 8.x.
⚙️ Bước 1 — Dựng sơ đồ và cấu hình thiết bị
Kéo ra 1 router 2911, 1 switch 2960-24TT, 1 Network Controller (mục End Devices), 2 PC. Nối cáp, đặt IP cho NC (tab Config → GigabitEthernet0 và Settings) và hai PC. Dán cấu hình — tài khoản này để controller đăng nhập vào thiết bị:
hostname R1
enable secret class
username netadmin privilege 15 secret Net@2026
ip domain-name vnexperts.local
crypto key generate rsa general-keys modulus 1024
line vty 0 4
login local
transport input all
interface gigabitEthernet 0/0
ip address 192.168.1.1 255.255.255.0
no shutdown
interface gigabitEthernet 0/1
ip address 192.168.2.1 255.255.255.0
no shutdown
end
hostname SW1
enable secret class
username netadmin privilege 15 secret Net@2026
ip domain-name vnexperts.local
crypto key generate rsa general-keys modulus 1024
line vty 0 15
login local
transport input all
interface vlan 1
ip address 192.168.1.2 255.255.255.0
no shutdown
ip default-gateway 192.168.1.1
end
Kiểm tra: PC-DEV ping được 192.168.1.10, R1, SW1 và PC2. Cho PC2 ping 192.168.2.1 một lần để R1 biết tới PC2.
⚙️ Bước 2 — Khởi tạo Network Controller
- PC-DEV → Desktop → Web Browser →
http://192.168.1.10. - Lần đầu, NC yêu cầu tạo tài khoản quản trị: Username
admin, Password và ConfirmVne@2026→ SETUP, rồi đăng nhập. - Vào mục Provisioning → phần Credentials: tạo một CLI credential — username
netadmin, passwordNet@2026, enable passwordclass. - Cũng trong Provisioning → Discovery → thêm discovery mới: kiểu IP Range từ
192.168.1.1tới192.168.1.2, chọn credential vừa tạo → lưu và chạy. - Đợi một lát (bấm Fast Forward Time nếu cần). Danh sách thiết bị phải có R1 và SW1 ở trạng thái kết nối được.
⚙️ Bước 3 — Xem tài liệu API
Trong giao diện NC, mở mục tài liệu API (API Docs). Tìm 3 mục bạn sắp dùng:
| Mục đích | Phương thức | Đường dẫn | Cần ticket? |
|---|---|---|---|
| Xin ticket | POST | /api/v1/ticket |
Không — gửi username/password trong body |
| Danh sách thiết bị mạng | GET | /api/v1/network-device |
Có — header X-Auth-Token |
| Đếm số thiết bị | GET | /api/v1/network-device/count |
Có |
| Danh sách host | GET | /api/v1/host |
Có |
⚙️ Bước 4 — Xin ticket bằng Python
PC-DEV → Programming → tạo project mới, chọn ngôn ngữ Python (mẫu trống) → mở file main.py, gõ:
import requests
import json
NC = "http://192.168.1.10/api/v1"
body = {"username": "admin", "password": "Vne@2026"}
r = requests.post(NC + "/ticket", data=json.dumps(body),
headers={"Content-Type": "application/json"}, timeout=30)
print("Status:", r.status_code)
print(r.text)
Bấm Run. Kết quả có mã trạng thái thành công (2xx) và một JSON dạng:
{
"response": {
"idleTimeout": 900,
"serviceTicket": "<chuỗi ticket>",
"sessionTimeout": 3600
},
...
}
Ticket chỉ dùng được trong một khoảng thời gian (idle 900 giây, tối đa 3600 giây). Hết hạn thì xin lại.
⚙️ Bước 5 — Gọi API lấy thiết bị và host
Thêm vào cuối main.py:
ticket = json.loads(r.text)["response"]["serviceTicket"]
hdr = {"X-Auth-Token": ticket}
r = requests.get(NC + "/network-device/count", headers=hdr, timeout=30)
print("So thiet bi:", r.text)
r = requests.get(NC + "/network-device", headers=hdr, timeout=30)
print(r.text)
r = requests.get(NC + "/host", headers=hdr, timeout=30)
print(r.text)
Chạy lại. Ba kết quả lần lượt là:
- Số thiết bị: trường
responsecó giá trị 2 (R1, SW1). - Danh sách thiết bị:
responselà một mảng, mỗi phần tử là một object mô tả một thiết bị — tìm trường chứa hostname và địa chỉ IP quản trị. - Danh sách host: các máy đầu cuối controller biết được (ví dụ PC2, PC-DEV) kèm IP, MAC, thiết bị và cổng chúng đang nối vào.
⚙️ Bước 6 — Thử gọi API không có ticket
Thêm một dòng gọi thiếu header:
r = requests.get(NC + "/network-device", timeout=30)
print("Khong co ticket:", r.status_code)
Controller từ chối, trả về mã lỗi nhóm 4xx (thường là 401 — chưa xác thực). Đây là lý do mọi lời gọi phải kèm ticket.
🔍 Kiểm tra kết quả
| # | Kiểm tra | Thao tác | Kết quả mong đợi |
|---|---|---|---|
| 1 | Discovery | Danh sách thiết bị trên web GUI của NC | Có R1, SW1 |
| 2 | Xin ticket | Bước 4 | Mã 2xx; JSON có serviceTicket |
| 3 | Đếm thiết bị | GET /network-device/count |
response = 2 |
| 4 | Danh sách thiết bị, host | GET /network-device, /host |
Mảng JSON có R1, SW1; có PC2 |
| 5 | Thiếu ticket | Bước 6 | Mã lỗi 4xx |
🛠️ Lỗi thường gặp & cách xử lý
| Triệu chứng | Nguyên nhân thường gặp | Cách kiểm tra & sửa |
|---|---|---|
| Discovery không thấy thiết bị | Sai CLI credential, thiết bị chưa có login local trên VTY, hoặc NC không ping được thiết bị |
Thử ping từ PC-DEV; kiểm tra username/enable secret trên thiết bị |
| Xin ticket báo lỗi | Sai tài khoản quản trị NC, thiếu header Content-Type, body không phải JSON | Dùng json.dumps(body) và header application/json |
KeyError khi lấy serviceTicket |
Xin ticket thất bại nên JSON không có trường này | In r.status_code và r.text trước khi tách trường |
| Lời gọi đang chạy tốt bỗng báo 401 | Ticket hết hạn | Xin ticket mới |
| Host list trống | Host chưa gửi gói nào nên thiết bị chưa học được | Cho PC2 ping gateway rồi gọi lại |
🏆 Thử thách mở rộng
- Thay vì in cả JSON, sửa script để in mỗi thiết bị một dòng: hostname và IP quản trị.
- Gọi API của Packet Tracer từ máy tính thật của bạn (curl hoặc Postman) thay vì từ PC trong Packet Tracer.
👉 Gợi ý đáp án
Thử thách 1: Duyệt mảng response. Tên trường dưới đây theo kiểu API của APIC-EM — nếu JSON trên phiên bản PT của bạn dùng tên khác, đổi cho khớp:
devices = json.loads(r.text)["response"]
for d in devices:
print(d["hostname"], d["managementIpAddress"])
Thử thách 2: Trong Packet Tracer bật cho phép truy cập REST API từ bên ngoài (Options → Preferences), rồi trên NC bật Real World Access với HTTP Port, ví dụ 58000. Từ máy thật (chỉ localhost được phép):
curl -X POST localhost:58000/api/v1/ticket -H "content-type: application/json" -d "{\"username\":\"admin\",\"password\":\"Vne@2026\"}"
Sau đó dùng ticket nhận được trong header X-Auth-Token để GET localhost:58000/api/v1/network-device.
💬 Hỏi & Đáp nhanh
| Phương thức HTTP | Ý nghĩa (CRUD) | Ví dụ |
|---|---|---|
| POST | Create — tạo mới | Xin ticket, thêm thiết bị |
| GET | Read — đọc | Lấy danh sách thiết bị |
| PUT / PATCH | Update — cập nhật | Sửa thông tin thiết bị |
| DELETE | Delete — xoá | Xoá thiết bị, thu hồi ticket |
❓ Mã trạng thái nào hay gặp?
✅ 2xx thành công (200 OK, 201 Created). 4xx lỗi phía người gọi (400 sai yêu cầu, 401 chưa xác thực, 403 không có quyền, 404 không tìm thấy). 5xx lỗi phía máy chủ (500).
❓ "Northbound API" là gì?
✅ API mà controller mở ra cho ứng dụng, script phía trên gọi vào — chính là REST API trong bài. "Southbound" là cách controller nói chuyện xuống thiết bị (ở đây là đăng nhập CLI; ngoài thực tế còn NETCONF, RESTCONF, OpenFlow…).
❓ Có phải học thuộc đoạn Python này cho đề thi?
⚠️ Không. CCNA yêu cầu hiểu REST API (phương thức, mã trạng thái, xác thực bằng token) và đọc được JSON. Viết script là để thấy tận tay các khái niệm đó.
📝 Bài tập đánh giá
Câu 1: Script cần lấy danh sách thiết bị từ controller. Phương thức HTTP nào phù hợp?
- A. POST
- B. GET
- C. PUT
- D. DELETE
Câu 2: Lời gọi API trả về mã 401. Nguyên nhân khả dĩ nhất?
- A. Đường dẫn API không tồn tại
- B. Máy chủ bị lỗi nội bộ
- C. Thiếu hoặc sai token xác thực
- D. Yêu cầu thành công nhưng không có dữ liệu
👉 Đáp án
- Câu 1: B — GET dùng để đọc dữ liệu.
- Câu 2: C — A là 404, B là 500, D vẫn là 2xx.
💡 Output trong bài là output mẫu trên Packet Tracer, trên máy bạn có thể khác một chút (ví dụ địa chỉ MAC).
📚 Bài viết thuộc khóa học CCNA của VNExperts
🧭 Điều hướng
| ⬅️ Bài trước | 🏠 Mục lục khóa học | Bài kế tiếp ➡️ |
|---|---|---|
| Bài 90: REST API cơ bản — cách network device "nói chuyện" qua API | Mục lục khóa học CCNA | Bài 91: JSON & YAML — định dạng dữ liệu dùng trong automation |