Infrastruktur
Seit ca einem Jahr haben wir im Datacenter-Bereich eine homogene Cisco-Infrastruktur. Im Rahmen eines Projektes sind Cisco UCS Systeme zusammen mit Cisco Nexus 5k Datacenter Switches beschafft worden.
Wir haben an zwei Standorten jeweiles zwei Nexus-Switches, an dem pro Seite jeweils ein Storage-System angeschlossen ist.
Zusätzlich haben wir an beiden Standorten Cisco-Ucs-Systeme aufgebaut.
Wir haben uns nun überlegt, wie wir unsere Server (und Blades) an die Nexus-Infrastruktur anbinden und haben uns dann für Fibre-Channel entschieden.
Dann stellte sich die Frage, wie man dann das Zoning über die Nexus-Switches löst. Klar ist, diese Aufgabe müssen wir Serveradmins übernehmen. Nachdem wir uns den Cisco Prime Datacenter Network Manager angeschaut hatten (Gui Lösung zum Managen von unter anderem auch Nexus-Switches) war uns klar, dass wir das lieber über die Konsole per Script machen wollen.
Natürlich ist bei vielen die Infrastruktur unterschiedlich und wir haben es bei uns auch bewusst relativ einfach gehalten.
Es wird also nur in einer Fabric ein Port des Storages auf einen Port des Servers gezont.
Skriptaufbau
Wir haben auf einem zentralen Linux-Server ein Skript gebaut, welches einen bestendenden Storage mit einem Server verbindet.
Was soll das Skript nun genau tun?
Das Skript soll sich zu den Fabric-Interconnects verbinden, sich von dort die Service-Profile holen und diese in einem Auswahlmenü präsentieren.
Dann soll die WWPN der vHBAs des ausgewählten Service-Profils besorgt werden und in ein Array geladen werden.
Schließlich soll der Device-Alias angelegt, die Zone gebaut und zum Zoneset hinzugefügt werden. Nach einer Sichtprüfung soll abgefragt werden ob die Zone jetzt aktiviert werden soll.
Das wars im Prinzip schon. Die eigentliche Konfiguration der Nexus-Switches wird per Shell-Funktion vorgenommen.
Hier das Skript.
#!/bin/bash # # Funktion zum Überprüfen ob ein (der Funktion mitgegebenes) Element im Array der Service-Profiles von FI-E12 existiert function exists() { element=${1} for i in ${arraye12[@]}; do if [ $i == $element ]; then echo "1" fi done return 0 } # Wegschreiben der Daten in einen Ordner, der nach dem aktuellen Datum + Uhrzeit benannt ist DATE=`date +%d%m%y-%H%M` mkdir -p /home/vi-admin/Backup/Zoning/$DATE FOLDER=/home/vi-admin/Backup/Zoning/$DATE # # Fest definierter Storage, mit dem gezont werden soll. Achtung: Diese Namen müssen als Device-Alias im jeweiligen Nexus existieren. STORAGE1="VSTORE1" STORAGE2="VSTORE2" # Funktion zum Erstellen der Zone auf NX1 function createzonenx1 { echo "conf t" > createzonenx1_$ziel.txt echo "zone name $ziel"_Port1" vsan 1234" >> createzonenx1_$ziel.txt echo "member device-alias $STORAGE1"_Port1"" >> createzonenx1_$ziel.txt echo "member device-alias $ziel"_Port1"" >> createzonenx1_$ziel.txt echo "sh zone" >> createzonenx1_$ziel.txt ssh fczoning@nexus1 < createzonenx1_$ziel.txt mv createzonenx1_$ziel.txt $FOLDER/ } # Funktion zum Erstellen der Zone auf NX2 function createzonenx2 { echo "conf t" > createzonenx2_$ziel.txt echo "zone name $ziel"_Port2" vsan 4321" >> createzonenx2_$ziel.txt echo "member device-alias $STORAGE1"_Port2"" >> createzonenx2_$ziel.txt echo "member device-alias $ziel"_Port2"" >> createzonenx2_$ziel.txt echo "sh zone" >> createzonenx2_$ziel.txt ssh fczoning@nexus2 < createzonenx2_$ziel.txt mv createzonenx2_$ziel.txt $FOLDER/ } # Funktion zum Erstellen der Zone auf NX3 function createzonenx3 { echo "conf t" > createzonenx3_$ziel.txt echo "zone name $ziel"_Port1" vsan 1234" >> createzonenx3_$ziel.txt echo "member device-alias $STORAGE2"_Port1"" >> createzonenx3_$ziel.txt echo "member device-alias $ziel"_Port1"" >> createzonenx3_$ziel.txt echo "sh zone" >> createzonenx3_$ziel.txt ssh fczoning@nexus3 < createzonenx3_$ziel.txt mv createzonenx3_$ziel.txt $FOLDER/ } # Funktion zum Erstellen der Zone auf NX4 function createzonenx4 { echo "conf t" > createzonenx4_$ziel.txt echo "zone name $ziel"_Port2" vsan 4321" >> createzonenx4_$ziel.txt echo "member device-alias $STORAGE2"_Port2"" >> createzonenx4_$ziel.txt echo "member device-alias $ziel"_Port2"" >> createzonenx4_$ziel.txt echo "sh zone" >> createzonenx4_$ziel.txt ssh fczoning@nexus4 < createzonenx4_$ziel.txt mv createzonenx4_$ziel.txt $FOLDER/ } # Funktion zum Hinzufügen der Zone zum Zoneset auf NX1 function addzonesetnx1 { echo "conf t" > addzonesetnx1_$ziel.txt echo "zoneset name FABRICA_UCS1 vsan 1234" >> addzonesetnx1_$ziel.txt echo "member $ziel"_Port1"" >> addzonesetnx1_$ziel.txt echo "sh zoneset" >> addzonesetnx1_$ziel.txt ssh fczoning@nexus1 < addzonesetnx1_$ziel.txt mv addzonesetnx1_$ziel.txt $FOLDER/ } # Funktion zum Hinzufügen der Zone zum Zoneset auf NX2 function addzonesetnx2 { echo "conf t" > addzonesetnx2_$ziel.txt echo "zoneset name FABRICB_UCS1 vsan 4321" >> addzonesetnx2_$ziel.txt echo "member $ziel"_Port2"" >> addzonesetnx2_$ziel.txt echo "sh zoneset" >> addzonesetnx2_$ziel.txt ssh fczoning@nexus2 < addzonesetnx2_$ziel.txt mv addzonesetnx2_$ziel.txt $FOLDER/ } # Funktion zum Hinzufügen der Zone zum Zoneset auf NX3 function addzonesetnx3 { echo "conf t" > addzonesetnx3_$ziel.txt echo "zoneset name FABRICA_UCS1 vsan 1234" >> addzonesetnx3_$ziel.txt echo "member $ziel"_Port1"" >> addzonesetnx3_$ziel.txt echo "sh zoneset" >> addzonesetnx3_$ziel.txt ssh fczoning@nexus3 < addzonesetnx3_$ziel.txt mv addzonesetnx3_$ziel.txt $FOLDER/ } # Funktion zum Hinzufügen der Zone zum Zoneset auf NX4 function addzonesetnx4 { echo "conf t" > addzonesetnx4_$ziel.txt echo "zoneset name FABRICB_UCS1 vsan 4321" >> addzonesetnx4_$ziel.txt echo "member $ziel"_Port2"" >> addzonesetnx4_$ziel.txt echo "sh zoneset" >> addzonesetnx4_$ziel.txt ssh fczoning@nexus4 < addzonesetnx4_$ziel.txt mv addzonesetnx4_$ziel.txt $FOLDER/ } # Funktion zum Erstellen des Device-Alias des Service-Profiles auf NX1 function createdevicealiasnx1 { echo "conf t" > createdevicealiasnx1_$ziel.txt echo "device-alias database" >> createdevicealiasnx1_$ziel.txt echo "device-alias name $ziel"_Port1" pwwn $i" >> createdevicealiasnx1_$ziel.txt echo "device-alias commit" >> createdevicealiasnx1_$ziel.txt echo "sh device-alias database" >> createdevicealiasnx1_$ziel.txt ssh fczoning@nexus1 < createdevicealiasnx1_$ziel.txt mv createdevicealiasnx1_$ziel.txt $FOLDER/ } # Funktion zum Erstellen des Device-Alias des Service-Profiles auf NX2 function createdevicealiasnx2 { echo "conf t" > createdevicealiasnx2_$ziel.txt echo "device-alias database" >> createdevicealiasnx2_$ziel.txt echo "device-alias name $ziel"_Port2" pwwn $i" >> createdevicealiasnx2_$ziel.txt echo "device-alias commit" >> createdevicealiasnx2_$ziel.txt echo "sh device-alias database" >> createdevicealiasnx2_$ziel.txt ssh fczoning@nexus2 < createdevicealiasnx2_$ziel.txt mv createdevicealiasnx2_$ziel.txt $FOLDER/ } # Funktion zum Erstellen des Device-Alias des Service-Profiles auf NX3 function createdevicealiasnx3 { echo "conf t" > createdevicealiasnx3_$ziel.txt echo "device-alias database" >> createdevicealiasnx3_$ziel.txt echo "device-alias name $ziel"_Port1" pwwn $i" >> createdevicealiasnx3_$ziel.txt echo "device-alias commit" >> createdevicealiasnx3_$ziel.txt echo "sh device-alias database" >> createdevicealiasnx3_$ziel.txt ssh fczoning@nexus3 < createdevicealiasnx3_$ziel.txt mv createdevicealiasnx3_$ziel.txt $FOLDER/ } # Funktion zum Erstellen des Device-Alias des Service-Profiles auf NX4 function createdevicealiasnx4 { echo "conf t" > createdevicealiasnx4_$ziel.txt echo "device-alias database" >> createdevicealiasnx4_$ziel.txt echo "device-alias name $ziel"_Port2" pwwn $i" >> createdevicealiasnx4_$ziel.txt echo "device-alias commit" >> createdevicealiasnx4_$ziel.txt echo "sh device-alias database" >> createdevicealiasnx4_$ziel.txt ssh fczoning@nexus4 < createdevicealiasnx4_$ziel.txt mv createdevicealiasnx4_$ziel.txt $FOLDER/ } # Funktion zum Aktivieren des Zonesets auf NX1 function activatezonesetnx1 { echo "conf t" > activatezonesetnx1_$ziel.txt echo "zoneset activate name FABRICA_UCS1 vsan 1234" >> activatezonesetnx1_$ziel.txt echo "wr" >> activatezonesetnx1_$ziel.txt ssh fczoning@nexus1 < activatezonesetnx1_$ziel.txt mv activatezonesetnx1_$ziel.txt $FOLDER/ } # Funktion zum Aktivieren des Zonesets auf NX2 function activatezonesetnx2 { echo "conf t" > activatezonesetnx2_$ziel.txt echo "zoneset activate name FABRICB_UCS1 vsan 4321" >> activatezonesetnx2_$ziel.txt echo "wr" >> activatezonesetnx2_$ziel.txt ssh fczoning@nexus2 < activatezonesetnx2_$ziel.txt mv activatezonesetnx2_$ziel.txt $FOLDER/ } # Funktion zum Aktivieren des Zonesets auf NX3 function activatezonesetnx3 { echo "conf t" > activatezonesetnx3_$ziel.txt echo "zoneset activate name FABRICA_UCS1 vsan 1234" >> activatezonesetnx3_$ziel.txt echo "wr" >> activatezonesetnx3_$ziel.txt ssh fczoning@nexus3 < activatezonesetnx3_$ziel.txt mv activatezonesetnx3_$ziel.txt $FOLDER/ } # Funktion zum Aktivieren des Zonesets auf NX4 function activatezonesetnx4 { echo "conf t" > activatezonesetnx4_$ziel.txt echo "zoneset activate name FABRICB_UCS1 vsan 4321" >> activatezonesetnx4_$ziel.txt echo "wr" >> activatezonesetnx4_$ziel.txt ssh fczoning@nexus4 < activatezonesetnx4_$ziel.txt mv activatezonesetnx4_$ziel.txt $FOLDER/ } # Alle Service-Profiles von fi1 und fi2 laden und in jeweils ein Array laden arraye12=(`ssh fczoning@fi1 "scope org AAA;show service-profile" |awk {'print $1'} |egrep -v "(Service|-)"| cut -c5-`) arraye21=(`ssh fczoning@fi2 "scope org AAA;show service-profile" |awk {'print $1'} |egrep -v "(Service|-)"| cut -c5-`) # Per Menü ein Service-Profile auswählen PS3="Auswahl: " echo "Bitte das Service Profil auswählen: " select ziel in "${arraye12[@]}" "${arraye21[@]}" "beenden"; do if [ $ziel == "beenden" ]; then break fi echo $ziel # Wenn das gewählte Service-Profile in Arraye12 existiert, dann Methoden für fi1 bzw nx1 und nx2 ausführen if [ "$(exists $ziel)" == "1" ]; then arrhbae12=(`ssh fczoning@fi1 "scope org AAA;scope service-profile \$ziel;show vhba" | awk {'print $3'} | tr '[:upper:]' '[:lower:]' |egrep -v "(id|-)" | tail -n +3`) # 3. Element des Arrays abfragen -> Entspricht dem 3.HBA des Service-Profiles for i in "${arrhbae12[2]}" do # Funktionsaufruf. Hier wird der jeweilige Nexus konfiguriert createdevicealiasnx1 createzonenx1 addzonesetnx1 # Abfrage ob die Zone nun aktiviert werden soll. Mit den Ausgaben der jeweiligen Funktionen kann man überprüfen ob das alles so korrekt ist. read -p "zoneset jetzt aktivieren? j n: " activate if [ $activate == "j" ]; then activatezonesetnx1 fi done for i in "${arrhbae12[3]}" do # Funktionsaufruf. Hier wird der jeweilige Nexus konfiguriert createdevicealiasnx2 createzonenx2 addzonesetnx2 # Abfrage ob die Zone nun aktiviert werden soll. Mit den Ausgaben der jeweiligen Funktionen kann man überprüfen ob das alles so korrekt ist. read -p "zoneset jetzt aktivieren? j n: " activate if [ $activate == "j" ]; then activatezonesetnx2 fi done exit 0 else arrhbae21=(`ssh fczoning@fi2 "scope org AAA;scope service-profile \$ziel;show vhba" | awk {'print $3'} | tr '[:upper:]' '[:lower:]' |egrep -v "(id|-)" | tail -n +3`) # 4. Element des Arrays abfragen -> Entspricht dem 3.HBA des Service-Profiles for i in "${arrhbae21[2]}" do # Funktionsaufruf. Hier wird der jeweilige Nexus konfiguriert createdevicealiasnx3 createzonenx3 addzonesetnx3 # Abfrage ob die Zone nun aktiviert werden soll. Mit den Ausgaben der jeweiligen Funktionen kann man überprüfen ob das alles so korrekt ist. read -p "zoneset jetzt aktivieren? j n: " activate if [ $activate == "j" ]; then activatezonesetnx3 fi done for i in "${arrhbae21[3]}" do # Funktionsaufruf. Hier wird der jeweilige Nexus konfiguriert createdevicealiasnx4 createzonenx4 addzonesetnx4 # Abfrage ob die Zone nun aktiviert werden soll. Mit den Ausgaben der jeweiligen Funktionen kann man überprüfen ob das alles so korrekt ist. read -p "zoneset jetzt aktivieren? j n: " activate if [ $activate == "j" ]; then activatezonesetnx4 fi done fi break done