===== 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