/etc/motd
里可以设置登录 Linux 服务器时显示的信息,但是只能显示静态信息,如果需要动态信息,可以通过 /etc/profile.d/
下的脚本来实现。本文记录一种通过脚本调用 CMDB 接口获取服务器的业务,机房,状态以及联系人信息,在登录时显示的方法。效果如下图。
Contents
CMDB接口规格
为简化 Shell 脚本的调用,CMDB 接口直接输出显示结果, 即带颜色的服务器信息。以下是基于 iTop CMDB 的实现实例。
<?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
即可。计划任务脚本如下:
#!/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=$[1]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
。
# 登录时显示机器业务信息
user=`who am i |awk '{print $1}'`
userSu=`whoami`
# 通过su sudo切换后,user和userSu变量将不同,此时不显示登录信息
if [ "$user"x == "$userSu"x ];then
cat /etc/logininfo.conf
fi
(全文完)
参考资料
↑1 | RANDOM%300 |
---|
发表回复