{
    "name"  : "系统是否主动关闭端口",
    "problems" : {
        "shutdown" : {
            "desc"      : "【问题】端口${0} 由于用户主动shutdown，导致端口无法LINKUP",
            "advice"    : ["【建议】重新配置，打开端口"
                          ,"配置举例： "
                          ,"\t\tRuijie#config "
                          ,"\t\tRuijie(config)#interface ${0} "
                          ,"\t\tRuijie(config-if)#no shutdown "
                          ,"\t\tRuijie(config-if)#en "
                          ,"\t\tRuijie#write"]
        },
        "phylink" : {
            "desc"      : "【问题】端口${0}检测到链路震荡，系统自动关闭震荡端口",
            "advice"    : ["【建议】"
                          ,"端口震荡常见原因及处理措施： "
                          ,"\t1. 线路（光模块/光纤/网线）未插紧或线路故障导致信号不稳定，请尝试重新插紧或更换线路（光模块/光纤/网线）测试。 "
                          ,"\t2. 端口硬件故障导致信号不稳定，请尝试将网线或光模块插在设备其它空闲端口上测试。 "
                          ,"\t3. 在配置模式下使用命令no physical-port dither protect关闭端口震荡检测规避此问题。 "
                          ,"规避方法示例： "
                          ,"\tRuijie#config "
                          ,"\tRuijie(config)#no physical-port dither protect "
                          ,"\tRuijie(config)#interface gigabitEthernet 1/1 "
                          ,"\tRuijie(config-if-GigabitEthernet 1/1)#no shutdown "
                          ,"\tRuijie(config-if-GigabitEthernet 1/1)#en "
                          ,"\tRuijie#write"]
        },
        "rldp" : {
            "desc"      : "【问题】端口${0}检测到环路，系统自动关闭环路端口",
            "advice"    : ["【建议】端口${1}存在环路，请按以下步骤排查（环路排查过程中可能引起设备丢包或CPU利用率增高）： "
                          ,"\t1. 关闭端口${2}的环路检测功能：no rldp enable "
                          ,"\t2. 查看端口及下联设备端口计数是否异常放大，逐级往下排查直到找到环路源。 "
                          ,"\t3. 如果步骤2无法定位，恢复端口并在端口上抓包，查看报文MAC/IP特征，确定报文源，恢复端口的命令是：rldp reset。"]
        }
    }
}
---------------------------code-------------------------------
#系统是否主动关闭端口
param = {}
param["status"] = precondition('status')
param["type"] = precondition('type')
param["name"] = precondition('name')
paramName = param["name"]
def jumpOut(proType):

    if proType == null:
        return 'skip'
    end
    if proType == 'shutdown':
        restore_cmd = []
        restore_cmd.push('end')
        restore_cmd.push('config')
        cmd = 'interface ' + paramName
        restore_cmd.push(cmd)
        restore_cmd.push('no shutdown')
        restore_cmd.push('end')
        restore_cmd.push('write')
        
        reback_cmd = []
        reback_cmd.push('end')
        reback_cmd.push('config')
        cmd = 'interface ' + paramName
        reback_cmd.push(cmd)
        reback_cmd.push('shutdown')
        reback_cmd.push('end')
        reback_cmd.push('write')
        add_problem('shutdown', [paramName], restore_cmd, reback_cmd)
        return 'warn'
    end
    if proType == 'phylink':
        add_problem('phylink', [paramName])
        return 'warn'
    end
    if proType == 'rldp':
        add_problem('rldp', [paramName,paramName,paramName])
        return 'warn'
    end
    return 'success'
end

def third():
    cmd = format('show rldp interface %s', paramName) 
    response = cli(cmd)
    responseArr = response.match(/port state[ ]*:[ ]*error(?:.|\r|\n)*?loop detect information[ ]*:(?:.|\r|\n)*?\saction:[ ]*shutdown-port/i)
    if responseArr != null:
        res = jumpOut('rldp')
        return res
    else:
        return 'success'
    end
    
end

def second():
    cmd = 'show run | include physical-port dither protect ' + paramName
    response = cli(cmd)
    if isInvalidCli(response):
        add_reason('无效指令：show run | include physical-port dither protect')
        return 'skip' 
    end
    responseArr = response.match(/\| include [^\r\n]*[\r\n]+(?:.|\r|\n)*?(physical\-port dither protect)/i)
    if responseArr == null:
        cmd = format('show log | include %s', paramName)
        response = cli(cmd)
        if isInvalidCli(response):
            add_reason('无效指令：show log | include')
            return 'skip' 
        end
        responseArr = response.match(/the interface will be shutdown\.[ ]*Please check the physical link/i)
        if responseArr != null:
            res = jumpOut("phylink") 
            return res
        else:
            res = third()
            return res
        end
    else:
        res = third()
        return res
    end
end

def first(response):
    responseArr = response.match(/shutdown/) 
    if responseArr != null:
        cli("configure")
        cmd = "interface " + paramName
        response = cli(cmd)
        response = cli('no shutdown')
        if isInvalidCli(response):
            add_reason('无效指令：interface')
            return 'skip' 
        end
        sleep(4000)
        cmd = format("show interface %s status", paramName)
        response = cli(cmd)
        if isInvalidCli(response):
            add_reason('无效指令：show interface')
            return 'skip' 
        end
        responseArr = response.match(/-----[ ]*[\r\n]+[^\r\n]*? (up)[ ]/i)   
        if responseArr != null:
            response = cli("shutdown")
            response = cli("end")
            res = jumpOut("shutdown")
            return res
        end        
        res = second()
        return res
    else:
        res = second()
        return res
    end    
end

def start():
    if param["status"] == 'up':
        res = jumpOut(null)
        return res
    end
    cmd = "show run interface " + paramName
    response = cli(cmd)
    if  isInvalidCli(response):
        add_reason('无效指令：show run interface')
        return 'skip' 
    end
    res = first(response)
    return res
end

start()


