r4309 JunOS 10 802.1q gateway
authorAlexey Andriyanov <alan@al-an.info>
Thu, 10 Mar 2011 09:31:32 +0000 (09:31 +0000)
committerAlexey Andriyanov <alan@al-an.info>
Thu, 10 Mar 2011 09:31:32 +0000 (09:31 +0000)
new deviceconfig connector jun10.connector written in Perl, supporting telnet and ssh
functions ***TranslatePushQueue now accepts additional parameter - vlan_names array
setDevice8021QConfig: added additional vlan_names param into function call
exportSwitch8021QConfig: idem
exec8021QDeploy: idem

jun10Read8021QConfig: new gateway function
jun10TranslatePushQueue: idem

ChangeLog
wwwroot/inc/deviceconfig.php
wwwroot/inc/functions.php
wwwroot/inc/gateways.php

index 441cd28aa2896a638d427666a0f5210f72f4effd..ee585c7716fe3b488fddb77bed8519d9fb2dd9e4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,5 @@
 0.19.2
+       new feature: JunOS10 802.1q gateway
        bugfix: port linking was broken for some users due to open PDO cursor
        bugfix: Permissions code editor was broken with Google Chrome
        update: new DB table indexes speeding up IP tree operations
index c3632e4b35569c805a60173bf6e479df2b73a55f..18e4e6ea933cfd2fb2c93c7c0b2e1801bd567f19 100644 (file)
@@ -1177,6 +1177,67 @@ function xos12TranslatePushQueue ($queue)
        return $ret;
 }
 
+function jun10TranslatePushQueue ($queue, $vlan_names)
+{
+       $ret = '';
+       if (! isset ($vlan_names))
+               $vlan_names = array();
+
+       foreach ($queue as $cmd)
+               switch ($cmd['opcode'])
+               {
+               case 'create VLAN':
+                       $ret .= "set vlans VLAN${cmd['arg1']} vlan-id ${cmd['arg1']}\n";
+                       break;
+               case 'destroy VLAN':
+                       if (isset ($vlan_names[$cmd['arg1']]))
+                               $ret .= "delete vlans " . $vlan_names[$cmd['arg1']] . "\n";
+                       break;
+               case 'add allowed':
+               case 'rem allowed':
+                       $del = ($cmd['opcode'] == 'rem allowed');
+                       $pre = ($del ? 'delete' : 'set') .
+                               " interfaces ${cmd['port']} unit 0 family ethernet-switching vlan members";
+                       if (count ($cmd['vlans']) > VLAN_MAX_ID - VLAN_MIN_ID)
+                               $ret .= "$pre " . ($del ? '' : 'all') . "\n";
+                       else
+                               while (! empty ($cmd['vlans']))
+                               {
+                                       $vlan = array_shift ($cmd['vlans']);
+                                       $ret .= "$pre $vlan\n";
+                                       if ($del and isset ($vlan_names[$vlan]))
+                                               $ret .= "$pre ${vlan_names[$vlan]}\n";
+                               }
+                       break;
+               case 'set native':
+                       $ret .= "set interfaces ${cmd['arg1']} unit 0 family ethernet-switching native-vlan-id ${cmd['arg2']}\n";
+                       break;
+               case 'unset native':
+                       $ret .= "delete interfaces ${cmd['arg1']} unit 0 family ethernet-switching native-vlan-id\n";
+                       break;
+               case 'set access':
+                       $ret .= "set interfaces ${cmd['arg1']} unit 0 family ethernet-switching vlan members ${cmd['arg2']}\n";
+                       break;
+               case 'unset access':
+                       $ret .= "delete interfaces ${cmd['arg1']} unit 0 family ethernet-switching vlan members\n";
+                       break;
+               case 'set mode':
+                       $ret .= "set interfaces ${cmd['arg1']} unit 0 family ethernet-switching port-mode ${cmd['arg2']}\n";
+                       break;
+               case 'begin configuration':
+                       $ret .= "configure exclusive\n";
+                       break;
+               case 'end configuration':
+                       $ret .= "commit confirmed 120\n";
+                       break;
+               case 'save configuration':
+                       break; // JunOS can`t apply configuration without saving it
+               default:
+                       throw new InvalidArgException ('opcode', $cmd['opcode']);
+               }
+       return $ret;
+}
+
 function xos12Read8021QConfig ($input)
 {
        $ret = array
@@ -1227,6 +1288,135 @@ function xos12Read8021QConfig ($input)
        return $ret;
 }
 
+function jun10Read8021QConfig ($input)
+{
+       $ret = array
+       (
+               'vlanlist' => array (1),
+               'vlannames' => array (1 => 'default'),
+               'portdata' => array(),
+       );
+       $lines = explode ("\n", $input);
+       
+       // get vlan list
+       $vlans = array('default' => 1);
+       $names = array();
+       while (count ($lines))
+       {
+               $line = trim (array_shift ($lines));
+               if (FALSE !== strpos ($line, '# END OF VLAN LIST'))
+                       break;
+               if (preg_match ('/^VLAN: (.*), 802.1Q Tag: (\d+)/', $line, $m))
+               {
+                       $ret['vlannames'][$m[2]] = $m[1];
+                       $vlans[$m[1]] = $m[2];
+               }
+       }
+       $ret['vlanlist'] = array_values ($vlans);
+
+       // get config groups list - throw an exception if a group contains ether-switching config
+       $current_group = NULL;
+       while (count ($lines))
+       {
+               $line = array_shift ($lines);
+               if (FALSE !== strpos ($line, '# END OF GROUP LIST'))
+                       break;
+               elseif (preg_match ('/^(\S+)(?:\s+{|;)$/', $line, $m))
+                       $current_group = $m[1];
+               elseif (isset ($current_group) and preg_match ('/^\s*family ethernet-switching\b/', $line))
+                       throw new RTGatewayError ("Config-group '$current_group' contains switchport commands, which is not supported");
+       }
+
+       // get interfaces config
+       $current = array
+       (
+               'is_range' => FALSE,
+               'is_ethernet' => FALSE,
+               'name' => NULL,
+               'config' => NULL,
+               'indent' => NULL,
+       );
+       while (count ($lines))
+       {
+               $line = array_shift ($lines);
+               if (preg_match ('/# END OF CONFIG|^(interface-range )?(\S+)\s+{$/', $line, $m)) // line starts with interface name
+               { // found interface section opening, or end-of-file
+                       if (isset ($current['name']) and $current['is_ethernet'])
+                       { 
+                               // add previous interface to the results
+                               if (! isset ($current['config']['mode']))
+                                       $current['config']['mode'] = 'access';
+                               if (! isset ($current['config']['native']))
+                                       $current['config']['native'] = $current['config']['native'] = 0;
+                               if (! isset ($current['config']['allowed']))
+                               {
+                                       if ($current['config']['mode'] == 'access')
+                                               $current['config']['allowed'] = array (1);
+                                       else
+                                               $current['config']['allowed'] = array();
+                               }
+                               if (
+                                       $current['config']['mode'] == 'trunk' and
+                                       $current['config']['native'] != 0 and
+                                       ! in_array ($current['config']['native'], $current['config']['allowed'])
+                               )
+                                       $current['config']['allowed'][] = $current['config']['native'];
+                               elseif ($current['config']['mode'] == 'access')
+                                       $current['config']['native'] = $current['config']['allowed'][0];
+                               $ret['portdata'][$current['name']] = $current['config'];
+                       }
+
+                       $current['is_ethernet'] = FALSE;
+                       $current['is_range'] = (TRUE == $m[1]);
+                       $current['name'] = $m[2];
+                       $current['config'] = array (
+                               'mode' => NULL,
+                               'allowed' => NULL,
+                               'native' => NULL,
+                       );
+                       $current['indent'] = NULL;
+               }
+               elseif (preg_match ('/^(\s+)family ethernet-switching\b/', $line, $m))
+               {
+                       if ($current['is_range'])
+                               throw new RTGatewayError ("interface-range '${current['name']}' contains switchport commands, which is not supported");
+                       $current['is_ethernet'] = TRUE;
+                       $current['indent'] = $m[1];
+               }
+               elseif (isset ($current['indent']) and $line == $config_indent . '}')
+                       $current['indent'] = NULL;
+               elseif ($current['is_ethernet'] and isset ($current['indent']))
+               {
+                       if (preg_match ('/^\s+port-mode (trunk|access);/', $line, $m))
+                               $current['config']['mode'] = $m[1];
+                       elseif (preg_match ('/^\s+native-vlan-id (\d+);/', $line, $m))
+                               $current['config']['native'] = $m[1];
+                       elseif (preg_match ('/^\s+members \[?(.*)\]?;$/', $line, $m))
+                       {
+                               $members = array();
+                               foreach (explode (' ', $m[1]) as $item)
+                               {
+                                       $item = trim ($item);
+                                       if (preg_match ('/^(\d+)(?:-(\d+))?$/', $item, $m))
+                                       {
+                                               if (isset ($m[2]) and $m[2] > $m[1])
+                                                       $members = array_merge (range ($m[1], $m[2]), $members);
+                                               else
+                                                       $members[] = $m[1];
+                                       }
+                                       elseif (isset ($vlans[$item]))
+                                               $members[] = $vlans[$item];
+                                       elseif ($item == 'all')
+                                               $members = array_merge (range (VLAN_MIN_ID, VLAN_MAX_ID), $members);
+                               }
+                               $current['config']['allowed'] = array_unique ($members);
+                       }
+               }
+       }
+       
+       return $ret;
+}
+
 function ciscoReadInterfaceStatus ($text)
 {
        $result = array();
index b1c49810c144f59887de222f6e12fb0fe3fff34f..3ab86d536fe878e44c1bb66a8949562152aadd47 100644 (file)
@@ -3250,7 +3250,8 @@ function exportSwitch8021QConfig
        $vswitch,
        $device_vlanlist,
        $before,
-       $changes
+       $changes,
+       $vlan_names
 )
 {
        $domain_vlanlist = getDomainVLANs ($vswitch['domain_id']);
@@ -3261,7 +3262,7 @@ function exportSwitch8021QConfig
                $crq[] = array ('opcode' => 'end configuration');
                if (considerConfiguredConstraint (spotEntity ('object', $vswitch['object_id']), '8021Q_WRI_AFTER_CONFT_LISTSRC'))
                        $crq[] = array ('opcode' => 'save configuration');
-               setDevice8021QConfig ($vswitch['object_id'], $crq);
+               setDevice8021QConfig ($vswitch['object_id'], $crq, $vlan_names);
        }
        return count ($crq);
 }
