{
    "name"  : "端口反复震荡触发SSC进程内存泄露",
    "problems" : {
        "copper_check" : {
            "desc"      : "【问题】设备存在端口${0}存在反复震荡导致SSC进程内存泄露。",
            "advice"    : "【建议】检查网线质量，建议更换环路。同时升级最新版或重启SSC进程可暂时自动修复。"
        },
        "fiber_check" : {
            "desc"      : "【问题】设备存在端口${0}为非锐捷光模块导致端口反复震荡引起SSC进程内存泄露。",
            "advice"    : "【建议】更换锐捷防伪光模块。同时升级最新版或重启SSC进程可暂时自动修复。"
        },
		"ruijie_light_module" : {
		    "desc"      : "【问题】设备存在端口XX为存在反复震荡引起SSC进程内存泄露。",
			"advice"    : "【建议】请检查光纤、光模块是否存在质量问题。同时升级最新版或重启SSC进程可暂时自动修复。"
		}
    }
}

---------------------------code-------------------------------
#检测设备是否匹配适用版本
cli_result = cli('show version')

#匹配到版本为11.0(1)B2、11.0(2)B1、11.0(3)B1、11.0(4)B1、11.4(1)B1，否则不执行该规则
reg = /(11.0\(1\)B2|11.0\(2\)B1|11.0\(3\)B1|11.0\(4\)B1|11.4\(1\)B1)/

if !reg.test(cli_result) :
    return 'skip'
end

#全局变量
state = 'PASS'
intf = []

#step 1------------------------------
cli_result = cli('show interface link-state-change statistics')
cli_result_list = cli_result.split('\r\n')
reg = /([^ ]+)\s+\w+\s+(\d+)\s+[^ ]+\s+[^ ]+/
foreach line in cli_result_list :
    matches = line.match(reg)
    if matches != null :
        if matches[2] > 100 :
		    #获取震荡次数超过100的端口
			port = marches[1]
		    intf.push(port)
			state = 'CONTINUE'
		end
	end
end

#step 2-------------------------------
is_continue()

cli_result = cli('show memory ssc_process')
reg = /System Memory: \d+KB total, \d+KB used, \d+KB free, ([\d\.]+)% used rate/
matches = cli_result.match(reg)
device_mode = get_device_model()
if matches != null :
	if device_mode.match(/(s78\d{2}e|s86\d{2}e|n18\d{3})$/i) :
		if marches[1] > 60:
			state = 'CONTINUE'
		end
	else :
		if marches[1] > 80:
			state = 'CONTINUE'
		end
	end
end

#step 3---------------------------------
is_continue()

foreach item in intf :
    type = check_type(item)
	if type != 'other' :
	    change_title('检测端口反复震荡触发SSC进程内存泄露')
		restore_cmd = 'run-system-shell Pkill -9 ssc_porcess Exit'
		if type == 'copper' :
			add_problem('copper_check',[item],restore_cmd)
			return 'warn'
		else if type == 'noruijie' :
		    add_problem('fiber_check',[item],restore_cmd)
			return 'warn'
		else if type == 'ruijie' :
			add_problem('ruijie_light_module',[item],restore_cmd)	
			return 'warn'
		end
	else :
	    state = 'CONTINUE'	
	end   
end

#step 4---------------------------------
is_continue()

change_title('未检测到端口反复震荡触发SSC进程内存泄露')
return 'success'

#----------------------------------
def is_continue():
	if state == 'PASS' :
		return 'skip'
	else :
		state = 'PASS'                                  
	end 
end

def check_type(port):
    cmd = format('show interfaces %s status',port)
    cli_result = cli(cmd)
    if cli_result.search('copper') != -1 :
        return 'copper'
	else if cli_result.search('fiber') != -1 :
	    if is_ruijie_module(port) : 
		    return 'ruijie'
		else :
		    return 'noruijie'
		end
	else :
	    return 'other'
    end	
end

def is_ruijie_module(port):
    cmd = format('show interfaces %s transceiver',port)
    cli_result = cli(cmd)
    if cli_result.search('Unknown') != -1:
        return 1
    end
    
    #是光模块则继续判断
    if cli_result.search('Transceiver Type') != -1 :
        cmd = format('show interfaces %s transceiver manuinfo',port)
        cli_result = cli(cmd)
        if is_match_ruijie_module(cli_result) :
            return 1
        end
    end
    return 0
end

def is_match_ruijie_module(str):
    reg_str = 'RUIJIE,XGIGA,FIBERXON,Star-cn,Gigalight,Volex Inc,Tyco,FINISAR,AVAGO,INNOLIGHT,OPNEXT,WTD,HG GENUINE,TRIXON INC'
    reg_str_list = reg_str.split(',')
    foreach data in reg_strList:
        if str.search(data) != -1:
            return 1
        end
    end
    return 0
end
