Реализация стандартного шлюза коммутатора Qtech/Zyxel (под Cisco2) на BeanShell со встроенным шлюзом DHCP

Материал из BiTel WiKi

Версия от 10:25, 29 декабря 2010; Mrustik (Обсуждение | вклад)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

После длительных раздумий вырисовалась связка Cisco2+(Zyxel/Qtech+DHCP) вместо предложенной разработчиками связки DHCP+Cisco2+Zyxel/Qtech. Данная связка нарисовалась в связи с тем, что некоторые параметры, которые нужно передать в шлюз DHCP, зависят от шлюза Zyxel/Qtech, а не от Cisco2, и получить к ним доступ в шлюзе DHCP не удалось. Т.е. шлюз Zyxel/Qtech совмещен с шлюзом DHCP. Суть состоит в том, что После синхронизации клиента на коммутаторе Zyxel, будет вызываться синхронизация с родительским шлюзом Cisco2, и синхронизация с сервером DHCP BgBilling'a. Все это написано для биллинга в.4.6 Ip адреса выдаются по влану клиента, т.к. в параметрах шлюза нельза менять vlan, а в сети может быть несколько одинаковых vlan находящихся в разных сегментах сети, принадлежащих одной сиске, влан клиента заносим в параметр договора. VLAN клиента уникальный в квартале. Можно выдавать ip адреса и по порту свича, что предпочтительней, но пока есть с этим у нас проблемы, поэтому и не используем. Конфигурация шлюза Cisco2:

#имя пользователя
login=test
#пароль шлюза который задаётся для enable 
cfg.pswd=123456
#диапазон выделения vlan 
range=1100-1900
#время ожидания ответа, по истечению которого, шлюз сбрасывает соединение и выдаёт ошибку
timeout=2000
#код Vlan клиента параметра договора
vlanId=1

Конфигурация типа шлюза Cisco2:

user_rule.editor.class=bitel.billing.module.services.ipn.editor.vlan.CiscoVlanContactRuleEditor
#gate_manager.class=bitel.billing.server.ipn.vlan.CiscoVlanGateWorker
#gate_manager.class=bitel.billing.server.ipn.DHCPGateWorker
gate_manager.class=bitel.billing.server.ipn.vlan.CiscoVlanParentGateWorker
use.script=1
#диапазон выделения vlan 
range=1100-1900

Команды шлюза Cisco2:

[DEFAULT]
 
[REMOVE]
   <LOOP>          
         no ip route {A} 255.255.255.255 Vlan{VID}
   </LOOP>          
[/REMOVE]
 
[OPEN]
   <LOOP>          
           ip route {A} 255.255.255.255 Vlan{VID}
           ip route {DHCP_Relay} 255.255.255.255 Vlan{VID}
   </LOOP>          
[/OPEN]
 
[CLOSE]
   <LOOP>          
        no ip route {A} 255.255.255.255 Vlan{VID}
   </LOOP>          
[/CLOSE]
[/DEFAULT]

Скрипт шлюза Cisco2:

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.StringTokenizer;
import java.util.Map.Entry;
import java.sql.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;
 
import org.apache.xml.serializer.ToXMLStream;
import org.xml.sax.SAXException;
 
import bitel.billing.common.module.ipn.IPNContractStatus;
import bitel.billing.server.ipn.GateWorker;
import bitel.billing.server.ipn.UserStatus;
import bitel.billing.server.ipn.bean.ManadUtils;
import bitel.billing.server.ipn.bean.VlanManager;
import bitel.billing.server.ipn.bean.GateType;
import bitel.billing.server.ipn.bean.RuleType;
import bitel.billing.server.ipn.bean.VlanManager;
import bitel.billing.server.ipn.bean.Gate;
import bitel.billing.server.util.DefaultServerSetup;
import bitel.billing.server.util.Utils;
import bitel.billing.server.util.telnet.TelnetSession;
import ru.bitel.bgbilling.common.DefaultSetup;
import bitel.billing.common.IPUtils;
import ru.bitel.bgbilling.common.DefaultSetup;
import bitel.billing.common.module.ipn.IPNContractStatus;
import bitel.billing.server.ipn.dlink.UserPortStatus;
import bitel.billing.server.ipn.dlink.UserPortStatus.UserPortStatusParser;
 
