💾

Zadaci za samostalan rad – Modul 24 – Automatizacija mreža

Rešenja se nalaze u /resenja/modul-24/05-zadaci-resenja.md — pokušajte da rešite zadatke samostalno pre nego što pogledate rešenja. Sve zadatke izvodite isključivo u sopstvenoj laboratoriji.

Nivo: Početni

Zadatak 1. Navedite tri koristi i dva rizika automatizacije mreže.

Zadatak 2. Napišite Python rečnik koji opisuje svič NS-HQ-SW-01 sa adresom 10.10.99.2 i tipom cisco_ios, a zatim listu od dva takva rečnika (drugi svič: NS-HQ-SW-02, 10.10.99.3). Kako biste iz liste pročitali adresu drugog sviča?

Zadatak 3. Prepišite sledeći YAML u JSON:

ruter:
  ime: VYOS1
  aktivan: true
  interfejsi:
    - eth0
    - eth1

Zadatak 4. Objasnite razliku između Paramiko-a i Netmiko-a. Zašto se za mrežne uređaje najčešće koristi Netmiko?

Nivo: Srednji

Zadatak 5. Napišite funkciju izvuci_verziju(izlaz) koja iz izlaza VyOS komande show version vraća tekst posle Version: (npr. VyOS 1.5-rolling-202509250021), ili None ako takvog reda nema.

