===== Automatic backup Cisco SAN switches ===== === First step: ssh without password === Automatic connexions from a UNIX host to Cisco without password: If you haven't yet enable ssh, go to the installation steps On the UNIX host print your public key (cat /root/.ssh/id_rsa.pub), use the first 2 word to add to the Cisco account Problem is solved, it was at NX5K as well. Its mainly caused by a documentation bug: Bind the sshkey to an existing nexus user. Take care that you **exactly use the first 2 words ** of the generated pubkey, allthough the key consists of 3 words: Nexus7KA(config)# username admin sshkey ssh-rsa AAAAB3Nz... Nexus7KA(config)# sh user-account admin user:admin this user account has no expiry date roles:network-operator ssh public key: ssh-rsa AAAAB3Nz.... Important hint: In the Cisco-SSH documentation you will see: "username User1 sshkey ssh-rsa AAAAB3Nz..." That is no new-line. It is a blanc: "ssh-rsa AAAAB3Nz…" === Second step: accept the ssh key for all switches === Try an ssh connection to each switch and accept the key === Third step: the backup script === Now on your unix server, create a script to backup the config: Customize the Cisco Shell prompt: [root@nim]/root/scripts # cat /root/scripts/backup_mds_config.sh #!/bin/ksh ##################################################### # #@(#) Backup Cisco switch config and zoning into /export/mksysb/ # This is used for a cron entry. No arguments are # allowed in cron.Absolute paths to commands must # be specified to ssh for it to work properly # ssh key exchange must be separately configured # for the account "USER" # # Adjust the variables for your host and switch ###################################################### dir=`dirname $0` #. $dir/.env export binpath=/root/scripts export sn=`basename $0 | cut -d. -f1` export logpath=/root/scripts/logs export logname=$logpath/$sn.log BACKUP_DIR=/export/mksysb/san DATE=`date "+%Y-%m-%d_%H%M%S"` SWITCH_NAME="mds1 mds2" USER=admin COMMAND1="copy running-config startup-config" COMMAND2="show startup-config" backup_config () { echo $DATE for switch in $(echo $SWITCH_NAME) do echo "Copy running to startup-config : $switch" ssh -l $USER $switch $COMMAND1 echo "Backup MDS $switch config to local file : $BACKUP_DIR/$switch.$DATE" ssh -l $USER $switch $COMMAND2 > $BACKUP_DIR/$switch.$DATE done } backup_config > $logname 2>&1 ===== Generate zoning commands for Cisco SAN switches ===== Samples: root@nim - /root/scripts/san > ./mkzone.sh config_file User Access Verification User Access Verification User Access Verification User Access Verification ##### ####### ### ##### # # # ##### #### # # # # # # # ## ## ## # # # # # # # # # # # # ## # # # #### ###### ###### # # ###### ##### # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ##### #### ##### ##### ### ##### ##### ** Login to switch mds9506-1 ** Enter the following commands: *************************************************** ssh admin@mds9506-1 copy run start config t c0:50:76:01:45:b6:00:18 fcalias name v_prodsrv1_p0 vsan 1 member pwwn c0:50:76:01:45:b6:00:18 c0:50:76:01:45:b6:00:08 fcalias name v_server1_p0 vsan 1 member pwwn c0:50:76:01:45:b6:00:08 exit config t zone name v_server1_p0_svc3-prd_p1 vsan 1 member fcalias v_server1_p0 member fcalias svc3-prd_p1 zone name v_server1_p0_svc3-prd_p3 vsan 1 member fcalias v_server1_p0 member fcalias svc3-prd_p3 zone name v_server1_p0_svc4-prd_p2 vsan 1 member fcalias v_server1_p0 member fcalias svc4-prd_p2 zone name v_server1_p0_svc4-prd_p4 vsan 1 member fcalias v_server1_p0 member fcalias svc4-prd_p4 zone name v_prodsrv1_p0_svc3-bcp_p1 vsan 1 member fcalias v_prodsrv1_p0 member fcalias svc3-bcp_p1 zone name v_prodsrv1_p0_svc3-bcp_p3 vsan 1 member fcalias v_prodsrv1_p0 member fcalias svc3-bcp_p3 zone name v_prodsrv1_p0_svc4-bcp_p2 vsan 1 member fcalias v_prodsrv1_p0 member fcalias svc4-bcp_p2 zone name v_prodsrv1_p0_svc4-bcp_p4 vsan 1 member fcalias v_prodsrv1_p0 member fcalias svc4-bcp_p4 exit zoneset name cfg_A_vsan1 vsan 1 member v_server1_p0_svc3-prd_p1 member v_server1_p0_svc3-prd_p3 member v_server1_p0_svc4-prd_p2 member v_server1_p0_svc4-prd_p4 member v_prodsrv1_p0_svc3-bcp_p1 member v_prodsrv1_p0_svc3-bcp_p3 member v_prodsrv1_p0_svc4-bcp_p2 member v_prodsrv1_p0_svc4-bcp_p4 exit zoneset distribute vsan 1 sleep 10 zoneset activate name cfg_A_vsan1 vsan 1 sleep 10 copy run start exit exit *************************************************** ** Logout of switch mds9506-1 ##### ####### ### ##### # # # ##### #### # # # # # # # # # ## ## # # # # # # # # # # # # ## # # # #### ###### ###### # # ###### ##### # # # # # # # # # # # # # ####### # # # # # # # # # # # # # # # # # ##### #### ##### ##### ### ##### # ** Login to switch mds9506-4 ** Enter the following commands: *************************************************** ssh admin@mds9506-4 copy run start config t c0:50:76:01:45:b6:00:12 fcalias name v_prodsrv1_p0 vsan 2 member pwwn c0:50:76:01:45:b6:00:12 c0:50:76:01:45:b6:00:02 fcalias name v_server1_p0 vsan 2 member pwwn c0:50:76:01:45:b6:00:02 exit config t zone name v_server1_p0_svc3-prd_p2 vsan 2 member fcalias v_server1_p0 member fcalias svc3-prd_p2 zone name v_server1_p0_svc3-prd_p4 vsan 2 member fcalias v_server1_p0 member fcalias svc3-prd_p4 zone name v_server1_p0_svc4-prd_p1 vsan 2 member fcalias v_server1_p0 member fcalias svc4-prd_p1 zone name v_server1_p0_svc4-prd_p3 vsan 2 member fcalias v_server1_p0 member fcalias svc4-prd_p3 zone name v_prodsrv1_p0_svc3-bcp_p2 vsan 2 member fcalias v_prodsrv1_p0 member fcalias svc3-bcp_p2 zone name v_prodsrv1_p0_svc3-bcp_p4 vsan 2 member fcalias v_prodsrv1_p0 member fcalias svc3-bcp_p4 zone name v_prodsrv1_p0_svc4-bcp_p1 vsan 2 member fcalias v_prodsrv1_p0 member fcalias svc4-bcp_p1 zone name v_prodsrv1_p0_svc4-bcp_p3 vsan 2 member fcalias v_prodsrv1_p0 member fcalias svc4-bcp_p3 exit zoneset name cfg_B_vsan2 vsan 2 member v_server1_p0_svc3-prd_p2 member v_server1_p0_svc3-prd_p4 member v_server1_p0_svc4-prd_p1 member v_server1_p0_svc4-prd_p3 member v_prodsrv1_p0_svc3-bcp_p2 member v_prodsrv1_p0_svc3-bcp_p4 member v_prodsrv1_p0_svc4-bcp_p1 member v_prodsrv1_p0_svc4-bcp_p3 exit zoneset distribute vsan 2 sleep 10 zoneset activate name cfg_B_vsan2 vsan 2 sleep 10 copy run start exit exit *************************************************** ** Logout of switch mds9506-4 ***** Warning report: WWN c0:50:76:01:45:b6:00:18 still exists fcalias name v_prpds1_p0 vsan 1 pwwn c0:50:76:01:45:b6:00:18 pwwn c0:50:76:01:45:b6:00:19 WWN c0:50:76:01:45:b6:00:08 still exists fcalias name v_prpas1_p0 vsan 1 pwwn c0:50:76:01:45:b6:00:08 pwwn c0:50:76:01:45:b6:00:09 WWN c0:50:76:01:45:b6:00:12 still exists fcalias name v_prpds1_p0 vsan 2 pwwn c0:50:76:01:45:b6:00:12 pwwn c0:50:76:01:45:b6:00:13 WWN c0:50:76:01:45:b6:00:02 still exists fcalias name v_prpas1_p0 vsan 2 pwwn c0:50:76:01:45:b6:00:02 pwwn c0:50:76:01:45:b6:00:03 mkzone.sh #!/bin/ksh93 #set -x # # mkzone.sh - Utility that will take a config file and generate a # procedure that can be used for Change Management as well # as cut/pasted into an ssh session to configure. # Script is able to be run on unix/linux platforms and # inside Cygwin on Windows. # # Usage: mkzone.sh # # This script generate commands to create zoning. # it detect on which fabric the wwn is available : show flogi database # So you have to bring your server up on SAN # # Condense the config file. Get rid of blank lines and comments. if [ ! -f ${1:-CONFIG} ]; then echo "ERROR: Config file ${1} not found." echo "Usage: mkzone.sh " echo "" exit 1 fi logpath=/root/scripts/san/logs errlog=$logpath/errlog cat ${1} | egrep -v "^$|^#" > $logpath/zones.config.$$ CONFIG=$logpath/zones.config.$$ CONFIG1=$logpath/zones.config.ok HOST_FABRIC_A=mds9506-1 HOST_FABRIC_B=mds9506-4 ALL_HOST_A="mds9506-1 mds9506-3" ALL_HOST_B="mds9506-2 mds9506-4" LOGIN=admin # Set some variables. #VSAN=`grep "^VSAN," ${CONFIG} | cut -d, -f2` #SWITCH_NAME=`grep "^SwitchName," ${CONFIG} | cut -d, -f2` #ZONESET_NAME=`grep "^ZonesetName," ${CONFIG} | cut -d, -f2` #ZONE_BY=`grep "^ZoneBy," ${CONFIG} | cut -d, -f2` DATE=`date '+%Y%m%d'` if [ -e $errlog ] then rm $errlog fi convert_wwn () { wwn=$1 wwn_nodot=$(echo $wwn | sed 's/://g;s/\.//g' | tr 'a-z' 'A-Z') wwn_dot=$(echo $wwn_nodot | sed 's/../&:/g;s/:$//' | tr 'A-Z' 'a-z') echo $wwn_dot } ssh $LOGIN@mds9506-1 "show flogi database" | grep : | grep fc > $logpath/flogi.A 2>/dev/null ssh $LOGIN@mds9506-3 "show flogi database" | grep : | grep fc >> $logpath/flogi.A 2>/dev/null ssh $LOGIN@mds9506-2 "show flogi database" | grep : | grep fc > $logpath/flogi.B 2>/dev/null ssh $LOGIN@mds9506-4 "show flogi database" | grep : | grep fc >> $logpath/flogi.B 2>/dev/null grep "^ARRAY" ${CONFIG} > $CONFIG1.A grep "^ARRAY" ${CONFIG} > $CONFIG1.B for line in $(grep "^SERVER" ${CONFIG}) do DEVICE_WWN=$(echo $line | cut -d, -f3) PWWN=$(convert_wwn $DEVICE_WWN) fabric=$(grep "$PWWN" $logpath/flogi.* | cut -d'.' -f2- | cut -d':' -f1) line1=$(echo $line | cut -d',' -f1-2) echo $fabric | egrep "A|B" > /dev/null if [ $? -ne 0 ] then echo "$PWWN doesn't exists on a FABRIC" else echo $line1,$PWWN,$fabric >> $CONFIG1.$fabric fi done for connect in ${HOST_FABRIC_A} ${HOST_FABRIC_B} do # Backup of config before ssh $LOGIN@$connect "show zoneset active" > $logpath/zoneset_active_before.$connect.$DATE 2>/dev/null ssh $LOGIN@$connect "show startup-config" > $logpath/backup_config.$connect.$DATE 2>/dev/null ssh $LOGIN@$connect "show zoneset brief active" > $logpath/zoneset.$connect 2>/dev/null VSAN=$(grep "zoneset name" $logpath/zoneset.$connect | awk '{print $5}') ZONESET_NAME=$(grep "zoneset name" $logpath/zoneset.$connect | awk '{print $3}') echo $ZONESET_NAME | grep "cfg_A" > /dev/null 2>&1 if [ $? -eq 0 ] then CONFIGOK="${CONFIG1}.A" else echo $ZONESET_NAME | grep "cfg_B" > /dev/null 2>&1 if [ $? -eq 0 ] then CONFIGOK="${CONFIG1}.B" else echo "ERROR fabric not found" exit 1 fi fi banner "$connect" echo "** Login to switch ${connect}" echo "** Enter the following commands:" echo "***************************************************" echo "" echo "ssh $LOGIN@${connect}" echo "copy run start" # echo "copy run bootflash:pre-${DATE}" echo "" # Check alias ssh $LOGIN@$connect "show fcalias" > $logpath/fcalias.$connect 2>/dev/null # Create the fcaliases. echo "config t" for TYPE in SERVER do for DEVICE in $(grep "^${TYPE}" ${CONFIGOK} | cut -d, -f2| sort -u) do DEVICE_WWN=$(grep ",${DEVICE}," ${CONFIGOK} | cut -d, -f3 | head -1) PWWN=$(convert_wwn $DEVICE_WWN) grep "fcalias $DEVICE " $logpath/fcalias.$connect > /dev/null 2>&1 if [ $? -eq 0 ] then grep -p "$PWWN" $logpath/fcalias.$connect > /dev/null 2>&1 if [ $? -eq 0 ] then echo "FCalias $DEVICE $DEVICE_WWN still exists" >> $errlog else echo "FCalias $DEVICE still exists but with wrong WWN" >> $errlog fi else grep $PWWN $logpath/fcalias.$connect > /dev/null 2>&1 if [ $? -eq 0 ] then echo "WWN $PWWN still exists" >> $errlog grep -p "$PWWN" $logpath/fcalias.$connect >> $errlog fi echo "fcalias name ${DEVICE} vsan ${VSAN}" echo "member pwwn ${PWWN}" fi done done echo "exit" echo "" # Create all of the zones echo "config t" ZONE_ADD="" for line in $(grep "^SERVER" ${CONFIGOK}) do SERVER=$(echo $line | cut -d, -f2) NUMBER=$(echo $line | cut -d, -f1 | sed 's/SERVER//') for storage in $(grep "^ARRAY${NUMBER}," ${CONFIGOK} | cut -d, -f2- | sed 's/,/\ /g') do case ${storage} in svc-prd) word1=svc3-prd ; word2=svc4-prd ;; svc-bcp) word1=svc3-bcp ; word2=svc4-bcp ;; ds8100prd) word1=ds8100prd ; word2=ds8100prd ;; ds8100bcp) word1=ds8100bcp ; word2=ds8100bcp ;; esac for ARRAY in $(egrep "$word1|$word2" $logpath/fcalias.$connect | awk '{print $3}' | grep -v "_mm_") do echo "zone name ${SERVER}_${ARRAY} vsan ${VSAN}" echo "member fcalias ${SERVER}" echo "member fcalias ${ARRAY}" ZONE_ADD=$(echo "$ZONE_ADD ${SERVER}_${ARRAY}") done done done echo "exit" echo "" # Create the active zoneset and activate it echo "zoneset name ${ZONESET_NAME} vsan ${VSAN}" for ZONEADD in ${ZONE_ADD} do echo "member ${ZONEADD}" done echo "exit" echo "zoneset distribute vsan ${VSAN}" echo "sleep 10" echo "zoneset activate name ${ZONESET_NAME} vsan ${VSAN}" echo "sleep 10" echo "copy run start" # echo "copy run bootflash:post-${DATE}" echo "exit" echo "exit" echo "***************************************************" echo "** Logout of switch ${connect}" # Backup of config after #ssh $LOGIN@$connect "show zoneset active" > $logpath/zoneset_active_after.$DATE 2>/dev/null done if [ -e $errlog ] then echo echo "***** Warning report:" cat $errlog fi # Clean up and exit. rm $CONFIG exit 0 config_file (server1 is connected to array1...) # Choose an array in ds8100prd ds8100bcp svc-prd svc-bcp # ARRAYx, # the array number and server number must match ARRAY1,svc-prd ARRAY2,ds8100prd ARRAY3,svc-prd ARRAY4,svc-prd ARRAY5,ds8100bcp ARRAY6,svc-prd ARRAY7,svc-prd ARRAY8,svc-prd # add SERVERx,, # WWN can be with different formats: C05076004B64002A c0:50:76:00:4b:64:00:2a SERVER1,v_prpas1_p0,c050760145b60002 SERVER1,v_prpas1_p0,c050760145b60008 SERVER1,v_prpas1_p1,c050760145b60006 SERVER1,v_prpas1_p1,c050760145b60004 SERVER2,v_prpds1_p0,c050760145b60012 SERVER2,v_prpds1_p0,c050760145b60018 SERVER2,v_prpds1_p1,c050760145b60016 SERVER2,v_prpds1_p1,c050760145b60014