Реализация стандартного шлюза Cisco на BeanShell
Материал из BiTel WiKi
(Различия между версиями)
Stark (Обсуждение | вклад) (Поправил шлюз в соотвествии с версией 4.6. добавил timeout) |
Stark (Обсуждение | вклад) (Поправил шлюз в соотвествии с версией 4.6) |
||
Строка 172: | Строка 172: | ||
if( status.ruleType != null ) | if( status.ruleType != null ) | ||
{ | { | ||
- | rule = | + | rule = generateRule( rule, status.gateType, status.ruleType ); |
} | } | ||
Версия 08:53, 16 марта 2009
конфигурация типа шлюза:
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<String, AclOptions>(); 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<Integer> 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<Integer> rules = currentAclOptions.openRulesFrom.get( ruleFrom ); if( rules == null ) { rules = new HashSet<Integer>(); 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 ); }