English · Ελληνικά
Το post του Ansible έστελνε config σαν κώδικα, αλλά από κάτω ακόμα έκανε screen-scraping το CLI. Το model-driven programmability είναι η ώριμη εκδοχή: δομημένα δεδομένα επικυρωμένα έναντι ενός schema, αλλαγμένα transactional, πάνω από NETCONF ή RESTCONF. Έτσι μιλάς στο σύγχρονο IOS-XE σαν API αντί να προσποιείσαι άνθρωπο σε τερματικό.
Η αυτοματοποίηση CLI — ακόμα και η καλή αυτοματοποίηση CLI — έχει μια οροφή: κάνεις parse output φτιαγμένο για ανθρώπους που δεν προοριζόταν ποτέ να γίνει parse, και στέλνεις γραμμές που είτε εφαρμόζονται καθαρά είτε αφήνουν τη συσκευή μισο-ρυθμισμένη. Το model-driven programmability αφαιρεί τις εικασίες. Το config και το state περιγράφονται από μοντέλα YANG (ένα schema)· διαβάζεις και γράφεις αυτά τα δομημένα δεδομένα πάνω από NETCONF (XML πάνω από SSH, port 830) ή RESTCONF (JSON/XML πάνω από HTTPS). Επειδή είναι επικυρωμένο με schema, μια άκυρη αλλαγή απορρίπτεται ολόκληρη αντί να εφαρμοστεί μισή, και το διάβασμα state σου δίνει καθαρό JSON αντί για output show για regex.
Το trade-off έναντι της προσέγγισης Ansible/CLI: το model-driven είναι πιο άκαμπτο και έχει καμπύλη μάθησης (πρέπει να μάθεις τα μοντέλα), αλλά είναι transactional, idempotent από τη φύση του, και πραγματικά προγραμματίσιμο. Για έναν στόλο που οδηγείς από λογισμικό — ένα pipeline NetBox-προς-δίκτυο, μια πύλη αυτοεξυπηρέτησης — αυτό είναι το interface που θέλεις. Απαιτεί σύγχρονο IOS-XE· το κλασικό IOS δεν το έχει.
ncclient (Python) ή/και curl01
Δύο χαρακτηριστικά, ένας χρήστης AAA. Το NETCONF ακούει σε SSH 830· το RESTCONF ταξιδεύει πάνω στον server HTTPS. Ενεργοποίησε ό,τι θα χρησιμοποιήσεις.
R1(config)# aaa new-model R1(config)# username auto privilege 15 secret <strong> # NETCONF πάνω από SSH (tcp/830): R1(config)# netconf-yang # RESTCONF πάνω από τον ασφαλή HTTP server (tcp/443): R1(config)# ip http secure-server R1(config)# restconf # Δώσε και στα δύο λίγα δευτερόλεπτα να αρχικοποιηθούν (το YANG stack ξεκινάει αργά). R1# show netconf-yang datastores
Τα NETCONF (830) και RESTCONF (443) είναι πλήρη κανάλια ρύθμισης — όλα όσα λέει το post θωράκισης management-plane ισχύουν εδώ. Περιόρισέ τα στον host αυτοματισμού σου με ACL control-plane/VTY, χρησιμοποίησε πραγματικό AAA (ιδανικά TACACS+), και ποτέ μην τα εκθέσεις σε οτιδήποτε μη έμπιστο. Ένα model-driven API είναι πιο ισχυρό από το CLI, που κόβει και προς τις δύο κατευθύνσεις.
02
Αν μπορείς να κάνεις curl, μπορείς να οδηγήσεις το RESTCONF. Διάβασε δομημένο state ως JSON, και κάνε PATCH μια αλλαγή με μικρό body — χωρίς session SSH, χωρίς scripts expect.
# READ: κάθε interface ως καθαρό JSON (μοντέλο ietf-interfaces). $ curl -sk -u auto:secret https://203.0.113.1/restconf/data/ietf-interfaces:interfaces \ -H 'Accept: application/yang-data+json' | jq . # CHANGE: όρισε ένα description στο Gi2 με PATCH (merge, idempotent). $ curl -sk -u auto:secret -X PATCH \ https://203.0.113.1/restconf/data/ietf-interfaces:interfaces/interface=GigabitEthernet2 \ -H 'Content-Type: application/yang-data+json' \ -d '{"ietf-interfaces:interface":{"name":"GigabitEthernet2","description":"uplink-to-core"}}' # Το να ξανατρέξεις το ίδιο PATCH είναι no-op — idempotent εκ κατασκευής.
03
Το πλεονέκτημα του NETCONF είναι το μοντέλο datastore: σε πλατφόρμες που υποστηρίζουν candidate config, στήνεις αλλαγές και τις κάνεις commit ατομικά — όλα ή τίποτα — που είναι ακριβώς αυτό που θέλεις για αλλαγές πολλών κομματιών.
from ncclient import manager m = manager.connect(host="203.0.113.1", port=830, username="auto", password="secret", hostkey_verify=False) # READ running config για ένα subtree μοντέλου: filt = "<interfaces xmlns='urn:ietf:params:xml:ns:yang:ietf-interfaces'/>" print(m.get_config(source="running", filter=("subtree", filt))) # WRITE: edit-config, μετά commit (πλατφόρμες με candidate): cfg = """<config><interfaces xmlns='urn:ietf:params:xml:ns:yang:ietf-interfaces'> <interface><name>GigabitEthernet2</name> <description>managed-by-netconf</description></interface> </interfaces></config>""" m.edit_config(target="candidate", config=cfg) m.commit() # ατομικό — απορρίπτεται ολόκληρο αν κάποιο κομμάτι είναι άκυρο
Υπάρχουν τρεις οικογένειες μοντέλων και θα τις συναντήσεις όλες: IETF (ietf-interfaces — φορητό, ελάχιστο κοινό παρονομαστή), OpenConfig (ουδέτερο ως προς τον κατασκευαστή, πλουσιότερο), και Cisco-IOS-XE-native (ό,τι μπορεί να κάνει το CLI, αλλά Cisco-specific). Ο φορητός κώδικας στοχεύει IETF/OpenConfig· ό,τι δεν καλύπτουν τα standard μοντέλα σε αναγκάζει στο native μοντέλο. Επίσης, δεν διαφημίζει κάθε πλατφόρμα/έκδοση εγγράψιμο datastore candidate — έλεγξε τις δυνατότητες που επιστρέφει η συσκευή στη σύνδεση και πέσε πίσω σε running αν χρειάζεται. Μην υποθέτεις· η συσκευή σου λέει τι υποστηρίζει.
04
Και τα δύο ρυθμίζουν τη συσκευή· είναι διαφορετικά εργαλεία για διαφορετικές δουλειές. Ορίστε η ειλικρινής σύγκριση ώστε να διαλέξεις σωστά.
| Διασταση | CLI / Ansible ios_config |
|---|---|
| Δεδομένα | Μη δομημένο κείμενο που κάνεις parse/παράγεις |
| Επικύρωση | Εφαρμόζεται γραμμή-γραμμή· μπορεί να μισο-εφαρμοστεί |
| Αναγνώσεις | output show → regex |
| Idempotency | Το μηχανικεύεις εσύ |
| Καλύτερο για | Γρήγορες νίκες, brownfield, οποιοδήποτε IOS |
| Διασταση | NETCONF / RESTCONF |
|---|---|
| Δεδομένα | Δομημένα, επικυρωμένα με schema (YANG) |
| Επικύρωση | Transactional — όλα ή τίποτα |
| Αναγνώσεις | Καθαρό JSON/XML |
| Idempotency | Εγγενές (merge στην επιθυμητή κατάσταση) |
| Καλύτερο για | Pipelines οδηγούμενα από λογισμικό, σύγχρονο IOS-XE |
Συμπερασματα
curl, μπορείς να διαβάζεις καθαρό JSON και να κάνεις PATCH idempotent αλλαγές.commit ατομικά, ώστε αλλαγές πολλών κομματιών να μην μισο-εφαρμόζονται ποτέ.show;Ένα push config που μισο-εφαρμόζεται και αφήνει μια συσκευή σε άγνωστη κατάσταση είναι χειρότερο από καθόλου αυτοματισμό. Χτίζω model-driven pipelines με NETCONF/RESTCONF σε υποδομές Cisco και MikroTik όπου οι αλλαγές είναι transactional — προσγειώνονται εντελώς ή καθόλου.
Κλεισε μια Discovery Call →