function renderFlatIP()
{
    if (isset($_REQUEST['attr_id']) && isset($_REQUEST['attr_value'])) {
        $params = array('attr_id' => $_REQUEST['attr_id'], 'attr_value' => $_REQUEST['attr_value']);
        $av = $_REQUEST['attr_value'];
        if ($av === 'NULL') {
            $av = NULL;
        }
        $nets = fetchNetworksByAttr($_REQUEST['attr_id'], $av, TRUE);
    } else {
        $params = array();
        $nets = array_merge(listCells('ipv4net'), listCells('ipv6net'));
    }
    $cf = getCellFilter();
    $nets = filterCellList($nets, $cf['expression']);
    echo "<table border=0 class=objectview>\n";
    echo "<tr><td class=pcleft>";
    startPortlet(sprintf("Networks (%d)", count($nets)));
    echo '<ol>';
    foreach ($nets as $network) {
        echo '<li>';
        renderCell($network);
        echo '</li>';
    }
    echo '</ol>';
    finishPortlet();
    echo '</td><td class=pcright>';
    renderCellFilterPortlet($cf, 'ipv4net', $nets, $params);
    echo '</td></tr></table>';
}
function FullRowView()
{
    if (isset($_REQUEST['row_id'])) {
        $row_id = $_REQUEST['row_id'];
    } else {
        $rack_id = 1;
    }
    global $frvVersion;
    $rowData = getRowInfo($row_id);
    $cellfilter = getCellFilter();
    $rackList = filterCellList(listCells('rack', $row_id), $cellfilter['expression']);
    // echo "<form method=post name=ImportObject action='?module=redirect&page=row&row_id=$row_id&tab=full_row_view&op=preparePrint'>";
    echo "<font size=1em color=gray>version {$frvVersion}&nbsp;</font>";
    // echo "<input type=submit name=got_very_fast_data value='Print view'>";
    // echo "</form>";
    echo '<table><tr><td nowrap="nowrap" valign="top">';
    $count = 1;
    foreach ($rackList as $rack) {
        // echo "<br>Schrank: ${rack['name']} ${rack['id']}";
        // $rackData = spotEntity ('rack', ${rack['id']});
        echo '<div class="phgrack" style="float: top; width: 240px">';
        renderReducedRack("{$rack['id']}");
        echo '</div>';
        echo '</td><td nowrap="nowrap" valign="top">';
    }
    echo '</td></tr></table>';
}
function renderUserListEditor()
{
    function printNewItemTR()
    {
        startPortlet('Add new');
        printOpFormIntro('createUser');
        echo '<table cellspacing=0 cellpadding=5 align=center>';
        echo '<tr><th>&nbsp;</th><th>&nbsp;</th><th>Tags</th></tr>';
        echo '<tr><th class=tdright>Username</th><td class=tdleft><input type=text size=64 name=username></td>';
        echo '<tr><th class=tdright>Real name</th><td class=tdleft><input type=text size=64 name=realname></td></tr>';
        echo '<tr><th class=tdright>Password</th><td class=tdleft><input type=password size=64 name=password></td></tr>';
        echo '<tr><th class=tdright>Tags</th><td class=tdleft>';
        printTagsPicker();
        echo '</td></tr>';
        echo '<tr><td colspan=2>';
        printImageHREF('CREATE', 'Add new account', TRUE);
        echo '</td></tr>';
        echo '</table></form>';
        finishPortlet();
    }
    if (getConfigVar('ADDNEW_AT_TOP') == 'yes') {
        printNewItemTR();
    }
    $accounts = listCells('user');
    startPortlet('Manage existing (' . count($accounts) . ')');
    echo '<table cellspacing=0 cellpadding=5 align=center class=widetable>';
    echo '<tr><th>Username</th><th>Real name</th><th>New password (use old if blank)</th><th>&nbsp;</th></tr>';
    foreach ($accounts as $account) {
        printOpFormIntro('updateUser', array('user_id' => $account['user_id']));
        echo "<tr><td><input type=text name=username value='{$account['user_name']}' size=16></td>";
        echo "<td><input type=text name=realname value='{$account['user_realname']}' size=24></td>";
        echo "<td><input type=password name=password size=40></td><td>";
        printImageHREF('save', 'Save changes', TRUE);
        echo '</td></form></tr>';
    }
    echo '</table><br>';
    finishPortlet();
    if (getConfigVar('ADDNEW_AT_TOP') != 'yes') {
        printNewItemTR();
    }
}
示例#4
0
function getProximateRacks($rack_id, $proximity = 0)
{
    $ret = array($rack_id);
    if ($proximity > 0) {
        $rack = spotEntity('rack', $rack_id);
        $rackList = doubleLink(listCells('rack', $rack['row_id']));
        $todo = $proximity;
        $cur_item = $rackList[$rack_id];
        while ($todo and array_key_exists('prev_key', $cur_item)) {
            $cur_item = $rackList[$cur_item['prev_key']];
            $ret[] = $cur_item['id'];
            $todo--;
        }
        $todo = $proximity;
        $cur_item = $rackList[$rack_id];
        while ($todo and array_key_exists('next_key', $cur_item)) {
            $cur_item = $rackList[$cur_item['next_key']];
            $ret[] = $cur_item['id'];
            $todo--;
        }
    }
    return $ret;
}
示例#5
0
function getNarrowObjectList($varname = '')
{
    $wideList = listCells('object');
    if (strlen($varname) and strlen(getConfigVar($varname))) {
        global $parseCache;
        if (!isset($parseCache[$varname])) {
            $parseCache[$varname] = spotPayload(getConfigVar($varname), 'SYNT_EXPR');
        }
        if ($parseCache[$varname]['result'] != 'ACK') {
            return array();
        }
        $wideList = filterCellList($wideList, $parseCache[$varname]['load']);
    }
    $ret = array();
    foreach ($wideList as $cell) {
        $ret[$cell['id']] = $cell['dname'];
    }
    return $ret;
}
function renderRealServerList()
{
    global $nextorder;
    $rslist = getRSList();
    $pool_list = listCells('ipv4rspool');
    echo "<table class=widetable border=0 cellpadding=10 cellspacing=0 align=center>\n";
    echo "<tr><th>RS pool</th><th>in service</th><th>real IP address</th><th>real port</th><th>RS configuration</th></tr>";
    $order = 'even';
    $last_pool_id = 0;
    foreach ($rslist as $rsinfo) {
        if ($last_pool_id != $rsinfo['rspool_id']) {
            $order = $nextorder[$order];
            $last_pool_id = $rsinfo['rspool_id'];
        }
        echo "<tr valign=top class=row_{$order}><td>";
        $dname = strlen($pool_list[$rsinfo['rspool_id']]['name']) ? $pool_list[$rsinfo['rspool_id']]['name'] : 'ANONYMOUS';
        echo mkA($dname, 'ipv4rspool', $rsinfo['rspool_id']);
        echo '</td><td align=center>';
        if ($rsinfo['inservice'] == 'yes') {
            printImageHREF('inservice', 'in service');
        } else {
            printImageHREF('notinservice', 'NOT in service');
        }
        echo '</td><td>' . mkA($rsinfo['rsip'], 'ipaddress', $rsinfo['rsip']) . '</td>';
        echo "<td>{$rsinfo['rsport']}</td>";
        echo "<td><pre>{$rsinfo['rsconfig']}</pre></td>";
        echo "</tr>\n";
    }
    echo "</table>";
}
 function get_realm_data($realm)
 {
     $name = NULL;
     $list = array();
     $options = array();
     switch ($realm) {
         case 'object':
             $name = 'Load balancer';
             $list = getNarrowObjectList('IPV4LB_LISTSRC');
             $options = array('name' => 'object_id');
             break;
         case 'ipvs':
             $name = 'Virtual service';
             $list = formatEntityList(listCells('ipvs'));
             $options = array('name' => 'vs_id');
             break;
         case 'ipv4rspool':
             $name = 'RS pool';
             $list = formatEntityList(listCells('ipv4rspool'));
             $options = array('name' => 'rspool_id');
             break;
         default:
             throw new InvalidArgException('realm', $realm);
     }
     return array('name' => $name, 'list' => $list, 'options' => $options);
 }
示例#8
0
文件: slb.php 项目: rhysm/racktables
function getIPv4RSPoolOptions()
{
    $ret = array();
    foreach (listCells('ipv4rspool') as $pool_id => $poolInfo) {
        $ret[$pool_id] = $poolInfo['name'];
    }
    return $ret;
}
示例#9
0
文件: interface.php 项目: xtha/salt
function renderDataIntegrityReport()
{
    global $nextorder;
    $violations = FALSE;
    // check 1: EntityLink rows referencing not-existent relatives
    // check 1.1: children
    $realms = array('location' => 'Location', 'object' => 'RackObject', 'rack' => 'Rack', 'row' => 'Row');
    $orphans = array();
    foreach ($realms as $realm => $table) {
        $result = usePreparedSelectBlade('SELECT EL.* FROM EntityLink EL ' . "LEFT JOIN {$table} ON EL.child_entity_id = {$table}.id " . "WHERE EL.child_entity_type = ? AND {$table}.id IS NULL", array($realm));
        $rows = $result->fetchAll(PDO::FETCH_ASSOC);
        unset($result);
        $orphans = array_merge($orphans, $rows);
    }
    if (count($orphans)) {
        $violations = TRUE;
        startPortlet('EntityLink: Missing Children (' . count($orphans) . ')');
        echo "<table cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
        echo "<tr><th>Parent</th><th>Child Type</th><th>Child ID</th></tr>\n";
        $order = 'odd';
        foreach ($orphans as $orphan) {
            $realm_name = formatRealmName($orphan['parent_entity_type']);
            $parent = spotEntity($orphan['parent_entity_type'], $orphan['parent_entity_id']);
            echo "<tr class=row_{$order}>";
            echo "<td>{$realm_name}: {$parent['name']}</td>";
            echo "<td>{$orphan['child_entity_type']}</td>";
            echo "<td>{$orphan['child_entity_id']}</td>";
            echo "</tr>\n";
            $order = $nextorder[$order];
        }
        echo "</table>\n";
        finishPortLet();
    }
    // check 1.2: parents
    $orphans = array();
    foreach ($realms as $realm => $table) {
        $result = usePreparedSelectBlade('SELECT EL.* FROM EntityLink EL ' . "LEFT JOIN {$table} ON EL.parent_entity_id = {$table}.id " . "WHERE EL.parent_entity_type = ? AND {$table}.id IS NULL", array($realm));
        $rows = $result->fetchAll(PDO::FETCH_ASSOC);
        unset($result);
        $orphans = array_merge($orphans, $rows);
    }
    if (count($orphans)) {
        $violations = TRUE;
        startPortlet('EntityLink: Missing Parents (' . count($orphans) . ')');
        echo "<table cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
        echo "<tr><th>Child</th><th>Parent Type</th><th>Parent ID</th></tr>\n";
        $order = 'odd';
        foreach ($orphans as $orphan) {
            $realm_name = formatRealmName($orphan['child_entity_type']);
            $child = spotEntity($orphan['child_entity_type'], $orphan['child_entity_id']);
            echo "<tr class=row_{$order}>";
            echo "<td>{$realm_name}: {$child['name']}</td>";
            echo "<td>{$orphan['parent_entity_type']}</td>";
            echo "<td>{$orphan['parent_entity_id']}</td>";
            echo "</tr>\n";
            $order = $nextorder[$order];
        }
        echo "</table>\n";
        finishPortLet();
    }
    // check 3: multiple tables referencing non-existent dictionary entries
    // check 3.1: AttributeMap
    $orphans = array();
    $result = usePreparedSelectBlade('SELECT AM.*, A.name AS attr_name, C.name AS chapter_name ' . 'FROM AttributeMap AM ' . 'LEFT JOIN Attribute A ON AM.attr_id = A.id ' . 'LEFT JOIN Chapter C ON AM.chapter_id = C.id ' . 'LEFT JOIN Dictionary D ON AM.objtype_id = D.dict_key ' . 'WHERE D.dict_key IS NULL');
    $orphans = $result->fetchAll(PDO::FETCH_ASSOC);
    unset($result);
    if (count($orphans)) {
        $violations = TRUE;
        startPortlet('AttributeMap: Invalid Mappings (' . count($orphans) . ')');
        echo "<table cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
        echo "<tr><th>Attribute</th><th>Chapter</th><th>Object TypeID</th></tr>\n";
        $order = 'odd';
        foreach ($orphans as $orphan) {
            echo "<tr class=row_{$order}>";
            echo "<td>{$orphan['attr_name']}</td>";
            echo "<td>{$orphan['chapter_name']}</td>";
            echo "<td>{$orphan['objtype_id']}</td>";
            echo "</tr>\n";
            $order = $nextorder[$order];
        }
        echo "</table>\n";
        finishPortLet();
    }
    // check 3.2: Object
    $orphans = array();
    $result = usePreparedSelectBlade('SELECT O.* FROM Object O ' . 'LEFT JOIN Dictionary D ON O.objtype_id = D.dict_key ' . 'WHERE D.dict_key IS NULL');
    $orphans = $result->fetchAll(PDO::FETCH_ASSOC);
    unset($result);
    if (count($orphans)) {
        $violations = TRUE;
        startPortlet('Object: Invalid Types (' . count($orphans) . ')');
        echo "<table cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
        echo "<tr><th>ID</th><th>Name</th><th>Type ID</th></tr>\n";
        $order = 'odd';
        foreach ($orphans as $orphan) {
            echo "<tr class=row_{$order}>";
            echo "<td>{$orphan['id']}</td>";
            echo "<td>{$orphan['name']}</td>";
            echo "<td>{$orphan['objtype_id']}</td>";
            echo "</tr>\n";
            $order = $nextorder[$order];
        }
        echo "</table>\n";
        finishPortLet();
    }
    // check 3.3: ObjectHistory
    $orphans = array();
    $result = usePreparedSelectBlade('SELECT OH.* FROM ObjectHistory OH ' . 'LEFT JOIN Dictionary D ON OH.objtype_id = D.dict_key ' . 'WHERE D.dict_key IS NULL');
    $orphans = $result->fetchAll(PDO::FETCH_ASSOC);
    unset($result);
    if (count($orphans)) {
        $violations = TRUE;
        startPortlet('ObjectHistory: Invalid Types (' . count($orphans) . ')');
        echo "<table cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
        echo "<tr><th>ID</th><th>Name</th><th>Type ID</th></tr>\n";
        $order = 'odd';
        foreach ($orphans as $orphan) {
            echo "<tr class=row_{$order}>";
            echo "<td>{$orphan['id']}</td>";
            echo "<td>{$orphan['name']}</td>";
            echo "<td>{$orphan['objtype_id']}</td>";
            echo "</tr>\n";
            $order = $nextorder[$order];
        }
        echo "</table>\n";
        finishPortLet();
    }
    // check 3.4: ObjectParentCompat
    $orphans = array();
    $result = usePreparedSelectBlade('SELECT OPC.*, PD.dict_value AS parent_name, CD.dict_value AS child_name ' . 'FROM ObjectParentCompat OPC ' . 'LEFT JOIN Dictionary PD ON OPC.parent_objtype_id = PD.dict_key ' . 'LEFT JOIN Dictionary CD ON OPC.child_objtype_id = CD.dict_key ' . 'WHERE PD.dict_key IS NULL OR CD.dict_key IS NULL');
    $orphans = $result->fetchAll(PDO::FETCH_ASSOC);
    unset($result);
    if (count($orphans)) {
        $violations = TRUE;
        startPortlet('Object Container Compatibility rules: Invalid Parent or Child Type (' . count($orphans) . ')');
        echo "<table cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
        echo "<tr><th>Parent</th><th>Parent Type ID</th><th>Child</th><th>Child Type ID</th></tr>\n";
        $order = 'odd';
        foreach ($orphans as $orphan) {
            echo "<tr class=row_{$order}>";
            echo "<td>{$orphan['parent_name']}</td>";
            echo "<td>{$orphan['parent_objtype_id']}</td>";
            echo "<td>{$orphan['child_name']}</td>";
            echo "<td>{$orphan['child_objtype_id']}</td>";
            echo "</tr>\n";
            $order = $nextorder[$order];
        }
        echo "</table>\n";
        finishPortLet();
    }
    // check 4: relationships that violate ObjectParentCompat Rules
    $invalids = array();
    $result = usePreparedSelectBlade('SELECT CO.id AS child_id, CO.objtype_id AS child_type_id, CD.dict_value AS child_type, CO.name AS child_name, ' . 'PO.id AS parent_id, PO.objtype_id AS parent_type_id, PD.dict_value AS parent_type, PO.name AS parent_name ' . 'FROM Object CO ' . 'LEFT JOIN EntityLink EL ON CO.id = EL.child_entity_id ' . 'LEFT JOIN Object PO ON EL.parent_entity_id = PO.id ' . 'LEFT JOIN ObjectParentCompat OPC ON PO.objtype_id = OPC.parent_objtype_id ' . 'LEFT JOIN Dictionary PD ON PO.objtype_id = PD.dict_key ' . 'LEFT JOIN Dictionary CD ON CO.objtype_id = CD.dict_key ' . "WHERE EL.parent_entity_type = 'object' AND EL.child_entity_type = 'object' " . 'AND OPC.parent_objtype_id IS NULL');
    $invalids = $result->fetchAll(PDO::FETCH_ASSOC);
    unset($result);
    if (count($invalids)) {
        $violations = TRUE;
        startPortlet('Objects: Violate Object Container Compatibility rules (' . count($invalids) . ')');
        echo "<table cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
        echo "<tr><th>Contained Obj Name</th><th>Contained Obj Type</th><th>Container Obj Name</th><th>Container Obj Type</th></tr>\n";
        $order = 'odd';
        foreach ($invalids as $invalid) {
            echo "<tr class=row_{$order}>";
            echo "<td>{$invalid['child_name']}</td>";
            echo "<td>{$invalid['child_type']}</td>";
            echo "<td>{$invalid['parent_name']}</td>";
            echo "<td>{$invalid['parent_type']}</td>";
            echo "</tr>\n";
            $order = $nextorder[$order];
        }
        echo "</table>\n";
        finishPortLet();
    }
    // check 5: Links that violate PortCompat Rules
    $invalids = array();
    $result = usePreparedSelectBlade('SELECT OA.id AS obja_id, OA.name AS obja_name, L.porta AS porta_id, PA.name AS porta_name, POIA.oif_name AS porta_type, ' . 'OB.id AS objb_id, OB.name AS objb_name, L.portb AS portb_id, PB.name AS portb_name, POIB.oif_name AS portb_type ' . 'FROM Link L ' . 'LEFT JOIN Port PA ON L.porta = PA.id ' . 'LEFT JOIN Object OA ON PA.object_id = OA.id ' . 'LEFT JOIN PortOuterInterface POIA ON PA.type = POIA.id ' . 'LEFT JOIN Port PB ON L.portb = PB.id ' . 'LEFT JOIN Object OB ON PB.object_id = OB.id ' . 'LEFT JOIN PortOuterInterface POIB ON PB.type = POIB.id ' . 'LEFT JOIN PortCompat PC on PA.type = PC.type1 AND PB.type = PC.type2 ' . 'WHERE PC.type1 IS NULL OR PC.type2 IS NULL');
    $invalids = $result->fetchAll(PDO::FETCH_ASSOC);
    unset($result);
    if (count($invalids)) {
        $violations = TRUE;
        startPortlet('Port Links: Violate Port Compatibility Rules (' . count($invalids) . ')');
        echo "<table cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
        echo "<tr><th>Object A</th><th>Port A Name</th><th>Port A Type</th><th>Object B</th><th>Port B Name</th><th>Port B Type</th></tr>\n";
        $order = 'odd';
        foreach ($invalids as $invalid) {
            echo "<tr class=row_{$order}>";
            echo "<td>{$invalid['obja_name']}</td>";
            echo "<td>{$invalid['porta_name']}</td>";
            echo "<td>{$invalid['porta_type']}</td>";
            echo "<td>{$invalid['objb_name']}</td>";
            echo "<td>{$invalid['portb_name']}</td>";
            echo "<td>{$invalid['portb_type']}</td>";
            echo "</tr>\n";
            $order = $nextorder[$order];
        }
        echo "</table>\n";
        finishPortLet();
    }
    // check 6: TagStorage rows referencing non-existent parents
    $realms = array('file' => array('table' => 'File', 'column' => 'id'), 'ipv4net' => array('table' => 'IPv4Network', 'column' => 'id'), 'ipv4rspool' => array('table' => 'IPv4RSPool', 'column' => 'id'), 'ipv4vs' => array('table' => 'IPv4VS', 'column' => 'id'), 'ipv6net' => array('table' => 'IPv6Network', 'column' => 'id'), 'ipvs' => array('table' => 'VS', 'column' => 'id'), 'location' => array('table' => 'Location', 'column' => 'id'), 'object' => array('table' => 'RackObject', 'column' => 'id'), 'rack' => array('table' => 'Rack', 'column' => 'id'), 'user' => array('table' => 'UserAccount', 'column' => 'user_id'), 'vst' => array('table' => 'VLANSwitchTemplate', 'column' => 'id'));
    $orphans = array();
    foreach ($realms as $realm => $details) {
        $result = usePreparedSelectBlade('SELECT TS.*, TT.tag FROM TagStorage TS ' . 'LEFT JOIN TagTree TT ON TS.tag_id = TT.id ' . "LEFT JOIN {$details['table']} ON TS.entity_id = {$details['table']}.{$details['column']} " . "WHERE TS.entity_realm = ? AND {$details['table']}.{$details['column']} IS NULL", array($realm));
        $rows = $result->fetchAll(PDO::FETCH_ASSOC);
        unset($result);
        $orphans = array_merge($orphans, $rows);
    }
    if (count($orphans)) {
        $violations = TRUE;
        startPortlet('TagStorage: Missing Parents (' . count($orphans) . ')');
        echo "<table cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
        echo "<tr><th>Tag</th><th>Parent Type</th><th>Parent ID</th></tr>\n";
        $order = 'odd';
        foreach ($orphans as $orphan) {
            $realm_name = formatRealmName($orphan['entity_realm']);
            echo "<tr class=row_{$order}>";
            echo "<td>{$orphan['tag']}</td>";
            echo "<td>{$realm_name}</td>";
            echo "<td>{$orphan['entity_id']}</td>";
            echo "</tr>\n";
            $order = $nextorder[$order];
        }
        echo "</table>\n";
        finishPortLet();
    }
    // check 7: FileLink rows referencing non-existent parents
    // re-use the realms list from the TagStorage check, with a few mods
    unset($realms['file'], $realms['vst']);
    $realms['row'] = array('table' => 'Row', 'column' => 'id');
    $orphans = array();
    foreach ($realms as $realm => $details) {
        $result = usePreparedSelectBlade('SELECT FL.*, F.name FROM FileLink FL ' . 'LEFT JOIN File F ON FL.file_id = F.id ' . "LEFT JOIN {$details['table']} ON FL.entity_id = {$details['table']}.{$details['column']} " . "WHERE FL.entity_type = ? AND {$details['table']}.{$details['column']} IS NULL", array($realm));
        $rows = $result->fetchAll(PDO::FETCH_ASSOC);
        unset($result);
        $orphans = array_merge($orphans, $rows);
    }
    if (count($orphans)) {
        $violations = TRUE;
        startPortlet('FileLink: Missing Parents (' . count($orphans) . ')');
        echo "<table cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
        echo "<tr><th>File</th><th>Parent Type</th><th>Parent ID</th></tr>\n";
        $order = 'odd';
        foreach ($orphans as $orphan) {
            $realm_name = formatRealmName($orphan['entity_type']);
            echo "<tr class=row_{$order}>";
            echo "<td>{$orphan['name']}</td>";
            echo "<td>{$realm_name}</td>";
            echo "<td>{$orphan['entity_id']}</td>";
            echo "</tr>\n";
            $order = $nextorder[$order];
        }
        echo "</table>\n";
        finishPortLet();
    }
    // check 8: missing triggers
    $triggers = array('Link-before-insert' => 'Link', 'Link-before-update' => 'Link');
    $result = usePreparedSelectBlade('SELECT TRIGGER_NAME, EVENT_OBJECT_TABLE ' . 'FROM information_schema.TRIGGERS WHERE TRIGGER_SCHEMA = SCHEMA()');
    $rows = $result->fetchAll(PDO::FETCH_ASSOC);
    unset($result);
    $existing_triggers = $missing_triggers = array();
    foreach ($rows as $row) {
        $existing_triggers[$row['TRIGGER_NAME']] = $row['EVENT_OBJECT_TABLE'];
    }
    foreach ($triggers as $trigger => $table) {
        if (!array_key_exists($trigger, $existing_triggers)) {
            $missing_triggers[$trigger] = $table;
        }
    }
    if (count($missing_triggers)) {
        $violations = TRUE;
        startPortlet('Missing Triggers (' . count($missing_triggers) . ')');
        echo "<table cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
        echo "<tr><th>Table</th><th>Trigger</th></tr>\n";
        $order = 'odd';
        foreach ($missing_triggers as $trigger => $table) {
            echo "<tr class=row_{$order}>";
            echo "<td>{$table}</td>";
            echo "<td>{$trigger}</td>";
            echo "</tr>\n";
            $order = $nextorder[$order];
        }
        echo "</table>\n";
        finishPortLet();
    }
    // check 9: missing foreign keys
    $fkeys = array('Atom-FK-molecule_id' => 'Atom', 'Atom-FK-rack_id' => 'Atom', 'AttributeMap-FK-chapter_id' => 'AttributeMap', 'AttributeMap-FK-attr_id' => 'AttributeMap', 'AttributeValue-FK-map' => 'AttributeValue', 'AttributeValue-FK-object' => 'AttributeValue', 'CachedPAV-FK-object-port' => 'CachedPAV', 'CachedPAV-FK-vlan_id' => 'CachedPAV', 'CachedPNV-FK-compound' => 'CachedPNV', 'CachedPVM-FK-object_id' => 'CachedPVM', 'CactiGraph-FK-server_id' => 'CactiGraph', 'CactiGraph-FK-server_id' => 'CactiGraph', 'Dictionary-FK-chapter_id' => 'Dictionary', 'FileLink-File_fkey' => 'FileLink', 'IPv4Allocation-FK-object_id' => 'IPv4Allocation', 'IPv4LB-FK-vs_id' => 'IPv4LB', 'IPv4LB-FK-object_id' => 'IPv4LB', 'IPv4LB-FK-rspool_id' => 'IPv4LB', 'IPv4NAT-FK-object_id' => 'IPv4NAT', 'IPv4RS-FK' => 'IPv4RS', 'IPv6Allocation-FK-object_id' => 'IPv6Allocation', 'Link-FK-a' => 'Link', 'Link-FK-b' => 'Link', 'MountOperation-FK-object_id' => 'MountOperation', 'MountOperation-FK-old_molecule_id' => 'MountOperation', 'MountOperation-FK-new_molecule_id' => 'MountOperation', 'MuninGraph-FK-server_id' => 'MuninGraph', 'MuninGraph-FK-server_id' => 'MuninGraph', 'ObjectHistory-FK-object_id' => 'ObjectHistory', 'ObjectLog-FK-object_id' => 'ObjectLog', 'Port-FK-iif-oif' => 'Port', 'Port-FK-object_id' => 'Port', 'PortAllowedVLAN-FK-object-port' => 'PortAllowedVLAN', 'PortAllowedVLAN-FK-vlan_id' => 'PortAllowedVLAN', 'PortCompat-FK-oif_id1' => 'PortCompat', 'PortCompat-FK-oif_id2' => 'PortCompat', 'PortInterfaceCompat-FK-iif_id' => 'PortInterfaceCompat', 'PortInterfaceCompat-FK-oif_id' => 'PortInterfaceCompat', 'PortLog_ibfk_1' => 'PortLog', 'PortNativeVLAN-FK-compound' => 'PortNativeVLAN', 'PortVLANMode-FK-object-port' => 'PortVLANMode', 'RackSpace-FK-rack_id' => 'RackSpace', 'RackSpace-FK-object_id' => 'RackSpace', 'TagStorage-FK-TagTree' => 'TagStorage', 'TagTree-K-parent_id' => 'TagTree', 'UserConfig-FK-varname' => 'UserConfig', 'VLANDescription-FK-domain_id' => 'VLANDescription', 'VLANDescription-FK-vlan_id' => 'VLANDescription', 'VLANIPv4-FK-compound' => 'VLANIPv4', 'VLANIPv4-FK-ipv4net_id' => 'VLANIPv4', 'VLANIPv6-FK-compound' => 'VLANIPv6', 'VLANIPv6-FK-ipv6net_id' => 'VLANIPv6', 'VLANSTRule-FK-vst_id' => 'VLANSTRule', 'VLANSwitch-FK-domain_id' => 'VLANSwitch', 'VLANSwitch-FK-object_id' => 'VLANSwitch', 'VLANSwitch-FK-template_id' => 'VLANSwitch', 'VSEnabledIPs-FK-object_id' => 'VSEnabledIPs', 'VSEnabledIPs-FK-rspool_id' => 'VSEnabledIPs', 'VSEnabledIPs-FK-vs_id-vip' => 'VSEnabledIPs', 'VSEnabledPorts-FK-object_id' => 'VSEnabledPorts', 'VSEnabledPorts-FK-rspool_id' => 'VSEnabledPorts', 'VSEnabledPorts-FK-vs_id-proto-vport' => 'VSEnabledPorts', 'VSIPs-vs_id' => 'VSIPs', 'VS-vs_id' => 'VSPorts');
    $result = usePreparedSelectBlade('SELECT CONSTRAINT_NAME, TABLE_NAME ' . 'FROM information_schema.TABLE_CONSTRAINTS ' . "WHERE CONSTRAINT_SCHEMA = SCHEMA() AND CONSTRAINT_TYPE = 'FOREIGN KEY'");
    $rows = $result->fetchAll(PDO::FETCH_ASSOC);
    unset($result);
    $existing_fkeys = $missing_fkeys = array();
    foreach ($rows as $row) {
        $existing_fkeys[$row['CONSTRAINT_NAME']] = $row['TABLE_NAME'];
    }
    foreach ($fkeys as $fkey => $table) {
        if (!array_key_exists($fkey, $existing_fkeys)) {
            $missing_fkeys[$fkey] = $table;
        }
    }
    if (count($missing_fkeys)) {
        $violations = TRUE;
        startPortlet('Missing Foreign Keys (' . count($missing_fkeys) . ')');
        echo "<table cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
        echo "<tr><th>Table</th><th>Key</th></tr>\n";
        $order = 'odd';
        foreach ($missing_fkeys as $fkey => $table) {
            echo "<tr class=row_{$order}>";
            echo "<td>{$table}</td>";
            echo "<td>{$fkey}</td>";
            echo "</tr>\n";
            $order = $nextorder[$order];
        }
        echo "</table>\n";
        finishPortLet();
    }
    // check 10: circular references
    //     - all affected members of the tree are displayed
    //     - it would be beneficial to only display the offending records
    // check 10.1: locations
    $invalids = array();
    $locations = listCells('location');
    foreach ($locations as $location) {
        try {
            $children = getLocationChildrenList($location['id']);
        } catch (RackTablesError $e) {
            $invalids[] = $location;
        }
    }
    if (count($invalids)) {
        $violations = TRUE;
        startPortlet('Locations: Tree Contains Circular References (' . count($invalids) . ')');
        echo "<table cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
        echo "<tr><th>Child ID</th><th>Child Location</th><th>Parent ID</th><th>Parent Location</th></tr>\n";
        $order = 'odd';
        foreach ($invalids as $invalid) {
            echo "<tr class=row_{$order}>";
            echo "<td>{$invalid['id']}</td>";
            echo "<td>{$invalid['name']}</td>";
            echo "<td>{$invalid['parent_id']}</td>";
            echo "<td>{$invalid['parent_name']}</td>";
            echo "</tr>\n";
            $order = $nextorder[$order];
        }
        echo "</table>\n";
        finishPortLet();
    }
    // check 10.2: objects
    $invalids = array();
    $objects = listCells('object');
    foreach ($objects as $object) {
        try {
            $children = getObjectContentsList($object['id']);
        } catch (RackTablesError $e) {
            $invalids[] = $object;
        }
    }
    if (count($invalids)) {
        $violations = TRUE;
        startPortlet('Objects: Tree Contains Circular References (' . count($invalids) . ')');
        echo "<table cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
        echo "<tr><th>Contained ID</th><th>Contained Object</th><th>Container ID</th><th>Container Object</th></tr>\n";
        $order = 'odd';
        foreach ($invalids as $invalid) {
            echo "<tr class=row_{$order}>";
            echo "<td>{$invalid['id']}</td>";
            echo "<td>{$invalid['name']}</td>";
            echo "<td>{$invalid['container_id']}</td>";
            echo "<td>{$invalid['container_name']}</td>";
            echo "</tr>\n";
            $order = $nextorder[$order];
        }
        echo "</table>\n";
        finishPortLet();
    }
    // check 10.3: tags
    $invalids = array();
    $tags = getTagList();
    foreach ($tags as $tag) {
        try {
            $children = getTagChildrenList($tag['id']);
        } catch (RackTablesError $e) {
            $invalids[] = $tag;
        }
    }
    if (count($invalids)) {
        $violations = TRUE;
        startPortlet('Tags: Tree Contains Circular References (' . count($invalids) . ')');
        echo "<table cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
        echo "<tr><th>Child ID</th><th>Child Tag</th><th>Parent ID</th><th>Parent Tag</th></tr>\n";
        $order = 'odd';
        foreach ($invalids as $invalid) {
            echo "<tr class=row_{$order}>";
            echo "<td>{$invalid['id']}</td>";
            echo "<td>{$invalid['tag']}</td>";
            echo "<td>{$invalid['parent_id']}</td>";
            printf('<td>%s</td>', $tags[$invalid['parent_id']]['tag']);
            echo "</tr>\n";
            $order = $nextorder[$order];
        }
        echo "</table>\n";
        finishPortLet();
    }
    if (!$violations) {
        echo '<h2>No integrity violations found</h2>';
    }
}
示例#10
0
文件: api.php 项目: xtha/salt
     foreach ($racklist as $rack_id) {
         usePreparedDeleteBlade('RackThumbnail', array('rack_id' => $rack_id));
     }
     // redirect to the depot method
     redirectUser($_SERVER['SCRIPT_NAME'] . "?method=get_depot");
     break;
     // get all objects
     //    UI equivalent: /index.php?page=depot&tab=default
     //    UI handler: renderDepot()
 // get all objects
 //    UI equivalent: /index.php?page=depot&tab=default
 //    UI handler: renderDepot()
 case 'get_depot':
     require_once 'inc/init.php';
     $cellfilter = getCellFilter();
     $objects = filterCellList(listCells('object'), $cellfilter['expression']);
     // get details if requested
     if (isset($_REQUEST['include_attrs'])) {
         foreach ($objects as $object_id => $object) {
             amplifyCell($object);
             // return the attributes in an array keyed on 'name', unless otherwise requested
             $key_attrs_on = 'name';
             if (isset($_REQUEST['key_attrs_on'])) {
                 $key_attrs_on = $_REQUEST['key_attrs_on'];
             }
             $attrs = array();
             foreach (getAttrValues($object_id) as $record) {
                 // check that the key exists for this record
                 if (!isset($record[$key_attrs_on])) {
                     throw new InvalidRequestArgException('key_attrs_on', $_REQUEST['key_attrs_on'], 'requested keying value not set for all attributes');
                 }
function getWattsPerRow()
{
    // assertions
    // find the needed attributes
    global $nextorder;
    // Was this function called with a specific row_id?
    if (isset($_REQUEST['row_id'])) {
        assertStringArg('row_id');
        $row_toshow = $_REQUEST['row_id'];
    } else {
        $row_toshow = -1;
    }
    //from renderRackspace(), interface.php:151
    $found_racks = array();
    $rows = array();
    $cellfilter = getCellFilter();
    $rackCount = 0;
    $order = 'odd';
    // get rackspace information
    foreach (getAllRows() as $row_id => $rowInfo) {
        $rackList = filterCellList(listCells('rack', $row_id), $cellfilter['expression']);
        $found_racks = array_merge($found_racks, $rackList);
        $rows[] = array('location_id' => $rowInfo['location_id'], 'location_name' => $rowInfo['location_name'], 'row_id' => $row_id, 'row_name' => $rowInfo['name'], 'racks' => $rackList);
        $rackCount += count($rackList);
    }
    // Main layout starts.
    echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
    // Left portlet with list of rows.
    echo "<tr><td class=pcleft width='50%'>";
    startPortlet('Rack Rows (' . count($rows) . ')');
    echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
    foreach ($rows as $row) {
        $row_id = $row['row_id'];
        $row_name = $row['row_name'];
        $row_location = $row['location_name'];
        $rackList = $row['racks'];
        echo "<tr class=row_{$order}><td width='20%'></td><td class=tdleft>";
        if (!count($rackList)) {
            echo "{$row_location} - {$row_name} (empty row)";
        } else {
            echo "<a href='" . makeHref(array('page' => 'reports', 'tab' => 'watts_per_row', 'row_id' => $row_id)) . "'>{$row_location} - {$row_name}</a>";
        }
        echo "<td><tr>\n";
        $order = $nextorder[$order];
    }
    echo "</td></tr>\n";
    echo "</table><br>\n";
    finishPortlet();
    echo "</td><td class=pcright>";
    // Right Portlet: Draw the racks in the selected row
    if ($row_toshow > -1) {
        $rowInfo = getRowInfo($row_toshow);
        $cellfilter = getCellFilter();
        $rackList = filterCellList(listCells('rack', $row_toshow), $cellfilter['expression']);
        $rackwidth = getRackImageWidth() * getConfigVar('ROW_SCALE');
        // Maximum number of racks per row is proportionally less, but at least 1.
        $maxPerRow = max(floor(getConfigVar('RACKS_PER_ROW') / getConfigVar('ROW_SCALE')), 1);
        $rackListIdx = 0;
        $rowTotalWattage = 0;
        $order = 'odd';
        startPortlet('Racks within ' . $rowInfo['name'] . ' (' . count($rackList) . ')');
        echo "<table border=0 cellspacing=5 align='center'><tr>";
        foreach ($rackList as $rack) {
            $rackTotalWattage = 0;
            // see renderRack(), interface.php:311
            $rackData = spotEntity('rack', $rack['id']);
            amplifyCell($rackData);
            $objectChildren = getEntityRelatives('children', 'object', $objectData['id']);
            foreach ($rackData['mountedObjects'] as $object) {
                $objectData = spotEntity('object', $object);
                amplifyCell($objectData);
                foreach (getAttrValues($objectData['id']) as $record) {
                    if ($record['name'] == 'Wattage consumption') {
                        $rackTotalWattage += $record['value'];
                    }
                }
            }
            if ($rackListIdx % $maxPerRow == 0) {
                echo $rackListIdx > 0 ? '</tr><tr>' : '<tr>';
            }
            echo "<td align=center class=row_{$order}><a href='" . makeHref(array('page' => 'rack', 'rack_id' => $rack['id'])) . "'>";
            echo "<img border=0 width={$rackwidth} height=" . getRackImageHeight($rack['height']) * getConfigVar('ROW_SCALE');
            echo " title='{$rack['height']} units'";
            echo "src='?module=image&img=minirack&rack_id={$rack['id']}'>";
            echo "<br>{$rack['name']} ({$rackTotalWattage})</a></td>";
            $order = $nextorder[$order];
            $rackListIdx++;
            $rowTotalWattage += $rackTotalWattage;
        }
        echo "</tr><tr><td align=center colspan=";
        print count($rackList);
        echo "><br><b>The row total for attribute Wattage consuption is:  {$rowTotalWattage}</b></td>\n";
        echo "</tr></table>\n";
        finishPortlet();
    }
    echo "</td></tr></table>";
}
function renderSearchNewIP4Range()
{
    global $pTable;
    // prepare $cellfilter
    $cellfilter = getCellFilter();
    if ($cellfilter['is_empty'] || !isset($_REQUEST['cfp'])) {
        if (defined('SPARE_SEARCH_PREDICATE') && isset($pTable[SPARE_SEARCH_PREDICATE])) {
            $_REQUEST['cfp'] = array(SPARE_SEARCH_PREDICATE);
            $cellfilter = getCellFilter();
        }
    }
    $mask = NULL;
    if (!empty($_REQUEST['pref_len'])) {
        $mask = intval($_REQUEST['pref_len']);
    }
    $nets = array();
    foreach (filterCellList(listCells('ipv4net'), $cellfilter['expression']) as $net) {
        if (!isset($mask)) {
            $nets[] = $net;
        } elseif ($net['mask'] <= $mask) {
            $is_aggregate = FALSE;
            foreach ($net['atags'] as $atag) {
                if ($atag['tag'] == '$aggregate') {
                    $is_aggregate = TRUE;
                } elseif (preg_match('/^\\$spare_(\\d+)$/', $atag['tag'], $m) && $mask >= $m[1]) {
                    $nets[] = $net;
                    continue 2;
                }
            }
            if (!$is_aggregate) {
                $nets[] = $net;
            }
        }
    }
    $filter = getOutputOf('renderCellFilterPortlet', $cellfilter, 'ipv4net', $nets);
    echo '<table width="100%"><tr valign=top>';
    echo '<td>';
    startPortlet("Results (" . count($nets) . ")");
    echo '<ul class="spare-nets">';
    foreach ($nets as $net) {
        echo '<li>';
        renderNetCellForAlloc($net, $mask);
        echo '</li>';
    }
    echo '</ul>';
    finishPortlet();
    echo '</td>';
    echo '<td width="33%">';
    echo preg_replace_callback('/(<form[^<>]*>)/', 'generatePrefixLengthInput', $filter);
    echo '</td>';
    echo '</tr></table>';
    addCSS(<<<END
ul.spare-nets {
\tlist-style: none;
\tpadding: 0px;
}
ul.spare-nets li {
\tmargin: 5px 0px;
}

END
, TRUE);
}
示例#13
0
function getLocationSelectAJAX()
{
    $locationlist = listCells('location');
    $locationtree = treeFromList($locationlist);
    // adds ['trace'] keys into $locationlist items
    $options = array();
    $selected_id = '';
    if (!isset($_REQUEST['locationid'])) {
        $options['error'] = "Sorry, param 'locationid' is empty. Reload page and try again";
    } elseif (!preg_match("/locationid_(\\d+)/i", $_REQUEST['locationid'], $m)) {
        $options['error'] = "Sorry, wrong format locationid:'" . $_REQUEST['locationid'] . "'. Reload page and try again";
    } else {
        $current_location_id = $m[1];
        $selected_id = $locationlist[$current_location_id]['parent_id'];
        echo $selected_id;
        echo "<option value=0>-- NONE --</option>";
    }
    foreach ($locationtree as $location) {
        if ($location['id'] == $current_location_id) {
            continue;
        }
        echo "<option value={$location['id']} ";
        if ($location['id'] == $selected_id) {
            echo 'selected ';
        }
        echo "style='font-weight: bold'>{$location['name']}</option>";
        if ($location['kidc'] > 0) {
            printLocationChildrenSelectOptions($location, 0, $selected_id, $current_location_id);
        }
    }
}
示例#14
0
 function __construct($object_id = NULL, $port_id = NULL, $allports = false, $hl = NULL, $remote_id = NULL)
 {
     $this->allports = $allports;
     $this->object_id = $object_id;
     $this->port_id = $port_id;
     $this->remote_id = $remote_id;
     $this->hl = $hl;
     $hllabel = "";
     /* suppress strict standards warnings for Image_GraphViz and PHP 5.4.0
      * output would corrupt image data
      */
     $this->errorlevel = error_reporting();
     error_reporting($this->errorlevel & ~E_STRICT);
     $graphattr = array('rankdir' => 'LR', 'nodesep' => '0');
     unset($_GET['module']);
     $_GET['all'] = 1;
     $graphattr['URL'] = $this->_makeHrefProcess($_GET);
     unset($_GET['all']);
     switch ($hl) {
         case 'o':
         case 'p':
             $this->alpha = '30';
             break;
     }
     //$this->gv = new Image_GraphViz(true, $graphattr, "map".$object_id);
     $this->gv = new lm_Image_GraphViz(true, $graphattr, "map" . $object_id);
     /* --------------------------- */
     if ($object_id === NULL) {
         /* all objects ! */
         unset($_GET['all']);
         $_GET['hl'] = 'o';
         $this->gv->addAttributes(array('label' => 'Showing all objects' . $hllabel, 'labelloc' => 't'));
         $objects = listCells('object');
         foreach ($objects as $obj) {
             //$this->addlinkchainsobject($obj['id']); // longer runtimes !!
             $this->_add($this->gv, $obj['id'], NULL);
         }
         // for all still faster and nicer looking graph
         return;
     } else {
         $object = spotEntity('object', $object_id);
         $this->gv->addAttributes(array('label' => "Graph for {$object['dname']}{$hllabel}", 'labelloc' => 't'));
         $this->addlinkchainsobject($object_id);
         //$this->_add($this->gv, $object_id, $port_id);
         $children = getEntityRelatives('children', 'object', $object_id);
         //'entity_id'
         foreach ($children as $child) {
             $this->addlinkchainsobject($child['entity_id']);
         }
         //	$this->_add($this->gv, $child['entity_id'], NULL);
     }
     /* add hl label */
     $this->gv->addAttributes(array('label' => $this->gv->graph['attributes']['label'] . $hllabel));
     //	portlist::var_dump_html($this->gv);
     //		portlist::var_dump_html($this->data);
     //		echo json_encode($this->data);
     //	$this->gv->saveParsedGraph('/tmp/graph.txt');
     //	error_reporting( E_ALL ^ E_NOTICE);
 }
示例#15
0
function getVSTOptions()
{
    $ret = array();
    foreach (listCells('vst') as $vst) {
        $ret[$vst['id']] = niftyString($vst['description'], 30, FALSE);
    }
    return $ret;
}
示例#16
0
文件: ophandlers.php 项目: xtha/salt
function rollTags()
{
    assertStringArg('sum', TRUE);
    assertUIntArg('realsum');
    if ($_REQUEST['sum'] != $_REQUEST['realsum']) {
        showFuncMessage(__FUNCTION__, 'ERR');
        return;
    }
    // Even if the user requested an empty tag list, don't bail out, but process existing
    // tag chains with "zero" extra. This will make sure, that the stuff processed will
    // have its chains refined to "normal" form.
    $extratags = isset($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
    $n_ok = 0;
    // Minimizing the extra chain early, so that tag rebuilder doesn't have to
    // filter out the same tag again and again. It will have own noise to cancel.
    $extrachain = getExplicitTagsOnly(buildTagChainFromIds($extratags));
    foreach (listCells('rack', getBypassValue()) as $rack) {
        if (rebuildTagChainForEntity('rack', $rack['id'], $extrachain)) {
            $n_ok++;
        }
        amplifyCell($rack);
        foreach ($rack['mountedObjects'] as $object_id) {
            if (rebuildTagChainForEntity('object', $object_id, $extrachain)) {
                $n_ok++;
            }
        }
    }
    showFuncMessage(__FUNCTION__, 'OK', array($n_ok));
}
示例#17
0
function getLocationSelectAJAX()
{
    $locationlist = listCells('location');
    $locationtree = treeFromList($locationlist);
    // adds ['trace'] keys into $locationlist items
    $options = array();
    $selected_id = '';
    if (!isset($_REQUEST['locationid'])) {
        $options['error'] = "Sorry, param 'locationid' is empty. Reload page and try again";
    } elseif (!preg_match("/locationid_(\\d+)/i", $_REQUEST['locationid'], $m)) {
        $options['error'] = "Sorry, wrong format locationid:'" . $_REQUEST['locationid'] . "'. Reload page and try again";
    } else {
        $current_location_id = $m[1];
        $selected_id = $locationlist[$current_location_id]['parent_id'];
        echo $selected_id;
        $options[0] = '-- NONE --';
        foreach ($locationlist as $location_id => $locationinfo) {
            if (!in_array($current_location_id, $locationinfo['trace']) && $current_location_id != $location_id) {
                $options[$location_id] = $locationinfo['name'];
            }
        }
    }
    foreach ($options as $location_id => $value) {
        echo "<option value='{$location_id}'" . ($location_id == $selected_id ? ' selected' : '') . '>' . htmlspecialchars($value) . '</option>';
    }
}
示例#18
0
function renderVSTRulesEditor($vst_id)
{
    $vst = spotEntity('vst', $vst_id);
    amplifyCell($vst);
    if ($vst['rulec']) {
        $source_options = array();
    } else {
        $source_options = array();
        foreach (listCells('vst') as $vst_id => $vst_info) {
            if ($vst_info['rulec']) {
                $source_options[$vst_id] = niftyString('(' . $vst_info['rulec'] . ') ' . $vst_info['description']);
            }
        }
    }
    addJS('js/vst_editor.js');
    echo '<center><h1>' . niftyString($vst['description']) . '</h1></center>';
    if (count($source_options)) {
        startPortlet('clone another template');
        printOpFormIntro('clone');
        echo '<input type=hidden name="mutex_rev" value="' . $vst['mutex_rev'] . '">';
        echo '<table cellspacing=0 cellpadding=5 align=center class=widetable>';
        echo '<tr><td>' . getSelect($source_options, array('name' => 'from_id')) . '</td>';
        echo '<td>' . getImageHREF('COPY', 'copy from selected', TRUE) . '</td></tr></table></form>';
        finishPortlet();
        startPortlet('add rules one by one');
    }
    printOpFormIntro('upd');
    echo '<table cellspacing=0 cellpadding=5 align=center class="widetable template-rules">';
    echo '<tr><th></th><th>sequence</th><th>regexp</th><th>role</th>';
    echo '<th>VLAN IDs</th><th>comment</th><th><a href="#" class="vst-add-rule initial">' . getImageHREF('add', 'Add rule') . '</a></th></tr>';
    global $port_role_options;
    $row_html = '<td><a href="#" class="vst-del-rule">' . getImageHREF('destroy', 'delete rule') . '</a></td>';
    $row_html .= '<td><input type=text name=rule_no value="%s" size=3></td>';
    $row_html .= '<td><input type=text name=port_pcre value="%s"></td>';
    $row_html .= '<td>%s</td>';
    $row_html .= '<td><input type=text name=wrt_vlans value="%s"></td>';
    $row_html .= '<td><input type=text name=description value="%s"></td>';
    $row_html .= '<td><a href="#" class="vst-add-rule">' . getImageHREF('add', 'Duplicate rule') . '</a></td>';
    addJS("var new_vst_row = '" . addslashes(sprintf($row_html, '', '', getSelect($port_role_options, array('name' => 'port_role'), 'anymode'), '', '')) . "';", TRUE);
    @session_start();
    foreach (isset($_SESSION['vst_edited']) ? $_SESSION['vst_edited'] : $vst['rules'] as $item) {
        printf('<tr>' . $row_html . '</tr>', $item['rule_no'], htmlspecialchars($item['port_pcre'], ENT_QUOTES), getSelect($port_role_options, array('name' => 'port_role'), $item['port_role']), $item['wrt_vlans'], $item['description']);
    }
    echo '</table>';
    echo '<input type=hidden name="template_json">';
    echo '<input type=hidden name="mutex_rev" value="' . $vst['mutex_rev'] . '">';
    echo '<center>' . getImageHref('SAVE', 'Save template', TRUE) . '</center>';
    echo '</form>';
    if (isset($_SESSION['vst_edited'])) {
        // draw current template
        renderVSTRules($vst['rules'], 'currently saved tamplate');
        unset($_SESSION['vst_edited']);
    }
    session_commit();
    if (count($source_options)) {
        finishPortlet();
    }
}