Zadatak 6. Napišite skriptu koja čita fajl adrese.txt (jedna adresa po redu; prazne redove i redove koji počinju sa # preskače), za svaku adresu proverava TCP port 22 i rezultate upisuje u ssh_provera.csv sa kolonama adresa,ssh.

Zadatak 7. Pronađite i ispravite najmanje četiri problema u ovom kodu:

from netmiko import ConnectHandler

uredjaj = {"device_type": "cisco", "host": "10.10.99.2",
           "username": "admin", "password": "Admin123"}
veza = ConnectHandler(**uredjaj)
veza.send_command("interface GigabitEthernet0/1")
veza.send_command("description UPLINK")

Zadatak 8. Koji HTTP statusni kod očekujete u svakoj situaciji? (a) uspešno čitanje liste uređaja; (b) API ključ je pogrešan; (c) traženi uređaj ne postoji; (d) uspešno kreiran nov zapis; (e) greška u samom API servisu.

Zadatak 9. Napišite Ansible inventory (INI) sa grupom ruteri (dva Cisco IOS rutera: 10.20.0.1 i 10.20.0.2) i grupom svicevi (tri Cisco IOS sviča: 10.20.99.2–10.20.99.4), sa zajedničkim promenljivim za vezu i korisnika netauto, bez lozinke.

Nivo: Napredni

Zadatak 10. Kolega je napisao ovaj zadatak. Zašto nije idempotentan i kako biste ga prepravili?

- name: Opis porta
  vyos.vyos.vyos_command:
    commands:
      - configure
      - set interfaces ethernet eth1 description 'WAN'
      - commit

Zadatak 11. Treba izmeniti ACL za SSH pristup na 50 rutera. Opišite plan bezbednog uvođenja izmene korak po korak, koristeći mehanizme iz ovog modula.

Zadatak 12. Backup skripta treba da radi svake noći iz cron-a, kada niko ne može da unese lozinku. Uporedite tri načina obezbeđivanja kredencijala i preporučite jedan za produkciju.

Zadatak 13. API monitoring sistema vraća sledeći JSON. Napišite kod koji ispisuje nazive uređaja u statusu down i ukupan broj takvih uređaja.

{"uredjaji": [
  {"ime": "NS-HQ-SW-01", "status": "up"},
  {"ime": "NS-HQ-SW-02", "status": "down"},
  {"ime": "BG-BR-R-01", "status": "down"},
  {"ime": "BG-BR-SW-01", "status": "up"}
]}

Praktičan zadatak

Zadatak 14. Proširite laboratoriju trećim ruterom VYOS3 (192.168.56.13, loopback 10.255.255.13/32). Navedite sve fajlove koje menjate. Zatim napišite playbook lldp.yml koji na svim ruterima uključuje LLDP (set service lldp interface all, Modul 23), pokrenite ga dva puta i objasnite rezultat drugog pokretanja.

Zadatak zasnovan na izlazu komande

Zadatak 15. Posle pokretanja ansible-playbook standard.yml --ask-vault-pass dobijen je ovaj izlaz:

TASK [Vremenska zona i poruka posle prijave] ***********************
ok: [vyos1]
fatal: [vyos2]: FAILED! => {"changed": false, "msg": "[Errno None] Unable to connect to port 22 on 192.168.56.12"}

PLAY RECAP *********************************************************
vyos1  : ok=1  changed=0  unreachable=0  failed=0  skipped=0
vyos2  : ok=0  changed=0  unreachable=0  failed=1  skipped=0

(a) Šta rezultat za vyos1 govori o njegovoj konfiguraciji? (b) Koji su mogući uzroci greške za vyos2 i kojim redosledom ih proveravate? (c) Kako posle ispravke ponovo pokrećete playbook samo za vyos2?

📖 Prikaži rešenje

Rešenja zadataka za samostalan rad – Modul 24 – Automatizacija mreža

Nivo: Početni

Zadatak 1. Koristi: brzina i skalabilnost, konzistentnost konfiguracija, manje ljudskih grešaka, ponovljivost i dokumentovanost postupka (kod u Git-u). Rizici: greška se u trenutku širi na veliki broj uređaja; curenje kredencijala iz koda; izmena koja preseca upravljački pristup na svim uređajima odjednom.

Zadatak 2.

svic = {"ime": "NS-HQ-SW-01", "ip": "10.10.99.2", "device_type": "cisco_ios"}

svicevi = [
    {"ime": "NS-HQ-SW-01", "ip": "10.10.99.2", "device_type": "cisco_ios"},
    {"ime": "NS-HQ-SW-02", "ip": "10.10.99.3", "device_type": "cisco_ios"},
]
print(svicevi[1]["ip"])

Indeksi liste počinju od 0, pa je drugi svič svicevi[1].

Zadatak 3.

{
  "ruter": {
    "ime": "VYOS1",
    "aktivan": true,
    "interfejsi": ["eth0", "eth1"]
  }
}

Zadatak 4. Paramiko je niskonivoska SSH biblioteka: daje vezu i kanal, ali ne zna ništa o mrežnim uređajima. Netmiko je izgrađen iznad Paramiko-a i sam rešava prepoznavanje prompta, isključivanje paging-a, prelazak u privilegovani i konfiguracioni režim, čuvanje konfiguracije i razlike između proizvođača (device_type). Zato je za mrežne uređaje potrebno mnogo manje koda i manje je grešaka.

Nivo: Srednji

Zadatak 5.

def izvuci_verziju(izlaz):
    for red in izlaz.splitlines():
        if red.startswith("Version:"):
            return red.split(":", 1)[1].strip()
    return None

Zadatak 6.

import csv
import socket


def port_otvoren(ip, port=22, timeout=2):
    try:
        with socket.create_connection((ip, port), timeout=timeout):
            return True
    except OSError:
        return False


with open("adrese.txt", encoding="utf-8") as f:
    adrese = [red.strip() for red in f if red.strip() and not red.strip().startswith("#")]

with open("ssh_provera.csv", "w", encoding="utf-8", newline="") as f:
    pisac = csv.writer(f)
    pisac.writerow(["adresa", "ssh"])
    for adresa in adrese:
        pisac.writerow([adresa, port_otvoren(adresa)])

Zadatak 7. Problemi:

  1. device_type mora biti tačan tip platforme — cisco_ios, ne cisco.
  2. Lozinka je upisana u kod — treba je čitati iz promenljive okruženja ili sa getpass.
  3. Konfiguracione komande se šalju sa send_command() — treba send_config_set(), koja ulazi u konfiguracioni režim.
  4. Konfiguracija se ne čuva — nedostaje save_config().
  5. Nema obrade grešaka i veza se ne zatvara — koristiti with i try/except.
import os

from netmiko import ConnectHandler
from netmiko.exceptions import NetmikoAuthenticationException, NetmikoTimeoutException

uredjaj = {
    "device_type": "cisco_ios",
    "host": "10.10.99.2",
    "username": os.environ["NET_USER"],
    "password": os.environ["NET_PASS"],
}
try:
    with ConnectHandler(**uredjaj) as veza:
        veza.send_config_set(["interface GigabitEthernet0/1", "description UPLINK"])
        veza.save_config()
except (NetmikoTimeoutException, NetmikoAuthenticationException) as greska:
    print("Izmena nije primenjena:", type(greska).__name__)

Zadatak 8. (a) 200; (b) 401 (neki API-ji vraćaju 403); (c) 404; (d) 201; (e) 500.

Zadatak 9.

[ruteri]
r1 ansible_host=10.20.0.1
r2 ansible_host=10.20.0.2

[svicevi]
sw1 ansible_host=10.20.99.2
sw2 ansible_host=10.20.99.3
sw3 ansible_host=10.20.99.4

[mreza:children]
ruteri
svicevi

[mreza:vars]
ansible_connection=ansible.netcommon.network_cli
ansible_network_os=cisco.ios.ios
ansible_user=netauto
ansible_become=true
ansible_become_method=enable

Grupa mreza (sa :children) omogućava da se zajedničke promenljive zadaju jednom, a playbook se i dalje može pokrenuti samo nad ruteri ili svicevi.

Nivo: Napredni

Zadatak 10. Modul vyos_command je namenjen operativnim komandama (show ...). Ne poredi ništa sa trenutnom konfiguracijom, pa bi svako pokretanje ponovo slalo komande. Uz to, ulazak u konfiguracioni režim preko ovog modula ne radi ispravno. Ispravno rešenje koristi vyos_config, koji šalje samo ono što nedostaje, sam radi commit i po želji save:

- name: Opis porta
  vyos.vyos.vyos_config:
    lines:
      - set interfaces ethernet eth1 description 'WAN'
    save: true

Zadatak 11. Primer plana:

  1. Odobrena izmena (change management) sa vremenom primene, planom povratka i odgovornom osobom.
  2. Backup konfiguracija svih 50 rutera neposredno pre izmene.
  3. Test u laboratoriji (GNS3/VirtualBox) sa istom verzijom softvera; provera da novi ACL i dalje dozvoljava pristup sa kontrolnog računara i monitoring servera.
  4. ansible-playbook ... --check --diff nad svim ruterima — pregled tačnih izmena.
  5. Primena na jedan ruter (--limit), uz automatski povratak (commit-confirm na VyOS-u, odnosno reload in / configure replace na Cisco-u); provera pristupa iz nove SSH sesije, pa tek onda potvrda.
  6. Primena u grupama (npr. serial: 5) uz max_fail_percentage: 0 — prva greška zaustavlja uvođenje.
  7. Posle svake grupe: provera dostupnosti skriptom (ping + SSH) i monitoringom.
  8. Završni backup i zapis u dnevnik izmena.

Zadatak 12.

NačinPrednostiNedostaci
Fajl sa promenljivim okruženja (chmod 600)Jednostavno, van koda i Git-aLozinka je na disku kao običan tekst; ko dobije pristup nalogu, dobija i lozinku
Ansible Vault sa fajlom lozinke za VaultTajne su šifrovane u repozitorijumuLozinka za Vault je opet na disku, pa se problem samo pomera
Sistem za tajne (HashiCorp Vault i sl.)Centralno upravljanje, evidencija pristupa, rotacija, kratkotrajni kredencijaliSloženije uvođenje i održavanje

Preporuka za produkciju: poseban nalog sa minimalnim pravima (za backup je dovoljno čitanje), sa SSH ključem ili kredencijalima iz sistema za tajne, uz evidenciju svake upotrebe (AAA/TACACS+, Modul 16).

Zadatak 13.

import json

with open("status.json", encoding="utf-8") as f:
    podaci = json.load(f)

pali = [u["ime"] for u in podaci["uredjaji"] if u["status"] == "down"]
for ime in pali:
    print(ime)
print("Ukupno nedostupnih:", len(pali))

Izlaz: NS-HQ-SW-02, BG-BR-R-01, Ukupno nedostupnih: 2.

Praktičan zadatak

Zadatak 14. Izmene:

  • Nova VyOS VM u VirtualBox-u (Koraci 1–2), sa adresom 192.168.56.13 i nalogom netauto; ručni ssh netauto@192.168.56.13 sa kontrolnog računara radi prihvatanja ključa hosta.
  • uredjaji.yaml — nov element:
  - ime: VYOS3
    host: 192.168.56.13
    device_type: vyos
    loopback: 10.255.255.13/32
  • ansible/inventory.ini — nov red vyos3 ansible_host=192.168.56.13 u grupi [vyos].
  • Python skripte se ne menjaju jer čitaju uredjaji.yaml, a Vault se ne menja jer je lozinka ista.

lldp.yml:

---
- name: Uključivanje LLDP-a
  hosts: vyos
  gather_facts: false
  tasks:
    - name: LLDP na svim interfejsima
      vyos.vyos.vyos_config:
        lines:
          - set service lldp interface all
        save: true

Prvo pokretanje: changed=1 za sva tri rutera. Drugo pokretanje: changed=0 — LLDP je već uključen, pa modul ništa ne šalje (idempotentnost). Provera na ruteru: show lldp neighbors.

Zadatak zasnovan na izlazu komande

Zadatak 15. (a) ok=1 changed=0 znači da vyos1 već ima tražena podešavanja; playbook ga je proverio i ništa nije menjao. (b) Ansible nije uspeo da otvori TCP vezu na port 22 rutera vyos2. Redosled provere:

  1. Da li je VM vyos2 pokrenut i da li je adresa u inventory-ju tačna? (ping 192.168.56.12)
  2. Da li je port 22 dostupan? (nc -zv 192.168.56.12 22 ili provera_dostupnosti.py)
  3. Ako ping radi, a port ne: na konzoli rutera proveriti SSH servis (show configuration commands | match ssh) i eventualna firewall pravila na ruteru.
  4. Tek kada port radi, dolaze na red autentifikacija (lozinka u Vault-u, nalog netauto) i ključ hosta.

(c) ansible-playbook standard.yml --ask-vault-pass --limit vyos2