Реализация стандартного шлюза Cisco на BeanShell
Материал из BiTel WiKi
(Различия между версиями)
Stark (Обсуждение | вклад) (Поправил шлюз в соотвествии с версией 4.6) |
Stark (Обсуждение | вклад) (исправил ошибки) |
||
(4 промежуточные версии не показаны) | |||
Строка 1: | Строка 1: | ||
конфигурация типа шлюза: | конфигурация типа шлюза: | ||
+ | |||
+ | От циски ожидается такое поведение (если начнет повисать и т.п) : | ||
+ | <source lang="bash"> | ||
+ | .. | ||
+ | login:xxxx | ||
+ | passsword: | ||
+ | |||
+ | # | ||
+ | </source> | ||
+ | |||
+ | Приглашение должно оканчиваться обязательно на # . Таково поведение стандартного шлюза cisco и скрипт его повторяет. | ||
<source lang="bash"> | <source lang="bash"> | ||
Строка 16: | Строка 27: | ||
import bitel.billing.server.util.ssh.*; | import bitel.billing.server.util.ssh.*; | ||
import ru.bitel.bgbilling.common.*; | import ru.bitel.bgbilling.common.*; | ||
- | + | ||
- | + | ||
protected void doSync() | protected void doSync() | ||
{ | { | ||
Строка 23: | Строка 34: | ||
port = gate.getPort(); | port = gate.getPort(); | ||
gid = gate.getId(); | gid = gate.getId(); | ||
- | + | ||
gateSetup = new DefaultServerSetup( gate.getConfig(), "\r\n" ); | gateSetup = new DefaultServerSetup( gate.getConfig(), "\r\n" ); | ||
- | + | ||
login = gateSetup.getStringValue( "login", "root" ); | login = gateSetup.getStringValue( "login", "root" ); | ||
pswd = gate.getKeyword(); | pswd = gate.getKeyword(); | ||
- | + | ||
timeout = gateSetup.getIntValue( "timeout", 0 ); | timeout = gateSetup.getIntValue( "timeout", 0 ); | ||
- | + | ||
if( log.isDebugEnabled() ) | if( log.isDebugEnabled() ) | ||
{ | { | ||
log.debug( gid + " gate: " + host + ":" + port + " login: " + login + " pswd: " + pswd ); | log.debug( gid + " gate: " + host + ":" + port + " login: " + login + " pswd: " + pswd ); | ||
} | } | ||
- | + | ||
session = null; | session = null; | ||
- | + | ||
+ | System.out.println("1111111111111111"); | ||
+ | |||
try | try | ||
{ | { | ||
Строка 43: | Строка 56: | ||
session.setTimeout( timeout ); | session.setTimeout( timeout ); | ||
session.connect(); | session.connect(); | ||
- | + | ||
session.command( "terminal length 0" ); | session.command( "terminal length 0" ); | ||
- | + | ||
result = new StringBuffer(); | result = new StringBuffer(); | ||
- | + | ||
- | + | ||
list = ( session.command( "show access-list" ) ); | list = ( session.command( "show access-list" ) ); | ||
result.append( list ); | result.append( list ); | ||
- | + | ||
if( log.isDebugEnabled() ) | if( log.isDebugEnabled() ) | ||
{ | { | ||
Строка 57: | Строка 70: | ||
log.debug( result ); | log.debug( result ); | ||
} | } | ||
- | + | ||
// код ACL - стуктура с описанием | // код ACL - стуктура с описанием | ||
aclMap = AclOptions.getAclMapById( gateSetup ); | aclMap = AclOptions.getAclMapById( gateSetup ); | ||
- | + | ||
// имя ACL - стуктура с описанием | // имя ACL - стуктура с описанием | ||
- | + | ||
- | aclByNameMap = new HashMap | + | aclByNameMap = new HashMap(); |
for( AclOptions option : aclMap.values() ) | for( AclOptions option : aclMap.values() ) | ||
{ | { | ||
aclByNameMap.put( option.name, option ); | aclByNameMap.put( option.name, option ); | ||
} | } | ||
- | + | ||
result.append( session.command( "configure terminal" ) ); | result.append( session.command( "configure terminal" ) ); | ||
- | + | ||
+ | System.out.println("222222222222222"); | ||
+ | |||
// проход по ACL списку с отметкой какие договора открыты | // проход по ACL списку с отметкой какие договора открыты | ||
markOpenFromRules( list, aclByNameMap ); | markOpenFromRules( list, aclByNameMap ); | ||
- | + | System.out.println("33333333333333333333333"); | |
// подготовка списка корректирующих команд | // подготовка списка корректирующих команд | ||
buildCommandsLists( aclMap ); | buildCommandsLists( aclMap ); | ||
- | + | ||
for( AclOptions options : aclMap.values() ) | for( AclOptions options : aclMap.values() ) | ||
{ | { | ||
Строка 83: | Строка 98: | ||
// TODO: extended или нет - надо смотреть в конфиге | // TODO: extended или нет - надо смотреть в конфиге | ||
result.append( session.command( "ip access-list extended " + options.name ) ); | result.append( session.command( "ip access-list extended " + options.name ) ); | ||
- | + | ||
if( log.isDebugEnabled() ) | if( log.isDebugEnabled() ) | ||
{ | { | ||
log.debug( gid + " ACL " + options.name ); | log.debug( gid + " ACL " + options.name ); | ||
} | } | ||
- | + | ||
for( String command : options.commands ) | for( String command : options.commands ) | ||
{ | { | ||
Строка 99: | Строка 114: | ||
} | } | ||
} | } | ||
- | + | System.out.println("44444444444444444444444444"); | |
result.append( session.command( "end" ) ); | result.append( session.command( "end" ) ); | ||
result.append( session.command( "exit", false ) ); | result.append( session.command( "exit", false ) ); | ||
- | + | ||
if (log.isDebugEnabled()) | if (log.isDebugEnabled()) | ||
{ | { | ||
Строка 109: | Строка 124: | ||
log.debug( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" ); | log.debug( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" ); | ||
} | } | ||
- | + | ||
// пауза пока считает команду exit | // пауза пока считает команду exit | ||
- | sleep( | + | Thread.sleep( 200 ); |
} | } | ||
catch ( Exception e ) | catch ( Exception e ) | ||
Строка 125: | Строка 140: | ||
} | } | ||
} | } | ||
- | + | ||
private void buildCommandsLists( aclMap ) | private void buildCommandsLists( aclMap ) | ||
{ | { | ||
Строка 132: | Строка 147: | ||
CiscoRuleOptions ruleOptions = CiscoRuleOptions.extractParams( status.rule.getRuleText() ); | CiscoRuleOptions ruleOptions = CiscoRuleOptions.extractParams( status.rule.getRuleText() ); | ||
AclOptions options = aclMap.get( ruleOptions.aclId ); | AclOptions options = aclMap.get( ruleOptions.aclId ); | ||
- | + | ||
// флаг того то правило есть на шлюзе | // флаг того то правило есть на шлюзе | ||
boolean flag = false; | boolean flag = false; | ||
- | + | ||
// правило для этого договора есть на шлюзе | // правило для этого договора есть на шлюзе | ||
if ( options.openRulesFrom.containsKey( ruleOptions.fromPos ) ) | if ( options.openRulesFrom.containsKey( ruleOptions.fromPos ) ) | ||
Строка 144: | Строка 159: | ||
if( options != null ) | if( options != null ) | ||
{ | { | ||
- | Set | + | Set rules = options.openRulesFrom.get( ruleOptions.fromPos ); |
- | + | ||
if( rules != null ) | if( rules != null ) | ||
{ | { | ||
Строка 155: | Строка 170: | ||
} | } | ||
} | } | ||
- | + | ||
flag = true; | flag = true; | ||
options.openRulesFrom.remove( ruleOptions.fromPos ); | options.openRulesFrom.remove( ruleOptions.fromPos ); | ||
} | } | ||
- | + | ||
// правила нет, а юзер открыт - добавляем правило | // правила нет, а юзер открыт - добавляем правило | ||
if ( !flag && | if ( !flag && | ||
Строка 165: | Строка 180: | ||
{ | { | ||
String rule = CiscoRuleOptions.clearFromParams( status.rule.getRuleText() ); | String rule = CiscoRuleOptions.clearFromParams( status.rule.getRuleText() ); | ||
- | + | ||
AclOptions acl = aclMap.get( ruleOptions.aclId ); | AclOptions acl = aclMap.get( ruleOptions.aclId ); | ||
if( acl != null ) | if( acl != null ) | ||
Строка 174: | Строка 189: | ||
rule = generateRule( rule, status.gateType, status.ruleType ); | rule = generateRule( rule, status.gateType, status.ruleType ); | ||
} | } | ||
- | + | ||
rulePos = ruleOptions.fromPos; | rulePos = ruleOptions.fromPos; | ||
- | + | ||
st = new StringTokenizer( rule, "\r\n" ); | st = new StringTokenizer( rule, "\r\n" ); | ||
while( st.hasMoreTokens() ) | while( st.hasMoreTokens() ) | ||
Строка 187: | Строка 202: | ||
} | } | ||
} | } | ||
- | + | ||
private void markOpenFromRules( result, aclByNameMap) | private void markOpenFromRules( result, aclByNameMap) | ||
{ | { | ||
Строка 193: | Строка 208: | ||
line = null; | line = null; | ||
currentAclOptions = null; | currentAclOptions = null; | ||
- | + | ||
st = new StringTokenizer( result, "\r\n" ); | st = new StringTokenizer( result, "\r\n" ); | ||
while( st.hasMoreTokens() ) | while( st.hasMoreTokens() ) | ||
{ | { | ||
line = st.nextToken().trim(); | line = st.nextToken().trim(); | ||
- | + | ||
accessPattern = Pattern.compile( "access list\\s+([\\w\\-]+)" ); | accessPattern = Pattern.compile( "access list\\s+([\\w\\-]+)" ); | ||
m = accessPattern.matcher( line ); | m = accessPattern.matcher( line ); | ||
Строка 205: | Строка 220: | ||
currentAcl = m.group( 1 ); | currentAcl = m.group( 1 ); | ||
currentAclOptions = aclByNameMap.get( currentAcl ); | currentAclOptions = aclByNameMap.get( currentAcl ); | ||
- | + | ||
if( log.isDebugEnabled() ) | if( log.isDebugEnabled() ) | ||
{ | { | ||
log.debug( gid + " ACL " + currentAcl + " not in billing control.." ); | log.debug( gid + " ACL " + currentAcl + " not in billing control.." ); | ||
} | } | ||
- | + | ||
continue; | continue; | ||
} | } | ||
- | + | ||
if( currentAclOptions == null ) | if( currentAclOptions == null ) | ||
{ | { | ||
continue; | continue; | ||
} | } | ||
- | + | ||
rulePattern = Pattern.compile( "^(\\d+)\\s+((permit)|(deny))" ); | rulePattern = Pattern.compile( "^(\\d+)\\s+((permit)|(deny))" ); | ||
m = rulePattern.matcher( line ); | m = rulePattern.matcher( line ); | ||
Строка 236: | Строка 251: | ||
ruleFrom = ((rule - currentAclOptions.fromPos) / currentAclOptions.onContact) * currentAclOptions.onContact | ruleFrom = ((rule - currentAclOptions.fromPos) / currentAclOptions.onContact) * currentAclOptions.onContact | ||
+ currentAclOptions.fromPos; | + currentAclOptions.fromPos; | ||
- | Set | + | Set rules = currentAclOptions.openRulesFrom.get( ruleFrom ); |
if( rules == null ) | if( rules == null ) | ||
{ | { | ||
- | rules = new HashSet | + | rules = new HashSet(); |
currentAclOptions.openRulesFrom.put( ruleFrom, rules ); | currentAclOptions.openRulesFrom.put( ruleFrom, rules ); | ||
} | } | ||
- | + | ||
rules.add( rule ); | rules.add( rule ); | ||
- | + | ||
if( log.isDebugEnabled() ) | if( log.isDebugEnabled() ) | ||
{ | { | ||
Строка 253: | Строка 268: | ||
} | } | ||
} | } | ||
- | + | ||
public static String generateRule( addresses, gateType, ruleType ) | public static String generateRule( addresses, gateType, ruleType ) | ||
{ | { | ||
Строка 259: | Строка 274: | ||
return ManadUtils.generateRule( ruleText, addresses, null, ruleType ); | return ManadUtils.generateRule( ruleText, addresses, null, ruleType ); | ||
} | } | ||
+ | |||
</source > | </source > |
Текущая версия на 11:20, 19 марта 2009
конфигурация типа шлюза:
От циски ожидается такое поведение (если начнет повисать и т.п) :
.. login:xxxx passsword: #
Приглашение должно оканчиваться обязательно на # . Таково поведение стандартного шлюза cisco и скрипт его повторяет.
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; System.out.println("1111111111111111"); 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" ) ); System.out.println("222222222222222"); // проход по ACL списку с отметкой какие договора открыты markOpenFromRules( list, aclByNameMap ); System.out.println("33333333333333333333333"); // подготовка списка корректирующих команд 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 ) ); } } } System.out.println("44444444444444444444444444"); result.append( session.command( "end" ) ); result.append( session.command( "exit", false ) ); if (log.isDebugEnabled()) { log.debug( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" ); log.debug( result.toString() ); log.debug( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" ); } // пауза пока считает команду exit Thread.sleep( 200 ); } 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 ); }