Automazione dei servizi di rete o come costruire un laboratorio virtuale utilizzando OpenDaylight, Postman e Vrnetlab

Automazione dei servizi di rete o come costruire un laboratorio virtuale utilizzando OpenDaylight, Postman e Vrnetlab

In questo articolo spiegherò come configurare OpenDaylight per lavorare con l'hardware di rete, e mostrerò come, utilizzando Postman e semplici richieste RESTCONF questo hardware può essere gestito. Non ci occuperemo dell'hardware fisico, ma invece costruiremo piccoli laboratori virtuali con un singolo router tramite Vrnetlab sopra Ubuntu 20.04 LTS.

Mostrerò la configurazione dettagliata prima con un esempio del router Juniper vMX 20.1R1.11, e poi confronteremo con la configurazione di Cisco xRV9000 7.0.2.

Contenuto

  • Competenze necessarie
  • Parte 1: discutiamo brevemente di OpenDaylight (in seguito ODL), Postman e Vrnetlab e perché ci servirà
  • Parte 2: descrizione del laboratorio virtuale
  • Parte 3: configuriamo OpenDaylight
  • Parte 4: configuriamo Vrnetlab
  • Parte 5: tramite Postman collegando il router virtuale (Juniper vMX) a ODL
  • Parte 6: otteniamo e modifichiamo la configurazione del router tramite Postman e ODL
  • Parte 7: aggiungiamo Cisco xRV9000
  • Conclusione
  • P.S.
  • Elenco della bibliografia

Competenze necessarie

Per evitare che l'articolo si trasformi in un lungo trattato, ho omesso alcuni dettagli tecnici (con riferimenti alla letteratura dove puoi leggerne).

Di conseguenza, vi propongo argomenti che sarebbe bene (ma quasi non è necessario) conoscere prima di leggere:

Parte 1: un po' di teoria

Automazione dei servizi di rete o come costruire un laboratorio virtuale utilizzando OpenDaylight, Postman e Vrnetlab

  • Una piattaforma SDN aperta per la gestione e l'automazione di vari tipi di reti, supportata da Linux Foundation
  • Java inside
  • Basato su Model-Driven Service Abstraction Level (MD-SAL)
  • Utilizza modelli YANG per la creazione automatica delle API RESTCONF dei dispositivi di rete

Il modulo principale per la gestione della rete. È attraverso di esso che comunicheremo con i dispositivi connessi. Gestito tramite la sua API.

Per ulteriori dettagli su OpenDaylight, potete leggere qui.

Automazione dei servizi di rete o come costruire un laboratorio virtuale utilizzando OpenDaylight, Postman e Vrnetlab

  • Strumento per il testing delle API
  • Interfaccia semplice e user-friendly

Nel nostro caso, è interessante come mezzo per inviare richieste REST all'API di OpenDaylight. Certamente, è possibile inviare richieste manualmente, ma in Postman tutto appare molto chiaro e si adatta perfettamente ai nostri scopi.

Per chi desidera approfondire: sono stati scritti molti materiali didattici su di esso (ad esempio).

Automazione dei servizi di rete o come costruire un laboratorio virtuale utilizzando OpenDaylight, Postman e Vrnetlab

  • Strumento per il deployment di router virtuali in Docker
  • Supporta: Cisco XRv, Juniper vMX, Arista vEOS, Nokia VSR e altri.
  • Open Source

Uno strumento molto interessante, ma poco conosciuto. In questo caso, utilizzeremo per avviare Juniper vMX e Cisco xRV9000 su una normale Ubuntu 20.04 LTS.

Puoi leggere di più su di esso su pagina del progetto.

Parte 2: lavoro di laboratorio

In questo tutorial configureremo il seguente sistema:

Automazione dei servizi di rete o come costruire un laboratorio virtuale utilizzando OpenDaylight, Postman e Vrnetlab

Come funziona

  • Juniper vMX che viene avviato in Docker un contenitore (utilizzando Vrnetlab) e funziona come un comune router virtuale.
  • ODL è collegato al router e permette di gestirlo.
  • Postman è avviato su una macchina separata e attraverso di esso inviamo comandi ODL: per collegare/disconnettere il router, modificare la configurazione, ecc.

Commento sul dispositivo del sistema

Juniper vMX e ODL richiedono molte risorse per il loro funzionamento stabile. Solo il vMX richiede 6 Gb di memoria RAM e 4 core. Pertanto, è stata presa la decisione di dedicare tutti i "pesanti" a una macchina separata (Heulett Packard Enterprise MicroServer ProLiant Gen8, Ubuntu 20.04 LTS). Il router, ovviamente, non "vola" su di essa, ma per esperimenti piccoli la performance è sufficiente.

Parte 3: configurare OpenDaylight

Automazione dei servizi di rete o come costruire un laboratorio virtuale utilizzando OpenDaylight, Postman e Vrnetlab

La versione attuale di ODL al momento della scrittura dell'articolo è — Magnesium SR1

1) Installiamo Java OpenJDK 11 (per istruzioni più dettagliate qui)

ubuntu:~$ sudo apt install default-jdk

2) Troviamo e scarichiamo una nuova build ODL da qui
3) Decomprimiamo l'archivio scaricato
4) Accediamo alla directory ottenuta
5) Avviamo ./bin/karaf

In questo passaggio ODL dovrebbe avviarsi e ci troveremo nella console (Per l'accesso esterno utilizziamo la porta 8181, che utilizzeremo più avanti).

Successivamente installiamo ODL Features, progettate per lavorare con i protocolli NETCONF e richieste RESTCONF. Per fare ciò, nella console ODL eseguiamo:

opendaylight-user@root> feature:install odl-netconf-topology odl-restconf-all

A questo punto la configurazione di base ODL è completata. (Per maggiori dettagli puoi leggere qui).

Parte 4: configurare Vrnetlab

Automazione dei servizi di rete o come costruire un laboratorio virtuale utilizzando OpenDaylight, Postman e Vrnetlab

Preparazione del sistema

Prima dell'installazione Vrnetlab è necessario installare i pacchetti richiesti per il suo funzionamento. Come ad esempio Docker, git, sshpass:

ubuntu:~$ sudo apt update
ubuntu:~$ sudo apt -y install python3-bs4 sshpass make
ubuntu:~$ sudo apt -y install git
ubuntu:~$ sudo apt install -y 
    apt-transport-https ca-certificates 
    curl gnupg-agent software-properties-common
ubuntu:~$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
ubuntu:~$ sudo add-apt-repository 
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu 
   $(lsb_release -cs) 
   stable"
ubuntu:~$ sudo apt update
ubuntu:~$ sudo apt install -y docker-ce docker-ce-cli containerd.io

Installazione di Vrnetlab

Per installare Vrnetlab cloniamo il repository corrispondente da github:

ubuntu:~$ cd ~
ubuntu:~$ git clone https://github.com/plajjan/vrnetlab.git

Passiamo alla directory vrnetlab:

ubuntu:~$ cd ~/vrnetlab

Qui puoi trovare tutti gli script necessari per l'avvio. Tieni presente che per ogni tipo di router è stata creata una directory corrispondente:

ubuntu:~/vrnetlab$ ls
CODE_OF_CONDUCT.md  config-engine-lite        openwrt           vr-bgp
CONTRIBUTING.md     csr                       routeros          vr-xcon
LICENSE             git-lfs-repo.sh           sros              vrnetlab.sh
Makefile            makefile-install.include  topology-machine  vrp
README.md           makefile-sanity.include   veos              vsr1000
ci-builder-image    makefile.include          vmx               xrv
common              nxos                      vqfx              xrv9k

Creiamo l'immagine del router

Ogni router supportato Vrnetlab, ha la sua procedura di configurazione unica. Nel caso Juniper vMX dobbiamo semplicemente inserire l'archivio .tgz con il router (puoi scaricarlo da sito ufficiale) nella directory vmx ed eseguire il comando make:

ubuntu:~$ cd ~/vrnetlab/vmx
ubuntu:~$ # Copiamo in questa directory l'archivio .tgz con il router
ubuntu:~$ sudo make

Costruzione dell'immagine vMX richiederà circa 10-20 minuti. È il momento ideale per preparare un caffè!

Perché ci vuole così tanto, vi chiederete?

Traduzione risposta dell'autore a questa domanda:

"Questo è dovuto al fatto che al primo avvio, VCP (Control Plane) legge il file di configurazione, che definisce se opererà come VRR VCP in vMX. In precedenza, questo avvio avveniva durante l'avvio di Docker, ma ciò significava che VCP veniva sempre riavviato una volta prima che il router virtuale diventasse disponibile, causando lunghi tempi di avvio (circa 5 minuti). Ora, il primo avvio di VCP avviene durante la costruzione dell'immagine Docker e, poiché la costruzione di Docker non può essere eseguita con l'opzione —privileged, ciò significa che qemu funziona senza accelerazione hardware KVM e quindi la costruzione richiede molto tempo. Durante questo processo vengono generati molti log, in modo che, almeno, possiate vedere cosa sta succedendo. Penso che la lunga costruzione non sia così spaventosa, perché creiamo l'immagine una sola volta e la avviamo molte volte."

Dopo si potrà vedere l'immagine del nostro router in Docker:

ubuntu:~$ sudo docker image list
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
vrnetlab/vr-vmx     20.1R1.11           b1b2369b453c        3 weeks ago         4.43GB
debian              stretch             614bb74b620e        7 weeks ago         101MB

Avviamo il contenitore vr-vmx

Eseguiamo con il comando:

ubuntu:~$ sudo docker run -d --privileged --name jun01 b1b2369b453c

Successivamente, possiamo visualizzare le informazioni sui contenitori attivi:

ubuntu:~$ sudo docker container list
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS                                                 NAMES
120f882c8712        b1b2369b453c        "/launch.py"        2 minuti fa       Attivo da 2 minuti (non sano)   22/tcp, 830/tcp, 5000/tcp, 10000-10099/tcp, 161/udp   jun01

Collegandoci al router

L'indirizzo IP dell'interfaccia di rete del router può essere ottenuto con il seguente comando:

ubuntu:~$ sudo docker inspect --format '{{.NetworkSettings.IPAddress}}' jun01
172.17.0.2

Per impostazione predefinita, Vrnetlab crea un utente nel router vrnetlab/VR-netlab9.
Collegandoci tramite ssh:

ubuntu:~$ ssh vrnetlab@172.17.0.2
L'autenticità dell'host '172.17.0.2 (172.17.0.2)' non può essere stabilita.
La chiave ECDSA fingerprint è SHA256:g9Sfg/k5qGBTOX96WiCWyoJJO9FxjzXYspRoDPv+C0Y.
Sei sicuro di voler continuare a connetterti (sì/no/[fingerprint])? sì
Avviso: '172.17.0.2' (ECDSA) è stato aggiunto permanentemente alla lista degli host conosciuti.
Password:
--- JUNOS 20.1R1.11 Kernel 64-bit  JNPR-11.0-20200219.fb120e7_buil
vrnetlab> show version
Modello: vmx
Junos: 20.1R1.11

A questo punto, la configurazione del router è completata.

Le raccomandazioni per l'installazione di router di diversi vendor possono essere trovate su il progetto github nelle relative directory.

Parte 5: Postman — collegare il router a OpenDaylight

Installazione di Postman

Per installarlo, basta scaricare l'applicazione da qui.

Collegare il router a ODL

Creiamo PUT richiesta:

Automazione dei servizi di rete o come costruire un laboratorio virtuale utilizzando OpenDaylight, Postman e Vrnetlab

  1. Stringa della richiesta:
    PUT http://10.132.1.202:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/jun01
  2. Corpo della richiesta (scheda Body):
    jun01
    172.17.0.2
    22
    vrnetlab
    VR-netlab9
    false
    jun01_cache
  3. Nella scheda Authorization, è necessario impostare il parametro Basic Auth e le credenziali: admin/admin. Questo è necessario per accedere a ODL:
    Automazione dei servizi di rete o come costruire un laboratorio virtuale utilizzando OpenDaylight, Postman e Vrnetlab
  4. Nella scheda Headers, devi aggiungere due intestazioni:
    • Accept application/xml
    • Content-Type application/xml

La nostra richiesta è formata. Inviamo. Se tutto è stato configurato correttamente, dovremmo ricevere lo stato "201 Created":

Automazione dei servizi di rete o come costruire un laboratorio virtuale utilizzando OpenDaylight, Postman e Vrnetlab

Cosa fa questa richiesta?

Stiamo creando un nodo all'interno di ODL con le impostazioni di un router reale a cui vogliamo accedere.

xmlns="urn:TBD:params:xml:ns:yang:network-topology"
xmlns="urn:opendaylight:netconf-node-topology"

Questi sono gli spazi dei nomi interni XML (XML namespace) per ODL secondo i quali crea il nodo.

In seguito, il nome del router è node-id, l'indirizzo del router è host e così via.

La riga più interessante è l'ultima. Directory cache dello schema crea una directory in cui vengono estratti tutti i file Schema YANG del router connesso. Puoi trovarli in $ODL_ROOT/cache/jun01_cache.

Verifichiamo la connessione del router

Creiamo GET richiesta:

  1. Stringa della richiesta:
    GET http://10.132.1.202:8181/restconf/operational/network-topology:network-topology/topology/topology-netconf/
  2. Nella scheda Authorization, è necessario impostare il parametro Basic Auth e login/password: admin/admin.

Inviamo. Dovremmo ricevere lo stato "200 OK" e un elenco di tutti i dispositivi supportati. Schema YANG:

Automazione dei servizi di rete o come costruire un laboratorio virtuale utilizzando OpenDaylight, Postman e Vrnetlab

Commento: Per vedere l'ultimo, nel mio caso, era necessario aspettare circa 10 minuti dopo l'esecuzione PUT, fino a quando tutti schema YANG vengono estratti su ODL. Fino a quel momento, eseguendo questa GET richiesta verrà visualizzato quanto segue:

Automazione dei servizi di rete o come costruire un laboratorio virtuale utilizzando OpenDaylight, Postman e Vrnetlab

Cancelliamo il router

Creiamo DELETE richiesta:

  1. Stringa della richiesta:
    DELETE http://10.132.1.202:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/jun01
  2. Nella scheda Authorization, è necessario impostare il parametro Basic Auth e login/password: admin/admin.

Parte 6: Modifichiamo la configurazione del router

Otteniamo la configurazione

Creiamo GET richiesta:

  1. Stringa della richiesta:
    GET http://10.132.1.202:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/jun01/yang-ext:mount/
  2. Nella scheda Authorization, è necessario impostare il parametro Basic Auth e login/password: admin/admin.

Inviamo. Dovremmo ricevere lo stato "200 OK" e la configurazione del router:

Automazione dei servizi di rete o come costruire un laboratorio virtuale utilizzando OpenDaylight, Postman e Vrnetlab

Creiamo una configurazione

Come esempio, creeremo la seguente configurazione e la modificheremo:

protocols {
    bgp {
        disable;
        shutdown;
    }
}

Creiamo POST richiesta:

  1. Stringa della richiesta:
    POST http://10.132.1.202:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/jun01/yang-ext:mount/junos-conf-root:configuration/junos-conf-protocols:protocols
  2. Corpo della richiesta (scheda Body):
  3. Nella scheda Authorization, è necessario impostare il parametro Basic Auth e login/password: admin/admin.
  4. Nella scheda Headers, devi aggiungere due intestazioni:
    • Accept application/xml
    • Content-Type application/xml

Dopo l'invio, dovremmo ricevere lo stato "204 No Content"

Per verificare che la configurazione sia cambiata, possiamo usare la richiesta precedente. Ma per esempio creeremo un'altra richiesta che ci mostrerà solo le informazioni sui protocolli configurati sul router.

Creiamo GET richiesta:

  1. Stringa della richiesta:
    GET http://10.132.1.202:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/jun01/yang-ext:mount/junos-conf-root:configuration/junos-conf-protocols:protocols
  2. Nella scheda Authorization, è necessario impostare il parametro Basic Auth e login/password: admin/admin.

Dopo aver eseguito la richiesta, vedremo quanto segue:

Automazione dei servizi di rete o come costruire un laboratorio virtuale utilizzando OpenDaylight, Postman e Vrnetlab

Modifichiamo la configurazione

Modificheremo le informazioni sul protocollo BGP. Dopo le nostre azioni, apparirà nel seguente modo:

protocols {
    bgp {
        disable;
    }
}

Creiamo PUT richiesta:

  1. Stringa della richiesta:
    PUT http://10.132.1.202:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/jun01/yang-ext:mount/junos-conf-root:configuration/junos-conf-protocols:protocols
  2. Corpo della richiesta (scheda Body):
  3. Nella scheda Authorization, è necessario impostare il parametro Basic Auth e login/password: admin/admin.
  4. Nella scheda Headers, devi aggiungere due intestazioni:
    • Accept application/xml
    • Content-Type application/xml

Utilizzando il precedente GET richiesta, vediamo le modifiche:

Automazione dei servizi di rete o come costruire un laboratorio virtuale utilizzando OpenDaylight, Postman e Vrnetlab

Rimuoviamo la configurazione

Creiamo DELETE richiesta:

  1. Stringa della richiesta:
    DELETE http://10.132.1.202:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/jun01/yang-ext:mount/junos-conf-root:configuration/junos-conf-protocols:protocols
  2. Nella scheda Authorization, è necessario impostare il parametro Basic Auth e login/password: admin/admin.

Quando chiamato GET dalla richiesta con le informazioni sui protocolli vedremo quanto segue:

Automazione dei servizi di rete o come costruire un laboratorio virtuale utilizzando OpenDaylight, Postman e Vrnetlab

Supplement:

Per cambiare la configurazione, non è necessario inviare il corpo della richiesta in formato XML. È possibile farlo anche in formato JSON.

Ad esempio, nella richiesta PUT per modificare la configurazione sostituiamo il corpo della richiesta con:

{
    "junos-conf-protocols:protocols": {
        "bgp": {
            "description" : "Cambiato in Postman" 
        }
    }
}

Non dimenticate di modificare nella scheda Headers le intestazioni in:

  • Accept application/json
  • Content-Type application/json

Dopo l'invio otterremo il seguente risultato (Risposta visualizzata usando GET richiesta):

Automazione dei servizi di rete o come costruire un laboratorio virtuale utilizzando OpenDaylight, Postman e Vrnetlab

Parte 7: aggiungiamo Cisco xRV9000

Perché parliamo solo di Juniper? Parliamo anche di Cisco!
Ho trovato un xRV9000 versione 7.0.2 (una bestia che richiede 8 GB di RAM e 4 core. Non è disponibile pubblicamente, quindi contattate Cisco) — lo avvieremo.

Avvio del contenitore

Il processo di creazione del contenitore Docker non è praticamente diverso da Juniper. Allo stesso modo, carichiamo il file .qcow2 con il router nella directory corrispondente al suo nome, (in questo caso xrv9k) e eseguiamo il comando make docker-image.

Dopo alcuni minuti vediamo che l'immagine è stata creata:

ubuntu:~$ sudo docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
vrnetlab/vr-xrv9k   7.0.2               54debc7973fc        4 ore fa          1.7GB
vrnetlab/vr-vmx     20.1R1.11           b1b2369b453c        4 settimane fa     4.43GB
debian              stretch             614bb74b620e        7 settimane fa     101MB

Avviamo il contenitore:

ubuntu:~$ sudo docker run -d --privileged --name xrv01 54debc7973fc

Dopo un po' verifichiamo che il contenitore sia avviato:

ubuntu:~$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                 PORTS                                                      NAMES
058c5ecddae3        54debc7973fc        "/launch.py"        4 ore fa          Up 4 ore (healthy)   22/tcp, 830/tcp, 5000-5003/tcp, 10000-10099/tcp, 161/udp   xrv01

Colleghiamoci via ssh:

ubuntu@ubuntu:~$ ssh vrnetlab@172.17.0.2
Password:

RP/0/RP0/CPU0:ios#show version
Lun Lug 6 12:19:28.036 UTC
Cisco IOS XR Software, Version 7.0.2
Copyright (c) 2013-2020 by Cisco Systems, Inc.

Build Information:
 Built By     : ahoang
 Built On     : Ven Mar 13 22:27:54 PDT 2020
 Built Host   : iox-ucs-029
 Workspace    : /auto/srcarchive15/prod/7.0.2/xrv9k/ws
 Version      : 7.0.2
 Location     : /opt/cisco/XR/packages/
 Label        : 7.0.2

cisco IOS-XRv 9000 () processor
System uptime is 3 hours 22 minutes

Colleghiamo il router a OpenDaylight

L'aggiunta avviene esattamente come per l'immagine vMX. È solo necessario cambiare i nomi.
PUT richiesta:
Automazione dei servizi di rete o come costruire un laboratorio virtuale utilizzando OpenDaylight, Postman e Vrnetlab

Dopo un po' chiamiamo GET una richiesta per verificare che tutto sia connesso:
Automazione dei servizi di rete o come costruire un laboratorio virtuale utilizzando OpenDaylight, Postman e Vrnetlab

Modifichiamo la configurazione

Configuriamo la seguente configurazione:

!
router ospf LAB
 mpls ldp auto-config
!

Creiamo POST richiesta:

  1. Stringa della richiesta:
    POST http://10.132.1.202:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/xrv01/yang-ext:mount/Cisco-IOS-XR-ipv4-ospf-cfg:ospf
  2. Corpo della richiesta (scheda Body):
    {
        "processes": {
            "process": [
                {
                    "process-name": "LAB",
                    "default-vrf": {
                        "process-scope": {
                            "ldp-auto-config": [
                                null
                            ]
                        }
                    }
                }
            ]
        }
    }
  3. Nella scheda Authorization, è necessario impostare il parametro Basic Auth e login/password: admin/admin.
  4. Nella scheda Headers, devi aggiungere due intestazioni:
    • Accept application/json
    • Content-Type application/json

Dopo l'esecuzione dovremmo ricevere lo stato "204 No Content".

Verifichiamo cosa abbiamo ottenuto.
Per fare questo, creiamo GET richiesta:

  1. Stringa della richiesta:
    GET http://10.132.1.202:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/xrv01/yang-ext:mount/Cisco-IOS-XR-ipv4-ospf-cfg:ospf
  2. Nella scheda Authorization, è necessario impostare il parametro Basic Auth e login/password: admin/admin.

Dopo l'esecuzione dovremmo vedere quanto segue:

Automazione dei servizi di rete o come costruire un laboratorio virtuale utilizzando OpenDaylight, Postman e Vrnetlab

Per rimuovere la configurazione, utilizziamo DELETE:

  1. Stringa della richiesta:
    DELETE http://10.132.1.202:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/xrv01/yang-ext:mount/Cisco-IOS-XR-ipv4-ospf-cfg:ospf
  2. Nella scheda Authorization, è necessario impostare il parametro Basic Auth e login/password: admin/admin.

Conclusione

Come avrete notato, le procedure di collegamento di Cisco e Juniper a OpenDaylight non sono diverse: questo apre ampie possibilità di personalizzazione. Dalla gestione delle configurazioni di tutti i componenti di rete alla creazione delle proprie politiche di rete.
In questo tutorial ho fornito dei semplici esempi su come interagire con l'hardware di rete utilizzando OpenDaylight. Senza dubbio, le richieste negli esempi forniti possono diventare molto più complesse e configurare interi servizi con un semplice clic del mouse: tutto è limitato solo dalla vostra fantasia.

Continua...

P.S.

Se per caso sapete già tutto questo o, al contrario, se avete approfondito e ODL vi ha colpito, vi consiglio di dare un'occhiata allo sviluppo di applicazioni sul controller ODL. Si può iniziare. da qui.

Buoni esperimenti!

Elenco delle opere

  1. Vrnetlab: Emulare reti usando KVM e Docker / Brian Linkletter
  2. OpenDaylight Cookbook / Mathieu Lemay, Alexis de Talhouet, Et al.
  3. Network Programmability with YANG / Benoît Claise, Loe Clarke, Jan Lindblad
  4. Learning XML, Second Edition / Erik T. Ray
  5. Effective DevOps / Jennifer Davis, Ryn Daniels

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster