r4274 printPageHeaders(): amend the last commit wrt JS files, CodePress isn't ready...
[racktables] / wwwroot / inc / functions.php
index 8d8f31eeedb4f40430f097562794b632a9262197..7eb0e6b17d34a06baff6dd9ed00b305aa7ba3c39 100644 (file)
@@ -379,10 +379,32 @@ function genericAssertion ($argname, $argtype)
                if (!in_array ($sic[$argname], array ('regular', 'shared', 'virtual', 'router')))
                        throw new InvalidRequestArgException ($argname, $sic[$argname], 'Unknown value');
                break;
+       case 'enum/dqcode':
+               assertStringArg ($argname);
+               global $dqtitle;
+               if (! array_key_exists ($sic[$argname], $dqtitle))
+                       throw new InvalidRequestArgException ($argname, $sic[$argname], 'Unknown value');
+               break;
        case 'iif':
                if (!array_key_exists ($sic[$argname], getPortIIFOptions()))
                        throw new InvalidRequestArgException ($argname, $sic[$argname], 'Unknown value');
                break;
+       case 'vlan':
+       case 'vlan1':
+               genericAssertion ($argname, 'uint');
+               if ($argtype == 'vlan' and $sic[$argname] == VLAN_DFL_ID)
+                       throw new InvalidRequestArgException ($argname, $sic[$argname], 'default VLAN cannot be changed');
+               if ($sic[$argname] > VLAN_MAX_ID or $sic[$argname] < VLAN_MIN_ID)
+                       throw new InvalidRequestArgException ($argname, $sic[$argname], 'out of valid range');
+               break;
+       case 'rackcode/expr':
+               genericAssertion ($argname, 'string0');
+               if ($sic[$argname] == '')
+                       return;
+               $parse = spotPayload ($sic[$argname], 'SYNT_EXPR');
+               if ($parse['result'] != 'ACK')
+                       throw new InvalidRequestArgException ($argname, $sic[$argname], 'RackCode parsing error');
+               break;
        default:
                throw new InvalidArgException ('argtype', $argtype); // comes not from user's input
        }
@@ -1919,7 +1941,7 @@ function IPv4NetworkCmp ($netA, $netB)
 
 function IPv6NetworkCmp ($netA, $netB)
 {
-       return strcmp ($netA['ip_bin'], $netB['ip_bin']);
+       return strcmp ($netA['ip_bin']->getBin(), $netB['ip_bin']->getBin());
 }
 
 // Modify the given tag tree so, that each level's items are sorted alphabetically.
@@ -2344,6 +2366,16 @@ function ip_long2quad ($quad)
       return long2ip($quad);
 }
 
+// translate static URI
+function TSURI ($URI)
+{
+       global $racktables_static_dir;
+       if (! isset ($racktables_static_dir))
+               return $URI;
+       return "?module=tsuri&uri=${URI}";
+}
+
+// make "A" HTML element
 function mkA ($text, $nextpage, $bypass = NULL, $nexttab = NULL)
 {
        global $page, $tab;
@@ -2367,6 +2399,7 @@ function mkA ($text, $nextpage, $bypass = NULL, $nexttab = NULL)
        return '<a href="' . makeHref ($args) . '">' . $text . '</a>';
 }
 
+// make "HREF" HTML attribute
 function makeHref($params = array())
 {
        $ret = 'index.php?';
@@ -2576,6 +2609,18 @@ function considerConfiguredConstraint ($cell, $varname)
        return judgeCell ($cell, $parseCache[$varname]['load']);
 }
 
+// Tell, if the given arbitrary RackCode text addresses the given record
+// (an empty text matches any record).
+function considerGivenConstraint ($cell, $filtertext)
+{
+       if ($filtertext == '')
+               return TRUE;
+       $parse = spotPayload ($filtertext, 'SYNT_EXPR');
+       if ($parse['result'] != 'ACK')
+               throw new InvalidRequestArgException ('filtertext', $filtertext, 'RackCode parsing error');
+       return judgeCell ($cell, $parse['load']);
+}
+
 // Return list of records in the given realm, which conform to
 // the given RackCode expression. If the realm is unknown or text
 // doesn't validate as a RackCode expression, return NULL.
