/etc/motd
里可以设置登录 Linux 服务器时显示的信息,但是只能显示静态信息,如果需要动态信息,可以通过 /etc/profile.d/
下的脚本来实现。本文记录一种通过脚本调用 CMDB 接口获取服务器的业务,机房,状态以及联系人信息,在登录时显示的方法。效果如下图。
Contents
CMDB接口规格
为简化 Shell 脚本的调用,CMDB 接口直接输出显示结果, 即带颜色的服务器信息。以下是基于 iTop CMDB 的实现实例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
<?php /** * Usage: * File Name: logininfo.php * Author: annhe * Created Time: 2017-03-29 10:05:48 * 用于登录机器时打印机器信息 * 机器上部署计划任务访问此接口 **/ require 'common/init.php'; define('HEAD',"\n##################### Server Info ######################\n"); define('WARN',"WARNING!!此机器未登记业务信息,有被下线风险"); define('TIP',"如果您认为以上信息有误,请及时联系运维修正错误"); define('TAIL',"\n########################################################\n"); function red($text) { return "\033[31m $text \033[0m"; } function blink($text) { return "\033[5;33m $text \033[0m"; } function skyblue($text) { return "\033[36m $text \033[0m"; } function yellow($text) { return "\033[33m $text \033[0m"; } function white($text) { return "\033[37m $text \033[0m"; } function errorInfo() { $info = HEAD . skyblue("获取业务信息失败,请联系运维") . TAIL; return $info; } function getApps($relations) { $apps = []; foreach($relations as $k => $v) { if(preg_match("/^Server::.*/", $k)) { foreach($v as $key => $val) { if(preg_match('/^ApplicationSolution::.*/', $val['key'])) { $item = explode('::', $val['key'])[2]; $item = explode('.', $item)[1]; $apps[] = $item; } } } } return $apps; } function getServerLoginInfo($ip) { global $iTopAPI; $query = "SELECT Server AS s JOIN PhysicalIP AS ip ON ip.connectableci_id=s.id WHERE ip.ipaddress = '$ip'"; $optional = array( 'output_fields' => array("Server"=>"status,location_name","ApplicationSolution"=>"name"), 'show_relations' => ["Server","ApplicationSolution","Location","Person"], 'hide_relations' => [], 'direction' => 'both', 'filter' => ["Server","ApplicationSolution","Person"], 'depth' => 2, ); $data = $iTopAPI->extRelated("Server", $query, "impacts", $optional); $data = json_decode($data, true); $obj = $data['objects']; if(!$obj) { return(errorInfo()); } $relations = $data['relations']; $apps = getApps($relations); $contacts = []; $location = ""; $status = ""; $map_status=array("production"=>"使用中","stock"=>"库存(此状态随时可能被下线)", "obsolete"=>"废弃(此状态随时可能被重装或关机)","implementation"=>"上线中"); foreach($obj as $k => $v) { if($v['class'] == "Person") { $contacts[] = $v['fields']['friendlyname']; } if($v['class'] == "Server") { $location = $v['fields']['location_name']; $status = $map_status[$v['fields']['status']]; } } if(!$apps) { $apps = blink("业 务:" . WARN); } else { $apps = implode(",", $apps); $apps = red("业 务:" . $apps); } $contacts = implode(",", $contacts); $info = HEAD; $info .= $apps . "\n"; $info .= skyblue("机 房:" . $location) . "\n"; $info .= skyblue("状 态:" . $status) . "\n"; $info .= white("联系人:" . $contacts) . "\n"; $info .= "\n" . yellow(TIP) . TAIL; return($info); } if(isset($_GET['ip'])) { $ip = $_GET['ip']; $key = "logininfo_" . $ip; if(isset($_GET['cache']) && $_GET['cache'] == "set") { $ret = getServerLoginInfo($ip); die(setCache($key, $ret)); } if(isset($_GET['cache']) && $_GET['cache'] == "false") { die(getServerLoginInfo($ip)); }else { // 首先获取缓存内容 $ret = getCache($key); if(!$ret) { $ret = getServerLoginInfo($ip); setCache($key, $ret); } die($ret); } }else { die(errorInfo()); } |
计划任务脚本
考虑到登录时才调用 CMDB,可能会有延迟,导致用户体验差,所以通过计划任务定时将获取信息,存储到 /etc/logininfo.conf
中,/etc/profile.d
下的脚本直接输出 logininfo.conf
即可。计划任务脚本如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#!/bin/bash # crontab需要设置PATH export PATH=$PATH:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin infoFile="/etc/logininfo.conf" tmpFile="/tmp/logininfo.conf" # 随机等待一段时间,防止cmdbapi请求量过大 if [ $# -lt 1 ];then waitS=$((RANDOM%300)) sleep $waitS fi # 登录时显示机器业务信息 IP=`ip add |grep -E "inet 10\." |grep -v "/32" |awk '{print $2}' |cut -f1 -d'/' |head -n 1` curl --connect-timeout 2 -s "http://cmdb.xxx.com/api/logininfo.php?ip=$IP" >$tmpFile grep "# Server Info #" $tmpFile &>/dev/null && cat $tmpFile > $infoFile |
但是这种方法会频繁调用 CMDB 接口,如果服务器量级较大,可能会对 CMDB 造成一定压力,CMDB 端应加缓存来优化性能。
profile脚本
然后在 /etc/profile.d/
下新建一个文件 info.sh
。
1 2 3 4 5 6 7 |
# 登录时显示机器业务信息 user=`who am i |awk '{print $1}'` userSu=`whoami` # 通过su sudo切换后,user和userSu变量将不同,此时不显示登录信息 if [ "$user"x == "$userSu"x ];then cat /etc/logininfo.conf fi |
(全文完)
发表回复