@@ -3696,7 +3697,8 @@ function exec8021QDeploy ($object_id, $do_push)
                        );
                        try
                        {
-                               $npushed += exportSwitch8021QConfig ($vswitch, $R['vlanlist'], $R['portdata'], $ok_to_push);
+                               $vlan_names = isset ($R['vlannames']) ? $R['vlannames'] : NULL;
+                               $npushed += exportSwitch8021QConfig ($vswitch, $R['vlanlist'], $R['portdata'], $ok_to_push, $vlan_names);
                                // update cache for ports deployed
                                replace8021QPorts ('cached', $vswitch['object_id'], $R['portdata'], $ok_to_push);
                                usePreparedExecuteBlade
index 72ed8bd3269934cded6158d8626ec783036e4202..b20bf3b7731a3f3e5a9b9341dae03fb5e0c2b07b 100644 (file)
@@ -35,6 +35,7 @@ $gwrxlator['get8021q'] = array
        'vrp55' => 'vrp55Read8021QConfig',
        'nxos4' => 'nxos4Read8021QConfig',
        'xos12' => 'xos12Read8021QConfig',
+       'jun10' => 'jun10Read8021QConfig',
 );
 $gwrxlator['getportstatus'] = array
 (
@@ -61,6 +62,7 @@ $gwpushxlator = array
        'vrp55' => 'vrp55TranslatePushQueue',
        'nxos4' => 'ios12TranslatePushQueue', // employ syntax compatibility
        'xos12' => 'xos12TranslatePushQueue',
+       'jun10' => 'jun10TranslatePushQueue',
 );
 
 // This function launches specified gateway with specified
@@ -324,6 +326,7 @@ function detectDeviceBreed ($object_id)
                1361 => 'vrp55',
                1369 => 'vrp55', // VRP versions 5.5 and 5.7 seem to be compatible
                1363 => 'fdry5',
+               1367 => 'jun10',
        );
        foreach (getAttrValues ($object_id) as $record)
                if ($record['id'] == 4 and array_key_exists ($record['key'], $breed_by_swcode))
@@ -341,14 +344,14 @@ function getRunning8021QConfig ($object_id)
        return $ret;
 }
 
-function setDevice8021QConfig ($object_id, $pseudocode)
+function setDevice8021QConfig ($object_id, $pseudocode, $vlan_names)
 {
        require_once 'deviceconfig.php';
        if ('' == $breed = detectDeviceBreed ($object_id))
                throw new RTGatewayError ('device breed unknown');
        global $gwpushxlator;
        // FIXME: this is a perfect place to log intended changes
-       gwDeployDeviceConfig ($object_id, $breed, unix2dos ($gwpushxlator[$breed] ($pseudocode)));
+       gwDeployDeviceConfig ($object_id, $breed, unix2dos ($gwpushxlator[$breed] ($pseudocode, $vlan_names)));
 }
 
 function gwRetrieveDeviceConfig ($object_id, $command)