Пример реализации скриптового универсального шлюза
Материал из BiTel WiKi
Max (Обсуждение | вклад) |
Max (Обсуждение | вклад) |
||
Строка 5: | Строка 5: | ||
---- | ---- | ||
- | Заходим в модуль IPN | + | Заходим в модуль IPN\n |
1. Создаём тип шлюза - Script-perl | 1. Создаём тип шлюза - Script-perl | ||
Закладка "Конфигурация" типа шлюза: | Закладка "Конфигурация" типа шлюза: |
Версия 20:07, 3 января 2009
Стоит задача привязки CISCO 6509 SUP-2/MSFC-2/PFC2 IOS (c6sup2_rp-JK2O3SV-M), Version 12.1(26)E9, RELEASE SOFTWARE (fc1) Так как весия IOS 12.1 поддерживает нумерацию правил акцесс-листа то из за этого шлюзы типа CISCO и CISCO2 не могут быть использованы для привязки данного железа к биллингу. Разработчиком был написан интерфейс в версии 4.5 который позволяет использовать внешние скрипты, куда собственно я и вынес логику общения биллинга с моей цыской.
Заходим в модуль IPN\n 1. Создаём тип шлюза - Script-perl Закладка "Конфигурация" типа шлюза:
user_rule.editor.class=bitel.billing.module.services.ipn.editor.ManadContractRuleEditor gate_manager.class=bitel.billing.server.ipn.ManadGateWorker use.script=1 script=/usr/local/BGBillingServer/ACC
АСС - есть скрипт на перле с логикой связи.
Закладка "Комманды" - оставляем пустой. Закладка "Типы правил" - оставляем пустой. В закладке "Скрипт" пишем следующее:
import bitel.billing.server.ipn.bean.AddressRange; import bitel.billing.server.ipn.UserStatus; import bitel.billing.server.ipn.bean.AddressRangeManager; import bitel.billing.server.util.DefaultServerSetup; import bitel.billing.server.util.Utils; import bitel.billing.common.IPUtils; protected void doSync() { date = new GregorianCalendar(); gateSetup = new DefaultServerSetup( gate.getConfig(), "\r\n" ); script = gateSetup.getStringValue( "script"); //цикл по всем договорам на этом шлюзе for( UserStatus status : statusList ) { cid = status.contractId; // AddressRangeManager man = new AddressRangeManager( con, mid ); addressList = man.getContractAddressRange( cid, date, -1 ); for ( AddressRange range : addressList) { ip = getIP( range); mask = getMask ( range) ; String host = gate.getHost(); if ( mask == null ) { log.info( "Incorrect range for cid = " + cid ); continue; } log.info( "script = " + script ); log.info( "ip = " + ip ); log.info( "mask = " + mask ); log.info( "host = " + host ); String [] arguments = { script, ip, mask, host, String.valueOf( status.status ) }; //выполняем команду Process process = Runtime.getRuntime().exec( arguments ); //ждем окончания работы процесса ..Это не обязательно process.waitFor(); log.info( "exitCode=" + process.exitValue() ); } } } getIP ( range ) { return IPUtils.convertIpToString( range.getAddr1() ); } getMask ( range ) { result = null; delta = range.getAddr2() - range.getAddr1() + 1; int pow = getPow( delta ); log.info( "pow = " + pow ); //махинация для того чтоб получить 0xFFFFFFFF -в beanshell не //получилось задать такое большое число и модификатор l в конце не работает ffMask = (0xFFFFFFF); ffMask = (ffMask << 8 ) | 0xFF; if ( pow >= 0 ) { mask = ffMask; mask = (mask << pow) & ffMask; result = IPUtils.convertIpToString( mask ); } return result; } //находим разницу между двумя ip(она должна быть степеью двойки) и //возращаем эту степень int getPow( long delta ) { int idx = 0; int count = 0; int pow = -1; while ( delta > 0 ) { if ( (delta & 1 ) == 1 ) { count ++; pow = idx; if ( count > 1) { break; } } delta = (delta >> 1); idx++; } //если не одна единица в числе, значит это не степень двойки и //диапазон задан неверно if ( count != 1 ) { pow = -1; } return pow; }
Нажимаем ОК. Тип шлюза создан! --- Идём в закладку Шлюзы. Создаём шлюз: В параметры Хост и порт шлюза, а так же Ключевое слово можно написать что угодно, оно для нас не имеет значения. В "Тип шлюза" - указываем созданный нами тип шлюза - Script-perl Комментарий и конфигурацию оставляем пустыми. Шлюз создан! --- Данный скрипт использует телнет для управления коммутатором. На цыске должен быть создан пользователь LOGIN с паролем PASS (крупные буквы заменить совими значениями). Для уменьшения проблем вот конфиг цыски оптимизированной под данную связку:
username LOGIN privilege 15 secret 5 PASS line vty 0 15 exec-timeout 0 0 privilege level 15 logging synchronous transport input telnet ssh transport output telnet ssh
Код скрипта логики ACC
#!/usr/bin/perl #edit 03.01.2009 23:21 Max $ip=@ARGV[0]; $netmask=@ARGV[1]; $nas=@ARGV[2]; $status=@ARGV[3]; #Wailcard netmask if($netmask eq '255.255.255.255'){$wnetmask='0.0.0.0';} elsif($netmask eq '255.255.255.252'){$wnetmask='0.0.0.3';} elsif($netmask eq '255.255.255.248'){$wnetmask='0.0.0.7';} elsif($netmask eq '255.255.255.240'){$wnetmask='0.0.0.15';} elsif($netmask eq '255.255.255.224'){$wnetmask='0.0.0.31';} elsif($netmask eq '255.255.255.192'){$wnetmask='0.0.0.63';} elsif($netmask eq '255.255.255.128'){$wnetmask='0.0.0.127';} elsif($netmask eq '255.255.255.0'){$wnetmask='0.0.0.255';} elsif($netmask eq '255.255.254.0'){$wnetmask='0.0.1.255';} elsif($netmask eq '255.255.252.0'){$wnetmask='0.0.3.255';} elsif($netmask eq '255.255.248.0'){$wnetmask='0.0.7.255';} elsif($netmask eq '255.255.240.0'){$wnetmask='0.0.15.255';} elsif($netmask eq '255.255.224.0'){$wnetmask='0.0.31.255';} else{&error;} if($status eq 0) {&auth;} else {&no_auth;} ########################################################### #AUTHORIZED################################################ ########################################################### sub auth{ #NAS if($nas eq '10.11.0.6'){&cisco_2600;} if($nas eq '10.11.0.10'){&cisco_2600;} if($nas eq '10.11.0.14'){&cisco_2600;} if($nas eq '10.11.0.1'){&cisco;} &error; } sub cisco{ use Net::Telnet (); $t = new Net::Telnet (Timeout => 30, Prompt => '/#/'); $t->open("$nas") || die("False\n"); '''Полужирное начертание'''$t->login("LOGIN", "PASS"); $t->cmd(String => 'conf t', Cmd_remove_mode => 0); $t->cmd("ip access-list extended 100"); $t->cmd("deny ip $ip $wnetmask any"); $t->cmd("no permit ip any any"); $t->cmd("permit ip any any"); $t->cmd("$cmd"); $t->cmd("exit"); exit 0; } sub cisco_2600{ use Net::Telnet (); $t = new Net::Telnet (Timeout => 30, Prompt => '/#/'); $t->open("$nas") || die("False\n"); '''Полужирное начертание'''$t->login("LOGIN", "PASS"); $t->cmd(String => 'conf t', Cmd_remove_mode => 0); $t->cmd("ip access-list extended 100"); $t->cmd("permit ip $ip $wnetmask any"); $t->cmd("no deny ip any any"); $t->cmd("deny ip any any"); $t->cmd("$cmd"); $t->cmd("exit"); exit 0; } ########################################################### #NOAUTH#################################################### ########################################################### sub no_auth{ #NAS if($nas eq '10.11.0.6'){&no_cisco_2600;} if($nas eq '10.11.0.10'){&no_cisco_2600;} if($nas eq '10.11.0.14'){&no_cisco_2600;} if($nas eq '10.11.0.1'){&no_cisco;} &error; } sub no_cisco{ use Net::Telnet (); $t = new Net::Telnet (Timeout => 30, Prompt => '/#/'); $t->open("$nas") || die("False\n"); '''Полужирное начертание'''$t->login("LOGIN", "PASS"); $t->cmd(String => 'conf t', Cmd_remove_mode => 0); $t->cmd("ip access-list extended 100"); $t->cmd("no deny ip $ip $wnetmask any"); $t->cmd("$cmd"); $t->cmd("exit"); exit 0; } sub no_cisco_2600{ use Net::Telnet (); $t = new Net::Telnet (Timeout => 30, Prompt => '/#/'); $t->open("$nas") || die("False\n"); '''Полужирное начертание'''$t->login("LOGIN", "PASS"); $t->cmd(String => 'conf t', Cmd_remove_mode => 0); $t->cmd("ip access-list extended 100"); $t->cmd("permit ip $ip $wnetmask any"); $t->cmd("$cmd"); $t->cmd("exit"); exit 0; } #НЕ ОПРЕДЕЛЁН NAS######################################################################### sub error{ open(ERR,">>/usr/local/BGBillingServer/log/err.connect.log"); print ERR "ERROR: CONNECT ip=$ip, netmask=$netmask|$wnetmask, nas=$nas, status=$status\n"; close ERR; exit 1; } ##########################################################################################