Реализация стандартного шлюза Mikrotik на BeanShell
Материал из BiTel WiKi
(Различия между версиями)
Stark (Обсуждение | вклад) (Новая: конфигурация типа шлюза : <source lang="bash"> user_rule.editor.class=bitel.billing.module.services.ipn.editor.ManadContractRuleEditor gate_manager.class=bitel.bill...) |
Stark (Обсуждение | вклад) (заменил стандартаную реализацию не telnet) |
||
(4 промежуточные версии не показаны) | |||
Строка 2: | Строка 2: | ||
<source lang="bash"> | <source lang="bash"> | ||
- | user_rule.editor.class=bitel.billing.module.services.ipn.editor. | + | user_rule.editor.class=bitel.billing.module.services.ipn.editor.MikrotikContractRuleEditor |
- | gate_manager.class=bitel.billing.server.ipn. | + | gate_manager.class=bitel.billing.server.ipn.MikrotikTelnetGateWorker |
use.script=1 | use.script=1 | ||
</source> | </source> | ||
- | Код : | + | Код шлюза: |
- | <source lang="java"> | + | <source lang="java"> |
+ | package bitel.billing.server.ipn; | ||
+ | |||
+ | import java.util.HashMap; | ||
+ | import java.util.Map; | ||
import java.util.regex.Matcher; | import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | import java.util.regex.Pattern; | ||
+ | import ru.bitel.bgbilling.common.DefaultSetup; | ||
+ | import ru.bitel.bgbilling.modules.ipn.server.bean.command.GateCommandUtil; | ||
+ | import ru.bitel.common.Preferences; | ||
import bitel.billing.common.module.ipn.IPNContractStatus; | import bitel.billing.common.module.ipn.IPNContractStatus; | ||
- | import bitel.billing.server. | + | import bitel.billing.server.ipn.bean.GateType; |
+ | import bitel.billing.server.ipn.bean.RuleType; | ||
import bitel.billing.server.util.ssh.SSHSessionExec; | import bitel.billing.server.util.ssh.SSHSessionExec; | ||
- | |||
- | + | public class MikrotikGateWorker | |
+ | extends GateWorker | ||
{ | { | ||
- | + | @Override | |
- | String host = gate.getHost(); | + | protected void doSync() |
- | + | { | |
- | + | String host = gate.getHost(); | |
- | + | int port = gate.getPort(); | |
- | + | Preferences gateSetup = new DefaultSetup( gate.getConfig(), "\r\n" ); | |
- | + | String login = gateSetup.get( "login", "root" ); | |
- | + | String pswd = gate.getKeyword(); | |
- | + | if ( log.isDebugEnabled() ) | |
- | + | { | |
+ | log.debug( " gate: " + host + ":" + port + " login: " + login + " pswd: " + pswd ); | ||
+ | } | ||
+ | |||
+ | SSHSessionExec session = null; | ||
+ | int timeout = gateSetup.getInt( "timeout", 0 ); | ||
+ | try | ||
+ | { | ||
+ | session = new SSHSessionExec( host, port, login, pswd ); | ||
+ | session.setTimeout( timeout ); | ||
- | + | // session.connect(); | |
- | + | for ( UserStatus status : statusList ) | |
- | + | { | |
- | + | Integer cid = status.contractId; | |
- | + | // правило для этого договора есть на шлюзе | |
- | + | if ( ruleExists( cid, status, session ) ) | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
{ | { | ||
- | + | // если правило есть а юзер заблокирован - удаляем правило | |
- | + | if ( status.status > 0 ) | |
- | + | { | |
- | + | // удаляем | |
- | + | if ( status.status == IPNContractStatus.STATUS_REMOVED ) | |
- | + | { | |
- | + | String[] rules = getDeleteRules( status ); | |
- | + | for ( String rule : rules ) | |
- | + | { | |
- | + | session.command( rule ); | |
- | + | } | |
- | + | } | |
- | + | // закрываем | |
- | + | else | |
- | + | { | |
- | + | String[] rules = getCloseRules( status ); | |
- | + | for ( String rule : rules ) | |
- | + | { | |
- | + | session.command( rule ); | |
- | + | } | |
- | + | } | |
- | + | } | |
- | + | } | |
- | + | else if ( status.status == IPNContractStatus.STATUS_OPEN ) | |
- | + | { | |
- | + | String[] rules = getOpenRules( status ); | |
- | + | for ( String rule : rules ) | |
- | + | { | |
- | + | session.command( rule ); | |
- | + | } | |
- | + | } | |
+ | } | ||
+ | } | ||
+ | catch( Exception e ) | ||
{ | { | ||
- | + | throw new RuntimeException( e ); | |
} | } | ||
- | + | finally | |
- | + | { | |
- | + | if ( session != null ) | |
- | + | { | |
- | + | session.disconnect(); | |
- | { | + | } |
- | + | } | |
- | + | } | |
- | + | ||
- | } | + | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | private boolean ruleExists( Integer cid, UserStatus status, SSHSessionExec session ) throws Exception | |
- | + | { | |
- | + | String answer = session.command( "ip firewall address-list print" ); | |
- | + | return answer.indexOf( "!!" + cid + "!!" ) >= 0; | |
- | + | } | |
+ | private String[] getOpenRules( UserStatus status ) | ||
+ | { | ||
+ | return getRules( status, "\\[OPEN\\](.*)\\[/OPEN\\]" ); | ||
+ | } | ||
- | return getRules( status, "\\[CLOSE\\] | + | private String[] getCloseRules( UserStatus status ) |
- | } | + | { |
- | + | return getRules( status, "\\[CLOSE\\](.*)\\[/CLOSE\\]" ); | |
- | + | } | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
+ | private String[] getDeleteRules( UserStatus status ) | ||
+ | { | ||
+ | return getRules( status, "\\[DELETE\\](.*)\\[/DELETE\\]" ); | ||
+ | } | ||
- | //типизированное правило | + | private String[] getRules( UserStatus status, |
- | + | String template ) | |
- | + | { | |
- | + | // пользовательское правило, без типа - то все оставляем как есть | |
- | + | String rule = status.rule.getRuleText(); | |
- | + | // типизированное правило | |
- | + | if ( status.ruleType != null ) | |
- | + | { | |
+ | rule = generateRule( rule, gateType, status.ruleType, status.contractId ); | ||
+ | } | ||
+ | Pattern pattern = Pattern.compile( template, Pattern.DOTALL ); | ||
+ | Matcher m = pattern.matcher( rule ); | ||
+ | if ( m.find() ) | ||
+ | { | ||
+ | rule = m.group( 1 ); | ||
+ | } | ||
+ | rule.replaceAll( "\r", "" ); | ||
+ | return rule.split( "\n" ); | ||
+ | } | ||
- | + | public static String generateRule( String addresses, GateType gateType, RuleType ruleType, int cid ) | |
- | + | ||
- | + | ||
{ | { | ||
- | rule = | + | String rule; |
- | + | Map<String, String> replacements = new HashMap<String, String>(); | |
- | + | replacements.put( "\\{CID\\}", String.valueOf( cid ) ); | |
- | + | ||
- | + | String ruleText = GateCommandUtil.getRule( gateType, ruleType ); | |
- | + | rule = GateCommandUtil.generateRule( ruleText, addresses, replacements, ruleType ); | |
- | + | return rule; | |
- | + | } | |
- | + | } | |
- | + | ||
- | + | ||
</source> | </source> |
Текущая версия на 13:32, 8 апреля 2010
конфигурация типа шлюза :
user_rule.editor.class=bitel.billing.module.services.ipn.editor.MikrotikContractRuleEditor gate_manager.class=bitel.billing.server.ipn.MikrotikTelnetGateWorker use.script=1
Код шлюза:
package bitel.billing.server.ipn; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import ru.bitel.bgbilling.common.DefaultSetup; import ru.bitel.bgbilling.modules.ipn.server.bean.command.GateCommandUtil; import ru.bitel.common.Preferences; import bitel.billing.common.module.ipn.IPNContractStatus; import bitel.billing.server.ipn.bean.GateType; import bitel.billing.server.ipn.bean.RuleType; import bitel.billing.server.util.ssh.SSHSessionExec; public class MikrotikGateWorker extends GateWorker { @Override protected void doSync() { String host = gate.getHost(); int port = gate.getPort(); Preferences gateSetup = new DefaultSetup( gate.getConfig(), "\r\n" ); String login = gateSetup.get( "login", "root" ); String pswd = gate.getKeyword(); if ( log.isDebugEnabled() ) { log.debug( " gate: " + host + ":" + port + " login: " + login + " pswd: " + pswd ); } SSHSessionExec session = null; int timeout = gateSetup.getInt( "timeout", 0 ); try { session = new SSHSessionExec( host, port, login, pswd ); session.setTimeout( timeout ); // session.connect(); for ( UserStatus status : statusList ) { Integer cid = status.contractId; // правило для этого договора есть на шлюзе if ( ruleExists( cid, status, session ) ) { // если правило есть а юзер заблокирован - удаляем правило if ( status.status > 0 ) { // удаляем if ( status.status == IPNContractStatus.STATUS_REMOVED ) { String[] rules = getDeleteRules( status ); for ( String rule : rules ) { session.command( rule ); } } // закрываем else { String[] rules = getCloseRules( status ); for ( String rule : rules ) { session.command( rule ); } } } } else if ( status.status == IPNContractStatus.STATUS_OPEN ) { String[] rules = getOpenRules( status ); for ( String rule : rules ) { session.command( rule ); } } } } catch( Exception e ) { throw new RuntimeException( e ); } finally { if ( session != null ) { session.disconnect(); } } } private boolean ruleExists( Integer cid, UserStatus status, SSHSessionExec session ) throws Exception { String answer = session.command( "ip firewall address-list print" ); return answer.indexOf( "!!" + cid + "!!" ) >= 0; } private String[] getOpenRules( UserStatus status ) { return getRules( status, "\\[OPEN\\](.*)\\[/OPEN\\]" ); } private String[] getCloseRules( UserStatus status ) { return getRules( status, "\\[CLOSE\\](.*)\\[/CLOSE\\]" ); } private String[] getDeleteRules( UserStatus status ) { return getRules( status, "\\[DELETE\\](.*)\\[/DELETE\\]" ); } private String[] getRules( UserStatus status, String template ) { // пользовательское правило, без типа - то все оставляем как есть String rule = status.rule.getRuleText(); // типизированное правило if ( status.ruleType != null ) { rule = generateRule( rule, gateType, status.ruleType, status.contractId ); } Pattern pattern = Pattern.compile( template, Pattern.DOTALL ); Matcher m = pattern.matcher( rule ); if ( m.find() ) { rule = m.group( 1 ); } rule.replaceAll( "\r", "" ); return rule.split( "\n" ); } public static String generateRule( String addresses, GateType gateType, RuleType ruleType, int cid ) { String rule; Map<String, String> replacements = new HashMap<String, String>(); replacements.put( "\\{CID\\}", String.valueOf( cid ) ); String ruleText = GateCommandUtil.getRule( gateType, ruleType ); rule = GateCommandUtil.generateRule( ruleText, addresses, replacements, ruleType ); return rule; } }