/////protected void doSync()
protected void parentSync( child, childWorker)
{
   try
   {
      log.info( "start of cisco........................................................");
      host = gate.getHost();
      port = gate.getPort();
 
      DefaultServerSetup gateSetup = new DefaultServerSetup( gate.getConfig(), "\r\n" );        
 
      pswdLogin = gate.getKeyword();
      login = gateSetup.getStringValue( "login");
      pswdCfg = gateSetup.getStringValue( "cfg.pswd");
      timeout = gateSetup.getIntValue( "timeout", 0 );
      vlanId = gateSetup.getIntValue( "vlanId",0);
      result = new StringBuffer();
 
      if( log.isDebugEnabled() )
      {
          log.debug( gate.getId() + " gate: " + host + ":" + port  + " pswdLogin: " + pswdLogin + " pswdCfg: " +        pswdCfg );
      }
      session = new TelnetSession( host, port);
       session.setTimeout( timeout );
      session.setLoginPromptSequence( ":" );                  
      session.connect();
      result.append( session.doCommand( login ) );
      session.setLoginPromptSequence( ">" );
      result.append( session.doCommand( pswdLogin ) );
      result.append( session.doCommand( "terminal length 0" ) );
      result.append( session.doCommand( "terminal width 0" ) );
      session.setLoginPromptSequence( ":" );
      result.append( session.doCommand( "enable" ) );
      session.setLoginPromptSequence( "#" );
      result.append( session.doCommand( pswdCfg ) );
 
      result.append( session.doCommand( "configure terminal" ) );
 
//      log.debug( "execute commands" );
//      log.info( "------1------");
//      log.info( "relayId = " + relayId);
      doCommands( session, result, child, vlanId);
 
      result.append( session.doCommand( "exit" ) );
        session.doCommandAsync( "exit" );
 
//      log.info("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
      log.info( result );
/*      log.info("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");      
      log.debug( "ok" );
*/ 
   } catch (Exception e)
   {
      throw new RuntimeException ( e );
   } 
 
   log.info( "end of cisco........................................................");
}
 
protected void add()
{
 
}
 
/////private void doCommands( TelnetSession session, StringBuffer result, vlanId, relayId) throws IOException
private void doCommands( TelnetSession session, StringBuffer result, Gate child, vlanId) throws IOException
{      
   for( UserStatus status : statusList )
   {
      gateId  = gate.getId();
//      log.info("gateId=" + gateId);
//        log.info("vlanId=" + vlanId);
//        log.info("contractId=" + status.contractId);
      int vid_dog = getVlan( status.contractId, vlanId );
/////      Relay = getRelay( status.contractId, relayId );
      DefaultServerSetup childSetup = new DefaultServerSetup( child.getConfig(), "\r\n" );        
      int vid = childSetup.getIntValue( "relay.vlan",1100);
      Relay = childSetup.getStringValue( "relay.ip","10.35.255.254");
//      log.info("vid=" + vid);   
//      log.info("Relay=" + Relay);   
      //TODO - подумать что сделать справилами на добавление
      rules = null;
      if (status.status == IPNContractStatus.STATUS_OPEN)
      {
         rules = getOpenRules( status, vid, Relay, vid_dog);
      }          
//      else if (status.status == IPNContractStatus.STATUS_REMOVED)
//      {
//         rules = getRemoveRules( status, vid );   
//      }
      //if closed and etc 
      else 
      {
         rules = getCloseRules( status, vid, Relay, vid_dog );
      }
      if (vid > 0)
      {
         for ( String rule : rules )
         {               
//      log.info("rule=" + rule);   
            result.append(  session.doCommand( rule ) );            
         }
      }
   }      
}
 
