I blogg #5 av CCIE Automation-reisen flyttes fokuset til nettverksverifisering og CI/CD. Ved hjelp av pyATS og GitLab CI bygges en pipeline som automatiserer prechecks, utrulling og postchecks, og sikrer repeterbare og pålitelige endringer i nettverket.
![<span id="hs_cos_wrapper_name" class="hs_cos_wrapper hs_cos_wrapper_meta_field hs_cos_wrapper_type_text" style="" data-hs-cos-general-type="meta_field" data-hs-cos-type="text" >[Min reise mot CCIE Automation #5] Bygging av nettverkspipelines for pålitelige endringer med pyATS og GitLab CI</span>](https://sicra.no/hs-fs/hubfs/two_guys_working_on_a_computer.jpg?width=1024&height=576&name=two_guys_working_on_a_computer.jpg)
(Denne artikkelen var tidligere en del av Bluetree.no. Siden Sicra og Bluetree har slått seg sammen, er nå innhold fra Bluetree overført til Sicra.)
[Min reise mot CCIE Automation #5] Bygging av nettverkspipelines for pålitelige endringer med pyATS og GitLab CI er del av en pågående CCIE Automation-serie. I forrige innlegg automatiserte jeg nettverksoppdagelse og rapportering med Python og Ansible. Denne gangen fokuserer jeg på verifisering av nettverk og CI/CD ved hjelp av pyATS og GitLab CI.
Etter å ha jobbet med Ansible i blogg #4 ønsket jeg å bevege meg over i noe som ligger nærmere nettverksverifisering og CI/CD-integrasjon.
Det er her pyATS og GitLab CI kommer inn.
pyATS er Ciscos Python-rammeverk for testing og validering av nettverksenheter. Det lar deg blant annet:
Med andre ord: i stedet for å lese CLI-output manuelt, kan koden faktisk forstå nettverkets tilstand.
GitLab CI lar oss kjøre pipelines hver gang vi pusher kode eller trigger jobber manuelt.
I stedet for å kjøre prechecks manuelt i et lab- eller produksjonsnettverk, lar vi GitLab:
Starte en container med pyATS
Koble til enheter basert på inventory- og testbed-filer
Kjøre verifiseringsjobber
Samle resultater og gjøre dem tilgjengelige som artifacts
Dette gir DevOps-lignende repeterbarhet også innen nettverksdrift.
Jeg bygget en GitLab CI-pipeline som består av fire steg:
Setup
Henter alle enheter fra Inventory API-et (tjenesten laget en tidligere gang, se GitLab-repositoriet) og genererer en pyATS testbed-fil som brukes i de neste stegene.
Prechecks
Verifiserer at syslog-servere er konfigurert.
Deploy
Ruller ut syslog-konfigurasjon.
Postchecks
Verifiserer at alle syslog-servere faktisk er konfigurert.
Pipelinen trigges ved å opprette en pipeline med definerte variabler:

Deretter kjøres de ulike stegene automatisk:

For hvert steg kan man åpne logger og se detaljer om hva som skjer. I precheck-steget vises for eksempel en advarsel. Ved å åpne precheck-loggen ser man at noen tester har feilet:

Tre av fire syslog-servere som skal rulles ut i neste steg finnes ikke i gjeldende konfigurasjon på nettverksenhetene.
Jeg har også lagt til at testresultater vises direkte i GitLab sitt webgrensesnitt.

Følgende filer og mappestruktur brukes:
pipelines/jobs/add_syslog/I tillegg er følgende filer oppdatert:
La oss bryte det ned steg for steg.
Filen .gitlab-ci.yml binder det hele sammen og definerer hvordan pipelinen skal kjøres. Jeg har fjernet deler av koden her for å kun vise relevante deler – se GitLab-repositoriet for komplett fil.
stages:
- setup
- precheck
- deploy
- postcheck
# This trigger should only be triggered when manually creating a pipeline in Gitlab Web UI
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "web"
when: always
- when: never
...
# Set default image to run by gitlab runner with the required software
default:
image: python:3.9-slim
before_script:
...
- apt-get update
- apt-get install -y --no-install-recommends openssh-client iputils-ping
...
- pip install --upgrade pip
- pip install -r pipelines/requirements.txt
# Setup stage runs a script that gets devices from InventoryAPI and generates a testbed file for the next stages
setup:
stage: setup
tags: ["nautix"]
variables:
DEVICE_USERNAME: $DEVICE_USERNAME
DEVICE_PASSWORD: $DEVICE_PASSWORD
SYSLOG_SERVERS: $SYSLOG_SERVERS
script:
- python pipelines/get_devices_from_inventory.py --outfile build/testbed.yml
artifacts:
paths:
- build/testbed.yml
expire_in: 1 week
# Precheck stage allows tests to fail, as it only check if any of the syslog servers are configured
precheck:
stage: precheck
needs: ["setup"]
tags: ["nautix"]
allow_failure: true
script:
- mkdir -p build/reports
- pyats run job pipelines/jobs/$JOB_NAME/precheck_job.py --testbed build/testbed.yml --xunit build/reports/precheck
artifacts:
when: always
paths:
- build/reports/
reports:
junit:
- build/reports/precheck/*.xml
# Deploy stage will configure the devices in testbed file with the syslog servers provided
deploy:
stage: deploy
needs:
- job: setup
artifacts: true
- job: precheck
tags: ["nautix"]
script:
- mkdir -p build/reports
- pyats run job pipelines/jobs/$JOB_NAME/deploy_job.py --testbed build/testbed.yml --xunit build/reports/deploy
artifacts:
when: always
paths:
- build/reports/
reports:
junit:
- build/reports/deploy/*.xml
# Postcheck stage will verify if the syslog servers are configured. It will mark the pipeline as failed if any of the syslog servers are missing
postcheck:
stage: postcheck
needs:
- job: setup
artifacts: true
- job: deploy
- job: precheck
tags: ["nautix"]
script:
- mkdir -p build/reports
- pyats run job pipelines/jobs/$JOB_NAME/postcheck_job.py --testbed build/testbed.yml --xunit build/reports/postcheck
artifacts:
when: always
paths:
- build/reports/
reports:
junit:
- build/reports/postcheck/*.xml
Først verifiseres det om nødvendige syslog-servere allerede er konfigurert. Her brukes to løkker: én på funksjonsnivå som itererer over syslog-serverne som er angitt, og én indre løkke som itererer over alle enheter i testbed-filen.

Dette scriptet kobler seg til enhetene og pusher syslog-konfigurasjon. pyATS-testen har samme struktur som precheck-testen, med Common Setup og Common Cleanup. For selve konfigurasjonen brukes device.configure()-kommandoen.
Merk: Deploy-steget kan enkelt byttes ut med en annen konfigurasjonsmetode, for eksempel NETCONF eller Ansible. Siden GitLab CI kaller en funksjon (deploy_job.py), kan denne erstattes med annen logikk uten å endre pipelinen.

Etter utrulling kjøres samme test som i precheck. Hvis en syslog-server fortsatt mangler, feiler pipelinen.
Dette gir en komplett før–etter-valideringssløyfe.

Når en pipeline trigges, plukker en GitLab runner opp jobben og kjører de ulike stegene. For at runneren skulle kunne hente enheter fra Inventory API-et, måtte jeg legge til en GitLab runner i docker-compose-filen og kjøre den lokalt.

For å gjøre GitLab runneren i stand til å kommunisere med GitLab Cloud og hente pipeline-jobber, måtte den registreres. I tillegg måtte jeg gjøre et «hack» for at containeren som runneren bruker til å kjøre stegene, skulle kunne nå Inventory.
# Register gitlab runner (You need to have this repo in your own gitlab account)
# GitLab instance URL: https://gitlab.com or your self-hosted URL
# Registration token: from your project/group in GitLab → Settings → CI/CD → Runners
# Description: nautix
# Executor: docker
# Default Docker image: python:3.9-slim
docker exec -it gitlab-runner gitlab-runner register
# Allow gitlab runner CI job container to talk with the Nautix services
sed -i '/\[runners.docker\]/a \ network_mode = "ccie-automation_default"' services/gitlab-runner/config/config.toml
I stedet for å bare «håpe» at endringer er korrekt utført, har vi nå:
Dette er NetDevOps i praksis.
Jeg har lagt dette nye brukstilfellet inn i Nautix-diagrammet.

I blogg #6 vil jeg fokusere på Terraform:
Blueprint item 2.8
Bruke Terraform til å tilstandsbasert administrere infrastruktur, basert på tilgjengelig dokumentasjon
2.8.a Løkkekontroll
2.8.b Ressursgrafer
2.8.c Bruk av variabler
2.8.d Henting av ressurser
2.8.e Provisionering av ressurser
2.8.f Håndtering av tilstand for provisjonerte ressurser
[Min reise mot CCIE Automation #1] Introduksjon + bygging av en Python CLI-applikasjon
[Min reise mot CCIE Automation #2] Inventory REST API og mikrotjenestearkitektur
[Min reise mot CCIE Automation #3] Orchestration API og NETCONF
[Min reise mot CCIE Automation #9] Anvendelse av OWASP Secure Coding Practices
[Min reise mot CCIE Automation #10] Fra Docker Compose til Kubernetes



