#function:将AC与GLPI数据库的MAC同步
#exception.mac单独存放于GLPI数据库,为以后GLPI二次开发做准备,mac,user,model,approval
#date: 2015.12.01邮件显示MAC属性信息,简化代码
#date: 2015.12.02修改部分NULL问题,练习left join on 多表联合查询,增加判断是否有重复的MAC
#date: 2015.12.03调试脚本在crontab运行发邮件的测试
#date: 2015.12.04增加对mysql查询和AC的连接做retry动作。
#提醒 如果添加到计划任务,注意 mac.add.del.exp脚本文件 添加删除文件路径
# 如果在手动执行脚本时,请确保计划任务没有正在执行本脚本,要不然有冲突!
#我已经遇到在调试过程中,因为计划任务刚巧在执行这个脚本,我也在手动执行这个脚本,导致AC 的MAC会被全部删除!
#date 2015.12.04 15:38 增加脚本是否已经被执行的判断语句,如果脚本已经被系统执行,那么本次就不执行!
# 使用方法
# 安装expect mysql-client mail
# yum install expect mysql
# mail使用CentOS自带的mailx,测试:echo "`date`" | mail -v -s "测试" user@163.com
# [root@pc0003 sync.for.mail]# pwd
# /sync.for.mail
# [root@pc0003 sync.for.mail]# ll
# -rwxr-xr-x. 1 root root 1.3K 12月 3 16:22 mac.add.del.exp
# -rwxr-xr-x. 1 root root 9.7K 12月 3 17:38 sync.for.mail.sh
# [root@pc0003 sync.for.mail]# vim /etc/crontab
# */5 * * * * root /bin/bash /sync.for.mail/sync.for.mail.sh > /dev/null 2>&1
mysql 8表 联合查询
8表联合查询的sql语句,输出 Mac Type User/Group Computer/Phone/Device AssetTag Status select upper(glpi_items_devicenetworkcards.mac), glpi_devicenetworkcards.designation, concat_ws(‘‘,glpi_users.realname,glpi_users.firstname,glpi_groups.name), concat_ws(‘‘,glpi_computers.name,glpi_peripherals.name,glpi_phones.name), concat_ws(‘‘,glpi_computers.otherserial,glpi_peripherals.otherserial,glpi_phones.otherserial), glpi_states.name from glpi_items_devicenetworkcards left join glpi_computers on glpi_computers.id=glpi_items_devicenetworkcards.items_id left join glpi_peripherals on glpi_items_devicenetworkcards.items_id=glpi_peripherals.id left join glpi_phones on glpi_items_devicenetworkcards.items_id=glpi_phones.id left join glpi_states on (glpi_computers.states_id=glpi_states.id) or (glpi_peripherals.states_id=glpi_states.id) or (glpi_phones.states_id=glpi_states.id) left join glpi_devicenetworkcards on glpi_items_devicenetworkcards.devicenetworkcards_id = glpi_devicenetworkcards.id left join glpi_users on (glpi_computers.users_id=glpi_users.id) or (glpi_peripherals.users_id=glpi_users.id) or (glpi_phones.users_id=glpi_users.id) left join glpi_groups on (glpi_computers.groups_id=glpi_groups.id) or (glpi_peripherals.groups_id=glpi_groups.id) or (glpi_phones.groups_id=glpi_groups.id) where glpi_devicenetworkcards.designation="Wireless" order by glpi_users.name;
邮件内容输出格式:
与AC 交互,有 mac地址查询,添加,删除,3种功能
[root@hghast001 sync.for.mail]# cat mac.add.del.exp
#!/usr/bin/expect -f
set var [lindex $argv 0]
set ip 192.168.AC.IP
set user AC.USER
set password AC.PASSWORD 没有引号
set timeout 1
spawn ssh $user@$ip
expect {
"*yes/no" { send "yes\r"; exp_continue}
"*password:" { send "$password\r" }
}
expect "<ac001>"
send "sys\r"
expect "\[ac001\]"
send "wlan\r"
expect "ac001-wlan-view"
if { $var == "add" } {
send "sta-whitelist-profile id 1\r"
expect "wlan-whitelist-prof"
set fd [open /sync.for.mail/MoreThanAC r]
while {[gets $fd line] != -1} {
expect "wlan-whitelist-prof"
send "sta-mac $line \r"
sleep 1
}
close $fd
}
if { $var == "del" } {
send "sta-whitelist-profile id 1\r"
expect "wlan-whitelist-prof"
set fd [open /sync.for.mail/MoreThanGlpi r]
while {[gets $fd line] != -1} {
expect "wlan-whitelist-prof"
send "undo sta-mac $line \r"
sleep 0.2
}
close $fd
}
if { $var == "search" } {
set i 0
expect "wlan-view"
send "sta-whitelist-profile id 1\r"
expect "wlan-whitelist-prof"
send "d th\r"
while {$i < 7} {
expect "More"
send "\t"
incr i
}
}
send "q \r"
expect "ac001-wlan-view"
send "q \r"
expect "ac001"
send "q \r"
expect "<ac001>"
#send "save all \r"
#expect "Are you sure to continue"
#
#send "y\r"
#expect "<ac001>"
send "q \r"
expect "closed."
#expect eof
interact
[root@hghast001 sync.for.mail]#主程序,会调用上面的与AC交互的程序,用来从mysql查询,Retry,比对,,重复提醒,发送邮件
[root@hghast001 sync.for.mail]# cat sync.for.mail.sh
#!/bin/bash
#date:2015.11.30
#function:将AC与GLPI数据库的MAC同步
#exception.mac单独存放于GLPI数据库,为以后GLPI二次开发做准备,mac,user,model,approval
#date: 2015.12.01邮件显示MAC属性信息,简化代码
#date: 2015.12.02修改部分NULL问题,练习left join on 多表联合查询,增加判断是否有重复的MAC
#date: 2015.12.03调试脚本在crontab运行发邮件的测试
#date: 2015.12.04增加对mysql查询和AC的连接做retry动作。
#提醒 如果添加到计划任务,注意 mac.add.del.exp脚本文件 添加删除文件路径
# 如果在手动执行脚本时,请确保计划任务没有正在执行本脚本,要不然有冲突!
#我已经遇到在调试过程中,因为计划任务刚巧在执行这个脚本,我也在手动执行这个脚本,导致AC 的MAC会被全部删除!
#date 2015.12.04 15:38 增加脚本是否已经被执行的判断语句,如果脚本已经被系统执行,那么本次就不执行!
# 使用方法
# 安装expect mysql-client mail
# yum install expect mysql
# mail使用CentOS自带的mailx,测试:echo "`date`" | mail -v -s "测试" user@163.com
# [root@pc0003 sync.for.mail]# pwd
# /sync.for.mail
# [root@pc0003 sync.for.mail]# ll
# -rwxr-xr-x. 1 root root 1.3K 12月 3 16:22 mac.add.del.exp
# -rwxr-xr-x. 1 root root 9.7K 12月 3 17:38 sync.for.mail.sh
# [root@pc0003 sync.for.mail]# vim /etc/crontab
# */5 * * * * root /bin/bash /sync.for.mail/sync.for.mail.sh > /dev/null 2>&1
#判断脚本是否已经正在被执行
ps aux > thread
grep "bin/bash ./sync.for.mail" thread > /dev/null
let num=`grep "bin/bash ./sync.for.mail" thread | wc -l`
if [ $num -gt 1 ];then
grep "bin/bash ./sync.for.mail" thread
echo "脚本已经被系统执行!,请3分钟后重试!"
rm -rf thread
exit 5
fi
rm -rf thread
#环境
cd /sync.for.mail
export PATH=$PATH:/usr/local/mysql/bin:/usr/lib64/qt-3.3/bin:/usr/local/mysql/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin:/usr/java/jdk1.7.0_79//bin:/usr/java/jdk1.7.0_79/jre/bin:/root/bin
# export TERM=xterm
# flag1全局变量用来判断是否需要向AC添加mac信息
# flag2全局变量用来判断是否需要从AC删除mac信息
# flag3全局变量用来判断是否有变更动作,并发送邮件
# flag4全局变量用来判断是否有重复的mac
clear
flag1=1
flag2=1
flag3=1
flag4=1
#清空临时文件,避免带来影响
cat /dev/null > MoreThanAC
cat /dev/null > MoreThanAC.info
cat /dev/null > MoreThanGlpi
cat /dev/null > MoreThanGlpi.info
cat /dev/null > WirelessView
cat /dev/null > exception.info
cat /dev/null > mail.info
cat /dev/null > GlpiAndExceptionMac
cat /dev/null > WlanMac
cat /dev/null > repeat
touch sync.log
# 日志文件的清空
let SyncLog=`cat sync.log|wc -l`
if [ $SyncLog -gt 9999 ];then
echo "`date` 清空日志" > sync.log
fi
####################################################################
#获取GlpiAndExceptionMac WlanMac 列表,做正反对比
mysql_user="user"
mysql_passwd="PASSWORD"
mysql_host="MYSQL_SERVER_IP"
while [ 1 ]
do
echo "从MySQL获取glpi Wireless Mac 和Exception Mac 列表"
mysql -h$mysql_host -p$mysql_passwd -u$mysql_user -Ne "use glpi; select glpi_devicenetworkcards.designation, upper(glpi_items_devicenetworkcards.mac) from glpi_items_devicenetworkcards,glpi_devicenetworkcards where glpi_items_devicenetworkcards.devicenetworkcards_id = glpi_devicenetworkcards.id and glpi_devicenetworkcards.designation=\"Wireless\";select mac from exception;" | egrep -o "([0-9a-fA-F]{2})(([/\s:][0-9a-fA-F]{2}){5})" | sed ‘s/://g‘|sed -r ‘s/^(.{4})(.{4})(.{4})$/\1-\2-\3/g‘ > MacList
let GlpiMacNum=`cat MacList|wc -l`
# 判断与mysql网络连接
if [ $GlpiMacNum -lt 50 ]
then
echo -e "`date` 正在重试与MySQL联络" >> sync.log
sleep 5
else
#把重复的mac 合并
echo "GLPI+exception有`sort MacList |uniq -c | awk ‘{print $2}‘|wc -l`个无线MAC"
cat MacList >>GlpiAndExceptionMac
break
fi
done
while [ 1 ]
do
echo "获取当前wlan.mac 列表"
expect /sync.for.mail/mac.add.del.exp search |grep "sta-mac" | egrep -o "([0-9a-fA-F]{4})(([/\s-][0-9a-fA-F]{4}){2})"| tr ‘[a-z]‘ ‘[A-Z]‘ > WlanMac
let ACMacNum=`cat WlanMac | wc -l`
if [ $ACMacNum -gt 50 ] ;then
echo "wlan 有`echo $ACMacNum`个无线MAC"
break
else
echo -e "`date` 正在重试与AC 连接" >> sync.log
sleep 5
fi
done
while [ 1 ]
do
echo "获取exception 一览表 "
mysql -h$mysql_host -p$mysql_passwd -u$mysql_user -Ne "use glpi;select * from exception;" > exception.info
let GlpiMacNum=`cat exception.info |wc -l`
# 判断与mysql网络连接
if [ $GlpiMacNum -lt 50 ]
then
echo -e "`date` 正在重试与MySQL联络" >> sync.log
sleep 5
else
break
fi
done
while [ 1 ]
do
echo "获取GLPI MAC地址属性一览表"
# 8表联合查询的sql语句,输出 Mac Type User/Group Computer/Phone/Device AssetTag Status
# select upper(glpi_items_devicenetworkcards.mac),
# glpi_devicenetworkcards.designation,
# concat_ws(‘‘,glpi_users.realname,glpi_users.firstname,glpi_groups.name),
# concat_ws(‘‘,glpi_computers.name,glpi_peripherals.name,glpi_phones.name),
# concat_ws(‘‘,glpi_computers.otherserial,glpi_peripherals.otherserial,glpi_phones.otherserial),
# glpi_states.name
# from glpi_items_devicenetworkcards
# left join glpi_computers on glpi_computers.id=glpi_items_devicenetworkcards.items_id
# left join glpi_peripherals on glpi_items_devicenetworkcards.items_id=glpi_peripherals.id
# left join glpi_phones on glpi_items_devicenetworkcards.items_id=glpi_phones.id
# left join glpi_states on (glpi_computers.states_id=glpi_states.id) or (glpi_peripherals.states_id=glpi_states.id) or (glpi_phones.states_id=glpi_states.id)
# left join glpi_devicenetworkcards on glpi_items_devicenetworkcards.devicenetworkcards_id = glpi_devicenetworkcards.id
# left join glpi_users on (glpi_computers.users_id=glpi_users.id) or (glpi_peripherals.users_id=glpi_users.id) or (glpi_phones.users_id=glpi_users.id)
# left join glpi_groups on (glpi_computers.groups_id=glpi_groups.id) or (glpi_peripherals.groups_id=glpi_groups.id) or (glpi_phones.groups_id=glpi_groups.id)
# where glpi_devicenetworkcards.designation="Wireless"
# order by glpi_users.name;
mysql -h$mysql_host -p$mysql_passwd -u$mysql_user -Ne "use glpi; select upper(glpi_items_devicenetworkcards.mac), glpi_devicenetworkcards.designation, concat_ws(‘‘,glpi_users.realname,glpi_users.firstname,glpi_groups.name), concat_ws(‘‘,glpi_computers.name,glpi_peripherals.name,glpi_phones.name), concat_ws(‘‘,glpi_computers.otherserial,glpi_peripherals.otherserial,glpi_phones.otherserial), glpi_states.name from glpi_items_devicenetworkcards left join glpi_computers on glpi_computers.id=glpi_items_devicenetworkcards.items_id left join glpi_peripherals on glpi_items_devicenetworkcards.items_id=glpi_peripherals.id left join glpi_phones on glpi_items_devicenetworkcards.items_id=glpi_phones.id left join glpi_states on (glpi_computers.states_id=glpi_states.id) or (glpi_peripherals.states_id=glpi_states.id) or (glpi_phones.states_id=glpi_states.id) left join glpi_devicenetworkcards on glpi_items_devicenetworkcards.devicenetworkcards_id = glpi_devicenetworkcards.id left join glpi_users on (glpi_computers.users_id=glpi_users.id) or (glpi_peripherals.users_id=glpi_users.id) or (glpi_phones.users_id=glpi_users.id) left join glpi_groups on (glpi_computers.groups_id=glpi_groups.id) or (glpi_peripherals.groups_id=glpi_groups.id) or (glpi_phones.groups_id=glpi_groups.id) where glpi_devicenetworkcards.designation=\"Wireless\" order by glpi_states.name;" > WirelessView
let GlpiMacNum=`cat WirelessView |wc -l`
# 判断与mysql网络连接
if [ $GlpiMacNum -lt 50 ]
then
echo -e "`date` 正在重试与MySQL联络" >> sync.log
sleep 5
else
break
fi
done
##################################################################
#开始比较,把比AC多的MAC 筛选出来,待添加到AC;如果没有需要添加的mac,邮件中就不会显示这一项
#编程思想:在for循环申明一个stat局部变量初始值为0,如果在每次内循环结束,stat值没有发生变化,说明本次外循环的值没有在内循环找到,这就是要被添加的MAC
for i in `cat GlpiAndExceptionMac`; do
stat=0
for j in `cat WlanMac`; do
if [ $i == $j ] ;then
stat=1
fi
done
if [ $stat -eq 0 ] ;then
#待添加的MAC地址保存到文件 MoreThanAC
echo $i >> MoreThanAC
#转换格式,并把mac地址保存,待发邮件
grep `echo $i | sed ‘s/\-//g‘|sed -r ‘s/^(.{2})(.{2})(.{2})(.{2})(.{2})(.{2})$/\1:\2:\3:\4:\5:\6/g‘` WirelessView >> MoreThanAC.info
flag1=0
fi
done
if [ $flag1 -eq 0 ] ;then
echo "开始向AC添加以下MAC";cat MoreThanAC
#执行添加mac地址的脚本
./mac.add.del.exp add
sed -i "1i往WLAN中新增MAC如下,有 `wc -l MoreThanAC |awk ‘{print $1}‘`个" MoreThanAC.info
#输出添加的mac地址信息到 邮件内容
cat MoreThanAC.info >>mail.info
echo -e "`date` \n`cat MoreThanAC.info`\n" >> sync.log
# 为邮件内容段落换行
echo "">>mail.info
flag3=0
fi
########################################################
#开始比较,把比GLPI多的MAC筛选出来,待从AC中删除;如果没有需要删除的mac,邮件中就不会显示这一项
for i in `cat WlanMac`; do
stat=0
for j in `cat GlpiAndExceptionMac`; do
if [ $i == $j ] ;then
stat=1
fi
done
if [ $stat -eq 0 ] ;then
echo $i >> MoreThanGlpi
#注意:待从AC中删除的MAC,也就是GLPI 中没有的MAC
echo $i | sed ‘s/\-//g‘|sed -r ‘s/^(.{2})(.{2})(.{2})(.{2})(.{2})(.{2})$/\1:\2:\3:\4:\5:\6/g‘ >> MoreThanGlpi.info
flag2=0
fi
done
if [ $flag2 -eq 0 ] ;then
echo -e "\n开始从AC删除以下MAC"; cat MoreThanGlpi
./mac.add.del.exp del
sed -i "1i 从WLAN中删除MAC如下,有 `wc -l MoreThanGlpi |awk ‘{print $1}‘`个" MoreThanGlpi.info
cat MoreThanGlpi.info >>mail.info
echo -e "`date` \n`cat MoreThanGlpi.info`\n" >> sync.log
echo "">> mail.info
flag3=0
fi
############################################################
#判断重复的mac,如果存在重复的mac,就发邮件;如果没有重复的mac,邮件中就不会显示这一项
for j in `sort WirelessView |awk ‘{print $1}‘|uniq -c|awk ‘{if ($1>1) print $2}‘` ; do
grep $j WirelessView >> repeat
if [ $? -eq 0 ] ;then
flag4=0
fi
done
if [ $flag4 -eq 0 ] ;then
flag3=0
sed -i "1iGLPI 数据库重复的Wireless MAC信息如下" repeat
cat repeat >> mail.info
echo "">>mail.info #段与段之间隔开
fi
############################################################
#如果有任何wireless mac 变动,发邮件出来
if [ $flag3 -eq 0 ] ;then
echo -e "GLPI Wireless Mac 一览表\n Mac Type User/Group Computer/Phone/Device AssetTag Status\n">>mail.info
cat -n WirelessView >> mail.info
echo -e "\n\nWLAN Exception Mac 一览表\n Mac User Model Approver\n ">>mail.info
cat -n exception.info >> mail.info
while [ 1 ]
do
echo "正在发送邮件"
cat mail.info | /bin/mail -v -s "Wireless Mac变更通知" Team_IT@公司logo.cn |grep "公司logo.cn.*Sent"
if [ $? -eq 0 ];then
echo "邮件发送成功"
break
else
echo "重新 发送邮件"
sleep 10
fi
done
else
echo -e "`date` 没有任何变动,就不发邮件了。" >> sync.log
fi
#清除临时文件
rm -rf MoreThanAC
rm -rf MoreThanAC.info
rm -rf MoreThanGlpi
rm -rf MoreThanGlpi.info
rm -rf WirelessView
rm -rf exception.info
rm -rf mail.info
rm -rf GlpiAndExceptionMac
rm -rf WlanMac
rm -rf MacList
rm -rf repeat
[root@hghast001 sync.for.mail]#本文出自 “折腾岁月。” 博客,谢绝转载!
AC 与 GLPI的MAC地址自动同步脚本 expect mail 【原创】
原文:http://990487026.blog.51cto.com/10133282/1719628