Example #1
0
function resolve8021QConflicts()
{
    global $sic, $dbxlink;
    assertUIntArg('mutex_rev', TRUE);
    // counts from 0
    assertUIntArg('nrows');
    // Divide submitted radio buttons into 3 groups:
    // left (saved version wins)
    // asis (ignore)
    // right (running version wins)
    $F = array();
    for ($i = 0; $i < $sic['nrows']; $i++) {
        if (!array_key_exists("i_{$i}", $sic)) {
            continue;
        }
        // let's hope other inputs are in place
        switch ($sic["i_{$i}"]) {
            case 'left':
            case 'right':
                $F[$sic["pn_{$i}"]] = array('mode' => $sic["rm_{$i}"], 'allowed' => array_fetch($sic, "ra_{$i}", array()), 'native' => $sic["rn_{$i}"], 'decision' => $sic["i_{$i}"]);
                break;
            default:
                // don't care
        }
    }
    $dbxlink->beginTransaction();
    try {
        if (NULL === ($vswitch = getVLANSwitchInfo($sic['object_id'], 'FOR UPDATE'))) {
            throw new InvalidArgException('object_id', $sic['object_id'], 'VLAN domain is not set for this object');
        }
        if ($vswitch['mutex_rev'] != $sic['mutex_rev']) {
            throw new InvalidRequestArgException('mutex_rev', $sic['mutex_rev'], 'expired form (table data has changed)');
        }
        $D = getStored8021QConfig($vswitch['object_id'], 'desired');
        $C = getStored8021QConfig($vswitch['object_id'], 'cached');
        $R = getRunning8021QConfig($vswitch['object_id']);
        $plan = get8021QSyncOptions($vswitch, $D, $C, $R['portdata']);
        $ndone = 0;
        foreach ($F as $port_name => $port) {
            if (!array_key_exists($port_name, $plan)) {
                continue;
            } elseif ($plan[$port_name]['status'] == 'merge_conflict') {
                // for R neither mutex nor revisions can be emulated, but revision change can be
                if (!same8021QConfigs($port, $R['portdata'][$port_name])) {
                    throw new InvalidRequestArgException("port {$port_name}", '(hidden)', 'expired form (switch data has changed)');
                }
                if ($port['decision'] == 'right') {
                    // D wins, frame R by writing value of R to C
                    $ndone += upd8021QPort('cached', $vswitch['object_id'], $port_name, $port);
                } elseif ($port['decision'] == 'left') {
                    // R wins, cross D up
                    $ndone += upd8021QPort('cached', $vswitch['object_id'], $port_name, $D[$port_name]);
                }
                // otherwise there was no decision made
            } elseif ($plan[$port_name]['status'] == 'delete_conflict' or $plan[$port_name]['status'] == 'martian_conflict') {
                if ($port['decision'] == 'left') {
                    // confirm deletion of local copy
                    $ndone += del8021QPort($vswitch['object_id'], $port_name);
                }
            }
            // otherwise ignore a decision that doesn't address a conflict
        }
    } catch (InvalidRequestArgException $e) {
        $dbxlink->rollBack();
        showFuncMessage(__FUNCTION__, 'ERR1');
        return;
    } catch (Exception $e) {
        $dbxlink->rollBack();
        showFuncMessage(__FUNCTION__, 'ERR2');
        return;
    }
    $dbxlink->commit();
    showFuncMessage(__FUNCTION__, 'OK', array($ndone));
}
Example #2
0
function formatVLANPackDiff($old, $current)
{
    $ret = '';
    $new_pack = serializeVLANPack($current);
    $new_size = substr_count($new_pack, ',');
    if (!same8021QConfigs($old, $current)) {
        $old_pack = serializeVLANPack($old);
        $old_size = substr_count($old_pack, ',');
        $ret .= '<s>' . $old_pack . '</s><br>';
        // make diff
        $added = groupIntsToRanges(array_diff($current['allowed'], $old['allowed']));
        $removed = groupIntsToRanges(array_diff($old['allowed'], $current['allowed']));
        if ($old['mode'] == $current['mode'] && $current['mode'] == 'trunk') {
            if (!empty($added)) {
                $ret .= '<span class="vlan-diff diff-add">+ ' . implode(', ', $added) . '</span><br>';
            }
            if (!empty($removed)) {
                $ret .= '<span class="vlan-diff diff-rem">- ' . implode(', ', $removed) . '</span><br>';
            }
        }
    }
    $ret .= $new_pack;
    return $ret;
}
Example #3
0
function replace8021QPorts($instance = 'desired', $object_id, $before, $changes)
{
    $done = 0;
    foreach ($changes as $port_name => $port) {
        if (!array_key_exists($port_name, $before) or !same8021QConfigs($port, $before[$port_name])) {
            upd8021QPort($instance, $object_id, $port_name, $port);
            $done++;
        }
    }
    return $done;
}
Example #4
0
function queueChangesToSwitch($switch_id, $order, $before, $check_only = FALSE)
{
    global $script_mode;
    $ret = array();
    $nsaved = 0;
    foreach ($order as $portname => $portorder) {
        if (!same8021QConfigs($portorder, $before[$portname])) {
            if ($script_mode) {
                $object = spotEntity('object', $switch_id);
                print $object['name'] . " {$portname}: " . serializeVLANPack($before[$portname]) . ' -> ' . serializeVLANPack($portorder) . "\n";
            }
            if (!$check_only) {
                upd8021QPort('desired', $switch_id, $portname, $portorder);
                $nsaved++;
            }
        }
    }
    if (!$check_only && $nsaved) {
        touchVLANSwitch($switch_id);
    }
    return $nsaved;
}