function renderObject8021QSyncPreview($object, $vswitch, $plan, $C, $R, $maxdecisions) { if (isset($_REQUEST['hl_port_id'])) { assertUIntArg('hl_port_id'); $hl_port_id = intval($_REQUEST['hl_port_id']); $hl_port_name = NULL; addAutoScrollScript("port-{$hl_port_id}"); foreach ($object['ports'] as $port) { if (mb_strlen($port['name']) && $port['id'] == $hl_port_id) { $hl_port_name = $port['name']; break; } } unset($object); } switchportInfoJS($vswitch['object_id']); // load JS code to make portnames interactive // initialize one of three popups: we've got data already $port_config = addslashes(json_encode(formatPortConfigHints($vswitch['object_id'], $R))); addJS(<<<END \$(document).ready(function(){ \tvar confData = \$.parseJSON('{$port_config}'); \tapplyConfData(confData); \tvar menuItem = \$('.context-menu-item.itemname-conf'); \tmenuItem.addClass(\$.contextMenu.disabledItemClassName); \tsetItemIcon(menuItem[0], 'ok'); }); END , TRUE); echo '<table cellspacing=0 cellpadding=5 align=center class=widetable width="100%">'; if ($maxdecisions) { echo '<tr><th colspan=2> </th><th colspan=3>discard</th><th> </th></tr>'; } echo '<tr valign=top><th>port</th><th width="40%">last saved version</th>'; if ($maxdecisions) { addJS('js/racktables.js'); printOpFormIntro('resolve8021QConflicts', array('mutex_rev' => $vswitch['mutex_rev'])); foreach (array('left', 'asis', 'right') as $pos) { echo "<th class=tdcenter><input type=radio name=column_radio value={$pos} " . "onclick=\"checkColumnOfRadios('i_', {$maxdecisions}, '_{$pos}')\"></th>"; } } echo '<th width="40%">running version</th></tr>'; $rownum = 0; $plan = sortPortList($plan); $domvlans = array_keys(getDomainVLANList($vswitch['domain_id'])); $default_port = array('mode' => 'access', 'allowed' => array(VLAN_DFL_ID), 'native' => VLAN_DFL_ID); foreach ($plan as $port_name => $item) { $trclass = $left_extra = $right_extra = $left_text = $right_text = ''; $radio_attrs = array(); switch ($item['status']) { case 'ok_to_delete': $left_text = serializeVLANPack($item['left']); $right_text = 'none'; $left_extra = ' trnull'; $right_extra = ' trok'; // no confirmation is necessary break; case 'delete_conflict': $trclass = 'trbusy'; $left_extra = ' trerror'; // can be fixed on request $right_extra = ' trnull'; $left_text = formatVLANPackDiff($item['lastseen'], $item['left']); $right_text = ' '; $radio_attrs = array('left' => '', 'asis' => ' checked', 'right' => ' disabled'); // dummy setting to suppress warnings in resolve8021QConflicts() $item['right'] = $default_port; break; case 'add_conflict': $trclass = 'trbusy'; $right_extra = ' trerror'; $left_text = ' '; $right_text = serializeVLANPack($item['right']); break; case 'ok_to_add': $trclass = 'trbusy'; $right_extra = ' trok'; $left_text = ' '; $right_text = serializeVLANPack($item['right']); break; case 'ok_to_merge': $trclass = 'trbusy'; $left_extra = ' trok'; $right_extra = ' trok'; // fall through // fall through case 'in_sync': $trclass = 'trbusy'; $left_text = $right_text = serializeVLANPack($item['both']); break; case 'ok_to_pull': // at least one of the sides is not in the default state $trclass = 'trbusy'; $right_extra = ' trok'; $left_text = serializeVLANPack($item['left']); $right_text = serializeVLANPack($item['right']); break; case 'ok_to_push': $trclass = ' trbusy'; $left_extra = ' trok'; $left_text = formatVLANPackDiff($C[$port_name], $item['left']); $right_text = serializeVLANPack($item['right']); break; case 'merge_conflict': $trclass = 'trbusy'; $left_extra = ' trerror'; $right_extra = ' trerror'; $left_text = formatVLANPackDiff($C[$port_name], $item['left']); $right_text = serializeVLANPack($item['right']); // enable, but consider each option independently // Don't accept running VLANs not in domain, and // don't offer anything, that VST will deny. // Consider domain and template constraints. $radio_attrs = array('left' => '', 'asis' => ' checked', 'right' => ''); if (!acceptable8021QConfig($item['right']) or count(array_diff($item['right']['allowed'], $domvlans)) or !goodModeForVSTRole($item['right']['mode'], $item['vst_role'])) { $radio_attrs['left'] = ' disabled'; } break; case 'ok_to_push_with_merge': $trclass = 'trbusy'; $left_extra = ' trok'; $right_extra = ' trwarning'; $left_text = formatVLANPackDiff($C[$port_name], $item['left']); $right_text = serializeVLANPack($item['right']); break; case 'none': $left_text = ' '; $right_text = ' '; break; case 'martian_conflict': if ($item['right']['mode'] == 'none') { $right_text = ' '; } else { $right_text = serializeVLANPack($item['right']); $right_extra = ' trerror'; } if ($item['left']['mode'] == 'none') { $left_text = ' '; } else { $left_text = serializeVLANPack($item['left']); $left_extra = ' trerror'; $radio_attrs = array('left' => '', 'asis' => ' checked', 'right' => ' disabled'); // idem, see above $item['right'] = $default_port; } break; default: $trclass = 'trerror'; $left_text = $right_text = 'internal rendering error'; break; } $anchor = ''; $td_class = ''; if (isset($hl_port_name) and $hl_port_name == $port_name) { $anchor = "name='port-{$hl_port_id}'"; $td_class = ' border_highlight'; } echo "<tr class='{$trclass}'><td class='tdleft{$td_class}' NOWRAP><a class='interactive-portname port-menu nolink' {$anchor}>{$port_name}</a></td>"; if (!count($radio_attrs)) { echo "<td class='tdleft{$left_extra}'>{$left_text}</td>"; if ($maxdecisions) { echo '<td> </td><td> </td><td> </td>'; } echo "<td class='tdleft{$right_extra}'>{$right_text}</td>"; } else { echo "<td class='tdleft{$left_extra}'><label for=i_{$rownum}_left>{$left_text}</label></td>"; foreach ($radio_attrs as $pos => $attrs) { echo "<td><input id=i_{$rownum}_{$pos} name=i_{$rownum} type=radio value={$pos}{$attrs}></td>"; } echo "<td class='tdleft{$right_extra}'><label for=i_{$rownum}_right>{$right_text}</label></td>"; } echo '</tr>'; if (count($radio_attrs)) { echo "<input type=hidden name=rm_{$rownum} value=" . $item['right']['mode'] . '>'; echo "<input type=hidden name=rn_{$rownum} value=" . $item['right']['native'] . '>'; foreach ($item['right']['allowed'] as $a) { echo "<input type=hidden name=ra_{$rownum}[] value={$a}>"; } echo "<input type=hidden name=pn_{$rownum} value='" . htmlspecialchars($port_name) . "'>"; } $rownum += count($radio_attrs) ? 1 : 0; } if ($rownum) { echo "<input type=hidden name=nrows value={$rownum}>"; echo '<tr><td colspan=2> </td><td colspan=3 align=center class=tdcenter>'; printImageHREF('UNLOCK', 'resolve conflicts', TRUE); echo '</td><td> </td></tr>'; } echo '</table>'; echo '</form>'; }
function render8021QReport() { if (!count($domains = getVLANDomainOptions())) { echo '<center><h3>(no VLAN configuration exists)</h3></center>'; return; } $vlanstats = array(); for ($i = VLAN_MIN_ID; $i <= VLAN_MAX_ID; $i++) { $vlanstats[$i] = array(); } $header = '<tr><th> </th>'; foreach ($domains as $domain_id => $domain_name) { foreach (getDomainVLANList($domain_id) as $vlan_id => $vlan_info) { $vlanstats[$vlan_id][$domain_id] = $vlan_info; } $header .= '<th>' . mkA($domain_name, 'vlandomain', $domain_id) . '</th>'; } $header .= '</tr>'; $output = $available = array(); for ($i = VLAN_MIN_ID; $i <= VLAN_MAX_ID; $i++) { if (!count($vlanstats[$i])) { $available[] = $i; } else { $output[$i] = FALSE; } } foreach (listToRanges($available) as $span) { if ($span['to'] - $span['from'] < 4) { for ($i = $span['from']; $i <= $span['to']; $i++) { $output[$i] = FALSE; } } else { $output[$span['from']] = TRUE; $output[$span['to']] = FALSE; } } ksort($output, SORT_NUMERIC); $header_delay = 0; startPortlet('VLAN existence per domain'); echo '<table border=1 cellspacing=0 cellpadding=5 align=center class=rackspace>'; foreach ($output as $vlan_id => $tbc) { if (--$header_delay <= 0) { echo $header; $header_delay = 25; } echo '<tr class="state_' . (count($vlanstats[$vlan_id]) ? 'T' : 'F'); echo '"><th class=tdright>' . $vlan_id . '</th>'; foreach (array_keys($domains) as $domain_id) { echo '<td class=tdcenter>'; if (array_key_exists($domain_id, $vlanstats[$vlan_id])) { echo mkA('∃', 'vlan', "{$domain_id}-{$vlan_id}"); } else { echo ' '; } echo '</td>'; } echo '</tr>'; if ($tbc) { echo '<tr class="state_A"><th>...</th><td colspan=' . count($domains) . '> </td></tr>'; } } echo '</table>'; finishPortlet(); }