Реализация стандартного шлюза Cisco на BeanShell
Материал из BiTel WiKi
конфигурация типа шлюза:
user_rule.editor.class=bitel.billing.module.services.ipn.editor.CiscoContractRuleEditor gate_manager.class=bitel.billing.server.ipn.CiscoGateWorker use.script=1
import java.util.*; import java.util.regex.*; import bitel.billing.common.module.ipn.*; import bitel.billing.server.ipn.bean.*; import bitel.billing.server.util.*; import bitel.billing.server.util.ssh.*; import ru.bitel.bgbilling.common.*;
protected void doSync()
{
host = gate.getHost();
port = gate.getPort();
gid = gate.getId();
gateSetup = new DefaultServerSetup( gate.getConfig(), "\r\n" );
login = gateSetup.getStringValue( "login", "root" );
pswd = gate.getKeyword();
timeout = gateSetup.getIntValue( "timeout", 0 );
if( log.isDebugEnabled() )
{
log.debug( gid + " gate: " + host + ":" + port + " login: " + login + " pswd: " + pswd );
}
session = null;
try
{
session = new SSHSession( host, port, login, pswd );
session.setTimeout( timeout );
session.connect();
session.command( "terminal length 0" );
result = new StringBuffer();
list = ( session.command( "show access-list" ) );
result.append( list );
if( log.isDebugEnabled() )
{
log.debug( gid +" AccessList taking.." );
log.debug( result );
}
// код ACL - стуктура с описанием
aclMap = AclOptions.getAclMapById( gateSetup );
// имя ACL - стуктура с описанием
aclByNameMap = new HashMap();
for( AclOptions option : aclMap.values() )
{
aclByNameMap.put( option.name, option );
}
result.append( session.command( "configure terminal" ) );
// проход по ACL списку с отметкой какие договора открыты
markOpenFromRules( list, aclByNameMap );
// подготовка списка корректирующих команд
buildCommandsLists( aclMap );
for( AclOptions options : aclMap.values() )
{
if( options.commands.size() > 0 )
{
// TODO: extended или нет - надо смотреть в конфиге
result.append( session.command( "ip access-list extended " + options.name ) );
if( log.isDebugEnabled() )
{
log.debug( gid + " ACL " + options.name );
}
for( String command : options.commands )
{
if( log.isDebugEnabled() )
{
log.debug( gid + " " + command );
}
result.append( session.command( command ) );
}
}
}
result.append( session.command( "end" ) );
result.append( session.command( "exit", false ) );
if (log.isDebugEnabled())
{
log.debug( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
log.debug( result.toString() );
log.debug( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
}
// пауза пока считает команду exit
sleep( 100 );
}
catch ( Exception e )
{
throw new RuntimeException ( e );
}
finally
{
if( session != null )
{
session.disconnect();
}
}
}
private void buildCommandsLists( aclMap ) {
for( status : statusList )
{
CiscoRuleOptions ruleOptions = CiscoRuleOptions.extractParams( status.rule.getRuleText() );
AclOptions options = aclMap.get( ruleOptions.aclId );
// флаг того то правило есть на шлюзе
boolean flag = false;
// правило для этого договора есть на шлюзе
if ( options.openRulesFrom.containsKey( ruleOptions.fromPos ) )
{
// если правило есть а юзер заблокирован - удаляем правило
if ( status.status > 0 )
{
if( options != null )
{
Set rules = options.openRulesFrom.get( ruleOptions.fromPos );
if( rules != null )
{
for( rule : rules )
{
options.commands.add( "no " + rule );
}
}
}
}
flag = true;
options.openRulesFrom.remove( ruleOptions.fromPos );
}
// правила нет, а юзер открыт - добавляем правило
if ( !flag &&
status.status == IPNContractStatus.STATUS_OPEN )
{
String rule = CiscoRuleOptions.clearFromParams( status.rule.getRuleText() );
AclOptions acl = aclMap.get( ruleOptions.aclId );
if( acl != null )
{
// типизированное правило
if( status.ruleType != null )
{
rule = generateRule( rule, status.gateType, status.ruleType );
}
rulePos = ruleOptions.fromPos;
st = new StringTokenizer( rule, "\r\n" );
while( st.hasMoreTokens() )
{
line = st.nextToken().trim();
acl.commands.add( (rulePos++) + " " + line );
}
}
}
}
}
private void markOpenFromRules( result, aclByNameMap) {
gid = gate.getId();
line = null;
currentAclOptions = null;
st = new StringTokenizer( result, "\r\n" );
while( st.hasMoreTokens() )
{
line = st.nextToken().trim();
accessPattern = Pattern.compile( "access list\\s+([\\w\\-]+)" ); m = accessPattern.matcher( line );
if( m.find() )
{
currentAcl = m.group( 1 );
currentAclOptions = aclByNameMap.get( currentAcl );
if( log.isDebugEnabled() )
{
log.debug( gid + " ACL " + currentAcl + " not in billing control.." );
}
continue;
}
if( currentAclOptions == null )
{
continue;
}
rulePattern = Pattern.compile( "^(\\d+)\\s+((permit)|(deny))" );
m = rulePattern.matcher( line );
if( m.find() )
{
rule = Utils.parseIntString( m.group( 1 ) );
if( rule < currentAclOptions.fromPos ||
rule > currentAclOptions.toPos )
{
if( log.isDebugEnabled() )
{
log.debug( gid + " Skip rule " + line );
}
}
else
{
ruleFrom = ((rule - currentAclOptions.fromPos) / currentAclOptions.onContact) * currentAclOptions.onContact + currentAclOptions.fromPos;
Set rules = currentAclOptions.openRulesFrom.get( ruleFrom );
if( rules == null )
{
rules = new HashSet();
currentAclOptions.openRulesFrom.put( ruleFrom, rules );
}
rules.add( rule );
if( log.isDebugEnabled() )
{
log.debug( gid + " Contact open from rule: " + ruleFrom );
}
}
}
}
}
public static String generateRule( addresses, gateType, ruleType ) {
ruleText = ManadUtils.getRule( gateType, ruleType ); return ManadUtils.generateRule( ruleText, addresses, null, ruleType );
}
</source >