getOpenRules( status, vid, Relay, vid_dog )
{
    return getRules( status, "\\[OPEN\\](.*)\\[/OPEN\\]", vid, Relay, vid_dog );
}
 
getCloseRules( status, vid, Relay, vid_dog )
{
    return getRules( status, "\\[CLOSE\\](.*)\\[/CLOSE\\]", vid, Relay, vid_dog );
}
 
getRemoveRules( UserStatus status, int vid, Relay, vid_dog )
{
    return getRules( status, "\\[REMOVE\\](.*)\\[/REMOVE\\]", vid, Relay, vid_dog );
}
 
getRules(  status, template, vid, Relay, vid_dog )
{
   // пользовательское правило, без типа - то все оставляем как есть
   rule = status.rule.getRuleText();
//   log.info("rule=" + rule);
        //порты идут до #, а адреса идут после  
   String [] parts  = rule.split( "#" );
   portsStr = "";
   addresesStr = "";
   if ( parts.length > 0 )
   {
       portsStr = parts[0];
   }
   if ( parts.length > 1 )
   {
      addresesStr = parts[1];
   }
   //типизированное правило
   if( status.ruleType != null )
   {   
       rule = generateRule( addresesStr, status.gateType, status.ruleType, vid, Relay, vid_dog );
   }
//   log.info("2rule=" + rule);
   pattern = Pattern.compile( template, Pattern.DOTALL );
   m = pattern.matcher( rule );
   if (m.find())
   {
       rule = m.group( 1 );
   }      
   rule.replaceAll( "\r", "" );
   parts  = rule.split( "\n" );
   result = new ArrayList();
   for ( String part : parts )
   {
      if ( !Utils.isEmptyString( part ))
      {
         result.add( part );
      }
   }
 
   return result;
}      
 
generateRule( addresses, gateType, ruleType, vid, Relay, vid_dog )
{      
//    ruleText = ManadUtils.getRule( gateType, ruleType );
   ruleText="[REMOVE]\n"+
      "<LOOP>\n"+
            "no ip route {A} 255.255.255.255 Vlan{VIDD}\n"+
      "</LOOP>\n"+
   "[/REMOVE]\n"+
   "[OPEN]\n"+
      "<LOOP>\n"+
              "ip route {A} 255.255.255.255 Vlan{VIDD}\n"+
              "ip route {DHCP_Relay} 255.255.255.255 Vlan{VID}\n"+
      "</LOOP>\n"+
   "[/OPEN]\n"+
   "[CLOSE]\n"+
      "<LOOP>\n"+
           "no ip route {A} 255.255.255.255 Vlan{VIDD}\n"+
      "</LOOP>\n"+
   "[/CLOSE]\n";
 
   log.info("ruleText = "+ruleText);
 
    replacements =  new HashMap ();
    if (Relay != null || Relay.length()>0 )
    {
       replacements.put( "\\{DHCP_Relay\\}", Relay );
   }
    if ( vid_dog > 0)
    {
        replacements.put( "\\{VIDD\\}", String.valueOf( vid_dog ) );
    }
    if ( vid > 0)
    {
        replacements.put( "\\{VID\\}", String.valueOf( vid ) );
    }
    return ManadUtils.generateRule( ruleText, addresses, replacements, ruleType );      
}
 
getVlan( cid , pid )
{
   int result = 1102; 
   String query =  "select val from contract_parameter_type_1 where cid=" + cid + " and pid= " + pid;
   PreparedStatement ps = con.prepareStatement( query ); 
   ResultSet rs = ps.executeQuery();
   rs.first();
//   log.info("Row = "+rs.getRow());
   if ( rs. isFirst() )
   {
//   log.info("---- First ------");
      result = rs.getInt(1);
   }
//   log.info("Vlan = "+result);
   return result;   
}

У нас имеется 2 вида свичей Zyxel и Qtech, шлюзы у них одинаковые, только разные команды. Конфигурация шлюза Qtech:

Личные инструменты