@@ -3317,12 +3362,39 @@ function filter8021QChangeRequests
 }
 
 // take port list with order applied and return uplink ports in the same format
-function produceUplinkPorts ($domain_vlanlist, $portlist)
+function produceUplinkPorts ($domain_vlanlist, $portlist, $object_id)
 {
        $ret = array();
        $employed = array();
+
+       // find VLANs for object's L3 allocations
+       $cell = spotEntity ('object', $object_id);
+       amplifyCell ($cell);
+       foreach (array ('ipv4', 'ipv6') as $family)
+       {
+               $seen_nets = array();
+               foreach ($cell[$family] as $ip => $allocation)
+               {
+                       if ($family == 'ipv6')
+                               $ip = new IPv6Address ($ip);
+                       if ($net_id = ($family == 'ipv6' ? getIPv6AddressNetworkId ($ip) : getIPv4AddressNetworkId ($ip)))
+                       {
+                               if (! isset($seen_nets[$net_id]))
+                                       $seen_nets[$net_id]     = 1;
+                               else
+                                       continue;
+                               $net = spotEntity ("${family}net", $net_id);
+                               amplifyCell ($net);
+                               foreach ($net['8021q'] as $vlan)
+                                       if (! in_array ($vlan['vlan_id'], $employed))
+                                               $employed[] = $vlan['vlan_id'];
+
+                       }
+               }
+       }
+
        foreach ($domain_vlanlist as $vlan_id => $vlan)
-               if ($vlan['vlan_type'] == 'compulsory')
+               if ($vlan['vlan_type'] == 'compulsory' and ! in_array ($vlan_id, $employed))
                        $employed[] = $vlan_id;
        foreach ($portlist as $port_name => $port)
                if ($port['vst_role'] != 'uplink')
@@ -3607,7 +3679,7 @@ function exec8021QDeploy ($object_id, $do_push)
        // Take new "desired" configuration and derive uplink port configuration
        // from it. Then cancel changes to immune VLANs and save resulting
        // changes (if any left).
-       $new_uplinks = filter8021QChangeRequests ($domain_vlanlist, $Dnew, produceUplinkPorts ($domain_vlanlist, $Dnew));
+       $new_uplinks = filter8021QChangeRequests ($domain_vlanlist, $Dnew, produceUplinkPorts ($domain_vlanlist, $Dnew, $vswitch['object_id']));
        $nsaved_uplinks += replace8021QPorts ('desired', $vswitch['object_id'], $Dnew, $new_uplinks);
        if ($nsaved + $nsaved_uplinks)
        {
@@ -3693,7 +3765,7 @@ function printPageHeaders ()
                if ($item['type'] == 'inline')
                        echo '<style type="text/css">' . "\n" . trim ($item['style'], "\r\n") . "\n</style>\n";
                elseif ($item['type'] == 'file')
-                       echo '<link rel="stylesheet" type="text/css" href="' . htmlspecialchars ($item['style']) . "\" />\n";
+                       echo '<link rel="stylesheet" type="text/css" href="' . TSURI ($item['style']) . "\" />\n";
 
        // add JS scripts
        foreach (addJS (NULL) as $group_name => $js_list)
@@ -3701,7 +3773,7 @@ function printPageHeaders ()
                        if ($item['type'] == 'inline')
                                echo '<script type="text/javascript">' . "\n" . trim ($item['script'], "\r\n") . "\n</script>\n";
                        elseif ($item['type'] == 'file')
-                               echo '<script type="text/javascript" src="' . htmlspecialchars($item['script']) . "\"></script>\n";
+                               echo '<script type="text/javascript" src="' . htmlspecialchars ($item['script']) . "\"></script>\n";
 }
 
 function strerror8021Q ($errno)
@@ -3844,7 +3916,7 @@ function recalc8021QPorts ($switch_id, $check_only = FALSE)
                        $remote_before = $remote_order;
                        if ($remote_order[$remote_pn]['vst_role'] == 'uplink')
                        {
-                               $remote_uplinks = filter8021QChangeRequests ($remote_domain_vlanlist, $remote_before, produceUplinkPorts ($remote_domain_vlanlist, $remote_order));
+                               $remote_uplinks = filter8021QChangeRequests ($remote_domain_vlanlist, $remote_before, produceUplinkPorts ($remote_domain_vlanlist, $remote_order, $remote_vswitch['object_id']));
                                $remote_port_order = $remote_uplinks[$remote_pn];
                                $new_order = produceDownlinkPort ($domain_vlanlist, $pn, array ($pn => $local_port_order), $remote_port_order);
                                $local_port_order = $new_order[$pn]; // this updates $order
@@ -3860,7 +3932,7 @@ function recalc8021QPorts ($switch_id, $check_only = FALSE)
        }
 
        // calculate local uplinks, store changes in $order
-       foreach (filter8021QChangeRequests ($domain_vlanlist, $before, produceUplinkPorts ($domain_vlanlist, $order)) as $pn => $portorder)
+       foreach (filter8021QChangeRequests ($domain_vlanlist, $before, produceUplinkPorts ($domain_vlanlist, $order, $vswitch['object_id'])) as $pn => $portorder)
                $order[$pn] = $portorder;
        // queue changes in D-config of local switch
        if ($changed = queueChangesToSwitch ($switch_id, $order, $before, $check_only))
@@ -4542,21 +4614,26 @@ function getMessagesCount ($message_type = 'all')
                }
                elseif ($_SESSION['log']['v'] == 2)
                        foreach ($_SESSION['log']['m'] as $msg)
