Završni praktični zadatak – Modul 24 – Automatizacija mreža
Cilj
Samostalno napraviti mali, bezbedan i dokumentovan skup alata za automatizaciju laboratorijske mreže sa tri rutera, koji svakodnevno proverava, čuva i usklađuje konfiguraciju — objedinjujući sve veštine ovog modula.
Scenario
Firma „Nova Mreža" planira da automatizuje upravljanje mrežom. Pre bilo kakvog rada u produkciji, uprava traži da se u laboratoriji dokaže da su alati pouzdani, bezbedni i razumljivi i drugim administratorima. Laboratorija ima tri VyOS rutera: dva u „centrali" i jedan u „poslovnici".
Zahtevi zadatka
- Laboratorija: tri VyOS rutera (VYOS1, VYOS2, VYOS3) i Ubuntu Server kontrolni računar u Host-only mreži, sa nalogom
netautona svim ruterima. - Izvor istine:
uredjaji.yamlsa svim ruterima i poljimaime,host,device_type,lokacija(centralailiposlovnica) iloopback. - Provera dostupnosti: skripta koja proverava ping i SSH i pravi JSON izveštaj sa vremenom provere; uređaje proverava paralelno.
- Backup: skripta koja čuva konfiguracije sa datumom i vremenom, prikazuje razlike u odnosu na prethodni backup i završava se greškom (izlazni kod različit od 0) ako backup nije uspeo za bar jedan uređaj.
- Standard: Ansible playbook koji na svim ruterima podešava vremensku zonu, poruku pre prijave, LLDP i opis upravljačkog interfejsa, sa lozinkom u Ansible Vault-u. Dokažite idempotentnost (drugo pokretanje:
changed=0). - Provera usklađenosti: Python skripta koja na svakom ruteru proverava da li
show configuration commandssadrži sve linije standarda, i pravi JSON izveštaj sa listom linija koje nedostaju po uređaju. Skripta samo izveštava — ne menja konfiguraciju. - Bezbedno uvođenje: dokumentujte uvođenje standarda redosledom
--check --diff→--limitna jedan ruter poslovnice → svi ruteri. Na jednom ruteru demonstrirajtecommit-confirmsa automatskim povratkom. - Git i dokumentacija: projekat u Git repozitorijumu sa najmanje pet smislenih commit-ova,
.gitignore-om iREADME.mdfajlom koji objašnjava namenu, pokretanje svake skripte i playbook-a i način zadavanja kredencijala.
Ograničenja i pravila
- Nijedna lozinka ni API ključ ne sme se naći u kodu, YAML fajlovima (osim šifrovanog Vault fajla) ni u Git istoriji.
- Sve skripte moraju nastaviti rad kada jedan uređaj nije dostupan i jasno prijaviti koji uređaj nije obrađen.
- Rad isključivo nad sopstvenim laboratorijskim uređajima.
Šta predati
- Ceo projekat (Git repozitorijum bez foldera
venv/ibackup/). - Izlaze pokretanja svih skripti i playbook-a (tekstualni fajl ili snimci ekrana), uključujući drugo pokretanje playbook-a (
changed=0). - JSON izveštaje o dostupnosti i usklađenosti — jedan u kome je sve usklađeno, i jedan posle namerne ručne izmene na jednom ruteru.
- Kratak opis demonstracije
commit-confirm-a.
Kriterijumi ocenjivanja
| Kriterijum | Broj poena |
|---|---|
Laboratorija i izvor istine (uredjaji.yaml) | 10 |
| Paralelna provera dostupnosti sa JSON izveštajem | 10 |
| Backup sa razlikama i ispravnim izlaznim kodom | 15 |
| Ansible playbook sa Vault-om i dokazanom idempotentnošću | 20 |
| Skripta za proveru usklađenosti | 20 |
Bezbedno uvođenje (--check, --limit, commit-confirm) | 10 |
Git, .gitignore, README.md, bez tajni u kodu | 15 |
| Ukupno | 100 |
Rešenje
Kompletno rešenje dostupno je u /resenja/modul-24/08-zavrsni-zadatak-resenje.md.
📖 Prikaži rešenje
Rešenje završnog zadatka – Modul 24
Ovo je jedno ispravno rešenje. Prihvataju se i drugačija imena fajlova i struktura koda, ako su ispunjeni svi zahtevi i pravila o kredencijalima.
Struktura projekta
nova-mreza-automatizacija/
├── .gitignore
├── README.md
├── uredjaji.yaml
├── zajednicko.py
├── provera_dostupnosti.py
├── backup.py
├── uskladjenost.py
└── ansible/
├── ansible.cfg
├── inventory.ini
├── group_vars/vyos/vars.yml
├── group_vars/vyos/vault.yml (šifrovano)
└── standard.yml
.gitignore:
venv/
backup/
izlazi/
*.json
.env
Izvor istine – uredjaji.yaml
---
uredjaji:
- ime: VYOS1
host: 192.168.56.11
device_type: vyos
lokacija: centrala
loopback: 10.255.255.11/32
- ime: VYOS2
host: 192.168.56.12
device_type: vyos
lokacija: centrala
loopback: 10.255.255.12/32
- ime: VYOS3
host: 192.168.56.13
device_type: vyos
lokacija: poslovnica
loopback: 10.255.255.13/32
zajednicko.py je isti kao u laboratorijskoj vežbi (Korak 5).
Paralelna provera dostupnosti – provera_dostupnosti.py
import json
import socket
import subprocess
from concurrent.futures import ThreadPoolExecutor
from datetime import datetime
from zajednicko import ucitaj_uredjaje
def ping(ip):
rezultat = subprocess.run(["ping", "-c", "2", "-W", "1", ip], capture_output=True)
return rezultat.returncode == 0
def port_otvoren(ip, port=22, timeout=2):
try:
with socket.create_connection((ip, port), timeout=timeout):
return True
except OSError:
return False
def proveri(u):
return {"ime": u["ime"], "host": u["host"], "lokacija": u["lokacija"],
"ping": ping(u["host"]), "ssh": port_otvoren(u["host"])}
with ThreadPoolExecutor(max_workers=10) as izvrsilac:
rezultati = list(izvrsilac.map(proveri, ucitaj_uredjaje()))
for r in rezultati:
print(f"{r['ime']:6} {r['lokacija']:11} ping={'OK' if r['ping'] else 'NE'} ssh={'OK' if r['ssh'] else 'NE'}")
with open("dostupnost.json", "w", encoding="utf-8") as f:
json.dump({"vreme": datetime.now().isoformat(timespec="seconds"), "uredjaji": rezultati},
f, indent=2, ensure_ascii=False)
Backup – backup.py
Isti kao u laboratorijskoj vežbi (Korak 8). Ispunjava zahteve: vremenska oznaka u nazivu, difflib razlike u odnosu na poslednji prethodni backup, nastavak rada kada uređaj nije dostupan, i raise SystemExit(...) na kraju. SystemExit sa tekstom završava proces sa izlaznim kodom 1. Provera: python backup.py; echo $?.
Ansible standard – ansible/standard.yml
ansible.cfg, inventory.ini (sa vyos3), group_vars/vyos/vars.yml i šifrovani vault.yml su kao u Koraku 11 vežbe.
---
- name: Standard Nova Mreža
hosts: vyos
gather_facts: false
tasks:
- name: Standardna podešavanja
vyos.vyos.vyos_config:
lines:
- set system time-zone 'Europe/Belgrade'
- set system login banner pre-login 'Samo za ovlascene korisnike'
- set service lldp interface all
- set interfaces ethernet eth0 description 'MGMT-HOSTONLY'
save: true
Provera usklađenosti – uskladjenost.py
import json
from datetime import datetime
from netmiko import ConnectHandler
from netmiko.exceptions import NetmikoAuthenticationException, NetmikoTimeoutException
from zajednicko import parametri_veze, ucitaj_uredjaje
STANDARD = [
"set system time-zone 'Europe/Belgrade'",
"set system login banner pre-login 'Samo za ovlascene korisnike'",
"set service lldp interface all",
"set interfaces ethernet eth0 description 'MGMT-HOSTONLY'",
]
def normalizuj(red):
return red.replace("'", "").strip()
izvestaj = {"vreme": datetime.now().isoformat(timespec="seconds"), "uredjaji": {}}
for u in ucitaj_uredjaje():
try:
with ConnectHandler(**parametri_veze(u)) as veza:
izlaz = veza.send_command("show configuration commands")
except (NetmikoTimeoutException, NetmikoAuthenticationException) as greska:
izvestaj["uredjaji"][u["ime"]] = {"greska": type(greska).__name__}
print(f"{u['ime']}: NIJE PROVEREN — {type(greska).__name__}")
continue
konfiguracija = {normalizuj(red) for red in izlaz.splitlines()}
nedostaje = [linija for linija in STANDARD if normalizuj(linija) not in konfiguracija]
izvestaj["uredjaji"][u["ime"]] = {"uskladjen": not nedostaje, "nedostaje": nedostaje}
print(f"{u['ime']}: {'USKLAĐEN' if not nedostaje else 'NEDOSTAJE ' + str(len(nedostaje)) + ' linija'}")
with open("uskladjenost.json", "w", encoding="utf-8") as f:
json.dump(izvestaj, f, indent=2, ensure_ascii=False)
Skripta samo čita konfiguraciju (send_command) i nikada ne šalje izmene. Normalizacija uklanja navodnike, kao što to radi i modul vyos_config, pa se ista linija sa navodnicima i bez njih smatra jednakom.
Primer izveštaja posle ručnog brisanja LLDP-a na VYOS3:
{
"vreme": "2026-09-25T14:02:11",
"uredjaji": {
"VYOS1": {"uskladjen": true, "nedostaje": []},
"VYOS2": {"uskladjen": true, "nedostaje": []},
"VYOS3": {"uskladjen": false, "nedostaje": ["set service lldp interface all"]}
}
}
Bezbedno uvođenje – dokumentovan redosled
ansible-playbook standard.yml --ask-vault-pass --check --diff— pregled linija koje bi bile poslate na svaki ruter; ništa nije promenjeno.ansible-playbook standard.yml --ask-vault-pass --limit vyos3— primena samo na ruter poslovnice; proverauskladjenost.py(VYOS3 usklađen) i ručna SSH prijava (pristup radi).ansible-playbook standard.yml --ask-vault-pass— primena na sve;changed=0za vyos3,changed=1za vyos1 i vyos2.- Ponovljeno pokretanje:
changed=0za sva tri — idempotentnost dokazana.
Demonstracija commit-confirm (konzola VYOS2):
configure
set interfaces ethernet eth0 address 192.168.56.99/24
delete interfaces ethernet eth0 address 192.168.56.12/24
commit-confirm 2
Upravljačka adresa je namerno promenjena, pa kontrolni računar gubi pristup na 192.168.56.12 (provera_dostupnosti.py: VYOS2 ping=NE). Izmena nije potvrđena (confirm) niti sačuvana (save). Posle dva minuta VYOS2 se vraća na prethodnu konfiguraciju (zavisno od verzije restartom ili ponovnim učitavanjem), pa provera_dostupnosti.py ponovo prikazuje ping=OK i ssh=OK.
README.md projekta (skraćeno)
# Automatizacija laboratorijske mreže Nova Mreža
Samo za laboratorijske uređaje iz `uredjaji.yaml`.
## Priprema
python3 -m venv venv && source venv/bin/activate
pip install netmiko pyyaml ansible
export NET_USER=netauto
read -s -p "Lozinka: " NET_PASS; echo; export NET_PASS
## Skripte
- provera_dostupnosti.py — ping i SSH za sve uređaje, izveštaj dostupnost.json
- backup.py — backup u backup/ sa razlikama; izlazni kod 1 ako neki uređaj nije obrađen
- uskladjenost.py — samo čita konfiguraciju; izveštaj uskladjenost.json
## Ansible
cd ansible
ansible-playbook standard.yml --ask-vault-pass --check --diff
ansible-playbook standard.yml --ask-vault-pass --limit <ruter>
ansible-playbook standard.yml --ask-vault-pass
## Kredencijali
Lozinke se ne upisuju u fajlove. Lozinka za Ansible je u ansible/group_vars/vyos/vault.yml (Ansible Vault).
Primer Git istorije
a1c3e02 Dodat .gitignore i README
b7d41f9 Izvor istine: uredjaji.yaml sa tri rutera
c2e9a10 Paralelna provera dostupnosti sa JSON izveštajem
d58f3b4 Backup sa razlikama i izlaznim kodom
e91a7c6 Ansible inventory, Vault i standard.yml
f03b8d2 Provera usklađenosti sa standardom
Provera da tajne nisu u istoriji: git log -p | grep -i -E "pass|lozinka|key" ne sme pokazati nijednu vrednost lozinke ili ključa (dozvoljena su imena promenljivih poput NET_PASS i šifrovan sadržaj vault.yml).
Napomena za ocenjivača
Ključno je da:
- skripte nastavljaju rad kada jedan uređaj nije dostupan;
backup.pyvraća izlazni kod različit od 0 kada backup nije uspeo za bar jedan uređaj;- provera usklađenosti ne menja konfiguraciju;
- drugo pokretanje playbook-a ima
changed=0; - u repozitorijumu i Git istoriji nema nijedne lozinke ni API ključa kao običnog teksta.