Ruby e Netconf

Questo post sarà molto breve perché descrive un esempio molto basilare di come usare il linguaggio di programmazione Ruby e il protocollo Netconf per interfacciarsi con un dispositivo Juniper, che esegue una qualche versione del sistema operativo JunOS, ed ottenere informazioni utili.

L’esempio mostrato introduce la possibilità di automatizzare, tramite script, operazioni ripetitive che normalmente potrebbero richiedere l’esecuzione di molti comandi da eseguire su più dispositivi, con relativo impegno di tempo e rischio di compiere errori.

Recuperare la mac-address table di uno switch

L’esigenza che vogliamo risolvere è quella di ottenere la tabella degli indirizzi MAC conosciuti da uno switch, eventualmente per trovarne uno in particolare e capire su quale porta è attestato.

L’esempio che segue implementa solo una parte della soluzione, ovvero quella di recuperare e stampare a video la tabella, mostrando soltanto il mac address, la porta corrispondente e la vlan.

# frozen_string_literal: true

require 'net/netconf'
require 'highline/import'

devices = { dev1: "192.168.1.1", dev2: "192.168.1.2" }
username = ask("Insert device username: "){|a| a.echo = true}
password = ask("Insert device password: "){|a| a.echo = false}

devices.values.each do |device|
  login = { target: device, username: username, password: password }
  Netconf::SSH.new(login) { |dev|
    mac_table = dev.rpc.get_ethernet_switching_table_information
    mac_table.xpath('//l2ng-mac-entry').each do |mac_entry|
      puts "#{mac_entry.xpath('l2ng-l2-mac-address').text} #{mac_entry.xpath('l2ng-l2-mac-logical-interface').text} #{mac_entry.xpath('l2ng-l2-mac-vlan-name').text}"
    end
  }
endCode language: Ruby (ruby)

Lo script presuppone che tutti i dispositivi elencati siano accessibili con le stesse credenziali username/password.

Chiaramente le informazioni recuperate con la chiamata rpc possono essere usate in un altro modo, ad esempio per popolare un array o un database da interrogare successivamente.

Problemi

Lo script mostrato funziona, ma termina con un’eccezione di timeout della connessione quando si arriva alla fine del blocco. Devo ancora capire se la connessione deve essere chiusa esplicitamente o se c’è qualche altra cosa da considerare.

Juniper, Ruby e Python

Juniper ha pubblicato un paio di librerie Ruby, vale a dire la già citata Netconf e ruby-junos-ez-stdlib; tuttavia, come si evince dalle date degli ultimi commit, esse non vengono più aggiornate da molti anni e presentano diversi problemi (si veda ad esempio questa issue).

Come molti altri vendor, evidentemente anche Juniper si è concentrata prevalentemente su Python per l’implementazione delle API dedicate all’automazione dei suoi dispositivi; la libreria denominata EZNC (che starebbe per easy netconf) è molto aggiornata e sicuramente molto più documentata rispetto alla sua equivalente per Ruby.

Powered by atecplugins.com