-                       {
-                               if ($message_type == 'all')
+                               if ($msg['c'] < 100)
                                {
-                                       ++$result;
-                                       continue;
+                                       if ($message_type == 'success' || $message_type == 'all')
+                                               ++$result;
+                               }
+                               elseif ($msg['c'] < 200)
+                               {
+                                       if ($message_type == 'error' || $message_type == 'all')
+                                               ++$result;
+                               }
+                               elseif ($msg['c'] < 300)
+                               {
+                                       if ($message_type == 'warning' || $message_type == 'all')
+                                               ++$result;
+                               }
+                               else
+                               {
+                                       if ($message_type == 'neutral' || $message_type == 'all')
+                                               ++$result;
                                }
-                               if ($message_type == 'success' and $msg['c'] < 100)
-                                       ++$result;
-                               elseif ($message_type == 'error' and $msg['c'] < 200)
-                                       ++$result;
-                               elseif ($message_type == 'warning' and $msg['c'] < 300)
-                                       ++$result;
-                               elseif ($message_type == 'neutral')
-                                       ++$result;
-                       }
        }
        return $result;
 }
@@ -4628,4 +4705,47 @@ function getConfigVar ($varname = '')
        return $configCache[$varname]['varvalue'];
 }
 
+// return portinfo array if object has a port with such name, or NULL
+function getPortinfoByName (&$object, $portname)
+{
+       if (! isset ($object['ports']))
+               amplifyCell ($object);
+       foreach ($object['ports'] as $portinfo)
+               if ($portinfo['name'] == $portname)
+                       return $portinfo;
+       return NULL;
+}
+
+function proxyStaticURI ($URI)
+{
+       $content_type = array
+       (
+               'css' => 'text/css',
+               'js' => 'text/javascript',
+               'html' => 'text/html',
+               'png' => 'image/png',
+               'gif' => 'image/gif',
+       );
+       global $racktables_static_dir;
+       $my_static_root = isset ($racktables_static_dir) ? $racktables_static_dir : '.';
+       $file_path = $my_static_root . '/' . $URI;
+       if (! file_exists ($file_path))
+       {
+               header ('404 Not Found');
+?><!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
+<html><head>
+<title>404 Not Found</title>
+</head><body>
+<h1>Not Found</h1>
+<p>The requested file was not found in this instance.</p>
+<hr>
+<address>RackTables static content proxy</address>
+</body></html><?php
+               exit;
+       }
+       $extension = preg_replace ('/^.+\.([a-z]+)$/', '$1', $URI);
+       header ('Content-type: ' . $content_type[$extension]);
+       readfile ($file_path);
+}
+
 ?>