{
    "name"  : "环路检测",
    "problems" : {
        "loop_check_muti" : {
            "desc"      : "【问题】 经检查端口${0}广播流量异常可能存在环路。",
            "advice"    : "【建议】 建议端口开启rldp功能解决环路问题，点击自动修复可解决该问题。注意：环路情况下有端口会被rldp shutdown。"
        },
        "loop_check_single" : {
            "desc"      : "【问题】 经检查端口${0}广播流量异常，下行端口存在环路。",
            "advice"    : "【建议】 建议优先排查下行网络环路问题，如影响到该设备网络运行可先行shutdown该端口。"
        }
    }
}
---------------------------code-------------------------------
stepResult = 'PASS'
result = 'PASS'
i = 0
port = ''

#step 1------
log_version = cli('show version')
if !log_version.match(/11./) :
    return 'skip'    
end

#step 2------
cli('clear counters')
cli('clear cpu-protect counters')
sleep(2000)

log_cpu_mboard = cli('show cpu-protect mboard')
if !is_drop(log_cpu_mboard):
    return 'skip'
end

log_slot = cli('show version slots')
log_slotList = log_slot.split('\r\n')
foreach data in log_slotList:
    r = data.match(/(\d+)\s+(\d+)\s+\d+[^\n]+ok/)
    if r!= null:
        dev = r[1]
        slot = r[2]
        if is_vsu():
            cmd = format('show cpu-protect slot %s/%s',dev,slot)
        else:
            cmd = format('show cpu-protect slot %s',slot)
        end
        log_cpu_card = cli(cmd)
        if !is_drop(log_cpu_card):
            return 'skip'
        end
    end
end

#step 3------
log_intf_usage = cli('show interfaces usage')
log_intf_usageList = log_intf_usage.split('\r\n')
reg_usage = /(\w+Ethernet\s+[^ ]+)\s+\d+\s+\w+bit\s+([\d\.]+)%/
j = 0
foreach data in log_intf_usageList:
    r = data.match(reg_usage)
    if r != null:
        if r[2] > 10:
            intf_list[j] = r[1]
		end
	end
	j = j + 1
end

#step 4------
restore_cmd = []
reback_cmd = []
foreach intf in intf_list :
    cmd = format("show interfaces %s counters summary",intf)
    log_intf_summary = cli(cmd)
    if is_loop(log_intf_summary):
        result = 'FAIL'
	    restore_cmd.push('interface ')
		restore_cmd.push(intf)
		restore_cmd.push('rldp port loop-detect shutdown-port')
		
        reback_cmd.push('interface ')
		reback_cmd.push(intf)
		reback_cmd.push('no rldp port loop-detect')

        port = port + intf + '、'
        i = i + 1
    end
end

if result == 'FAIL' && i >= 2 :
    change_title('检查到环境中存在环路')
	restore_cmd.unshift('config rldp enable ')
	reback_cmd.unshift('config no rldp enable ')
    add_problem('loop_check_muti',[port],restore_cmd,reback_cmd)
    return 'warn'
end
if result == 'FAIL' && i == 1 :
    change_title('检查到环境中存在环路')
	restore_cmd.unshift('config ')
	reback_cmd.unshift('config no ')
    add_problem('loop_check_single',[port],restore_cmd,reback_cmd)
    return 'warn'
end
change_title('未检测到环境中存在环路')
return 'success'

def is_loop(str):
    result = 0
    strList = str.split('\r\n')
    reg_intf_loop = /[^ ]+\s+\d+\s+(\d+)\s+(\d+)\s+(\d+)/
    i = 0
    foreach data in strList:
        r = data.match(reg_intf_loop)
        if r != null:
            used_1 = r[1]
            used_2 = r[2]
            used_3 = r[3]
            used = parse_int(used_2)+parse_int(used_3)
            total = parse_int(used_1)+parse_int(used_2)+parse_int(used_3)
            proportion = used/total
            if proportion > 0.1:
                result = 1
                return result
            end
        end
    end
    return result
end

def is_drop(str):
    result = 0
    strList = str.split('\r\n')
    reg_11 = /[^ ]+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+(\d+)/
    reg_10 = /[^ ]+\s+\d+\s+\d+\s+(\d+)/
    foreach data in strList:
        r11 = data.match(reg_11)
        r10 = data.match(reg_10)
        if r11 != null:
            if r11[1] > 0:
                result = 1
                break
            end
        end 
        if r10 != null:
            if r10[1] > 0:
                result = 1
                break
            end
        end 
    end
    return result
end

def is_vsu():
    str = cli('show switch virtual config')
	if str.search('Invalid input | Unknown command.') == -1 :
        add_reason('无效指令：show switch virtual config')
        return 'skip'    
    end
    if str.search('switch convert mode virtual') :
        return 1
    else:
        return 0
    end
end
