From 1e9600430278fac2c3e93ce0c7b7f3bfa315f6fe Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Thu, 9 Feb 2012 18:50:13 +0000 Subject: [PATCH] add DevicePort POD --- .gitignore | 1 + Netdisco/lib/Netdisco/DB/Result/DevicePort.pm | 224 +++++++++++++++--- 2 files changed, 189 insertions(+), 36 deletions(-) diff --git a/.gitignore b/.gitignore index ab21a5e9..8a840010 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ Netdisco/environments/development.yml Netdisco/logs/development.log +*.swp test.pl diff --git a/Netdisco/lib/Netdisco/DB/Result/DevicePort.pm b/Netdisco/lib/Netdisco/DB/Result/DevicePort.pm index 8dd58b13..86e395d4 100644 --- a/Netdisco/lib/Netdisco/DB/Result/DevicePort.pm +++ b/Netdisco/lib/Netdisco/DB/Result/DevicePort.pm @@ -64,6 +64,33 @@ __PACKAGE__->set_primary_key("port", "ip"); # Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02 # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:lcbweb0loNwHoWUuxTN/hA +=head1 RELATIONSHIPS + +=head2 nodes + +Returns the set of Nodes whose MAC addresses are associated with this Device +Port. + +=over 4 + +=item * + +Rows returned are sorted by the Node MAC address. + +=item * + +The Node's related IP addresses (that is, entries from the C table) +will also be retrieved. + +=item * + +The additional column C is a preformatted value for the +C field, which reads as "X days/weeks/months/years" ago. + +=back + +=cut + __PACKAGE__->has_many( nodes => 'Netdisco::DB::Result::Node', { 'foreign.switch' => 'self.ip', @@ -73,11 +100,10 @@ __PACKAGE__->has_many( nodes => 'Netdisco::DB::Result::Node', prefetch => 'ips', order_by => 'me.mac', '+select' => [ - \"replace(age(date_trunc('minute', me.time_last + interval '30 second'))::text, 'mon', 'month')", - ], - '+as' => [ - 'me.time_last', + \"replace(age(date_trunc('minute', + me.time_last + interval '30 second'))::text, 'mon', 'month')", ], + '+as' => [ 'me.time_last_age' ], }, ); @@ -89,27 +115,72 @@ sub get_nodes { }); } +=head2 neighbor_alias + +When a device port has an attached neighbor device, this relationship will +return the IP address of the neighbor. See the C helper method if +what you really want is to retrieve the Device entry for that neighbor. + +The JOIN is of type "LEFT" in case the neighbor device is known but has not +been fully discovered by Netdisco and so does not exist itself in the +database. + +=cut + __PACKAGE__->belongs_to( neighbor_alias => 'Netdisco::DB::Result::DeviceIp', { 'foreign.alias' => 'self.remote_ip', }, - { - join_type => 'left', - }, + { join_type => 'LEFT' }, ); -# FIXME make this more efficient by specifying the full join to DBIC -sub neighbor { return eval { (shift)->neighbor_alias->device } } + +=head2 device + +Returns the Device table entry to which the given Port is related. + +=over 4 + +=item * + +Additional columns C, C, +C provide preformatted timestamps of the C, +C and C fields. + +=item * + +The additional column C provides a performatted value for the +device uptime which reads as "X days/weeks/months/years" ago. + +=back + +=cut + __PACKAGE__->belongs_to( device => 'Netdisco::DB::Result::Device', 'ip', { '+select' => [ - \"replace(age(timestamp 'epoch' + uptime / 100 * interval '1 second', timestamp '1970-01-01 00:00:00-00')::text, 'mon', 'month')", + \"replace(age(timestamp 'epoch' + uptime / 100 * interval '1 second', + timestamp '1970-01-01 00:00:00-00')::text, 'mon', 'month')", \"to_char(last_discover, 'YYYY-MM-DD HH24:MI')", \"to_char(last_macsuck, 'YYYY-MM-DD HH24:MI')", \"to_char(last_arpnip, 'YYYY-MM-DD HH24:MI')", ], - '+as' => [qw/ uptime last_discover last_macsuck last_arpnip /], + '+as' => [qw/ + uptime_age + last_discover_stamp + last_macsuck_stamp + last_arpnip_stamp + /], }, ); + +=head2 port_vlans_tagged + +Returns a set of rows from the C table relating to this +port, where the VLANs are all tagged. See also the C +relationship. + +=cut + __PACKAGE__->has_many( port_vlans_tagged => 'Netdisco::DB::Result::DevicePortVlan', { 'foreign.ip' => 'self.ip', @@ -119,12 +190,29 @@ __PACKAGE__->has_many( port_vlans_tagged => 'Netdisco::DB::Result::DevicePortVla where => { -not_bool => 'me.native' }, } ); + +=head2 tagged_vlans + +As compared to C, this relationship returns a set of VLAN +row objects for the VLANs on the given port, which might be more useful if you +want to find out details such as the VLAN name. + +See also C. + +=cut + __PACKAGE__->many_to_many( tagged_vlans => 'port_vlans_tagged', 'vlan' ); -# weirdly I could not get row.tagged.vlans.count to work in TT -# so gave up and wrote this instead. -sub tagged_vlans_count { - return (shift)->tagged_vlans->count; -} + + +=head2 native_port_vlan + +Returns an entry from the C table relating to this port, +where the VLAN is not tagged. + +See also the C helper method. + +=cut + __PACKAGE__->might_have( native_port_vlan => 'Netdisco::DB::Result::DevicePortVlan', { 'foreign.ip' => 'self.ip', @@ -134,10 +222,15 @@ __PACKAGE__->might_have( native_port_vlan => 'Netdisco::DB::Result::DevicePortVl where => { -bool => 'me.native' }, } ); -sub native_vlan { - my $row = shift; - return eval { $row->native_port_vlan->vlan || undef }; -}; + +=head2 oui + +Returns the C table entry matching this Port. You can then join on this +relation and retrieve the Company name from the related table. + +The JOIN is of type LEFT, in case the OUI table has not been populated. + +=cut __PACKAGE__->belongs_to( oui => 'Netdisco::DB::Result::Oui', sub { @@ -146,28 +239,87 @@ __PACKAGE__->belongs_to( oui => 'Netdisco::DB::Result::Oui', "$args->{foreign_alias}.oui" => { '=' => \"substring(cast($args->{self_alias}.mac as varchar) for 8)" } }; - } + }, + { join_type => 'LEFT' } ); +=head1 ADDITIONAL METHODS + +=head2 + +Returns the Device entry for the neighbour Device on the given port. + +Might return an undefined value if there is no neighbor on the port, or if the +neighbor has not been fully discovered by Netdisco and so does not exist in +the database. + +=cut + +# FIXME make this more efficient by specifying the full join to DBIC +sub neighbor { return eval { (shift)->neighbor_alias->device } } + +=head2 native_vlan + +This is a convenience method to be used instead of the C +relationship described above. + +Whereas the C relation returns the entire row from the +C table, this helper returns the VLAN number itself from +that row - probably the thing you actually want in the end. + +=cut + +sub native_vlan { + my $row = shift; + return eval { $row->native_port_vlan->vlan || undef }; +}; + +=head2 tagged_vlans_count + +Returns the number of tagged VLANs active on this device port. + +=cut + +sub tagged_vlans_count { + return (shift)->tagged_vlans->count; +} + +=head2 is_free( $quantity, $unit ) + +This method can be used to evaluate whether a device port could be considered +unused, based on the last time it changed from the "up" state to a "down" +state. + +Pass in two parameters, first the C<$quantity> which must be an integer, and +second the C<$unit> which must be a string of either C, C, +C or C. + +A True value is returned if the port is in a "down" state but administratively +"up", yet last changed state at or further back than the parameters' time +window. If the port is not in the correct state, or last changed state more +recently, then a False value is returned. + +=cut + sub is_free { - my ($row, $num, $unit) = @_; - return unless $num =~ m/^\d+$/ - and $unit =~ m/(?:days|weeks|months|years)/; + my ($row, $num, $unit) = @_; + return unless $num =~ m/^\d+$/ + and $unit =~ m/(?:days|weeks|months|years)/; - return 0 unless - ($row->up_admin and $row->up_admin eq 'up') - and ($row->up and $row->up eq 'down'); + return 0 unless + ($row->up_admin and $row->up_admin eq 'up') + and ($row->up and $row->up eq 'down'); - my $quan = { - days => (60 * 60 * 24), - weeks => (60 * 60 * 24 * 7), - months => (60 * 60 * 24 * 31), - years => (60 * 60 * 24 * 365), - }; - my $total = $num * $quan->{$unit}; + my $quan = { + days => (60 * 60 * 24), + weeks => (60 * 60 * 24 * 7), + months => (60 * 60 * 24 * 31), + years => (60 * 60 * 24 * 365), + }; + my $total = $num * $quan->{$unit}; - my $diff_sec = $row->lastchange / 100; - return ($diff_sec >= $total ? 1 : 0); + my $diff_sec = $row->lastchange / 100; + return ($diff_sec >= $total ? 1 : 0); } 1;