Commit 332c8b81 authored by Leigh Stoller's avatar Leigh Stoller

Work on wires table schema change, but lots of other stuff:

1. Beef up MakeFake in Interface/Wires and use that from Port library
   instead of existing fake stuff.

2. Add a Create routine for wires, remove all the direct insertions
   scattered around the code.

3. Add some Lookup routines, so we can remove a bunch of direct queries
   to the DB scattered around the code.

4. Add a trivial wrapper Interface::Type, and give it one useful
   function for now, to map generic speed to interface object.
parent 7983c9cc
......@@ -172,6 +172,8 @@ sub role($) { return field($_[0], 'role'); }
sub type($) { return field($_[0], 'interface_type'); }
sub logical($) { return field($_[0], 'logical'); }
sub speed($) { return field($_[0], 'current_speed'); }
sub trunk_mode($) { return field($_[0], 'trunk_mode'); }
sub trunk($) { return field($_[0], 'trunk'); }
sub current_speed($) { return field($_[0], 'current_speed'); }
sub mask($) { return field($_[0], 'mask'); }
sub uuid($) { return field($_[0], 'uuid'); }
......@@ -598,16 +600,35 @@ sub DeleteWire($)
#
# Create a fake object, as for the mapper (assign_wrapper) during debugging.
# Port library uses this too.
#
sub MakeFake($$$)
{
my ($class, $node, $argref) = @_;
my $nodeid = $node->node_id();
my $query_result =
DBQueryWarn("show columns from interfaces");
return undef
if (!$query_result);
while (my ($slot) = $query_result->fetchrow_array()) {
if (!exists($argref->{$slot})) {
$argref->{$slot} = "";
}
}
my $nodeid = ref($node) ? $node->node_id() : $node;
$argref->{'node_id'} = $nodeid;
my $self = {};
$self->{"DBROW"} = $argref;
$self->{"STATE"} = {
"node_id" => $nodeid,
"card" => $argref->{'card'},
"port" => $argref->{'port'},
"iface" => $argref->{'iface'},
"tagged" => 0,
"enabled" => 1,
};
bless($self, $class);
# Cache by card,port and by iface
......@@ -1224,10 +1245,72 @@ sub logical($) { return $_[0]->field('logical'); }
sub trunkid($) { return $_[0]->field('trunkid'); }
sub IsActive($) { return ($_[0]->type() eq "Unused" ? 0 : 1); }
#
# Create a wire by Interfaces.
#
sub Create($$$$$)
{
my ($self, $interface1, $interface2, $type, $argref) = @_;
my $node_id1 = $interface1->node_id();
my $card1 = $interface1->card();
my $port1 = $interface1->port();
my $iface1 = $interface1->iface();
my $node_id2 = $interface2->node_id();
my $card2 = $interface2->card();
my $port2 = $interface2->port();
my $iface2 = $interface2->iface();
my $command = "insert into wires set".
" type='$type', " .
" node_id1='$node_id1',card1=$card1,port1=$port1, " .
" iface1='$iface1', ".
" node_id2='$node_id2',card2=$card2,port2=$port2, ".
" iface2='$iface2'";
$command .= ",cable=" . DBQuoteSpecial($argref->{'cable'})
if (exists($argref->{'cable'}));
$command .= ",len=" . DBQuoteSpecial($argref->{'cablelen'})
if (exists($argref->{'cablelen'}));
$command .= ",external_wire=" . DBQuoteSpecial($argref->{'external_wire'})
if (exists($argref->{'external_wire'}));
$command .= ",external_interface=" .
DBQuoteSpecial($argref->{'external_interface'})
if (exists($argref->{'external_interface'}));
DBQueryWarn($command) or
return undef;
return Interface::Wire->Lookup($interface1);
}
#
# Create a fake object. Port library uses this too.
#
sub MakeFake($$)
{
my ($class, $argref) = @_;
my $query_result =
DBQueryWarn("show columns from wires");
return undef
if (!$query_result);
while (my ($slot) = $query_result->fetchrow_array()) {
if (!exists($argref->{$slot})) {
$argref->{$slot} = "";
}
}
my $self = {};
$self->{"DBROW"} = $argref;
bless($self, $class);
return $self;
}
#
# Find me a wire from either side using nodeid,card,port.
#
sub LookupAny($$$$)
sub LookupAny($$$;$)
{
my ($class, $nodeid, $card, $port) = @_;
......@@ -1246,36 +1329,65 @@ sub LookupAny($$$$)
bless($wire, $class);
return $wire;
}
sub LookupAnyByIface($$$)
{
my ($class, $nodeid, $iface) = @_;
my $query_result =
DBQueryWarn("select * from wires ".
"where (node_id1='$nodeid' and iface1='$iface') or ".
" (node_id2='$nodeid' and iface2='$iface')");
return undef
if (!$query_result || !$query_result->numrows);
my $wire = {};
$wire->{"DBROW"} = $query_result->fetchrow_hashref();
bless($wire, $class);
return $wire;
}
sub LookupAnyByIfaces($$$$$)
{
my ($class, $nodeid1, $iface1, $nodeid2, $iface2) = @_;
my $query_result =
DBQueryWarn("select * from wires ".
"where ((node_id1='$nodeid1' and iface1='$iface1') and ".
" (node_id2='$nodeid2' and iface2='$iface2')) or ".
" ((node_id2='$nodeid1' and iface2='$iface1') and ".
" (node_id1='$nodeid2' and iface1='$iface2'))");
return undef
if (!$query_result || !$query_result->numrows);
my $wire = {};
$wire->{"DBROW"} = $query_result->fetchrow_hashref();
bless($wire, $class);
return $wire;
}
#
# Delete a logical wire and its interfaces. For safety, refuse to delete
# a real wire via this interface.
# Delete a wire. For safety refuse to delete a real wire unless flag given.
#
sub Delete($)
sub Delete($;$)
{
my ($self) = @_;
my ($interface1, $interface2) = $self->Interfaces();
my ($self, $real) = @_;
my $logical = ($real ? 0 : 1);
if (! $self->logical()) {
if ($logical && !$self->logical()) {
print STDERR "Refusing to delete real $self\n";
return -1;
}
if (defined($interface1) && $interface1->logical()) {
$interface1->Delete() == 0
or return -1;
}
if (defined($interface2) && $interface2->logical()) {
$interface2->Delete() == 0
or return -1;
}
my $node_id1 = $self->node_id1();
my $card1 = $self->card1();
my $port1 = $self->port1();
my $iface1 = $self->iface1();
my $node_id2 = $self->node_id2();
my $iface2 = $self->iface2();
return -1
if (!DBQueryWarn("delete from wires ".
"where logical=1 and node_id1='$node_id1' and ".
" card1=$card1 and port1=$port1"));
"where node_id1='$node_id1' and iface1='$iface1' and ".
" node_id2='$node_id2' and iface2='$iface2'"));
return 0;
}
......@@ -1449,7 +1561,17 @@ sub DeleteLogicalWires($$)
print STDERR "$wire is still active; cannot delete!\n";
$errors++;
}
if ($wire->Delete()) {
my ($interface1, $interface2) = $wire->Interfaces();
if (defined($interface1) && $interface1->logical()) {
$interface1->Delete() == 0
or return -1;
}
if (defined($interface2) && $interface2->logical()) {
$interface2->Delete() == 0
or return -1;
}
if ($wire->Delete(0)) {
print STDERR "$wire could not be deleted!\n";
$errors++;
}
......@@ -1655,6 +1777,114 @@ sub Stringify($)
return "[LogicalWire: $nodeA:$ifaceA/$nodeB:$ifaceB]";
}
##############################################################################
#
# A trivial wrapper class for interface_types.
#
package Interface::Type;
use libdb;
use Node;
use libtestbed;
use English;
use overload ('""' => 'Stringify');
#
# Lookup by interface type name.
#
sub Lookup($$)
{
my ($class, $type) = @_;
if ($type !~ /^[-\w]+$/) {
return undef;
}
my $query_result =
DBQueryWarn("select * from interface_types where type='$type'");
return undef
if (!$query_result || !$query_result->numrows);
my $blob = {};
$blob->{"DBROW"} = $query_result->fetchrow_hashref();
$blob->{"CAPS"} = {};
# Load capabilities.
$query_result =
DBQueryWarn("select * from interface_capabilities where type='$type'");
return undef
if (!$query_result);
while (my $row = $query_result->fetchrow_hashref()) {
my $key = $row->{'capkey'};
my $val = $row->{'capval'};
$blob->{"CAPS"}->{$key} = $val;
}
bless($blob, $class);
return $blob;
}
sub field($$) { return $_[0]->{'DBROW'}->{$_[1]}; }
sub type($) { return $_[0]->field('type'); }
sub max_speed($) { return $_[0]->field('max_speed'); }
sub manufacturer($) { return $_[0]->field('manufacturer'); }
sub model($) { return $_[0]->field('model'); }
sub ports($) { return $_[0]->field('ports'); }
sub connector($) { return $_[0]->field('connector'); }
sub capability($$)
{
my ($self, $capkey) = @_;
return undef
if (!exists($self->{'CAPS'}->{$capkey}));
return $self->{'CAPS'}->{$capkey};
}
#
# Stringify for output.
#
sub Stringify($)
{
my ($self) = @_;
my $type = $self->type();
my $speed = $self->max_speed();
return "[InterfaceType: $type:$speed]";
}
#
# Find me the generic type given a speed.
#
sub GenericType($$)
{
my ($class, $speed) = @_;
my $itype;
if ($speed eq "100Mb" || "$speed" eq "100000") {
$itype = "generic";
}
elsif ($speed eq "1Gb" || "$speed" eq "1000000") {
$itype = "generic_1G";
}
elsif ($speed eq "10Gb" || "$speed" eq "10000000") {
$itype = "generic_10G";
}
elsif ($speed eq "25Gb" || "$speed" eq "25000000") {
$itype = "generic_25G";
}
elsif ($speed eq "40Gb" || "$speed" eq "40000000") {
$itype = "generic_40G";
}
elsif ($speed eq "56Gb" || "$speed" eq "56000000") {
$itype = "generic_56G";
}
elsif ($speed eq "100Gb" || "$speed" eq "100000000") {
$itype = "generic_100G";
}
else {
return undef;
}
return Interface::Type->Lookup($itype);
}
# _Always_ make sure that this 1 is at the end of the file...
1;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment