make an App::Netdisco dist using Module::Install
This commit is contained in:
44
Netdisco/lib/App/Netdisco.pm
Normal file
44
Netdisco/lib/App/Netdisco.pm
Normal file
@@ -0,0 +1,44 @@
|
||||
package App::Netdisco;
|
||||
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
use 5.10.0;
|
||||
|
||||
use File::ShareDir 'module_dir';
|
||||
use Path::Class;
|
||||
|
||||
our $VERSION = '2.00_009';
|
||||
|
||||
BEGIN {
|
||||
if (not length $ENV{DANCER_APPDIR}
|
||||
or not -f file($ENV{DANCER_APPDIR}, 'config.yml')) {
|
||||
|
||||
my $auto = dir(File::ShareDir::module_dir('App::Netdisco'))->absolute;
|
||||
|
||||
$ENV{DANCER_APPDIR} ||= $auto->stringify;
|
||||
$ENV{DANCER_CONFDIR} ||= $auto->stringify;
|
||||
|
||||
$ENV{DANCER_ENVDIR} ||= $auto->subdir('environments')->stringify;
|
||||
$ENV{DANCER_PUBLIC} ||= $auto->subdir('public')->stringify;
|
||||
$ENV{DANCER_VIEWS} ||= $auto->subdir('views')->stringify;
|
||||
}
|
||||
}
|
||||
|
||||
=head1 App::Netdisco
|
||||
|
||||
Netdisco is an Open Source web-based network management tool.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Oliver Gorwits <oliver@cpan.org>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2012 by The Netdisco Developer Team.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
31
Netdisco/lib/App/Netdisco/DB.pm
Normal file
31
Netdisco/lib/App/Netdisco/DB.pm
Normal file
@@ -0,0 +1,31 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Schema';
|
||||
|
||||
__PACKAGE__->load_namespaces;
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:tQTf/oInVydRDsuIFLSU4A
|
||||
|
||||
our $VERSION = 3; # schema version used for upgrades, keep as integer
|
||||
|
||||
use Path::Class;
|
||||
use File::Basename;
|
||||
|
||||
my (undef, $libpath, undef) = fileparse( $INC{ 'App/Netdisco/DB.pm' } );
|
||||
our $schema_versions_dir = Path::Class::Dir->new($libpath)
|
||||
->subdir("DB", "schema_versions")->stringify;
|
||||
|
||||
__PACKAGE__->load_components(qw/Schema::Versioned/);
|
||||
__PACKAGE__->upgrade_directory($schema_versions_dir);
|
||||
|
||||
# You can replace this text with custom code or comments, and it will be preserved on regeneration
|
||||
1;
|
||||
58
Netdisco/lib/App/Netdisco/DB/Result/Admin.pm
Normal file
58
Netdisco/lib/App/Netdisco/DB/Result/Admin.pm
Normal file
@@ -0,0 +1,58 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::Admin;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
__PACKAGE__->table("admin");
|
||||
__PACKAGE__->add_columns(
|
||||
"job",
|
||||
{
|
||||
data_type => "integer",
|
||||
is_auto_increment => 1,
|
||||
is_nullable => 0,
|
||||
sequence => "admin_job_seq",
|
||||
},
|
||||
"entered",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
"started",
|
||||
{ data_type => "timestamp", is_nullable => 1 },
|
||||
"finished",
|
||||
{ data_type => "timestamp", is_nullable => 1 },
|
||||
"device",
|
||||
{ data_type => "inet", is_nullable => 1 },
|
||||
"port",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"action",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"subaction",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"status",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"username",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"userip",
|
||||
{ data_type => "inet", is_nullable => 1 },
|
||||
"log",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"debug",
|
||||
{ data_type => "boolean", is_nullable => 1 },
|
||||
);
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:gW4JW4pMgrufFIxFeYPYpw
|
||||
|
||||
__PACKAGE__->set_primary_key("job");
|
||||
|
||||
# You can replace this text with custom code or comments, and it will be preserved on regeneration
|
||||
1;
|
||||
184
Netdisco/lib/App/Netdisco/DB/Result/Device.pm
Normal file
184
Netdisco/lib/App/Netdisco/DB/Result/Device.pm
Normal file
@@ -0,0 +1,184 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::Device;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
__PACKAGE__->table("device");
|
||||
__PACKAGE__->add_columns(
|
||||
"ip",
|
||||
{ data_type => "inet", is_nullable => 0 },
|
||||
"creation",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
"dns",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"description",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"uptime",
|
||||
{ data_type => "bigint", is_nullable => 1 },
|
||||
"contact",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"name",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"location",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"layers",
|
||||
{ data_type => "varchar", is_nullable => 1, size => 8 },
|
||||
"ports",
|
||||
{ data_type => "integer", is_nullable => 1 },
|
||||
"mac",
|
||||
{ data_type => "macaddr", is_nullable => 1 },
|
||||
"serial",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"model",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"ps1_type",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"ps2_type",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"ps1_status",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"ps2_status",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"fan",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"slots",
|
||||
{ data_type => "integer", is_nullable => 1 },
|
||||
"vendor",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"os",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"os_ver",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"log",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"snmp_ver",
|
||||
{ data_type => "integer", is_nullable => 1 },
|
||||
"snmp_comm",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"snmp_class",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"vtp_domain",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"last_discover",
|
||||
{ data_type => "timestamp", is_nullable => 1 },
|
||||
"last_macsuck",
|
||||
{ data_type => "timestamp", is_nullable => 1 },
|
||||
"last_arpnip",
|
||||
{ data_type => "timestamp", is_nullable => 1 },
|
||||
);
|
||||
__PACKAGE__->set_primary_key("ip");
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:671/XuuvsO2aMB1+IRWFjg
|
||||
|
||||
=head1 RELATIONSHIPS
|
||||
|
||||
=head2 device_ips
|
||||
|
||||
Returns rows from the C<device_ip> table which relate to this Device. That is,
|
||||
all the interface IP aliases configured on the Device.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->has_many( device_ips => 'App::Netdisco::DB::Result::DeviceIp', 'ip' );
|
||||
|
||||
=head2 vlans
|
||||
|
||||
Returns the C<device_vlan> entries for this Device. That is, the list of VLANs
|
||||
configured on or known by this Device.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->has_many( vlans => 'App::Netdisco::DB::Result::DeviceVlan', 'ip' );
|
||||
|
||||
=head2 ports
|
||||
|
||||
Returns the set of ports on this Device.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->has_many( ports => 'App::Netdisco::DB::Result::DevicePort', 'ip' );
|
||||
|
||||
=head2 port_vlans
|
||||
|
||||
Returns the set of VLANs known to be configured on Ports on this Device,
|
||||
either tagged or untagged.
|
||||
|
||||
The JOIN is of type "RIGHT" meaning that the results are constrained to VLANs
|
||||
only on Ports on this Device.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->has_many(
|
||||
port_vlans => 'App::Netdisco::DB::Result::DevicePortVlan',
|
||||
'ip', { join_type => 'RIGHT' }
|
||||
);
|
||||
|
||||
# helper which assumes we've just RIGHT JOINed to Vlans table
|
||||
sub vlan { return (shift)->vlans->first }
|
||||
|
||||
=head1 ADDITIONAL COLUMNS
|
||||
|
||||
=head2 uptime_age
|
||||
|
||||
Formatted version of the C<uptime> field.
|
||||
|
||||
The format is in "X days/months/years" style, similar to:
|
||||
|
||||
1 year 4 months 05:46:00
|
||||
|
||||
=cut
|
||||
|
||||
sub uptime_age { return (shift)->get_column('uptime_age') }
|
||||
|
||||
=head2 last_discover_stamp
|
||||
|
||||
Formatted version of the C<last_discover> field, accurate to the minute.
|
||||
|
||||
The format is somewhat like ISO 8601 or RFC3339 but without the middle C<T>
|
||||
between the date stamp and time stamp. That is:
|
||||
|
||||
2012-02-06 12:49
|
||||
|
||||
=cut
|
||||
|
||||
sub last_discover_stamp { return (shift)->get_column('last_discover_stamp') }
|
||||
|
||||
=head2 last_macsuck_stamp
|
||||
|
||||
Formatted version of the C<last_macsuck> field, accurate to the minute.
|
||||
|
||||
The format is somewhat like ISO 8601 or RFC3339 but without the middle C<T>
|
||||
between the date stamp and time stamp. That is:
|
||||
|
||||
2012-02-06 12:49
|
||||
|
||||
=cut
|
||||
|
||||
sub last_macsuck_stamp { return (shift)->get_column('last_macsuck_stamp') }
|
||||
|
||||
=head2 last_arpnip_stamp
|
||||
|
||||
Formatted version of the C<last_arpnip> field, accurate to the minute.
|
||||
|
||||
The format is somewhat like ISO 8601 or RFC3339 but without the middle C<T>
|
||||
between the date stamp and time stamp. That is:
|
||||
|
||||
2012-02-06 12:49
|
||||
|
||||
=cut
|
||||
|
||||
sub last_arpnip_stamp { return (shift)->get_column('last_arpnip_stamp') }
|
||||
|
||||
1;
|
||||
59
Netdisco/lib/App/Netdisco/DB/Result/DeviceIp.pm
Normal file
59
Netdisco/lib/App/Netdisco/DB/Result/DeviceIp.pm
Normal file
@@ -0,0 +1,59 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::DeviceIp;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
__PACKAGE__->table("device_ip");
|
||||
__PACKAGE__->add_columns(
|
||||
"ip",
|
||||
{ data_type => "inet", is_nullable => 0 },
|
||||
"alias",
|
||||
{ data_type => "inet", is_nullable => 0 },
|
||||
"subnet",
|
||||
{ data_type => "cidr", is_nullable => 1 },
|
||||
"port",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"dns",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"creation",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
);
|
||||
__PACKAGE__->set_primary_key("ip", "alias");
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:/ugGtBSGyrJ7s6yqJ9bclQ
|
||||
|
||||
=head1 RELATIONSHIPS
|
||||
|
||||
=head2 device
|
||||
|
||||
Returns the entry from the C<device> table to which this IP alias relates.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->belongs_to( device => 'App::Netdisco::DB::Result::Device', 'ip' );
|
||||
|
||||
=head2 device_port
|
||||
|
||||
Returns the Port on which this IP address is configured (typically a loopback,
|
||||
routed port or virtual interface).
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->add_unique_constraint(['alias']);
|
||||
|
||||
__PACKAGE__->belongs_to( device_port => 'App::Netdisco::DB::Result::DevicePort',
|
||||
{ 'foreign.port' => 'self.port', 'foreign.ip' => 'self.ip' } );
|
||||
|
||||
1;
|
||||
59
Netdisco/lib/App/Netdisco/DB/Result/DeviceModule.pm
Normal file
59
Netdisco/lib/App/Netdisco/DB/Result/DeviceModule.pm
Normal file
@@ -0,0 +1,59 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::DeviceModule;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
__PACKAGE__->table("device_module");
|
||||
__PACKAGE__->add_columns(
|
||||
"ip",
|
||||
{ data_type => "inet", is_nullable => 0 },
|
||||
"index",
|
||||
{ data_type => "integer", is_nullable => 0 },
|
||||
"description",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"type",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"parent",
|
||||
{ data_type => "integer", is_nullable => 1 },
|
||||
"name",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"class",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"pos",
|
||||
{ data_type => "integer", is_nullable => 1 },
|
||||
"hw_ver",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"fw_ver",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"sw_ver",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"serial",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"model",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"fru",
|
||||
{ data_type => "boolean", is_nullable => 1 },
|
||||
"creation",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
"last_discover",
|
||||
{ data_type => "timestamp", is_nullable => 1 },
|
||||
);
|
||||
__PACKAGE__->set_primary_key("ip", "index");
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:nuwxZBoiip9trdJFmgk3Fw
|
||||
|
||||
|
||||
# You can replace this text with custom code or comments, and it will be preserved on regeneration
|
||||
1;
|
||||
253
Netdisco/lib/App/Netdisco/DB/Result/DevicePort.pm
Normal file
253
Netdisco/lib/App/Netdisco/DB/Result/DevicePort.pm
Normal file
@@ -0,0 +1,253 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::DevicePort;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
__PACKAGE__->table("device_port");
|
||||
__PACKAGE__->add_columns(
|
||||
"ip",
|
||||
{ data_type => "inet", is_nullable => 0 },
|
||||
"port",
|
||||
{ data_type => "text", is_nullable => 0 },
|
||||
"creation",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
"descr",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"up",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"up_admin",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"type",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"duplex",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"duplex_admin",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"speed",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"name",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"mac",
|
||||
{ data_type => "macaddr", is_nullable => 1 },
|
||||
"mtu",
|
||||
{ data_type => "integer", is_nullable => 1 },
|
||||
"stp",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"remote_ip",
|
||||
{ data_type => "inet", is_nullable => 1 },
|
||||
"remote_port",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"remote_type",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"remote_id",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"vlan",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"pvid",
|
||||
{ data_type => "integer", is_nullable => 1 },
|
||||
"lastchange",
|
||||
{ data_type => "bigint", is_nullable => 1 },
|
||||
);
|
||||
__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 device
|
||||
|
||||
Returns the Device table entry to which the given Port is related.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->belongs_to( device => 'App::Netdisco::DB::Result::Device', 'ip');
|
||||
|
||||
=head2 nodes / active_nodes / nodes_with_age / active_nodes_with_age
|
||||
|
||||
Returns the set of Nodes whose MAC addresses are associated with this Device
|
||||
Port.
|
||||
|
||||
The C<active> variants return only the subset of nodes currently in the switch
|
||||
MAC address table, that is the active ones.
|
||||
|
||||
The C<with_age> variants add an additional column C<time_last_age>, a
|
||||
preformatted value for the Node's C<time_last> field, which reads as "X
|
||||
days/weeks/months/years".
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->has_many( nodes => 'App::Netdisco::DB::Result::Node',
|
||||
{
|
||||
'foreign.switch' => 'self.ip',
|
||||
'foreign.port' => 'self.port',
|
||||
},
|
||||
{ join_type => 'LEFT' },
|
||||
);
|
||||
|
||||
__PACKAGE__->has_many( nodes_with_age => 'App::Netdisco::DB::Result::Virtual::NodeWithAge',
|
||||
{
|
||||
'foreign.switch' => 'self.ip',
|
||||
'foreign.port' => 'self.port',
|
||||
},
|
||||
{ join_type => 'LEFT' },
|
||||
);
|
||||
|
||||
__PACKAGE__->has_many( active_nodes => 'App::Netdisco::DB::Result::Virtual::ActiveNode',
|
||||
{
|
||||
'foreign.switch' => 'self.ip',
|
||||
'foreign.port' => 'self.port',
|
||||
},
|
||||
{ join_type => 'LEFT' },
|
||||
);
|
||||
|
||||
__PACKAGE__->has_many( active_nodes_with_age => 'App::Netdisco::DB::Result::Virtual::ActiveNodeWithAge',
|
||||
{
|
||||
'foreign.switch' => 'self.ip',
|
||||
'foreign.port' => 'self.port',
|
||||
},
|
||||
{ join_type => 'LEFT' },
|
||||
);
|
||||
|
||||
=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<neighbor> 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 => 'App::Netdisco::DB::Result::DeviceIp',
|
||||
{ 'foreign.alias' => 'self.remote_ip' },
|
||||
{ join_type => 'LEFT' },
|
||||
);
|
||||
|
||||
=head2 power
|
||||
|
||||
Returns a row from the C<device_port_power> table if one refers to this
|
||||
device port.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->might_have( power => 'App::Netdisco::DB::Result::DevicePortPower', {
|
||||
'foreign.ip' => 'self.ip', 'foreign.port' => 'self.port',
|
||||
});
|
||||
|
||||
=head2 port_vlans_tagged
|
||||
|
||||
Returns a set of rows from the C<device_port_vlan> table relating to this
|
||||
port, where the VLANs are all tagged.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->has_many( port_vlans_tagged => 'App::Netdisco::DB::Result::Virtual::DevicePortVlanTagged',
|
||||
{
|
||||
'foreign.ip' => 'self.ip',
|
||||
'foreign.port' => 'self.port',
|
||||
},
|
||||
{ join_type => 'LEFT' },
|
||||
);
|
||||
|
||||
=head2 tagged_vlans
|
||||
|
||||
As compared to C<port_vlans_tagged>, 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<tagged_vlans_count>.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->many_to_many( tagged_vlans => 'port_vlans_tagged', 'vlan' );
|
||||
|
||||
|
||||
=head2 oui
|
||||
|
||||
Returns the C<oui> 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 => 'App::Netdisco::DB::Result::Oui',
|
||||
sub {
|
||||
my $args = shift;
|
||||
return {
|
||||
"$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
|
||||
|
||||
sub neighbor {
|
||||
my $row = shift;
|
||||
return eval { $row->neighbor_alias->device || undef };
|
||||
}
|
||||
|
||||
=head1 ADDITIONAL COLUMNS
|
||||
|
||||
=head2 tagged_vlans_count
|
||||
|
||||
Returns the number of tagged VLANs active on this device port. Enable this
|
||||
column by applying the C<with_vlan_count()> modifier to C<search()>.
|
||||
|
||||
=cut
|
||||
|
||||
sub tagged_vlans_count { return (shift)->get_column('tagged_vlans_count') }
|
||||
|
||||
=head2 lastchange_stamp
|
||||
|
||||
Formatted version of the C<lastchange> field, accurate to the minute. Enable
|
||||
this column by applying the C<with_vlan_count()> modifier to C<search()>.
|
||||
|
||||
The format is somewhat like ISO 8601 or RFC3339 but without the middle C<T>
|
||||
between the date stamp and time stamp. That is:
|
||||
|
||||
2012-02-06 12:49
|
||||
|
||||
=cut
|
||||
|
||||
sub lastchange_stamp { return (shift)->get_column('lastchange_stamp') }
|
||||
|
||||
=head2 is_free
|
||||
|
||||
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.
|
||||
|
||||
See the C<with_is_free> and C<only_free_ports> modifiers to C<search()>.
|
||||
|
||||
=cut
|
||||
|
||||
sub is_free { return (shift)->get_column('is_free') }
|
||||
|
||||
1;
|
||||
49
Netdisco/lib/App/Netdisco/DB/Result/DevicePortLog.pm
Normal file
49
Netdisco/lib/App/Netdisco/DB/Result/DevicePortLog.pm
Normal file
@@ -0,0 +1,49 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::DevicePortLog;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
__PACKAGE__->table("device_port_log");
|
||||
__PACKAGE__->add_columns(
|
||||
"id",
|
||||
{
|
||||
data_type => "integer",
|
||||
is_auto_increment => 1,
|
||||
is_nullable => 0,
|
||||
sequence => "device_port_log_id_seq",
|
||||
},
|
||||
"ip",
|
||||
{ data_type => "inet", is_nullable => 1 },
|
||||
"port",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"reason",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"log",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"username",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"userip",
|
||||
{ data_type => "inet", is_nullable => 1 },
|
||||
"action",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"creation",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:5moCbYoDG2BqT7VrP/MRkA
|
||||
|
||||
|
||||
# You can replace this text with custom code or comments, and it will be preserved on regeneration
|
||||
1;
|
||||
46
Netdisco/lib/App/Netdisco/DB/Result/DevicePortPower.pm
Normal file
46
Netdisco/lib/App/Netdisco/DB/Result/DevicePortPower.pm
Normal file
@@ -0,0 +1,46 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::DevicePortPower;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
__PACKAGE__->table("device_port_power");
|
||||
__PACKAGE__->add_columns(
|
||||
"ip",
|
||||
{ data_type => "inet", is_nullable => 0 },
|
||||
"port",
|
||||
{ data_type => "text", is_nullable => 0 },
|
||||
"module",
|
||||
{ data_type => "integer", is_nullable => 1 },
|
||||
"admin",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"status",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"class",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"power",
|
||||
{ data_type => "integer", is_nullable => 1 },
|
||||
);
|
||||
__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:sHcdItRUFUOAtIZQjdWbcg
|
||||
|
||||
=head1 RELATIONSHIPS
|
||||
|
||||
=head2 port
|
||||
|
||||
Returns the entry from the C<port> table for which this Power entry applies.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->belongs_to( port => 'App::Netdisco::DB::Result::DevicePort', {
|
||||
'foreign.ip' => 'self.ip', 'foreign.port' => 'self.port',
|
||||
});
|
||||
|
||||
1;
|
||||
31
Netdisco/lib/App/Netdisco/DB/Result/DevicePortSsid.pm
Normal file
31
Netdisco/lib/App/Netdisco/DB/Result/DevicePortSsid.pm
Normal file
@@ -0,0 +1,31 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::DevicePortSsid;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
__PACKAGE__->table("device_port_ssid");
|
||||
__PACKAGE__->add_columns(
|
||||
"ip",
|
||||
{ data_type => "inet", is_nullable => 1 },
|
||||
"port",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"ssid",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"broadcast",
|
||||
{ data_type => "boolean", is_nullable => 1 },
|
||||
"bssid",
|
||||
{ data_type => "macaddr", is_nullable => 1 },
|
||||
);
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:zvgylKzUQtizJZCe1rEdUg
|
||||
|
||||
|
||||
# You can replace this text with custom code or comments, and it will be preserved on regeneration
|
||||
1;
|
||||
76
Netdisco/lib/App/Netdisco/DB/Result/DevicePortVlan.pm
Normal file
76
Netdisco/lib/App/Netdisco/DB/Result/DevicePortVlan.pm
Normal file
@@ -0,0 +1,76 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::DevicePortVlan;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
__PACKAGE__->table("device_port_vlan");
|
||||
__PACKAGE__->add_columns(
|
||||
"ip",
|
||||
{ data_type => "inet", is_nullable => 0 },
|
||||
"port",
|
||||
{ data_type => "text", is_nullable => 0 },
|
||||
"vlan",
|
||||
{ data_type => "integer", is_nullable => 0 },
|
||||
"native",
|
||||
{ data_type => "boolean", default_value => \"false", is_nullable => 0 },
|
||||
"creation",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
"last_discover",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
"vlantype",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
);
|
||||
__PACKAGE__->set_primary_key("ip", "port", "vlan");
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:/3KLjJ3D18pGaPEaw9EU5w
|
||||
|
||||
=head1 RELATIONSHIPS
|
||||
|
||||
=head2 device
|
||||
|
||||
Returns the entry from the C<device> table which hosts the Port on which this
|
||||
VLAN is configured.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->belongs_to( device => 'App::Netdisco::DB::Result::Device', 'ip' );
|
||||
|
||||
=head2 port
|
||||
|
||||
Returns the entry from the C<port> table on which this VLAN is configured.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->belongs_to( port => 'App::Netdisco::DB::Result::DevicePort', {
|
||||
'foreign.ip' => 'self.ip', 'foreign.port' => 'self.port',
|
||||
});
|
||||
|
||||
=head2 vlan
|
||||
|
||||
Returns the entry from the C<device_vlan> table describing this VLAN in
|
||||
detail, typically in order that the C<name> can be retrieved.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->belongs_to( vlan => 'App::Netdisco::DB::Result::DeviceVlan', {
|
||||
'foreign.ip' => 'self.ip', 'foreign.vlan' => 'self.vlan',
|
||||
});
|
||||
|
||||
1;
|
||||
29
Netdisco/lib/App/Netdisco/DB/Result/DevicePortWireless.pm
Normal file
29
Netdisco/lib/App/Netdisco/DB/Result/DevicePortWireless.pm
Normal file
@@ -0,0 +1,29 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::DevicePortWireless;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
__PACKAGE__->table("device_port_wireless");
|
||||
__PACKAGE__->add_columns(
|
||||
"ip",
|
||||
{ data_type => "inet", is_nullable => 1 },
|
||||
"port",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"channel",
|
||||
{ data_type => "integer", is_nullable => 1 },
|
||||
"power",
|
||||
{ data_type => "integer", is_nullable => 1 },
|
||||
);
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:T5GmnCj/9BB7meiGZ3xN7g
|
||||
|
||||
|
||||
# You can replace this text with custom code or comments, and it will be preserved on regeneration
|
||||
1;
|
||||
30
Netdisco/lib/App/Netdisco/DB/Result/DevicePower.pm
Normal file
30
Netdisco/lib/App/Netdisco/DB/Result/DevicePower.pm
Normal file
@@ -0,0 +1,30 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::DevicePower;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
__PACKAGE__->table("device_power");
|
||||
__PACKAGE__->add_columns(
|
||||
"ip",
|
||||
{ data_type => "inet", is_nullable => 0 },
|
||||
"module",
|
||||
{ data_type => "integer", is_nullable => 0 },
|
||||
"power",
|
||||
{ data_type => "integer", is_nullable => 1 },
|
||||
"status",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
);
|
||||
__PACKAGE__->set_primary_key("ip", "module");
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:awZRI/IH2VewzGlxISsr7w
|
||||
|
||||
|
||||
# You can replace this text with custom code or comments, and it will be preserved on regeneration
|
||||
1;
|
||||
42
Netdisco/lib/App/Netdisco/DB/Result/DeviceRoute.pm
Normal file
42
Netdisco/lib/App/Netdisco/DB/Result/DeviceRoute.pm
Normal file
@@ -0,0 +1,42 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::DeviceRoute;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
__PACKAGE__->table("device_route");
|
||||
__PACKAGE__->add_columns(
|
||||
"ip",
|
||||
{ data_type => "inet", is_nullable => 0 },
|
||||
"network",
|
||||
{ data_type => "cidr", is_nullable => 0 },
|
||||
"creation",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
"dest",
|
||||
{ data_type => "inet", is_nullable => 0 },
|
||||
"last_discover",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
);
|
||||
__PACKAGE__->set_primary_key("ip", "network", "dest");
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:3jcvPP60E5BvwnUbXql7mQ
|
||||
|
||||
|
||||
# You can replace this text with custom code or comments, and it will be preserved on regeneration
|
||||
1;
|
||||
87
Netdisco/lib/App/Netdisco/DB/Result/DeviceVlan.pm
Normal file
87
Netdisco/lib/App/Netdisco/DB/Result/DeviceVlan.pm
Normal file
@@ -0,0 +1,87 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::DeviceVlan;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
__PACKAGE__->table("device_vlan");
|
||||
__PACKAGE__->add_columns(
|
||||
"ip",
|
||||
{ data_type => "inet", is_nullable => 0 },
|
||||
"vlan",
|
||||
{ data_type => "integer", is_nullable => 0 },
|
||||
"description",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"creation",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
"last_discover",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
);
|
||||
__PACKAGE__->set_primary_key("ip", "vlan");
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:hBJRcdzOic4d3u4pD1m8iA
|
||||
|
||||
=head1 RELATIONSHIPS
|
||||
|
||||
=head2 device
|
||||
|
||||
Returns the entry from the C<device> table on which this VLAN entry was discovered.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->belongs_to( device => 'App::Netdisco::DB::Result::Device', 'ip' );
|
||||
|
||||
=head2 port_vlans_tagged
|
||||
|
||||
Link relationship for C<tagging_ports>, see below.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->has_many( port_vlans_tagged => 'App::Netdisco::DB::Result::Virtual::DevicePortVlanTagged',
|
||||
{ 'foreign.ip' => 'self.ip', 'foreign.vlan' => 'self.vlan' },
|
||||
);
|
||||
|
||||
=head2 port_vlans_native
|
||||
|
||||
Link relationship to support C<native_ports>, see below.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->has_many( port_vlans_native => 'App::Netdisco::DB::Result::Virtual::DevicePortVlanNative',
|
||||
{ 'foreign.ip' => 'self.ip', 'foreign.vlan' => 'self.vlan' },
|
||||
);
|
||||
|
||||
=head2 tagging_ports
|
||||
|
||||
Returns the set of Device Ports on which this VLAN is configured to be tagged.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->many_to_many( tagging_ports => 'port_vlans_tagged', 'port' );
|
||||
|
||||
=head2 native_ports
|
||||
|
||||
Returns the set of Device Ports on which this VLAN is the native VLAN (that
|
||||
is, untagged).
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->many_to_many( native_ports => 'port_vlans_native', 'port' );
|
||||
|
||||
1;
|
||||
41
Netdisco/lib/App/Netdisco/DB/Result/Log.pm
Normal file
41
Netdisco/lib/App/Netdisco/DB/Result/Log.pm
Normal file
@@ -0,0 +1,41 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::Log;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
__PACKAGE__->table("log");
|
||||
__PACKAGE__->add_columns(
|
||||
"id",
|
||||
{
|
||||
data_type => "integer",
|
||||
is_auto_increment => 1,
|
||||
is_nullable => 0,
|
||||
sequence => "log_id_seq",
|
||||
},
|
||||
"creation",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
"class",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"entry",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"logfile",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
);
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:eonwOHvvzWm88Ug+IGKuzg
|
||||
|
||||
|
||||
# You can replace this text with custom code or comments, and it will be preserved on regeneration
|
||||
1;
|
||||
135
Netdisco/lib/App/Netdisco/DB/Result/Node.pm
Normal file
135
Netdisco/lib/App/Netdisco/DB/Result/Node.pm
Normal file
@@ -0,0 +1,135 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::Node;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
__PACKAGE__->table("node");
|
||||
__PACKAGE__->add_columns(
|
||||
"mac",
|
||||
{ data_type => "macaddr", is_nullable => 0 },
|
||||
"switch",
|
||||
{ data_type => "inet", is_nullable => 0 },
|
||||
"port",
|
||||
{ data_type => "text", is_nullable => 0 },
|
||||
"active",
|
||||
{ data_type => "boolean", is_nullable => 1 },
|
||||
"oui",
|
||||
{ data_type => "varchar", is_nullable => 1, size => 8 },
|
||||
"time_first",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
"time_recent",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
"time_last",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
);
|
||||
__PACKAGE__->set_primary_key("mac", "switch", "port");
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:sGGyKEfUkoIFVtmj1wnH7A
|
||||
|
||||
=head1 RELATIONSHIPS
|
||||
|
||||
=head2 device
|
||||
|
||||
Returns the single C<device> to which this Node entry was associated at the
|
||||
time of discovery.
|
||||
|
||||
The JOIN is of type LEFT, in case the C<device> is no longer present in the
|
||||
database but the relation is being used in C<search()>.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->belongs_to( device => 'App::Netdisco::DB::Result::Device',
|
||||
{ 'foreign.ip' => 'self.switch' }, { join_type => 'LEFT' } );
|
||||
|
||||
=head2 device_port
|
||||
|
||||
Returns the single C<device_port> to which this Node entry was associated at
|
||||
the time of discovery.
|
||||
|
||||
The JOIN is of type LEFT, in case the C<device> is no longer present in the
|
||||
database but the relation is being used in C<search()>.
|
||||
|
||||
=cut
|
||||
|
||||
# device port may have been deleted (reconfigured modules?) but node remains
|
||||
__PACKAGE__->belongs_to( device_port => 'App::Netdisco::DB::Result::DevicePort',
|
||||
{ 'foreign.ip' => 'self.switch', 'foreign.port' => 'self.port' },
|
||||
{ join_type => 'LEFT' }
|
||||
);
|
||||
|
||||
=head2 ips
|
||||
|
||||
Returns the set of C<node_ip> entries associated with this Node. That is, the
|
||||
IP addresses which this MAC address was hosting at the time of discovery.
|
||||
|
||||
Note that the Active status of the returned IP entries will all be the same as
|
||||
the current Node's.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->has_many( ips => 'App::Netdisco::DB::Result::NodeIp',
|
||||
{ 'foreign.mac' => 'self.mac', 'foreign.active' => 'self.active' } );
|
||||
|
||||
=head2 oui
|
||||
|
||||
Returns the C<oui> table entry matching this Node. 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 => 'App::Netdisco::DB::Result::Oui', 'oui',
|
||||
{ join_type => 'LEFT' } );
|
||||
|
||||
=head1 ADDITIONAL COLUMNS
|
||||
|
||||
=head2 time_first_stamp
|
||||
|
||||
Formatted version of the C<time_first> field, accurate to the minute.
|
||||
|
||||
The format is somewhat like ISO 8601 or RFC3339 but without the middle C<T>
|
||||
between the date stamp and time stamp. That is:
|
||||
|
||||
2012-02-06 12:49
|
||||
|
||||
=cut
|
||||
|
||||
sub time_first_stamp { return (shift)->get_column('time_first_stamp') }
|
||||
|
||||
=head2 time_last_stamp
|
||||
|
||||
Formatted version of the C<time_last> field, accurate to the minute.
|
||||
|
||||
The format is somewhat like ISO 8601 or RFC3339 but without the middle C<T>
|
||||
between the date stamp and time stamp. That is:
|
||||
|
||||
2012-02-06 12:49
|
||||
|
||||
=cut
|
||||
|
||||
sub time_last_stamp { return (shift)->get_column('time_last_stamp') }
|
||||
|
||||
1;
|
||||
209
Netdisco/lib/App/Netdisco/DB/Result/NodeIp.pm
Normal file
209
Netdisco/lib/App/Netdisco/DB/Result/NodeIp.pm
Normal file
@@ -0,0 +1,209 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::NodeIp;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
__PACKAGE__->table("node_ip");
|
||||
__PACKAGE__->add_columns(
|
||||
"mac",
|
||||
{ data_type => "macaddr", is_nullable => 0 },
|
||||
"ip",
|
||||
{ data_type => "inet", is_nullable => 0 },
|
||||
"dns",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"active",
|
||||
{ data_type => "boolean", is_nullable => 1 },
|
||||
"time_first",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
"time_last",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
);
|
||||
__PACKAGE__->set_primary_key("mac", "ip");
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:9+CuvuVWH88WxAf6IBij8g
|
||||
|
||||
=head1 RELATIONSHIPS
|
||||
|
||||
=head2 oui
|
||||
|
||||
Returns the C<oui> table entry matching this Node. 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 => 'App::Netdisco::DB::Result::Oui',
|
||||
sub {
|
||||
my $args = shift;
|
||||
return {
|
||||
"$args->{foreign_alias}.oui" =>
|
||||
{ '=' => \"substring(cast($args->{self_alias}.mac as varchar) for 8)" }
|
||||
};
|
||||
},
|
||||
{ join_type => 'LEFT' }
|
||||
);
|
||||
|
||||
=head2 node_ips
|
||||
|
||||
Returns the set of all C<node_ip> entries which are associated together with
|
||||
this IP. That is, all the IP addresses hosted on the same interface (MAC
|
||||
address) as the current Node IP entry.
|
||||
|
||||
Note that the set will include the original Node IP object itself. If you wish
|
||||
to find the I<other> IPs excluding this one, see the C<ip_aliases> helper
|
||||
routine, below.
|
||||
|
||||
Remember you can pass a filter to this method to find only active or inactive
|
||||
nodes, but do take into account that both the C<node> and C<node_ip> tables
|
||||
include independent C<active> fields.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->has_many( node_ips => 'App::Netdisco::DB::Result::NodeIp',
|
||||
{ 'foreign.mac' => 'self.mac' } );
|
||||
|
||||
=head2 nodes
|
||||
|
||||
Returns the set of C<node> entries associated with this IP. That is, all the
|
||||
MAC addresses recorded which have ever hosted this IP Address.
|
||||
|
||||
Remember you can pass a filter to this method to find only active or inactive
|
||||
nodes, but do take into account that both the C<node> and C<node_ip> tables
|
||||
include independent C<active> fields.
|
||||
|
||||
See also the C<node_sightings> helper routine, below.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->has_many( nodes => 'App::Netdisco::DB::Result::Node',
|
||||
{ 'foreign.mac' => 'self.mac' } );
|
||||
|
||||
my $search_attr = {
|
||||
order_by => {'-desc' => 'time_last'},
|
||||
'+columns' => {
|
||||
time_first_stamp => \"to_char(time_first, 'YYYY-MM-DD HH24:MI')",
|
||||
time_last_stamp => \"to_char(time_last, 'YYYY-MM-DD HH24:MI')",
|
||||
},
|
||||
};
|
||||
|
||||
=head2 ip_aliases( \%cond, \%attrs? )
|
||||
|
||||
Returns the set of other C<node_ip> entries hosted on the same interface (MAC
|
||||
address) as the current Node IP, excluding the current IP itself.
|
||||
|
||||
Remember you can pass a filter to this method to find only active or inactive
|
||||
nodes, but do take into account that both the C<node> and C<node_ip> tables
|
||||
include independent C<active> fields.
|
||||
|
||||
=over 4
|
||||
|
||||
=item *
|
||||
|
||||
Results are ordered by time last seen.
|
||||
|
||||
=item *
|
||||
|
||||
Additional columns C<time_first_stamp> and C<time_last_stamp> provide
|
||||
preformatted timestamps of the C<time_first> and C<time_last> fields.
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
sub ip_aliases {
|
||||
my ($row, $cond, $attrs) = @_;
|
||||
|
||||
my $rs = $row->node_ips({ip => { '!=' => $row->ip }});
|
||||
|
||||
return $rs
|
||||
->search_rs({}, $search_attr)
|
||||
->search($cond, $attrs);
|
||||
}
|
||||
|
||||
=head2 node_sightings( \%cond, \%attrs? )
|
||||
|
||||
Returns the set of C<node> entries associated with this IP. That is, all the
|
||||
MAC addresses recorded which have ever hosted this IP Address.
|
||||
|
||||
Remember you can pass a filter to this method to find only active or inactive
|
||||
nodes, but do take into account that both the C<node> and C<node_ip> tables
|
||||
include independent C<active> fields.
|
||||
|
||||
=over 4
|
||||
|
||||
=item *
|
||||
|
||||
Results are ordered by time last seen.
|
||||
|
||||
=item *
|
||||
|
||||
Additional columns C<time_first_stamp> and C<time_last_stamp> provide
|
||||
preformatted timestamps of the C<time_first> and C<time_last> fields.
|
||||
|
||||
=item *
|
||||
|
||||
A JOIN is performed on the Device table and the Device DNS column prefetched.
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
sub node_sightings {
|
||||
my ($row, $cond, $attrs) = @_;
|
||||
|
||||
return $row
|
||||
->nodes({}, {
|
||||
'+columns' => [qw/ device.dns /],
|
||||
join => 'device',
|
||||
})
|
||||
->search_rs({}, $search_attr)
|
||||
->search($cond, $attrs);
|
||||
}
|
||||
|
||||
=head1 ADDITIONAL COLUMNS
|
||||
|
||||
=head2 time_first_stamp
|
||||
|
||||
Formatted version of the C<time_first> field, accurate to the minute.
|
||||
|
||||
The format is somewhat like ISO 8601 or RFC3339 but without the middle C<T>
|
||||
between the date stamp and time stamp. That is:
|
||||
|
||||
2012-02-06 12:49
|
||||
|
||||
=cut
|
||||
|
||||
sub time_first_stamp { return (shift)->get_column('time_first_stamp') }
|
||||
|
||||
=head2 time_last_stamp
|
||||
|
||||
Formatted version of the C<time_last> field, accurate to the minute.
|
||||
|
||||
The format is somewhat like ISO 8601 or RFC3339 but without the middle C<T>
|
||||
between the date stamp and time stamp. That is:
|
||||
|
||||
2012-02-06 12:49
|
||||
|
||||
=cut
|
||||
|
||||
sub time_last_stamp { return (shift)->get_column('time_last_stamp') }
|
||||
|
||||
1;
|
||||
37
Netdisco/lib/App/Netdisco/DB/Result/NodeMonitor.pm
Normal file
37
Netdisco/lib/App/Netdisco/DB/Result/NodeMonitor.pm
Normal file
@@ -0,0 +1,37 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::NodeMonitor;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
__PACKAGE__->table("node_monitor");
|
||||
__PACKAGE__->add_columns(
|
||||
"mac",
|
||||
{ data_type => "macaddr", is_nullable => 0 },
|
||||
"active",
|
||||
{ data_type => "boolean", is_nullable => 1 },
|
||||
"why",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"cc",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"date",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
);
|
||||
__PACKAGE__->set_primary_key("mac");
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:0prRdz2XYlFuE+nahsI2Yg
|
||||
|
||||
|
||||
# You can replace this text with custom code or comments, and it will be preserved on regeneration
|
||||
1;
|
||||
50
Netdisco/lib/App/Netdisco/DB/Result/NodeNbt.pm
Normal file
50
Netdisco/lib/App/Netdisco/DB/Result/NodeNbt.pm
Normal file
@@ -0,0 +1,50 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::NodeNbt;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
__PACKAGE__->table("node_nbt");
|
||||
__PACKAGE__->add_columns(
|
||||
"mac",
|
||||
{ data_type => "macaddr", is_nullable => 0 },
|
||||
"ip",
|
||||
{ data_type => "inet", is_nullable => 1 },
|
||||
"nbname",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"domain",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"server",
|
||||
{ data_type => "boolean", is_nullable => 1 },
|
||||
"nbuser",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"active",
|
||||
{ data_type => "boolean", is_nullable => 1 },
|
||||
"time_first",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
"time_last",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
);
|
||||
__PACKAGE__->set_primary_key("mac");
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:XFpxaGAWE13iizQIuVOP3g
|
||||
|
||||
|
||||
# You can replace this text with custom code or comments, and it will be preserved on regeneration
|
||||
1;
|
||||
49
Netdisco/lib/App/Netdisco/DB/Result/NodeWireless.pm
Normal file
49
Netdisco/lib/App/Netdisco/DB/Result/NodeWireless.pm
Normal file
@@ -0,0 +1,49 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::NodeWireless;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
__PACKAGE__->table("node_wireless");
|
||||
__PACKAGE__->add_columns(
|
||||
"mac",
|
||||
{ data_type => "macaddr", is_nullable => 0 },
|
||||
"uptime",
|
||||
{ data_type => "integer", is_nullable => 1 },
|
||||
"maxrate",
|
||||
{ data_type => "integer", is_nullable => 1 },
|
||||
"txrate",
|
||||
{ data_type => "integer", is_nullable => 1 },
|
||||
"sigstrength",
|
||||
{ data_type => "integer", is_nullable => 1 },
|
||||
"sigqual",
|
||||
{ data_type => "integer", is_nullable => 1 },
|
||||
"rxpkt",
|
||||
{ data_type => "integer", is_nullable => 1 },
|
||||
"txpkt",
|
||||
{ data_type => "integer", is_nullable => 1 },
|
||||
"rxbyte",
|
||||
{ data_type => "bigint", is_nullable => 1 },
|
||||
"txbyte",
|
||||
{ data_type => "bigint", is_nullable => 1 },
|
||||
"time_last",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
);
|
||||
__PACKAGE__->set_primary_key("mac");
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:3xsSiWzL85ih3vhdews8Hg
|
||||
|
||||
|
||||
# You can replace this text with custom code or comments, and it will be preserved on regeneration
|
||||
1;
|
||||
26
Netdisco/lib/App/Netdisco/DB/Result/Oui.pm
Normal file
26
Netdisco/lib/App/Netdisco/DB/Result/Oui.pm
Normal file
@@ -0,0 +1,26 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::Oui;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
__PACKAGE__->table("oui");
|
||||
__PACKAGE__->add_columns(
|
||||
"oui",
|
||||
{ data_type => "varchar", is_nullable => 0, size => 8 },
|
||||
"company",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
);
|
||||
__PACKAGE__->set_primary_key("oui");
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:s51mj6SvstPd4GdNEy9SoA
|
||||
|
||||
|
||||
# You can replace this text with custom code or comments, and it will be preserved on regeneration
|
||||
1;
|
||||
38
Netdisco/lib/App/Netdisco/DB/Result/Process.pm
Normal file
38
Netdisco/lib/App/Netdisco/DB/Result/Process.pm
Normal file
@@ -0,0 +1,38 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::Process;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
__PACKAGE__->table("process");
|
||||
__PACKAGE__->add_columns(
|
||||
"controller",
|
||||
{ data_type => "integer", is_nullable => 0 },
|
||||
"device",
|
||||
{ data_type => "inet", is_nullable => 0 },
|
||||
"action",
|
||||
{ data_type => "text", is_nullable => 0 },
|
||||
"status",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"count",
|
||||
{ data_type => "integer", is_nullable => 1 },
|
||||
"creation",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:28hTnOo4oNwJabiWWHBgCw
|
||||
|
||||
|
||||
# You can replace this text with custom code or comments, and it will be preserved on regeneration
|
||||
1;
|
||||
33
Netdisco/lib/App/Netdisco/DB/Result/Session.pm
Normal file
33
Netdisco/lib/App/Netdisco/DB/Result/Session.pm
Normal file
@@ -0,0 +1,33 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::Session;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
__PACKAGE__->table("sessions");
|
||||
__PACKAGE__->add_columns(
|
||||
"id",
|
||||
{ data_type => "char", is_nullable => 0, size => 32 },
|
||||
"creation",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
"a_session",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
);
|
||||
__PACKAGE__->set_primary_key("id");
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:khNPh72VjQh8QHayuW/p1w
|
||||
|
||||
|
||||
# You can replace this text with custom code or comments, and it will be preserved on regeneration
|
||||
1;
|
||||
38
Netdisco/lib/App/Netdisco/DB/Result/Subnet.pm
Normal file
38
Netdisco/lib/App/Netdisco/DB/Result/Subnet.pm
Normal file
@@ -0,0 +1,38 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::Subnet;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
__PACKAGE__->table("subnets");
|
||||
__PACKAGE__->add_columns(
|
||||
"net",
|
||||
{ data_type => "cidr", is_nullable => 0 },
|
||||
"creation",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
"last_discover",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
);
|
||||
__PACKAGE__->set_primary_key("net");
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:1EHOfYx8PYOHoTkViZR6OA
|
||||
|
||||
|
||||
# You can replace this text with custom code or comments, and it will be preserved on regeneration
|
||||
1;
|
||||
22
Netdisco/lib/App/Netdisco/DB/Result/Topology.pm
Normal file
22
Netdisco/lib/App/Netdisco/DB/Result/Topology.pm
Normal file
@@ -0,0 +1,22 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::Topology;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
|
||||
__PACKAGE__->table("topology");
|
||||
|
||||
__PACKAGE__->add_columns(
|
||||
"dev1",
|
||||
{ data_type => "inet", is_nullable => 0 },
|
||||
"port1",
|
||||
{ data_type => "text", is_nullable => 0 },
|
||||
"dev2",
|
||||
{ data_type => "inet", is_nullable => 0 },
|
||||
"port2",
|
||||
{ data_type => "text", is_nullable => 0 },
|
||||
);
|
||||
|
||||
1;
|
||||
45
Netdisco/lib/App/Netdisco/DB/Result/User.pm
Normal file
45
Netdisco/lib/App/Netdisco/DB/Result/User.pm
Normal file
@@ -0,0 +1,45 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::User;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
__PACKAGE__->table("users");
|
||||
__PACKAGE__->add_columns(
|
||||
"username",
|
||||
{ data_type => "varchar", is_nullable => 0, size => 50 },
|
||||
"password",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"creation",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
"last_on",
|
||||
{ data_type => "timestamp", is_nullable => 1 },
|
||||
"port_control",
|
||||
{ data_type => "boolean", default_value => \"false", is_nullable => 1 },
|
||||
"ldap",
|
||||
{ data_type => "boolean", default_value => \"false", is_nullable => 1 },
|
||||
"admin",
|
||||
{ data_type => "boolean", default_value => \"false", is_nullable => 1 },
|
||||
"fullname",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"note",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
);
|
||||
__PACKAGE__->set_primary_key("username");
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:2awpSJkzXP7+8eyT4vGjfw
|
||||
|
||||
|
||||
# You can replace this text with custom code or comments, and it will be preserved on regeneration
|
||||
1;
|
||||
43
Netdisco/lib/App/Netdisco/DB/Result/UserLog.pm
Normal file
43
Netdisco/lib/App/Netdisco/DB/Result/UserLog.pm
Normal file
@@ -0,0 +1,43 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::UserLog;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
__PACKAGE__->table("user_log");
|
||||
__PACKAGE__->add_columns(
|
||||
"entry",
|
||||
{
|
||||
data_type => "integer",
|
||||
is_auto_increment => 1,
|
||||
is_nullable => 0,
|
||||
sequence => "user_log_entry_seq",
|
||||
},
|
||||
"username",
|
||||
{ data_type => "varchar", is_nullable => 1, size => 50 },
|
||||
"userip",
|
||||
{ data_type => "inet", is_nullable => 1 },
|
||||
"event",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"details",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"creation",
|
||||
{
|
||||
data_type => "timestamp",
|
||||
default_value => \"current_timestamp",
|
||||
is_nullable => 1,
|
||||
original => { default_value => \"now()" },
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:BFrhjYJOhcLIHeWviu9rjw
|
||||
|
||||
|
||||
# You can replace this text with custom code or comments, and it will be preserved on regeneration
|
||||
1;
|
||||
19
Netdisco/lib/App/Netdisco/DB/Result/Virtual/ActiveNode.pm
Normal file
19
Netdisco/lib/App/Netdisco/DB/Result/Virtual/ActiveNode.pm
Normal file
@@ -0,0 +1,19 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::Virtual::ActiveNode;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'App::Netdisco::DB::Result::Node';
|
||||
|
||||
__PACKAGE__->load_components('Helper::Row::SubClass');
|
||||
__PACKAGE__->subclass;
|
||||
|
||||
__PACKAGE__->table_class('DBIx::Class::ResultSource::View');
|
||||
__PACKAGE__->table("active_node");
|
||||
__PACKAGE__->result_source_instance->is_virtual(1);
|
||||
__PACKAGE__->result_source_instance->view_definition(q{
|
||||
SELECT * FROM node WHERE active
|
||||
});
|
||||
|
||||
1;
|
||||
@@ -0,0 +1,27 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::Virtual::ActiveNodeWithAge;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'App::Netdisco::DB::Result::Virtual::ActiveNode';
|
||||
|
||||
__PACKAGE__->load_components('Helper::Row::SubClass');
|
||||
__PACKAGE__->subclass;
|
||||
|
||||
__PACKAGE__->table_class('DBIx::Class::ResultSource::View');
|
||||
__PACKAGE__->table("active_node_with_age");
|
||||
__PACKAGE__->result_source_instance->is_virtual(1);
|
||||
__PACKAGE__->result_source_instance->view_definition(q{
|
||||
SELECT *,
|
||||
replace(age( date_trunc( 'minute', time_last + interval '30 second' ) ) ::text, 'mon', 'month')
|
||||
AS time_last_age
|
||||
FROM node WHERE active
|
||||
});
|
||||
|
||||
__PACKAGE__->add_columns(
|
||||
"time_last_age",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
);
|
||||
|
||||
1;
|
||||
34
Netdisco/lib/App/Netdisco/DB/Result/Virtual/DeviceLinks.pm
Normal file
34
Netdisco/lib/App/Netdisco/DB/Result/Virtual/DeviceLinks.pm
Normal file
@@ -0,0 +1,34 @@
|
||||
package App::Netdisco::DB::Result::Virtual::DeviceLinks;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
|
||||
__PACKAGE__->table_class('DBIx::Class::ResultSource::View');
|
||||
|
||||
__PACKAGE__->table('device_links');
|
||||
__PACKAGE__->result_source_instance->is_virtual(1);
|
||||
__PACKAGE__->result_source_instance->view_definition(<<ENDSQL
|
||||
SELECT dp.ip AS left_ip, di.ip AS right_ip
|
||||
FROM ( SELECT device_port.ip, device_port.remote_ip
|
||||
FROM device_port
|
||||
WHERE device_port.remote_port IS NOT NULL
|
||||
GROUP BY device_port.ip, device_port.remote_ip
|
||||
ORDER BY device_port.ip) dp
|
||||
LEFT JOIN device_ip di ON dp.remote_ip = di.alias
|
||||
WHERE di.ip IS NOT NULL
|
||||
ORDER BY dp.ip
|
||||
ENDSQL
|
||||
);
|
||||
|
||||
__PACKAGE__->add_columns(
|
||||
'left_ip' => {
|
||||
data_type => 'inet',
|
||||
},
|
||||
'right_ip' => {
|
||||
data_type => 'inet',
|
||||
},
|
||||
);
|
||||
|
||||
1;
|
||||
@@ -0,0 +1,19 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::Virtual::DevicePortVlanNative;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'App::Netdisco::DB::Result::DevicePortVlan';
|
||||
|
||||
__PACKAGE__->load_components('Helper::Row::SubClass');
|
||||
__PACKAGE__->subclass;
|
||||
|
||||
__PACKAGE__->table_class('DBIx::Class::ResultSource::View');
|
||||
__PACKAGE__->table("device_port_vlan_native");
|
||||
__PACKAGE__->result_source_instance->is_virtual(1);
|
||||
__PACKAGE__->result_source_instance->view_definition(q{
|
||||
SELECT * FROM device_port_vlan WHERE native
|
||||
});
|
||||
|
||||
1;
|
||||
@@ -0,0 +1,19 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::Virtual::DevicePortVlanTagged;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'App::Netdisco::DB::Result::DevicePortVlan';
|
||||
|
||||
__PACKAGE__->load_components('Helper::Row::SubClass');
|
||||
__PACKAGE__->subclass;
|
||||
|
||||
__PACKAGE__->table_class('DBIx::Class::ResultSource::View');
|
||||
__PACKAGE__->table("device_port_vlan_tagged");
|
||||
__PACKAGE__->result_source_instance->is_virtual(1);
|
||||
__PACKAGE__->result_source_instance->view_definition(q{
|
||||
SELECT * FROM device_port_vlan WHERE NOT native
|
||||
});
|
||||
|
||||
1;
|
||||
27
Netdisco/lib/App/Netdisco/DB/Result/Virtual/NodeWithAge.pm
Normal file
27
Netdisco/lib/App/Netdisco/DB/Result/Virtual/NodeWithAge.pm
Normal file
@@ -0,0 +1,27 @@
|
||||
use utf8;
|
||||
package App::Netdisco::DB::Result::Virtual::NodeWithAge;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'App::Netdisco::DB::Result::Node';
|
||||
|
||||
__PACKAGE__->load_components('Helper::Row::SubClass');
|
||||
__PACKAGE__->subclass;
|
||||
|
||||
__PACKAGE__->table_class('DBIx::Class::ResultSource::View');
|
||||
__PACKAGE__->table("node_with_age");
|
||||
__PACKAGE__->result_source_instance->is_virtual(1);
|
||||
__PACKAGE__->result_source_instance->view_definition(q{
|
||||
SELECT *,
|
||||
replace(age( date_trunc( 'minute', time_last + interval '30 second' ) ) ::text, 'mon', 'month')
|
||||
AS time_last_age
|
||||
FROM node
|
||||
});
|
||||
|
||||
__PACKAGE__->add_columns(
|
||||
"time_last_age",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
);
|
||||
|
||||
1;
|
||||
412
Netdisco/lib/App/Netdisco/DB/ResultSet/Device.pm
Normal file
412
Netdisco/lib/App/Netdisco/DB/ResultSet/Device.pm
Normal file
@@ -0,0 +1,412 @@
|
||||
package App::Netdisco::DB::ResultSet::Device;
|
||||
use base 'DBIx::Class::ResultSet';
|
||||
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
use NetAddr::IP::Lite ':lower';
|
||||
|
||||
=head1 ADDITIONAL METHODS
|
||||
|
||||
=head2 with_times
|
||||
|
||||
This is a modifier for any C<search()> (including the helpers below) which
|
||||
will add the following additional synthesized columns to the result set:
|
||||
|
||||
=over 4
|
||||
|
||||
=item uptime_age
|
||||
|
||||
=item last_discover_stamp
|
||||
|
||||
=item last_macsuck_stamp
|
||||
|
||||
=item last_arpnip_stamp
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
sub with_times {
|
||||
my ($rs, $cond, $attrs) = @_;
|
||||
|
||||
return $rs
|
||||
->search_rs($cond, $attrs)
|
||||
->search({},
|
||||
{
|
||||
'+columns' => {
|
||||
uptime_age => \("replace(age(timestamp 'epoch' + uptime / 100 * interval '1 second', "
|
||||
."timestamp '1970-01-01 00:00:00-00')::text, 'mon', 'month')"),
|
||||
last_discover_stamp => \"to_char(last_discover, 'YYYY-MM-DD HH24:MI')",
|
||||
last_macsuck_stamp => \"to_char(last_macsuck, 'YYYY-MM-DD HH24:MI')",
|
||||
last_arpnip_stamp => \"to_char(last_arpnip, 'YYYY-MM-DD HH24:MI')",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
=head2 search_by_field( \%cond, \%attrs? )
|
||||
|
||||
This variant of the standard C<search()> method returns a ResultSet of Device
|
||||
entries. It is written to support web forms which accept fields that match and
|
||||
locate Devices in the database.
|
||||
|
||||
The hashref parameter should contain fields from the Device table which will
|
||||
be intelligently used in a search query.
|
||||
|
||||
In addition, you can provide the key C<matchall> which, given a True or False
|
||||
value, controls whether fields must all match or whether any can match, to
|
||||
select a row.
|
||||
|
||||
Supported keys:
|
||||
|
||||
=over 4
|
||||
|
||||
=item matchall
|
||||
|
||||
If a True value, fields must all match to return a given row of the Device
|
||||
table, otherwise any field matching will cause the row to be included in
|
||||
results.
|
||||
|
||||
=item name
|
||||
|
||||
Can match the C<name> field as a substring.
|
||||
|
||||
=item location
|
||||
|
||||
Can match the C<location> field as a substring.
|
||||
|
||||
=item description
|
||||
|
||||
Can match the C<description> field as a substring (usually this field contains
|
||||
a description of the vendor operating system).
|
||||
|
||||
=item model
|
||||
|
||||
Will match exactly the C<model> field.
|
||||
|
||||
=item os_ver
|
||||
|
||||
Will match exactly the C<os_ver> field, which is the operating sytem software version.
|
||||
|
||||
=item vendor
|
||||
|
||||
Will match exactly the C<vendor> (manufacturer).
|
||||
|
||||
=item dns
|
||||
|
||||
Can match any of the Device IP address aliases as a substring.
|
||||
|
||||
=item ip
|
||||
|
||||
Can be a string IP or a NetAddr::IP object, either way being treated as an
|
||||
IPv4 or IPv6 prefix within which the device must have one IP address alias.
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
sub search_by_field {
|
||||
my ($rs, $p, $attrs) = @_;
|
||||
|
||||
die "condition parameter to search_by_field must be hashref\n"
|
||||
if ref {} ne ref $p or 0 == scalar keys %$p;
|
||||
|
||||
my $op = $p->{matchall} ? '-and' : '-or';
|
||||
|
||||
# this is a bit of an inelegant trick to catch junk data entry,
|
||||
# whilst avoiding returning *all* entries in the table
|
||||
if (length $p->{ip} and 'NetAddr::IP::Lite' ne ref $p->{ip}) {
|
||||
$p->{ip} = ( NetAddr::IP::Lite->new($p->{ip})
|
||||
|| NetAddr::IP::Lite->new('255.255.255.255') );
|
||||
}
|
||||
|
||||
return $rs
|
||||
->search_rs({}, $attrs)
|
||||
->search({
|
||||
$op => [
|
||||
($p->{name} ? ('me.name' =>
|
||||
{ '-ilike' => "\%$p->{name}\%" }) : ()),
|
||||
($p->{location} ? ('me.location' =>
|
||||
{ '-ilike' => "\%$p->{location}\%" }) : ()),
|
||||
($p->{description} ? ('me.description' =>
|
||||
{ '-ilike' => "\%$p->{description}\%" }) : ()),
|
||||
|
||||
($p->{model} ? ('me.model' =>
|
||||
{ '-in' => $p->{model} }) : ()),
|
||||
($p->{os_ver} ? ('me.os_ver' =>
|
||||
{ '-in' => $p->{os_ver} }) : ()),
|
||||
($p->{vendor} ? ('me.vendor' =>
|
||||
{ '-in' => $p->{vendor} }) : ()),
|
||||
|
||||
($p->{dns} ? (
|
||||
-or => [
|
||||
'me.dns' => { '-ilike' => "\%$p->{dns}\%" },
|
||||
'device_ips.dns' => { '-ilike' => "\%$p->{dns}\%" },
|
||||
]) : ()),
|
||||
|
||||
($p->{ip} ? (
|
||||
-or => [
|
||||
'me.ip' => { '<<=' => $p->{ip}->cidr },
|
||||
'device_ips.alias' => { '<<=' => $p->{ip}->cidr },
|
||||
]) : ()),
|
||||
],
|
||||
},
|
||||
{
|
||||
order_by => [qw/ me.dns me.ip /],
|
||||
(($p->{dns} or $p->{ip}) ? (
|
||||
join => 'device_ips',
|
||||
distinct => 1,
|
||||
) : ()),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
=head2 search_fuzzy( $value )
|
||||
|
||||
This method accepts a single parameter only and returns a ResultSet of rows
|
||||
from the Device table where one field matches the passed parameter.
|
||||
|
||||
The following fields are inspected for a match:
|
||||
|
||||
=over 4
|
||||
|
||||
=item contact
|
||||
|
||||
=item serial
|
||||
|
||||
=item location
|
||||
|
||||
=item name
|
||||
|
||||
=item description
|
||||
|
||||
=item dns
|
||||
|
||||
=item ip (including aliases)
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
sub search_fuzzy {
|
||||
my ($rs, $q) = @_;
|
||||
|
||||
die "missing param to search_fuzzy\n"
|
||||
unless $q;
|
||||
$q = "\%$q\%" if $q !~ m/\%/;
|
||||
|
||||
# basic IP check is a string match
|
||||
my $ip_clause = [
|
||||
'me.ip::text' => { '-ilike' => $q },
|
||||
'device_ips.alias::text' => { '-ilike' => $q },
|
||||
];
|
||||
|
||||
# but also allow prefix search
|
||||
(my $qc = $q) =~ s/\%//g;
|
||||
if (my $ip = NetAddr::IP::Lite->new($qc)) {
|
||||
$ip_clause = [
|
||||
'me.ip' => { '<<=' => $ip->cidr },
|
||||
'device_ips.alias' => { '<<=' => $ip->cidr },
|
||||
];
|
||||
}
|
||||
|
||||
return $rs->search(
|
||||
{
|
||||
-or => [
|
||||
'me.contact' => { '-ilike' => $q },
|
||||
'me.serial' => { '-ilike' => $q },
|
||||
'me.location' => { '-ilike' => $q },
|
||||
'me.name' => { '-ilike' => $q },
|
||||
'me.description' => { '-ilike' => $q },
|
||||
-or => [
|
||||
'me.dns' => { '-ilike' => $q },
|
||||
'device_ips.dns' => { '-ilike' => $q },
|
||||
],
|
||||
-or => $ip_clause,
|
||||
],
|
||||
},
|
||||
{
|
||||
order_by => [qw/ me.dns me.ip /],
|
||||
join => 'device_ips',
|
||||
distinct => 1,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
=head2 carrying_vlan( \%cond, \%attrs? )
|
||||
|
||||
my $set = $rs->carrying_vlan({ vlan => 123 });
|
||||
|
||||
Like C<search()>, this returns a ResultSet of matching rows from the Device
|
||||
table.
|
||||
|
||||
The returned devices each are aware of the given Vlan and have at least one
|
||||
Port configured in the Vlan (either tagged, or not).
|
||||
|
||||
=over 4
|
||||
|
||||
=item *
|
||||
|
||||
The C<cond> parameter must be a hashref containing a key C<vlan> with
|
||||
the value to search for.
|
||||
|
||||
=item *
|
||||
|
||||
Results are ordered by the Device DNS and IP fields.
|
||||
|
||||
=item *
|
||||
|
||||
Related rows from the C<device_vlan> table will be prefetched.
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
sub carrying_vlan {
|
||||
my ($rs, $cond, $attrs) = @_;
|
||||
|
||||
die "vlan number required for carrying_vlan\n"
|
||||
if ref {} ne ref $cond or !exists $cond->{vlan};
|
||||
|
||||
$cond->{'vlans.vlan'} = $cond->{vlan};
|
||||
$cond->{'port_vlans.vlan'} = delete $cond->{vlan};
|
||||
|
||||
return $rs
|
||||
->search_rs($cond,
|
||||
{
|
||||
order_by => [qw/ me.dns me.ip /],
|
||||
columns => [qw/ me.ip me.dns me.model me.os me.vendor /],
|
||||
join => 'port_vlans',
|
||||
prefetch => 'vlans',
|
||||
})
|
||||
->search({}, $attrs);
|
||||
}
|
||||
|
||||
=head2 carrying_vlan_name( \%cond, \%attrs? )
|
||||
|
||||
my $set = $rs->carrying_vlan_name({ name => 'Branch Office' });
|
||||
|
||||
Like C<search()>, this returns a ResultSet of matching rows from the Device
|
||||
table.
|
||||
|
||||
The returned devices each are aware of the named Vlan and have at least one
|
||||
Port configured in the Vlan (either tagged, or not).
|
||||
|
||||
=over 4
|
||||
|
||||
=item *
|
||||
|
||||
The C<cond> parameter must be a hashref containing a key C<name> with
|
||||
the value to search for. The value may optionally include SQL wildcard
|
||||
characters.
|
||||
|
||||
=item *
|
||||
|
||||
Results are ordered by the Device DNS and IP fields.
|
||||
|
||||
=item *
|
||||
|
||||
Related rows from the C<device_vlan> table will be prefetched.
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
sub carrying_vlan_name {
|
||||
my ($rs, $cond, $attrs) = @_;
|
||||
|
||||
die "vlan name required for carrying_vlan_name\n"
|
||||
if ref {} ne ref $cond or !exists $cond->{name};
|
||||
|
||||
$cond->{'vlans.description'} = { '-ilike' => $cond->{name} };
|
||||
|
||||
return $rs
|
||||
->search_rs({}, {
|
||||
order_by => [qw/ me.dns me.ip /],
|
||||
columns => [qw/ me.ip me.dns me.model me.os me.vendor /],
|
||||
prefetch => 'vlans',
|
||||
})
|
||||
->search($cond, $attrs);
|
||||
}
|
||||
|
||||
=head2 get_models
|
||||
|
||||
Returns a sorted list of Device models with the following columns only:
|
||||
|
||||
=over 4
|
||||
|
||||
=item vendor
|
||||
|
||||
=item model
|
||||
|
||||
=item count
|
||||
|
||||
=back
|
||||
|
||||
Where C<count> is the number of instances of that Vendor's Model in the
|
||||
Netdisco database.
|
||||
|
||||
=cut
|
||||
|
||||
sub get_models {
|
||||
my $rs = shift;
|
||||
return $rs->search({}, {
|
||||
select => [ 'vendor', 'model', { count => 'ip' } ],
|
||||
as => [qw/vendor model count/],
|
||||
group_by => [qw/vendor model/],
|
||||
order_by => [{-asc => 'vendor'}, {-desc => 'count'}, {-asc => 'model'}],
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
=head2 get_releases
|
||||
|
||||
Returns a sorted list of Device OS releases with the following columns only:
|
||||
|
||||
=over 4
|
||||
|
||||
=item os
|
||||
|
||||
=item os_ver
|
||||
|
||||
=item count
|
||||
|
||||
=back
|
||||
|
||||
Where C<count> is the number of devices running that OS release in the
|
||||
Netdisco database.
|
||||
|
||||
=cut
|
||||
|
||||
sub get_releases {
|
||||
my $rs = shift;
|
||||
return $rs->search({}, {
|
||||
select => [ 'os', 'os_ver', { count => 'ip' } ],
|
||||
as => [qw/os os_ver count/],
|
||||
group_by => [qw/os os_ver/],
|
||||
order_by => [{-asc => 'os'}, {-desc => 'count'}, {-asc => 'os_ver'}],
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
=head2 get_distinct_col( $column )
|
||||
|
||||
Returns an asciibetical sorted list of the distinct values in the given column
|
||||
of the Device table. This is useful for web forms when you want to provide a
|
||||
drop-down list of possible options.
|
||||
|
||||
=cut
|
||||
|
||||
sub get_distinct_col {
|
||||
my ($rs, $col) = @_;
|
||||
return $rs unless $col;
|
||||
|
||||
return $rs->search({},
|
||||
{
|
||||
columns => [$col],
|
||||
order_by => $col,
|
||||
distinct => 1
|
||||
}
|
||||
)->get_column($col)->all;
|
||||
}
|
||||
|
||||
1;
|
||||
136
Netdisco/lib/App/Netdisco/DB/ResultSet/DevicePort.pm
Normal file
136
Netdisco/lib/App/Netdisco/DB/ResultSet/DevicePort.pm
Normal file
@@ -0,0 +1,136 @@
|
||||
package App::Netdisco::DB::ResultSet::DevicePort;
|
||||
use base 'DBIx::Class::ResultSet';
|
||||
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
|
||||
=head1 ADDITIONAL METHODS
|
||||
|
||||
=head2 with_times
|
||||
|
||||
This is a modifier for any C<search()> (including the helpers below) which
|
||||
will add the following additional synthesized columns to the result set:
|
||||
|
||||
=over 4
|
||||
|
||||
=item lastchange_stamp
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
sub with_times {
|
||||
my ($rs, $cond, $attrs) = @_;
|
||||
|
||||
return $rs
|
||||
->search_rs($cond, $attrs)
|
||||
->search({},
|
||||
{
|
||||
'+columns' => { lastchange_stamp =>
|
||||
\("to_char(device.last_discover - (device.uptime - lastchange) / 100 * interval '1 second', "
|
||||
."'YYYY-MM-DD HH24:MI:SS')") },
|
||||
join => 'device',
|
||||
});
|
||||
}
|
||||
|
||||
=head2 with_free_ports
|
||||
|
||||
This is a modifier for any C<search()> (including the helpers below) which
|
||||
will add the following additional synthesized columns to the result set:
|
||||
|
||||
=over 4
|
||||
|
||||
=item is_free
|
||||
|
||||
=back
|
||||
|
||||
In the C<$cond> hash (the first parameter) pass in the C<age_num> which must
|
||||
be an integer, and the C<age_unit> which must be a string of either C<days>,
|
||||
C<weeks>, C<months> or C<years>.
|
||||
|
||||
=cut
|
||||
|
||||
sub with_is_free {
|
||||
my ($rs, $cond, $attrs) = @_;
|
||||
|
||||
my $interval = (delete $cond->{age_num}) .' '. (delete $cond->{age_unit});
|
||||
|
||||
return $rs
|
||||
->search_rs($cond, $attrs)
|
||||
->search({},
|
||||
{
|
||||
'+columns' => { is_free =>
|
||||
\["up != 'up' and "
|
||||
."age(to_timestamp(extract(epoch from device.last_discover) "
|
||||
."- (device.uptime - lastchange)/100)) "
|
||||
."> ?::interval",
|
||||
[{} => $interval]] },
|
||||
join => 'device',
|
||||
});
|
||||
}
|
||||
|
||||
=head2 only_free_ports
|
||||
|
||||
This is a modifier for any C<search()> (including the helpers below) which
|
||||
will restrict results based on whether the port is considered "free".
|
||||
|
||||
In the C<$cond> hash (the first parameter) pass in the C<age_num> which must
|
||||
be an integer, and the C<age_unit> which must be a string of either C<days>,
|
||||
C<weeks>, C<months> or C<years>.
|
||||
|
||||
=cut
|
||||
|
||||
sub only_free_ports {
|
||||
my ($rs, $cond, $attrs) = @_;
|
||||
|
||||
my $interval = (delete $cond->{age_num}) .' '. (delete $cond->{age_unit});
|
||||
|
||||
return $rs
|
||||
->search_rs($cond, $attrs)
|
||||
->search(
|
||||
{
|
||||
'up' => { '!=' => 'up' },
|
||||
},{
|
||||
where =>
|
||||
\["age(to_timestamp(extract(epoch from device.last_discover) "
|
||||
."- (device.uptime - lastchange)/100)) "
|
||||
."> ?::interval",
|
||||
[{} => $interval]],
|
||||
join => 'device' },
|
||||
);
|
||||
}
|
||||
|
||||
=head2 with_vlan_count
|
||||
|
||||
This is a modifier for any C<search()> (including the helpers below) which
|
||||
will add the following additional synthesized columns to the result set:
|
||||
|
||||
=over 4
|
||||
|
||||
=item tagged_vlans_count
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
sub with_vlan_count {
|
||||
my ($rs, $cond, $attrs) = @_;
|
||||
|
||||
return $rs
|
||||
->search_rs($cond, $attrs)
|
||||
->search({},
|
||||
{
|
||||
'+columns' => { tagged_vlans_count =>
|
||||
$rs->result_source->schema->resultset('Virtual::DevicePortVlanTagged')
|
||||
->search(
|
||||
{
|
||||
'dpvt.ip' => { -ident => 'me.ip' },
|
||||
'dpvt.port' => { -ident => 'me.port' },
|
||||
},
|
||||
{ alias => 'dpvt' }
|
||||
)->count_rs->as_query
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
1;
|
||||
62
Netdisco/lib/App/Netdisco/DB/ResultSet/Node.pm
Normal file
62
Netdisco/lib/App/Netdisco/DB/ResultSet/Node.pm
Normal file
@@ -0,0 +1,62 @@
|
||||
package App::Netdisco::DB::ResultSet::Node;
|
||||
use base 'DBIx::Class::ResultSet';
|
||||
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
|
||||
=head1 search_by_mac( \%cond, \%attrs? )
|
||||
|
||||
my $set = $rs->search_by_mac({mac => '00:11:22:33:44:55', active => 1});
|
||||
|
||||
Like C<search()>, this returns a ResultSet of matching rows from the Node
|
||||
table.
|
||||
|
||||
=over 4
|
||||
|
||||
=item *
|
||||
|
||||
The C<cond> parameter must be a hashref containing a key C<mac> with
|
||||
the value to search for.
|
||||
|
||||
=item *
|
||||
|
||||
Results are ordered by time last seen.
|
||||
|
||||
=item *
|
||||
|
||||
Additional columns C<time_first_stamp> and C<time_last_stamp> provide
|
||||
preformatted timestamps of the C<time_first> and C<time_last> fields.
|
||||
|
||||
=item *
|
||||
|
||||
A JOIN is performed on the Device table and the Device C<dns> column
|
||||
prefetched.
|
||||
|
||||
=back
|
||||
|
||||
To limit results only to active nodes, set C<< {active => 1} >> in C<cond>.
|
||||
|
||||
=cut
|
||||
|
||||
sub search_by_mac {
|
||||
my ($rs, $cond, $attrs) = @_;
|
||||
|
||||
die "mac address required for search_by_mac\n"
|
||||
if ref {} ne ref $cond or !exists $cond->{mac};
|
||||
|
||||
$cond->{'me.mac'} = delete $cond->{mac};
|
||||
|
||||
return $rs
|
||||
->search_rs({}, {
|
||||
order_by => {'-desc' => 'time_last'},
|
||||
'+columns' => [
|
||||
'device.dns',
|
||||
{ time_first_stamp => \"to_char(time_first, 'YYYY-MM-DD HH24:MI')" },
|
||||
{ time_last_stamp => \"to_char(time_last, 'YYYY-MM-DD HH24:MI')" },
|
||||
],
|
||||
join => 'device',
|
||||
})
|
||||
->search($cond, $attrs);
|
||||
}
|
||||
|
||||
1;
|
||||
167
Netdisco/lib/App/Netdisco/DB/ResultSet/NodeIp.pm
Normal file
167
Netdisco/lib/App/Netdisco/DB/ResultSet/NodeIp.pm
Normal file
@@ -0,0 +1,167 @@
|
||||
package App::Netdisco::DB::ResultSet::NodeIp;
|
||||
use base 'DBIx::Class::ResultSet';
|
||||
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
|
||||
my $search_attr = {
|
||||
order_by => {'-desc' => 'time_last'},
|
||||
'+columns' => [
|
||||
'oui.company',
|
||||
{ time_first_stamp => \"to_char(time_first, 'YYYY-MM-DD HH24:MI')" },
|
||||
{ time_last_stamp => \"to_char(time_last, 'YYYY-MM-DD HH24:MI')" },
|
||||
],
|
||||
join => 'oui'
|
||||
};
|
||||
|
||||
=head1 search_by_ip( \%cond, \%attrs? )
|
||||
|
||||
my $set = $rs->search_by_ip({ip => '192.0.2.1', active => 1});
|
||||
|
||||
Like C<search()>, this returns a ResultSet of matching rows from the
|
||||
NodeIp table.
|
||||
|
||||
=over 4
|
||||
|
||||
=item *
|
||||
|
||||
The C<cond> parameter must be a hashref containing a key C<ip> with the value
|
||||
to search for. Value can either be a simple string of IPv4 or IPv6, or a
|
||||
NetAddr::IP object in which case all results within the CIDR/Prefix will be
|
||||
retrieved.
|
||||
|
||||
=item *
|
||||
|
||||
Results are ordered by time last seen.
|
||||
|
||||
=item *
|
||||
|
||||
Additional columns C<time_first_stamp> and C<time_last_stamp> provide
|
||||
preformatted timestamps of the C<time_first> and C<time_last> fields.
|
||||
|
||||
=item *
|
||||
|
||||
A JOIN is performed on the OUI table and the OUI C<company> column prefetched.
|
||||
|
||||
=back
|
||||
|
||||
To limit results only to active IPs, set C<< {active => 1} >> in C<cond>.
|
||||
|
||||
=cut
|
||||
|
||||
sub search_by_ip {
|
||||
my ($rs, $cond, $attrs) = @_;
|
||||
|
||||
die "ip address required for search_by_ip\n"
|
||||
if ref {} ne ref $cond or !exists $cond->{ip};
|
||||
|
||||
# handle either plain text IP or NetAddr::IP (/32 or CIDR)
|
||||
my ($op, $ip) = ('=', delete $cond->{ip});
|
||||
|
||||
if ('NetAddr::IP::Lite' eq ref $ip and $ip->num > 1) {
|
||||
$op = '<<=';
|
||||
$ip = $ip->cidr;
|
||||
}
|
||||
$cond->{ip} = { $op => $ip };
|
||||
|
||||
return $rs
|
||||
->search_rs({}, $search_attr)
|
||||
->search($cond, $attrs);
|
||||
}
|
||||
|
||||
=head1 search_by_name( \%cond, \%attrs? )
|
||||
|
||||
my $set = $rs->search_by_name({dns => 'foo.example.com', active => 1});
|
||||
|
||||
Like C<search()>, this returns a ResultSet of matching rows from the
|
||||
NodeIp table.
|
||||
|
||||
=over 4
|
||||
|
||||
=item *
|
||||
|
||||
The NodeIp table must have a C<dns> column for this search to work. Typically
|
||||
this column is the IP's DNS PTR record, cached at the time of Netdisco Arpnip.
|
||||
|
||||
=item *
|
||||
|
||||
The C<cond> parameter must be a hashref containing a key C<dns> with the value
|
||||
to search for. The value may optionally include SQL wildcard characters.
|
||||
|
||||
=item *
|
||||
|
||||
Results are ordered by time last seen.
|
||||
|
||||
=item *
|
||||
|
||||
Additional columns C<time_first_stamp> and C<time_last_stamp> provide
|
||||
preformatted timestamps of the C<time_first> and C<time_last> fields.
|
||||
|
||||
=item *
|
||||
|
||||
A JOIN is performed on the OUI table and the OUI C<company> column prefetched.
|
||||
|
||||
=back
|
||||
|
||||
To limit results only to active IPs, set C<< {active => 1} >> in C<cond>.
|
||||
|
||||
=cut
|
||||
|
||||
sub search_by_dns {
|
||||
my ($rs, $cond, $attrs) = @_;
|
||||
|
||||
die "dns field required for search_by_dns\n"
|
||||
if ref {} ne ref $cond or !exists $cond->{dns};
|
||||
|
||||
$cond->{dns} = { '-ilike' => delete $cond->{dns} };
|
||||
|
||||
return $rs
|
||||
->search_rs({}, $search_attr)
|
||||
->search($cond, $attrs);
|
||||
}
|
||||
|
||||
=head1 search_by_mac( \%cond, \%attrs? )
|
||||
|
||||
my $set = $rs->search_by_mac({mac => '00:11:22:33:44:55', active => 1});
|
||||
|
||||
Like C<search()>, this returns a ResultSet of matching rows from the
|
||||
NodeIp table.
|
||||
|
||||
=over 4
|
||||
|
||||
=item *
|
||||
|
||||
The C<cond> parameter must be a hashref containing a key C<mac> with the value
|
||||
to search for.
|
||||
|
||||
=item *
|
||||
|
||||
Results are ordered by time last seen.
|
||||
|
||||
=item *
|
||||
|
||||
Additional columns C<time_first_stamp> and C<time_last_stamp> provide
|
||||
preformatted timestamps of the C<time_first> and C<time_last> fields.
|
||||
|
||||
=item *
|
||||
|
||||
A JOIN is performed on the OUI table and the OUI C<company> column prefetched.
|
||||
|
||||
=back
|
||||
|
||||
To limit results only to active IPs, set C<< {active => 1} >> in C<cond>.
|
||||
|
||||
=cut
|
||||
|
||||
sub search_by_mac {
|
||||
my ($rs, $cond, $attrs) = @_;
|
||||
|
||||
die "mac address required for search_by_mac\n"
|
||||
if ref {} ne ref $cond or !exists $cond->{mac};
|
||||
|
||||
return $rs
|
||||
->search_rs({}, $search_attr)
|
||||
->search($cond, $attrs);
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -0,0 +1,425 @@
|
||||
--
|
||||
-- Created by SQL::Translator::Producer::PostgreSQL
|
||||
-- Created on Wed Oct 10 14:24:20 2012
|
||||
--
|
||||
--
|
||||
-- Table: admin.
|
||||
--
|
||||
CREATE TABLE "admin" (
|
||||
"job" serial NOT NULL,
|
||||
"entered" timestamp DEFAULT current_timestamp,
|
||||
"started" timestamp,
|
||||
"finished" timestamp,
|
||||
"device" inet,
|
||||
"port" text,
|
||||
"action" text,
|
||||
"subaction" text,
|
||||
"status" text,
|
||||
"username" text,
|
||||
"userip" inet,
|
||||
"log" text,
|
||||
"debug" boolean
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device.
|
||||
--
|
||||
CREATE TABLE "device" (
|
||||
"ip" inet NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"dns" text,
|
||||
"description" text,
|
||||
"uptime" bigint,
|
||||
"contact" text,
|
||||
"name" text,
|
||||
"location" text,
|
||||
"layers" character varying(8),
|
||||
"ports" integer,
|
||||
"mac" macaddr,
|
||||
"serial" text,
|
||||
"model" text,
|
||||
"ps1_type" text,
|
||||
"ps2_type" text,
|
||||
"ps1_status" text,
|
||||
"ps2_status" text,
|
||||
"fan" text,
|
||||
"slots" integer,
|
||||
"vendor" text,
|
||||
"os" text,
|
||||
"os_ver" text,
|
||||
"log" text,
|
||||
"snmp_ver" integer,
|
||||
"snmp_comm" text,
|
||||
"snmp_class" text,
|
||||
"vtp_domain" text,
|
||||
"last_discover" timestamp,
|
||||
"last_macsuck" timestamp,
|
||||
"last_arpnip" timestamp,
|
||||
PRIMARY KEY ("ip")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_module.
|
||||
--
|
||||
CREATE TABLE "device_module" (
|
||||
"ip" inet NOT NULL,
|
||||
"index" integer NOT NULL,
|
||||
"description" text,
|
||||
"type" text,
|
||||
"parent" integer,
|
||||
"name" text,
|
||||
"class" text,
|
||||
"pos" integer,
|
||||
"hw_ver" text,
|
||||
"fw_ver" text,
|
||||
"sw_ver" text,
|
||||
"serial" text,
|
||||
"model" text,
|
||||
"fru" boolean,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"last_discover" timestamp,
|
||||
PRIMARY KEY ("ip", "index")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_port_log.
|
||||
--
|
||||
CREATE TABLE "device_port_log" (
|
||||
"id" serial NOT NULL,
|
||||
"ip" inet,
|
||||
"port" text,
|
||||
"reason" text,
|
||||
"log" text,
|
||||
"username" text,
|
||||
"userip" inet,
|
||||
"action" text,
|
||||
"creation" timestamp DEFAULT current_timestamp
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_port_power.
|
||||
--
|
||||
CREATE TABLE "device_port_power" (
|
||||
"ip" inet NOT NULL,
|
||||
"port" text NOT NULL,
|
||||
"module" integer,
|
||||
"admin" text,
|
||||
"status" text,
|
||||
"class" text,
|
||||
"power" integer,
|
||||
PRIMARY KEY ("port", "ip")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_port_ssid.
|
||||
--
|
||||
CREATE TABLE "device_port_ssid" (
|
||||
"ip" inet,
|
||||
"port" text,
|
||||
"ssid" text,
|
||||
"broadcast" boolean
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_port_wireless.
|
||||
--
|
||||
CREATE TABLE "device_port_wireless" (
|
||||
"ip" inet,
|
||||
"port" text,
|
||||
"channel" integer,
|
||||
"power" integer
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_power.
|
||||
--
|
||||
CREATE TABLE "device_power" (
|
||||
"ip" inet NOT NULL,
|
||||
"module" integer NOT NULL,
|
||||
"power" integer,
|
||||
"status" text,
|
||||
PRIMARY KEY ("ip", "module")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_route.
|
||||
--
|
||||
CREATE TABLE "device_route" (
|
||||
"ip" inet NOT NULL,
|
||||
"network" cidr NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"dest" inet NOT NULL,
|
||||
"last_discover" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("ip", "network", "dest")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: log.
|
||||
--
|
||||
CREATE TABLE "log" (
|
||||
"id" serial NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"class" text,
|
||||
"entry" text,
|
||||
"logfile" text
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: node_ip.
|
||||
--
|
||||
CREATE TABLE "node_ip" (
|
||||
"mac" macaddr NOT NULL,
|
||||
"ip" inet NOT NULL,
|
||||
"active" boolean,
|
||||
"time_first" timestamp DEFAULT current_timestamp,
|
||||
"time_last" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("mac", "ip")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: node_monitor.
|
||||
--
|
||||
CREATE TABLE "node_monitor" (
|
||||
"mac" macaddr NOT NULL,
|
||||
"active" boolean,
|
||||
"why" text,
|
||||
"cc" text,
|
||||
"date" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("mac")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: node_nbt.
|
||||
--
|
||||
CREATE TABLE "node_nbt" (
|
||||
"mac" macaddr NOT NULL,
|
||||
"ip" inet,
|
||||
"nbname" text,
|
||||
"domain" text,
|
||||
"server" boolean,
|
||||
"nbuser" text,
|
||||
"active" boolean,
|
||||
"time_first" timestamp DEFAULT current_timestamp,
|
||||
"time_last" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("mac")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: node_wireless.
|
||||
--
|
||||
CREATE TABLE "node_wireless" (
|
||||
"mac" macaddr NOT NULL,
|
||||
"uptime" integer,
|
||||
"maxrate" integer,
|
||||
"txrate" integer,
|
||||
"sigstrength" integer,
|
||||
"sigqual" integer,
|
||||
"rxpkt" integer,
|
||||
"txpkt" integer,
|
||||
"rxbyte" bigint,
|
||||
"txbyte" bigint,
|
||||
"time_last" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("mac")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: oui.
|
||||
--
|
||||
CREATE TABLE "oui" (
|
||||
"oui" character varying(8) NOT NULL,
|
||||
"company" text,
|
||||
PRIMARY KEY ("oui")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: process.
|
||||
--
|
||||
CREATE TABLE "process" (
|
||||
"controller" integer NOT NULL,
|
||||
"device" inet NOT NULL,
|
||||
"action" text NOT NULL,
|
||||
"status" text,
|
||||
"count" integer,
|
||||
"creation" timestamp DEFAULT current_timestamp
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: sessions.
|
||||
--
|
||||
CREATE TABLE "sessions" (
|
||||
"id" character(32) NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"a_session" text,
|
||||
PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: subnets.
|
||||
--
|
||||
CREATE TABLE "subnets" (
|
||||
"net" cidr NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"last_discover" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("net")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: user_log.
|
||||
--
|
||||
CREATE TABLE "user_log" (
|
||||
"entry" serial NOT NULL,
|
||||
"username" character varying(50),
|
||||
"userip" inet,
|
||||
"event" text,
|
||||
"details" text,
|
||||
"creation" timestamp DEFAULT current_timestamp
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: users.
|
||||
--
|
||||
CREATE TABLE "users" (
|
||||
"username" character varying(50) NOT NULL,
|
||||
"password" text,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"last_on" timestamp,
|
||||
"port_control" boolean DEFAULT false,
|
||||
"ldap" boolean DEFAULT false,
|
||||
"admin" boolean DEFAULT false,
|
||||
"fullname" text,
|
||||
"note" text,
|
||||
PRIMARY KEY ("username")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_vlan.
|
||||
--
|
||||
CREATE TABLE "device_vlan" (
|
||||
"ip" inet NOT NULL,
|
||||
"vlan" integer NOT NULL,
|
||||
"description" text,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"last_discover" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("ip", "vlan")
|
||||
);
|
||||
CREATE INDEX "device_vlan_idx_ip" on "device_vlan" ("ip");
|
||||
|
||||
--
|
||||
-- Table: device_ip.
|
||||
--
|
||||
CREATE TABLE "device_ip" (
|
||||
"ip" inet NOT NULL,
|
||||
"alias" inet NOT NULL,
|
||||
"subnet" cidr,
|
||||
"port" text,
|
||||
"dns" text,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("ip", "alias"),
|
||||
CONSTRAINT "device_ip_alias" UNIQUE ("alias")
|
||||
);
|
||||
CREATE INDEX "device_ip_idx_ip" on "device_ip" ("ip");
|
||||
CREATE INDEX "device_ip_idx_ip_port" on "device_ip" ("ip", "port");
|
||||
|
||||
--
|
||||
-- Table: device_port.
|
||||
--
|
||||
CREATE TABLE "device_port" (
|
||||
"ip" inet NOT NULL,
|
||||
"port" text NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"descr" text,
|
||||
"up" text,
|
||||
"up_admin" text,
|
||||
"type" text,
|
||||
"duplex" text,
|
||||
"duplex_admin" text,
|
||||
"speed" text,
|
||||
"name" text,
|
||||
"mac" macaddr,
|
||||
"mtu" integer,
|
||||
"stp" text,
|
||||
"remote_ip" inet,
|
||||
"remote_port" text,
|
||||
"remote_type" text,
|
||||
"remote_id" text,
|
||||
"vlan" text,
|
||||
"pvid" integer,
|
||||
"lastchange" bigint,
|
||||
PRIMARY KEY ("port", "ip")
|
||||
);
|
||||
CREATE INDEX "device_port_idx_ip" on "device_port" ("ip");
|
||||
CREATE INDEX "device_port_idx_remote_ip" on "device_port" ("remote_ip");
|
||||
|
||||
--
|
||||
-- Table: device_port_vlan.
|
||||
--
|
||||
CREATE TABLE "device_port_vlan" (
|
||||
"ip" inet NOT NULL,
|
||||
"port" text NOT NULL,
|
||||
"vlan" integer NOT NULL,
|
||||
"native" boolean DEFAULT false NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"last_discover" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("ip", "port", "vlan")
|
||||
);
|
||||
CREATE INDEX "device_port_vlan_idx_ip" on "device_port_vlan" ("ip");
|
||||
CREATE INDEX "device_port_vlan_idx_ip_port" on "device_port_vlan" ("ip", "port");
|
||||
CREATE INDEX "device_port_vlan_idx_ip_vlan" on "device_port_vlan" ("ip", "vlan");
|
||||
|
||||
--
|
||||
-- Table: node.
|
||||
--
|
||||
CREATE TABLE "node" (
|
||||
"mac" macaddr NOT NULL,
|
||||
"switch" inet NOT NULL,
|
||||
"port" text NOT NULL,
|
||||
"active" boolean,
|
||||
"oui" character varying(8),
|
||||
"time_first" timestamp DEFAULT current_timestamp,
|
||||
"time_recent" timestamp DEFAULT current_timestamp,
|
||||
"time_last" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("mac", "switch", "port")
|
||||
);
|
||||
CREATE INDEX "node_idx_switch" on "node" ("switch");
|
||||
CREATE INDEX "node_idx_switch_port" on "node" ("switch", "port");
|
||||
CREATE INDEX "node_idx_oui" on "node" ("oui");
|
||||
|
||||
-- Not used in Netdisco, because they upset the legacy netdisco.pm code
|
||||
--
|
||||
-- --
|
||||
-- -- Foreign Key Definitions
|
||||
-- --
|
||||
--
|
||||
-- ALTER TABLE "device_vlan" ADD CONSTRAINT "device_vlan_fk_ip" FOREIGN KEY ("ip")
|
||||
-- REFERENCES "device" ("ip") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_ip" ADD CONSTRAINT "device_ip_fk_ip" FOREIGN KEY ("ip")
|
||||
-- REFERENCES "device" ("ip") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_ip" ADD CONSTRAINT "device_ip_fk_ip_port" FOREIGN KEY ("ip", "port")
|
||||
-- REFERENCES "device_port" ("ip", "port") DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_port" ADD CONSTRAINT "device_port_fk_ip" FOREIGN KEY ("ip")
|
||||
-- REFERENCES "device" ("ip") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_port" ADD CONSTRAINT "device_port_fk_remote_ip" FOREIGN KEY ("remote_ip")
|
||||
-- REFERENCES "device_ip" ("alias") DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_port_vlan" ADD CONSTRAINT "device_port_vlan_fk_ip" FOREIGN KEY ("ip")
|
||||
-- REFERENCES "device" ("ip") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_port_vlan" ADD CONSTRAINT "device_port_vlan_fk_ip_port" FOREIGN KEY ("ip", "port")
|
||||
-- REFERENCES "device_port" ("ip", "port") DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_port_vlan" ADD CONSTRAINT "device_port_vlan_fk_ip_vlan" FOREIGN KEY ("ip", "vlan")
|
||||
-- REFERENCES "device_vlan" ("ip", "vlan") DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "node" ADD CONSTRAINT "node_fk_switch" FOREIGN KEY ("switch")
|
||||
-- REFERENCES "device" ("ip") DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "node" ADD CONSTRAINT "node_fk_switch_port" FOREIGN KEY ("switch", "port")
|
||||
-- REFERENCES "device_port" ("ip", "port") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "node" ADD CONSTRAINT "node_fk_oui" FOREIGN KEY ("oui")
|
||||
-- REFERENCES "oui" ("oui") DEFERRABLE;
|
||||
--
|
||||
@@ -0,0 +1,438 @@
|
||||
--
|
||||
-- Created by SQL::Translator::Producer::PostgreSQL
|
||||
-- Created on Wed Oct 10 15:38:36 2012
|
||||
--
|
||||
--
|
||||
-- Table: admin.
|
||||
--
|
||||
CREATE TABLE "admin" (
|
||||
"job" serial NOT NULL,
|
||||
"entered" timestamp DEFAULT current_timestamp,
|
||||
"started" timestamp,
|
||||
"finished" timestamp,
|
||||
"device" inet,
|
||||
"port" text,
|
||||
"action" text,
|
||||
"subaction" text,
|
||||
"status" text,
|
||||
"username" text,
|
||||
"userip" inet,
|
||||
"log" text,
|
||||
"debug" boolean
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device.
|
||||
--
|
||||
CREATE TABLE "device" (
|
||||
"ip" inet NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"dns" text,
|
||||
"description" text,
|
||||
"uptime" bigint,
|
||||
"contact" text,
|
||||
"name" text,
|
||||
"location" text,
|
||||
"layers" character varying(8),
|
||||
"ports" integer,
|
||||
"mac" macaddr,
|
||||
"serial" text,
|
||||
"model" text,
|
||||
"ps1_type" text,
|
||||
"ps2_type" text,
|
||||
"ps1_status" text,
|
||||
"ps2_status" text,
|
||||
"fan" text,
|
||||
"slots" integer,
|
||||
"vendor" text,
|
||||
"os" text,
|
||||
"os_ver" text,
|
||||
"log" text,
|
||||
"snmp_ver" integer,
|
||||
"snmp_comm" text,
|
||||
"snmp_class" text,
|
||||
"vtp_domain" text,
|
||||
"last_discover" timestamp,
|
||||
"last_macsuck" timestamp,
|
||||
"last_arpnip" timestamp,
|
||||
PRIMARY KEY ("ip")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_module.
|
||||
--
|
||||
CREATE TABLE "device_module" (
|
||||
"ip" inet NOT NULL,
|
||||
"index" integer NOT NULL,
|
||||
"description" text,
|
||||
"type" text,
|
||||
"parent" integer,
|
||||
"name" text,
|
||||
"class" text,
|
||||
"pos" integer,
|
||||
"hw_ver" text,
|
||||
"fw_ver" text,
|
||||
"sw_ver" text,
|
||||
"serial" text,
|
||||
"model" text,
|
||||
"fru" boolean,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"last_discover" timestamp,
|
||||
PRIMARY KEY ("ip", "index")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_port_log.
|
||||
--
|
||||
CREATE TABLE "device_port_log" (
|
||||
"id" serial NOT NULL,
|
||||
"ip" inet,
|
||||
"port" text,
|
||||
"reason" text,
|
||||
"log" text,
|
||||
"username" text,
|
||||
"userip" inet,
|
||||
"action" text,
|
||||
"creation" timestamp DEFAULT current_timestamp
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_port_power.
|
||||
--
|
||||
CREATE TABLE "device_port_power" (
|
||||
"ip" inet NOT NULL,
|
||||
"port" text NOT NULL,
|
||||
"module" integer,
|
||||
"admin" text,
|
||||
"status" text,
|
||||
"class" text,
|
||||
"power" integer,
|
||||
PRIMARY KEY ("port", "ip")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_port_ssid.
|
||||
--
|
||||
CREATE TABLE "device_port_ssid" (
|
||||
"ip" inet,
|
||||
"port" text,
|
||||
"ssid" text,
|
||||
"broadcast" boolean,
|
||||
"bssid" macaddr
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_port_wireless.
|
||||
--
|
||||
CREATE TABLE "device_port_wireless" (
|
||||
"ip" inet,
|
||||
"port" text,
|
||||
"channel" integer,
|
||||
"power" integer
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_power.
|
||||
--
|
||||
CREATE TABLE "device_power" (
|
||||
"ip" inet NOT NULL,
|
||||
"module" integer NOT NULL,
|
||||
"power" integer,
|
||||
"status" text,
|
||||
PRIMARY KEY ("ip", "module")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_route.
|
||||
--
|
||||
CREATE TABLE "device_route" (
|
||||
"ip" inet NOT NULL,
|
||||
"network" cidr NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"dest" inet NOT NULL,
|
||||
"last_discover" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("ip", "network", "dest")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: log.
|
||||
--
|
||||
CREATE TABLE "log" (
|
||||
"id" serial NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"class" text,
|
||||
"entry" text,
|
||||
"logfile" text
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: node_ip.
|
||||
--
|
||||
CREATE TABLE "node_ip" (
|
||||
"mac" macaddr NOT NULL,
|
||||
"ip" inet NOT NULL,
|
||||
"active" boolean,
|
||||
"time_first" timestamp DEFAULT current_timestamp,
|
||||
"time_last" timestamp DEFAULT current_timestamp,
|
||||
"dns" text,
|
||||
PRIMARY KEY ("mac", "ip")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: node_monitor.
|
||||
--
|
||||
CREATE TABLE "node_monitor" (
|
||||
"mac" macaddr NOT NULL,
|
||||
"active" boolean,
|
||||
"why" text,
|
||||
"cc" text,
|
||||
"date" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("mac")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: node_nbt.
|
||||
--
|
||||
CREATE TABLE "node_nbt" (
|
||||
"mac" macaddr NOT NULL,
|
||||
"ip" inet,
|
||||
"nbname" text,
|
||||
"domain" text,
|
||||
"server" boolean,
|
||||
"nbuser" text,
|
||||
"active" boolean,
|
||||
"time_first" timestamp DEFAULT current_timestamp,
|
||||
"time_last" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("mac")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: node_wireless.
|
||||
--
|
||||
CREATE TABLE "node_wireless" (
|
||||
"mac" macaddr NOT NULL,
|
||||
"uptime" integer,
|
||||
"maxrate" integer,
|
||||
"txrate" integer,
|
||||
"sigstrength" integer,
|
||||
"sigqual" integer,
|
||||
"rxpkt" integer,
|
||||
"txpkt" integer,
|
||||
"rxbyte" bigint,
|
||||
"txbyte" bigint,
|
||||
"time_last" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("mac")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: oui.
|
||||
--
|
||||
CREATE TABLE "oui" (
|
||||
"oui" character varying(8) NOT NULL,
|
||||
"company" text,
|
||||
PRIMARY KEY ("oui")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: process.
|
||||
--
|
||||
CREATE TABLE "process" (
|
||||
"controller" integer NOT NULL,
|
||||
"device" inet NOT NULL,
|
||||
"action" text NOT NULL,
|
||||
"status" text,
|
||||
"count" integer,
|
||||
"creation" timestamp DEFAULT current_timestamp
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: sessions.
|
||||
--
|
||||
CREATE TABLE "sessions" (
|
||||
"id" character(32) NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"a_session" text,
|
||||
PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: subnets.
|
||||
--
|
||||
CREATE TABLE "subnets" (
|
||||
"net" cidr NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"last_discover" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("net")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: topology.
|
||||
--
|
||||
CREATE TABLE "topology" (
|
||||
"dev1" inet NOT NULL,
|
||||
"port1" text NOT NULL,
|
||||
"dev2" inet NOT NULL,
|
||||
"port2" text NOT NULL
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: user_log.
|
||||
--
|
||||
CREATE TABLE "user_log" (
|
||||
"entry" serial NOT NULL,
|
||||
"username" character varying(50),
|
||||
"userip" inet,
|
||||
"event" text,
|
||||
"details" text,
|
||||
"creation" timestamp DEFAULT current_timestamp
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: users.
|
||||
--
|
||||
CREATE TABLE "users" (
|
||||
"username" character varying(50) NOT NULL,
|
||||
"password" text,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"last_on" timestamp,
|
||||
"port_control" boolean DEFAULT false,
|
||||
"ldap" boolean DEFAULT false,
|
||||
"admin" boolean DEFAULT false,
|
||||
"fullname" text,
|
||||
"note" text,
|
||||
PRIMARY KEY ("username")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_vlan.
|
||||
--
|
||||
CREATE TABLE "device_vlan" (
|
||||
"ip" inet NOT NULL,
|
||||
"vlan" integer NOT NULL,
|
||||
"description" text,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"last_discover" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("ip", "vlan")
|
||||
);
|
||||
CREATE INDEX "device_vlan_idx_ip" on "device_vlan" ("ip");
|
||||
|
||||
--
|
||||
-- Table: device_ip.
|
||||
--
|
||||
CREATE TABLE "device_ip" (
|
||||
"ip" inet NOT NULL,
|
||||
"alias" inet NOT NULL,
|
||||
"subnet" cidr,
|
||||
"port" text,
|
||||
"dns" text,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("ip", "alias"),
|
||||
CONSTRAINT "device_ip_alias" UNIQUE ("alias")
|
||||
);
|
||||
CREATE INDEX "device_ip_idx_ip" on "device_ip" ("ip");
|
||||
CREATE INDEX "device_ip_idx_ip_port" on "device_ip" ("ip", "port");
|
||||
|
||||
--
|
||||
-- Table: device_port.
|
||||
--
|
||||
CREATE TABLE "device_port" (
|
||||
"ip" inet NOT NULL,
|
||||
"port" text NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"descr" text,
|
||||
"up" text,
|
||||
"up_admin" text,
|
||||
"type" text,
|
||||
"duplex" text,
|
||||
"duplex_admin" text,
|
||||
"speed" text,
|
||||
"name" text,
|
||||
"mac" macaddr,
|
||||
"mtu" integer,
|
||||
"stp" text,
|
||||
"remote_ip" inet,
|
||||
"remote_port" text,
|
||||
"remote_type" text,
|
||||
"remote_id" text,
|
||||
"vlan" text,
|
||||
"pvid" integer,
|
||||
"lastchange" bigint,
|
||||
PRIMARY KEY ("port", "ip")
|
||||
);
|
||||
CREATE INDEX "device_port_idx_ip" on "device_port" ("ip");
|
||||
CREATE INDEX "device_port_idx_remote_ip" on "device_port" ("remote_ip");
|
||||
|
||||
--
|
||||
-- Table: device_port_vlan.
|
||||
--
|
||||
CREATE TABLE "device_port_vlan" (
|
||||
"ip" inet NOT NULL,
|
||||
"port" text NOT NULL,
|
||||
"vlan" integer NOT NULL,
|
||||
"native" boolean DEFAULT false NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"last_discover" timestamp DEFAULT current_timestamp,
|
||||
"vlantype" text,
|
||||
PRIMARY KEY ("ip", "port", "vlan")
|
||||
);
|
||||
CREATE INDEX "device_port_vlan_idx_ip" on "device_port_vlan" ("ip");
|
||||
CREATE INDEX "device_port_vlan_idx_ip_port" on "device_port_vlan" ("ip", "port");
|
||||
CREATE INDEX "device_port_vlan_idx_ip_vlan" on "device_port_vlan" ("ip", "vlan");
|
||||
|
||||
--
|
||||
-- Table: node.
|
||||
--
|
||||
CREATE TABLE "node" (
|
||||
"mac" macaddr NOT NULL,
|
||||
"switch" inet NOT NULL,
|
||||
"port" text NOT NULL,
|
||||
"active" boolean,
|
||||
"oui" character varying(8),
|
||||
"time_first" timestamp DEFAULT current_timestamp,
|
||||
"time_recent" timestamp DEFAULT current_timestamp,
|
||||
"time_last" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("mac", "switch", "port")
|
||||
);
|
||||
CREATE INDEX "node_idx_switch" on "node" ("switch");
|
||||
CREATE INDEX "node_idx_switch_port" on "node" ("switch", "port");
|
||||
CREATE INDEX "node_idx_oui" on "node" ("oui");
|
||||
|
||||
-- Not used in Netdisco, because they upset the legacy netdisco.pm code
|
||||
--
|
||||
-- --
|
||||
-- -- Foreign Key Definitions
|
||||
-- --
|
||||
--
|
||||
-- ALTER TABLE "device_vlan" ADD CONSTRAINT "device_vlan_fk_ip" FOREIGN KEY ("ip")
|
||||
-- REFERENCES "device" ("ip") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_ip" ADD CONSTRAINT "device_ip_fk_ip" FOREIGN KEY ("ip")
|
||||
-- REFERENCES "device" ("ip") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_ip" ADD CONSTRAINT "device_ip_fk_ip_port" FOREIGN KEY ("ip", "port")
|
||||
-- REFERENCES "device_port" ("ip", "port") DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_port" ADD CONSTRAINT "device_port_fk_ip" FOREIGN KEY ("ip")
|
||||
-- REFERENCES "device" ("ip") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_port" ADD CONSTRAINT "device_port_fk_remote_ip" FOREIGN KEY ("remote_ip")
|
||||
-- REFERENCES "device_ip" ("alias") DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_port_vlan" ADD CONSTRAINT "device_port_vlan_fk_ip" FOREIGN KEY ("ip")
|
||||
-- REFERENCES "device" ("ip") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_port_vlan" ADD CONSTRAINT "device_port_vlan_fk_ip_port" FOREIGN KEY ("ip", "port")
|
||||
-- REFERENCES "device_port" ("ip", "port") DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_port_vlan" ADD CONSTRAINT "device_port_vlan_fk_ip_vlan" FOREIGN KEY ("ip", "vlan")
|
||||
-- REFERENCES "device_vlan" ("ip", "vlan") DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "node" ADD CONSTRAINT "node_fk_switch" FOREIGN KEY ("switch")
|
||||
-- REFERENCES "device" ("ip") DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "node" ADD CONSTRAINT "node_fk_switch_port" FOREIGN KEY ("switch", "port")
|
||||
-- REFERENCES "device_port" ("ip", "port") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "node" ADD CONSTRAINT "node_fk_oui" FOREIGN KEY ("oui")
|
||||
-- REFERENCES "oui" ("oui") DEFERRABLE;
|
||||
--
|
||||
@@ -0,0 +1,3 @@
|
||||
--
|
||||
-- Created by SQL::Translator::Producer::PostgreSQL
|
||||
-- Created on Wed Oct 10 14:24:20 2012
|
||||
@@ -0,0 +1,19 @@
|
||||
-- Convert schema '/home/sy0/git/netdisco-frontend-sandpit/Netdisco/lib/Netdisco/DB/schema_versions/Netdisco-DB-1-PostgreSQL.sql' to '/home/sy0/git/netdisco-frontend-sandpit/Netdisco/lib/Netdisco/DB/schema_versions/Netdisco-DB-2-PostgreSQL.sql':;
|
||||
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE "topology" (
|
||||
"dev1" inet NOT NULL,
|
||||
"port1" text NOT NULL,
|
||||
"dev2" inet NOT NULL,
|
||||
"port2" text NOT NULL
|
||||
);
|
||||
|
||||
ALTER TABLE device_port_ssid ADD COLUMN bssid macaddr;
|
||||
|
||||
ALTER TABLE device_port_vlan ADD COLUMN vlantype text;
|
||||
|
||||
ALTER TABLE node_ip ADD COLUMN dns text;
|
||||
|
||||
COMMIT;
|
||||
|
||||
@@ -0,0 +1,450 @@
|
||||
--
|
||||
-- Created by SQL::Translator::Producer::PostgreSQL
|
||||
-- Created on Wed Oct 10 14:24:20 2012
|
||||
--
|
||||
--
|
||||
-- Table: admin.
|
||||
--
|
||||
DROP TABLE "admin" CASCADE;
|
||||
CREATE TABLE "admin" (
|
||||
"job" serial NOT NULL,
|
||||
"entered" timestamp DEFAULT current_timestamp,
|
||||
"started" timestamp,
|
||||
"finished" timestamp,
|
||||
"device" inet,
|
||||
"port" text,
|
||||
"action" text,
|
||||
"subaction" text,
|
||||
"status" text,
|
||||
"username" text,
|
||||
"userip" inet,
|
||||
"log" text,
|
||||
"debug" boolean
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device.
|
||||
--
|
||||
DROP TABLE "device" CASCADE;
|
||||
CREATE TABLE "device" (
|
||||
"ip" inet NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"dns" text,
|
||||
"description" text,
|
||||
"uptime" bigint,
|
||||
"contact" text,
|
||||
"name" text,
|
||||
"location" text,
|
||||
"layers" character varying(8),
|
||||
"ports" integer,
|
||||
"mac" macaddr,
|
||||
"serial" text,
|
||||
"model" text,
|
||||
"ps1_type" text,
|
||||
"ps2_type" text,
|
||||
"ps1_status" text,
|
||||
"ps2_status" text,
|
||||
"fan" text,
|
||||
"slots" integer,
|
||||
"vendor" text,
|
||||
"os" text,
|
||||
"os_ver" text,
|
||||
"log" text,
|
||||
"snmp_ver" integer,
|
||||
"snmp_comm" text,
|
||||
"snmp_class" text,
|
||||
"vtp_domain" text,
|
||||
"last_discover" timestamp,
|
||||
"last_macsuck" timestamp,
|
||||
"last_arpnip" timestamp,
|
||||
PRIMARY KEY ("ip")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_module.
|
||||
--
|
||||
DROP TABLE "device_module" CASCADE;
|
||||
CREATE TABLE "device_module" (
|
||||
"ip" inet NOT NULL,
|
||||
"index" integer NOT NULL,
|
||||
"description" text,
|
||||
"type" text,
|
||||
"parent" integer,
|
||||
"name" text,
|
||||
"class" text,
|
||||
"pos" integer,
|
||||
"hw_ver" text,
|
||||
"fw_ver" text,
|
||||
"sw_ver" text,
|
||||
"serial" text,
|
||||
"model" text,
|
||||
"fru" boolean,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"last_discover" timestamp,
|
||||
PRIMARY KEY ("ip", "index")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_port_log.
|
||||
--
|
||||
DROP TABLE "device_port_log" CASCADE;
|
||||
CREATE TABLE "device_port_log" (
|
||||
"id" serial NOT NULL,
|
||||
"ip" inet,
|
||||
"port" text,
|
||||
"reason" text,
|
||||
"log" text,
|
||||
"username" text,
|
||||
"userip" inet,
|
||||
"action" text,
|
||||
"creation" timestamp DEFAULT current_timestamp
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_port_power.
|
||||
--
|
||||
DROP TABLE "device_port_power" CASCADE;
|
||||
CREATE TABLE "device_port_power" (
|
||||
"ip" inet NOT NULL,
|
||||
"port" text NOT NULL,
|
||||
"module" integer,
|
||||
"admin" text,
|
||||
"status" text,
|
||||
"class" text,
|
||||
"power" integer,
|
||||
PRIMARY KEY ("port", "ip")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_port_ssid.
|
||||
--
|
||||
DROP TABLE "device_port_ssid" CASCADE;
|
||||
CREATE TABLE "device_port_ssid" (
|
||||
"ip" inet,
|
||||
"port" text,
|
||||
"ssid" text,
|
||||
"broadcast" boolean
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_port_wireless.
|
||||
--
|
||||
DROP TABLE "device_port_wireless" CASCADE;
|
||||
CREATE TABLE "device_port_wireless" (
|
||||
"ip" inet,
|
||||
"port" text,
|
||||
"channel" integer,
|
||||
"power" integer
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_power.
|
||||
--
|
||||
DROP TABLE "device_power" CASCADE;
|
||||
CREATE TABLE "device_power" (
|
||||
"ip" inet NOT NULL,
|
||||
"module" integer NOT NULL,
|
||||
"power" integer,
|
||||
"status" text,
|
||||
PRIMARY KEY ("ip", "module")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_route.
|
||||
--
|
||||
DROP TABLE "device_route" CASCADE;
|
||||
CREATE TABLE "device_route" (
|
||||
"ip" inet NOT NULL,
|
||||
"network" cidr NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"dest" inet NOT NULL,
|
||||
"last_discover" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("ip", "network", "dest")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: log.
|
||||
--
|
||||
DROP TABLE "log" CASCADE;
|
||||
CREATE TABLE "log" (
|
||||
"id" serial NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"class" text,
|
||||
"entry" text,
|
||||
"logfile" text
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: node_ip.
|
||||
--
|
||||
DROP TABLE "node_ip" CASCADE;
|
||||
CREATE TABLE "node_ip" (
|
||||
"mac" macaddr NOT NULL,
|
||||
"ip" inet NOT NULL,
|
||||
"active" boolean,
|
||||
"time_first" timestamp DEFAULT current_timestamp,
|
||||
"time_last" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("mac", "ip")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: node_monitor.
|
||||
--
|
||||
DROP TABLE "node_monitor" CASCADE;
|
||||
CREATE TABLE "node_monitor" (
|
||||
"mac" macaddr NOT NULL,
|
||||
"active" boolean,
|
||||
"why" text,
|
||||
"cc" text,
|
||||
"date" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("mac")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: node_nbt.
|
||||
--
|
||||
DROP TABLE "node_nbt" CASCADE;
|
||||
CREATE TABLE "node_nbt" (
|
||||
"mac" macaddr NOT NULL,
|
||||
"ip" inet,
|
||||
"nbname" text,
|
||||
"domain" text,
|
||||
"server" boolean,
|
||||
"nbuser" text,
|
||||
"active" boolean,
|
||||
"time_first" timestamp DEFAULT current_timestamp,
|
||||
"time_last" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("mac")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: node_wireless.
|
||||
--
|
||||
DROP TABLE "node_wireless" CASCADE;
|
||||
CREATE TABLE "node_wireless" (
|
||||
"mac" macaddr NOT NULL,
|
||||
"uptime" integer,
|
||||
"maxrate" integer,
|
||||
"txrate" integer,
|
||||
"sigstrength" integer,
|
||||
"sigqual" integer,
|
||||
"rxpkt" integer,
|
||||
"txpkt" integer,
|
||||
"rxbyte" bigint,
|
||||
"txbyte" bigint,
|
||||
"time_last" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("mac")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: oui.
|
||||
--
|
||||
DROP TABLE "oui" CASCADE;
|
||||
CREATE TABLE "oui" (
|
||||
"oui" character varying(8) NOT NULL,
|
||||
"company" text,
|
||||
PRIMARY KEY ("oui")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: process.
|
||||
--
|
||||
DROP TABLE "process" CASCADE;
|
||||
CREATE TABLE "process" (
|
||||
"controller" integer NOT NULL,
|
||||
"device" inet NOT NULL,
|
||||
"action" text NOT NULL,
|
||||
"status" text,
|
||||
"count" integer,
|
||||
"creation" timestamp DEFAULT current_timestamp
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: sessions.
|
||||
--
|
||||
DROP TABLE "sessions" CASCADE;
|
||||
CREATE TABLE "sessions" (
|
||||
"id" character(32) NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"a_session" text,
|
||||
PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: subnets.
|
||||
--
|
||||
DROP TABLE "subnets" CASCADE;
|
||||
CREATE TABLE "subnets" (
|
||||
"net" cidr NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"last_discover" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("net")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: user_log.
|
||||
--
|
||||
DROP TABLE "user_log" CASCADE;
|
||||
CREATE TABLE "user_log" (
|
||||
"entry" serial NOT NULL,
|
||||
"username" character varying(50),
|
||||
"userip" inet,
|
||||
"event" text,
|
||||
"details" text,
|
||||
"creation" timestamp DEFAULT current_timestamp
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: users.
|
||||
--
|
||||
DROP TABLE "users" CASCADE;
|
||||
CREATE TABLE "users" (
|
||||
"username" character varying(50) NOT NULL,
|
||||
"password" text,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"last_on" timestamp,
|
||||
"port_control" boolean DEFAULT false,
|
||||
"ldap" boolean DEFAULT false,
|
||||
"admin" boolean DEFAULT false,
|
||||
"fullname" text,
|
||||
"note" text,
|
||||
PRIMARY KEY ("username")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_vlan.
|
||||
--
|
||||
DROP TABLE "device_vlan" CASCADE;
|
||||
CREATE TABLE "device_vlan" (
|
||||
"ip" inet NOT NULL,
|
||||
"vlan" integer NOT NULL,
|
||||
"description" text,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"last_discover" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("ip", "vlan")
|
||||
);
|
||||
CREATE INDEX "device_vlan_idx_ip" on "device_vlan" ("ip");
|
||||
|
||||
--
|
||||
-- Table: device_ip.
|
||||
--
|
||||
DROP TABLE "device_ip" CASCADE;
|
||||
CREATE TABLE "device_ip" (
|
||||
"ip" inet NOT NULL,
|
||||
"alias" inet NOT NULL,
|
||||
"subnet" cidr,
|
||||
"port" text,
|
||||
"dns" text,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("ip", "alias"),
|
||||
CONSTRAINT "device_ip_alias" UNIQUE ("alias")
|
||||
);
|
||||
CREATE INDEX "device_ip_idx_ip" on "device_ip" ("ip");
|
||||
CREATE INDEX "device_ip_idx_ip_port" on "device_ip" ("ip", "port");
|
||||
|
||||
--
|
||||
-- Table: device_port.
|
||||
--
|
||||
DROP TABLE "device_port" CASCADE;
|
||||
CREATE TABLE "device_port" (
|
||||
"ip" inet NOT NULL,
|
||||
"port" text NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"descr" text,
|
||||
"up" text,
|
||||
"up_admin" text,
|
||||
"type" text,
|
||||
"duplex" text,
|
||||
"duplex_admin" text,
|
||||
"speed" text,
|
||||
"name" text,
|
||||
"mac" macaddr,
|
||||
"mtu" integer,
|
||||
"stp" text,
|
||||
"remote_ip" inet,
|
||||
"remote_port" text,
|
||||
"remote_type" text,
|
||||
"remote_id" text,
|
||||
"vlan" text,
|
||||
"pvid" integer,
|
||||
"lastchange" bigint,
|
||||
PRIMARY KEY ("port", "ip")
|
||||
);
|
||||
CREATE INDEX "device_port_idx_ip" on "device_port" ("ip");
|
||||
CREATE INDEX "device_port_idx_remote_ip" on "device_port" ("remote_ip");
|
||||
|
||||
--
|
||||
-- Table: device_port_vlan.
|
||||
--
|
||||
DROP TABLE "device_port_vlan" CASCADE;
|
||||
CREATE TABLE "device_port_vlan" (
|
||||
"ip" inet NOT NULL,
|
||||
"port" text NOT NULL,
|
||||
"vlan" integer NOT NULL,
|
||||
"native" boolean DEFAULT false NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"last_discover" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("ip", "port", "vlan")
|
||||
);
|
||||
CREATE INDEX "device_port_vlan_idx_ip" on "device_port_vlan" ("ip");
|
||||
CREATE INDEX "device_port_vlan_idx_ip_port" on "device_port_vlan" ("ip", "port");
|
||||
CREATE INDEX "device_port_vlan_idx_ip_vlan" on "device_port_vlan" ("ip", "vlan");
|
||||
|
||||
--
|
||||
-- Table: node.
|
||||
--
|
||||
DROP TABLE "node" CASCADE;
|
||||
CREATE TABLE "node" (
|
||||
"mac" macaddr NOT NULL,
|
||||
"switch" inet NOT NULL,
|
||||
"port" text NOT NULL,
|
||||
"active" boolean,
|
||||
"oui" character varying(8),
|
||||
"time_first" timestamp DEFAULT current_timestamp,
|
||||
"time_recent" timestamp DEFAULT current_timestamp,
|
||||
"time_last" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("mac", "switch", "port")
|
||||
);
|
||||
CREATE INDEX "node_idx_switch" on "node" ("switch");
|
||||
CREATE INDEX "node_idx_switch_port" on "node" ("switch", "port");
|
||||
CREATE INDEX "node_idx_oui" on "node" ("oui");
|
||||
|
||||
-- Not used in Netdisco, because they upset the legacy netdisco.pm code
|
||||
--
|
||||
-- --
|
||||
-- -- Foreign Key Definitions
|
||||
-- --
|
||||
--
|
||||
-- ALTER TABLE "device_vlan" ADD CONSTRAINT "device_vlan_fk_ip" FOREIGN KEY ("ip")
|
||||
-- REFERENCES "device" ("ip") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_ip" ADD CONSTRAINT "device_ip_fk_ip" FOREIGN KEY ("ip")
|
||||
-- REFERENCES "device" ("ip") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_ip" ADD CONSTRAINT "device_ip_fk_ip_port" FOREIGN KEY ("ip", "port")
|
||||
-- REFERENCES "device_port" ("ip", "port") DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_port" ADD CONSTRAINT "device_port_fk_ip" FOREIGN KEY ("ip")
|
||||
-- REFERENCES "device" ("ip") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_port" ADD CONSTRAINT "device_port_fk_remote_ip" FOREIGN KEY ("remote_ip")
|
||||
-- REFERENCES "device_ip" ("alias") DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_port_vlan" ADD CONSTRAINT "device_port_vlan_fk_ip" FOREIGN KEY ("ip")
|
||||
-- REFERENCES "device" ("ip") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_port_vlan" ADD CONSTRAINT "device_port_vlan_fk_ip_port" FOREIGN KEY ("ip", "port")
|
||||
-- REFERENCES "device_port" ("ip", "port") DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_port_vlan" ADD CONSTRAINT "device_port_vlan_fk_ip_vlan" FOREIGN KEY ("ip", "vlan")
|
||||
-- REFERENCES "device_vlan" ("ip", "vlan") DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "node" ADD CONSTRAINT "node_fk_switch" FOREIGN KEY ("switch")
|
||||
-- REFERENCES "device" ("ip") DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "node" ADD CONSTRAINT "node_fk_switch_port" FOREIGN KEY ("switch", "port")
|
||||
-- REFERENCES "device_port" ("ip", "port") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "node" ADD CONSTRAINT "node_fk_oui" FOREIGN KEY ("oui")
|
||||
-- REFERENCES "oui" ("oui") DEFERRABLE;
|
||||
--
|
||||
@@ -0,0 +1,464 @@
|
||||
--
|
||||
-- Created by SQL::Translator::Producer::PostgreSQL
|
||||
-- Created on Wed Oct 10 15:38:36 2012
|
||||
--
|
||||
--
|
||||
-- Table: admin.
|
||||
--
|
||||
DROP TABLE "admin" CASCADE;
|
||||
CREATE TABLE "admin" (
|
||||
"job" serial NOT NULL,
|
||||
"entered" timestamp DEFAULT current_timestamp,
|
||||
"started" timestamp,
|
||||
"finished" timestamp,
|
||||
"device" inet,
|
||||
"port" text,
|
||||
"action" text,
|
||||
"subaction" text,
|
||||
"status" text,
|
||||
"username" text,
|
||||
"userip" inet,
|
||||
"log" text,
|
||||
"debug" boolean
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device.
|
||||
--
|
||||
DROP TABLE "device" CASCADE;
|
||||
CREATE TABLE "device" (
|
||||
"ip" inet NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"dns" text,
|
||||
"description" text,
|
||||
"uptime" bigint,
|
||||
"contact" text,
|
||||
"name" text,
|
||||
"location" text,
|
||||
"layers" character varying(8),
|
||||
"ports" integer,
|
||||
"mac" macaddr,
|
||||
"serial" text,
|
||||
"model" text,
|
||||
"ps1_type" text,
|
||||
"ps2_type" text,
|
||||
"ps1_status" text,
|
||||
"ps2_status" text,
|
||||
"fan" text,
|
||||
"slots" integer,
|
||||
"vendor" text,
|
||||
"os" text,
|
||||
"os_ver" text,
|
||||
"log" text,
|
||||
"snmp_ver" integer,
|
||||
"snmp_comm" text,
|
||||
"snmp_class" text,
|
||||
"vtp_domain" text,
|
||||
"last_discover" timestamp,
|
||||
"last_macsuck" timestamp,
|
||||
"last_arpnip" timestamp,
|
||||
PRIMARY KEY ("ip")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_module.
|
||||
--
|
||||
DROP TABLE "device_module" CASCADE;
|
||||
CREATE TABLE "device_module" (
|
||||
"ip" inet NOT NULL,
|
||||
"index" integer NOT NULL,
|
||||
"description" text,
|
||||
"type" text,
|
||||
"parent" integer,
|
||||
"name" text,
|
||||
"class" text,
|
||||
"pos" integer,
|
||||
"hw_ver" text,
|
||||
"fw_ver" text,
|
||||
"sw_ver" text,
|
||||
"serial" text,
|
||||
"model" text,
|
||||
"fru" boolean,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"last_discover" timestamp,
|
||||
PRIMARY KEY ("ip", "index")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_port_log.
|
||||
--
|
||||
DROP TABLE "device_port_log" CASCADE;
|
||||
CREATE TABLE "device_port_log" (
|
||||
"id" serial NOT NULL,
|
||||
"ip" inet,
|
||||
"port" text,
|
||||
"reason" text,
|
||||
"log" text,
|
||||
"username" text,
|
||||
"userip" inet,
|
||||
"action" text,
|
||||
"creation" timestamp DEFAULT current_timestamp
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_port_power.
|
||||
--
|
||||
DROP TABLE "device_port_power" CASCADE;
|
||||
CREATE TABLE "device_port_power" (
|
||||
"ip" inet NOT NULL,
|
||||
"port" text NOT NULL,
|
||||
"module" integer,
|
||||
"admin" text,
|
||||
"status" text,
|
||||
"class" text,
|
||||
"power" integer,
|
||||
PRIMARY KEY ("port", "ip")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_port_ssid.
|
||||
--
|
||||
DROP TABLE "device_port_ssid" CASCADE;
|
||||
CREATE TABLE "device_port_ssid" (
|
||||
"ip" inet,
|
||||
"port" text,
|
||||
"ssid" text,
|
||||
"broadcast" boolean,
|
||||
"bssid" macaddr
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_port_wireless.
|
||||
--
|
||||
DROP TABLE "device_port_wireless" CASCADE;
|
||||
CREATE TABLE "device_port_wireless" (
|
||||
"ip" inet,
|
||||
"port" text,
|
||||
"channel" integer,
|
||||
"power" integer
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_power.
|
||||
--
|
||||
DROP TABLE "device_power" CASCADE;
|
||||
CREATE TABLE "device_power" (
|
||||
"ip" inet NOT NULL,
|
||||
"module" integer NOT NULL,
|
||||
"power" integer,
|
||||
"status" text,
|
||||
PRIMARY KEY ("ip", "module")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_route.
|
||||
--
|
||||
DROP TABLE "device_route" CASCADE;
|
||||
CREATE TABLE "device_route" (
|
||||
"ip" inet NOT NULL,
|
||||
"network" cidr NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"dest" inet NOT NULL,
|
||||
"last_discover" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("ip", "network", "dest")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: log.
|
||||
--
|
||||
DROP TABLE "log" CASCADE;
|
||||
CREATE TABLE "log" (
|
||||
"id" serial NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"class" text,
|
||||
"entry" text,
|
||||
"logfile" text
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: node_ip.
|
||||
--
|
||||
DROP TABLE "node_ip" CASCADE;
|
||||
CREATE TABLE "node_ip" (
|
||||
"mac" macaddr NOT NULL,
|
||||
"ip" inet NOT NULL,
|
||||
"active" boolean,
|
||||
"time_first" timestamp DEFAULT current_timestamp,
|
||||
"time_last" timestamp DEFAULT current_timestamp,
|
||||
"dns" text,
|
||||
PRIMARY KEY ("mac", "ip")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: node_monitor.
|
||||
--
|
||||
DROP TABLE "node_monitor" CASCADE;
|
||||
CREATE TABLE "node_monitor" (
|
||||
"mac" macaddr NOT NULL,
|
||||
"active" boolean,
|
||||
"why" text,
|
||||
"cc" text,
|
||||
"date" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("mac")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: node_nbt.
|
||||
--
|
||||
DROP TABLE "node_nbt" CASCADE;
|
||||
CREATE TABLE "node_nbt" (
|
||||
"mac" macaddr NOT NULL,
|
||||
"ip" inet,
|
||||
"nbname" text,
|
||||
"domain" text,
|
||||
"server" boolean,
|
||||
"nbuser" text,
|
||||
"active" boolean,
|
||||
"time_first" timestamp DEFAULT current_timestamp,
|
||||
"time_last" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("mac")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: node_wireless.
|
||||
--
|
||||
DROP TABLE "node_wireless" CASCADE;
|
||||
CREATE TABLE "node_wireless" (
|
||||
"mac" macaddr NOT NULL,
|
||||
"uptime" integer,
|
||||
"maxrate" integer,
|
||||
"txrate" integer,
|
||||
"sigstrength" integer,
|
||||
"sigqual" integer,
|
||||
"rxpkt" integer,
|
||||
"txpkt" integer,
|
||||
"rxbyte" bigint,
|
||||
"txbyte" bigint,
|
||||
"time_last" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("mac")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: oui.
|
||||
--
|
||||
DROP TABLE "oui" CASCADE;
|
||||
CREATE TABLE "oui" (
|
||||
"oui" character varying(8) NOT NULL,
|
||||
"company" text,
|
||||
PRIMARY KEY ("oui")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: process.
|
||||
--
|
||||
DROP TABLE "process" CASCADE;
|
||||
CREATE TABLE "process" (
|
||||
"controller" integer NOT NULL,
|
||||
"device" inet NOT NULL,
|
||||
"action" text NOT NULL,
|
||||
"status" text,
|
||||
"count" integer,
|
||||
"creation" timestamp DEFAULT current_timestamp
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: sessions.
|
||||
--
|
||||
DROP TABLE "sessions" CASCADE;
|
||||
CREATE TABLE "sessions" (
|
||||
"id" character(32) NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"a_session" text,
|
||||
PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: subnets.
|
||||
--
|
||||
DROP TABLE "subnets" CASCADE;
|
||||
CREATE TABLE "subnets" (
|
||||
"net" cidr NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"last_discover" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("net")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: topology.
|
||||
--
|
||||
DROP TABLE "topology" CASCADE;
|
||||
CREATE TABLE "topology" (
|
||||
"dev1" inet NOT NULL,
|
||||
"port1" text NOT NULL,
|
||||
"dev2" inet NOT NULL,
|
||||
"port2" text NOT NULL
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: user_log.
|
||||
--
|
||||
DROP TABLE "user_log" CASCADE;
|
||||
CREATE TABLE "user_log" (
|
||||
"entry" serial NOT NULL,
|
||||
"username" character varying(50),
|
||||
"userip" inet,
|
||||
"event" text,
|
||||
"details" text,
|
||||
"creation" timestamp DEFAULT current_timestamp
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: users.
|
||||
--
|
||||
DROP TABLE "users" CASCADE;
|
||||
CREATE TABLE "users" (
|
||||
"username" character varying(50) NOT NULL,
|
||||
"password" text,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"last_on" timestamp,
|
||||
"port_control" boolean DEFAULT false,
|
||||
"ldap" boolean DEFAULT false,
|
||||
"admin" boolean DEFAULT false,
|
||||
"fullname" text,
|
||||
"note" text,
|
||||
PRIMARY KEY ("username")
|
||||
);
|
||||
|
||||
--
|
||||
-- Table: device_vlan.
|
||||
--
|
||||
DROP TABLE "device_vlan" CASCADE;
|
||||
CREATE TABLE "device_vlan" (
|
||||
"ip" inet NOT NULL,
|
||||
"vlan" integer NOT NULL,
|
||||
"description" text,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"last_discover" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("ip", "vlan")
|
||||
);
|
||||
CREATE INDEX "device_vlan_idx_ip" on "device_vlan" ("ip");
|
||||
|
||||
--
|
||||
-- Table: device_ip.
|
||||
--
|
||||
DROP TABLE "device_ip" CASCADE;
|
||||
CREATE TABLE "device_ip" (
|
||||
"ip" inet NOT NULL,
|
||||
"alias" inet NOT NULL,
|
||||
"subnet" cidr,
|
||||
"port" text,
|
||||
"dns" text,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("ip", "alias"),
|
||||
CONSTRAINT "device_ip_alias" UNIQUE ("alias")
|
||||
);
|
||||
CREATE INDEX "device_ip_idx_ip" on "device_ip" ("ip");
|
||||
CREATE INDEX "device_ip_idx_ip_port" on "device_ip" ("ip", "port");
|
||||
|
||||
--
|
||||
-- Table: device_port.
|
||||
--
|
||||
DROP TABLE "device_port" CASCADE;
|
||||
CREATE TABLE "device_port" (
|
||||
"ip" inet NOT NULL,
|
||||
"port" text NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"descr" text,
|
||||
"up" text,
|
||||
"up_admin" text,
|
||||
"type" text,
|
||||
"duplex" text,
|
||||
"duplex_admin" text,
|
||||
"speed" text,
|
||||
"name" text,
|
||||
"mac" macaddr,
|
||||
"mtu" integer,
|
||||
"stp" text,
|
||||
"remote_ip" inet,
|
||||
"remote_port" text,
|
||||
"remote_type" text,
|
||||
"remote_id" text,
|
||||
"vlan" text,
|
||||
"pvid" integer,
|
||||
"lastchange" bigint,
|
||||
PRIMARY KEY ("port", "ip")
|
||||
);
|
||||
CREATE INDEX "device_port_idx_ip" on "device_port" ("ip");
|
||||
CREATE INDEX "device_port_idx_remote_ip" on "device_port" ("remote_ip");
|
||||
|
||||
--
|
||||
-- Table: device_port_vlan.
|
||||
--
|
||||
DROP TABLE "device_port_vlan" CASCADE;
|
||||
CREATE TABLE "device_port_vlan" (
|
||||
"ip" inet NOT NULL,
|
||||
"port" text NOT NULL,
|
||||
"vlan" integer NOT NULL,
|
||||
"native" boolean DEFAULT false NOT NULL,
|
||||
"creation" timestamp DEFAULT current_timestamp,
|
||||
"last_discover" timestamp DEFAULT current_timestamp,
|
||||
"vlantype" text,
|
||||
PRIMARY KEY ("ip", "port", "vlan")
|
||||
);
|
||||
CREATE INDEX "device_port_vlan_idx_ip" on "device_port_vlan" ("ip");
|
||||
CREATE INDEX "device_port_vlan_idx_ip_port" on "device_port_vlan" ("ip", "port");
|
||||
CREATE INDEX "device_port_vlan_idx_ip_vlan" on "device_port_vlan" ("ip", "vlan");
|
||||
|
||||
--
|
||||
-- Table: node.
|
||||
--
|
||||
DROP TABLE "node" CASCADE;
|
||||
CREATE TABLE "node" (
|
||||
"mac" macaddr NOT NULL,
|
||||
"switch" inet NOT NULL,
|
||||
"port" text NOT NULL,
|
||||
"active" boolean,
|
||||
"oui" character varying(8),
|
||||
"time_first" timestamp DEFAULT current_timestamp,
|
||||
"time_recent" timestamp DEFAULT current_timestamp,
|
||||
"time_last" timestamp DEFAULT current_timestamp,
|
||||
PRIMARY KEY ("mac", "switch", "port")
|
||||
);
|
||||
CREATE INDEX "node_idx_switch" on "node" ("switch");
|
||||
CREATE INDEX "node_idx_switch_port" on "node" ("switch", "port");
|
||||
CREATE INDEX "node_idx_oui" on "node" ("oui");
|
||||
|
||||
-- Not used in Netdisco, because they upset the legacy netdisco.pm code
|
||||
--
|
||||
-- --
|
||||
-- -- Foreign Key Definitions
|
||||
-- --
|
||||
--
|
||||
-- ALTER TABLE "device_vlan" ADD CONSTRAINT "device_vlan_fk_ip" FOREIGN KEY ("ip")
|
||||
-- REFERENCES "device" ("ip") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_ip" ADD CONSTRAINT "device_ip_fk_ip" FOREIGN KEY ("ip")
|
||||
-- REFERENCES "device" ("ip") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_ip" ADD CONSTRAINT "device_ip_fk_ip_port" FOREIGN KEY ("ip", "port")
|
||||
-- REFERENCES "device_port" ("ip", "port") DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_port" ADD CONSTRAINT "device_port_fk_ip" FOREIGN KEY ("ip")
|
||||
-- REFERENCES "device" ("ip") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_port" ADD CONSTRAINT "device_port_fk_remote_ip" FOREIGN KEY ("remote_ip")
|
||||
-- REFERENCES "device_ip" ("alias") DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_port_vlan" ADD CONSTRAINT "device_port_vlan_fk_ip" FOREIGN KEY ("ip")
|
||||
-- REFERENCES "device" ("ip") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_port_vlan" ADD CONSTRAINT "device_port_vlan_fk_ip_port" FOREIGN KEY ("ip", "port")
|
||||
-- REFERENCES "device_port" ("ip", "port") DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "device_port_vlan" ADD CONSTRAINT "device_port_vlan_fk_ip_vlan" FOREIGN KEY ("ip", "vlan")
|
||||
-- REFERENCES "device_vlan" ("ip", "vlan") DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "node" ADD CONSTRAINT "node_fk_switch" FOREIGN KEY ("switch")
|
||||
-- REFERENCES "device" ("ip") DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "node" ADD CONSTRAINT "node_fk_switch_port" FOREIGN KEY ("switch", "port")
|
||||
-- REFERENCES "device_port" ("ip", "port") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
|
||||
--
|
||||
-- ALTER TABLE "node" ADD CONSTRAINT "node_fk_oui" FOREIGN KEY ("oui")
|
||||
-- REFERENCES "oui" ("oui") DEFERRABLE;
|
||||
--
|
||||
23
Netdisco/lib/App/Netdisco/Daemon/DB.pm
Normal file
23
Netdisco/lib/App/Netdisco/Daemon/DB.pm
Normal file
@@ -0,0 +1,23 @@
|
||||
use utf8;
|
||||
package App::Netdisco::Daemon::DB;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Schema';
|
||||
|
||||
__PACKAGE__->load_namespaces;
|
||||
|
||||
our $VERSION = 1; # schema version used for upgrades, keep as integer
|
||||
|
||||
use Path::Class;
|
||||
use File::Basename;
|
||||
|
||||
my (undef, $libpath, undef) = fileparse( $INC{ 'App/Netdisco/Daemon/DB.pm' } );
|
||||
our $schema_versions_dir = Path::Class::Dir->new($libpath)
|
||||
->subdir("DB", "schema_versions")->stringify;
|
||||
|
||||
__PACKAGE__->load_components(qw/Schema::Versioned/);
|
||||
__PACKAGE__->upgrade_directory($schema_versions_dir);
|
||||
|
||||
1;
|
||||
37
Netdisco/lib/App/Netdisco/Daemon/DB/Result/Admin.pm
Normal file
37
Netdisco/lib/App/Netdisco/Daemon/DB/Result/Admin.pm
Normal file
@@ -0,0 +1,37 @@
|
||||
use utf8;
|
||||
package App::Netdisco::Daemon::DB::Result::Admin;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
__PACKAGE__->table("admin");
|
||||
__PACKAGE__->add_columns(
|
||||
"job",
|
||||
{
|
||||
data_type => "integer",
|
||||
is_nullable => 0,
|
||||
},
|
||||
"started",
|
||||
{ data_type => "timestamp", is_nullable => 1 },
|
||||
"finished",
|
||||
{ data_type => "timestamp", is_nullable => 1 },
|
||||
"device",
|
||||
{ data_type => "inet", is_nullable => 1 },
|
||||
"port",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"action",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"subaction",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"status",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"log",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"debug",
|
||||
{ data_type => "boolean", is_nullable => 1 },
|
||||
);
|
||||
|
||||
__PACKAGE__->set_primary_key("job");
|
||||
|
||||
1;
|
||||
111
Netdisco/lib/App/Netdisco/Daemon/Worker/Interactive.pm
Normal file
111
Netdisco/lib/App/Netdisco/Daemon/Worker/Interactive.pm
Normal file
@@ -0,0 +1,111 @@
|
||||
package App::Netdisco::Daemon::Worker::Interactive;
|
||||
|
||||
use Dancer qw/:moose :syntax :script/;
|
||||
use Dancer::Plugin::DBIC 'schema';
|
||||
use Try::Tiny;
|
||||
|
||||
use Role::Tiny;
|
||||
use namespace::clean;
|
||||
|
||||
# add dispatch methods for interactive actions
|
||||
with 'App::Netdisco::Daemon::Worker::Interactive::DeviceActions',
|
||||
'App::Netdisco::Daemon::Worker::Interactive::PortActions';
|
||||
|
||||
sub worker_body {
|
||||
my $self = shift;
|
||||
|
||||
# get all pending jobs
|
||||
my $rs = schema('daemon')->resultset('Admin')->search({
|
||||
action => [qw/location contact portcontrol portname vlan power/],
|
||||
status => 'queued',
|
||||
});
|
||||
|
||||
while (1) {
|
||||
while (my $job = $rs->next) {
|
||||
my $target = 'set_'. $job->action;
|
||||
next unless $self->can($target);
|
||||
|
||||
# mark job as running
|
||||
next unless $self->lock_job($job);
|
||||
|
||||
# do job
|
||||
my ($status, $log);
|
||||
try {
|
||||
($status, $log) = $self->$target($job);
|
||||
}
|
||||
catch { warn "error running job: $_\n" };
|
||||
|
||||
# revert to queued status if we failed to action the job
|
||||
if (not $status) {
|
||||
$self->revert_job($job->job);
|
||||
}
|
||||
else {
|
||||
# update job state to done/error with log
|
||||
$self->close_job($job->job, $status, $log);
|
||||
}
|
||||
}
|
||||
|
||||
# reset iterator so ->next() triggers another DB query
|
||||
$rs->reset;
|
||||
$self->gd_sleep( setting('daemon_sleep_time') || 5 );
|
||||
}
|
||||
}
|
||||
|
||||
sub lock_job {
|
||||
my ($self, $job) = @_;
|
||||
my $happy = 1;
|
||||
|
||||
# lock db table, check job state is still queued, update to running
|
||||
try {
|
||||
my $status_updated = schema('daemon')->txn_do(sub {
|
||||
my $row = schema('daemon')->resultset('Admin')->find(
|
||||
{job => $job->job},
|
||||
{for => 'update'}
|
||||
);
|
||||
|
||||
$happy = 0 if $row->status ne 'queued';
|
||||
$row->update({status => "running-$$", started => \"datetime('now')" });
|
||||
});
|
||||
|
||||
$happy = 0 if not $status_updated;
|
||||
}
|
||||
catch {
|
||||
warn "error locking job: $_\n";
|
||||
$happy = 0;
|
||||
};
|
||||
|
||||
return $happy;
|
||||
}
|
||||
|
||||
sub revert_job {
|
||||
my ($self, $id) = @_;
|
||||
|
||||
try {
|
||||
schema('daemon')->resultset('Admin')
|
||||
->find($id)
|
||||
->update({status => 'queued', started => undef});
|
||||
}
|
||||
catch { warn "error reverting job: $_\n" };
|
||||
}
|
||||
|
||||
sub close_job {
|
||||
my ($self, $id, $status, $log) = @_;
|
||||
|
||||
try {
|
||||
my $local = schema('daemon')->resultset('Admin')->find($id);
|
||||
|
||||
schema('netdisco')->resultset('Admin')
|
||||
->find($id)
|
||||
->update({
|
||||
status => $status,
|
||||
log => $log,
|
||||
started => $local->started,
|
||||
finished => \'now()',
|
||||
});
|
||||
|
||||
$local->delete;
|
||||
}
|
||||
catch { warn "error closing job: $_\n" };
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -0,0 +1,49 @@
|
||||
package App::Netdisco::Daemon::Worker::Interactive::DeviceActions;
|
||||
|
||||
use App::Netdisco::Util::Connect qw/snmp_connect get_device/;
|
||||
use App::Netdisco::Daemon::Worker::Interactive::Util ':all';
|
||||
|
||||
use Role::Tiny;
|
||||
use namespace::clean;
|
||||
|
||||
sub set_location {
|
||||
my ($self, $job) = @_;
|
||||
return _set_device_generic($job->device, 'location', $job->subaction);
|
||||
}
|
||||
|
||||
sub set_contact {
|
||||
my ($self, $job) = @_;
|
||||
return _set_device_generic($job->device, 'contact', $job->subaction);
|
||||
}
|
||||
|
||||
sub _set_device_generic {
|
||||
my ($ip, $slot, $data) = @_;
|
||||
$data ||= '';
|
||||
|
||||
# snmp connect using rw community
|
||||
my $info = snmp_connect($ip)
|
||||
or return error("Failed to connect to device [$ip] to update $slot");
|
||||
|
||||
my $method = 'set_'. $slot;
|
||||
my $rv = $info->$method($data);
|
||||
|
||||
if (!defined $rv) {
|
||||
return error(sprintf 'Failed to set %s on [%s]: %s',
|
||||
$slot, $ip, ($info->error || ''));
|
||||
}
|
||||
|
||||
# confirm the set happened
|
||||
$info->clear_cache;
|
||||
my $new_data = ($info->$slot || '');
|
||||
if ($new_data ne $data) {
|
||||
return error("Verify of $slot update failed on [$ip]: $new_data");
|
||||
}
|
||||
|
||||
# update netdisco DB
|
||||
my $device = get_device($ip);
|
||||
$device->update({$slot => $data});
|
||||
|
||||
return done("Updated $slot on [$ip] to [$data]");
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -0,0 +1,136 @@
|
||||
package App::Netdisco::Daemon::Worker::Interactive::PortActions;
|
||||
|
||||
use App::Netdisco::Util::Connect ':all';
|
||||
use App::Netdisco::Util::Permissions ':all';
|
||||
use App::Netdisco::Daemon::Worker::Interactive::Util ':all';
|
||||
|
||||
use Role::Tiny;
|
||||
use namespace::clean;
|
||||
|
||||
sub set_portname {
|
||||
my ($self, $job) = @_;
|
||||
return _set_port_generic($job, 'alias', 'name');
|
||||
}
|
||||
|
||||
sub set_portcontrol {
|
||||
my ($self, $job) = @_;
|
||||
|
||||
my $port = get_port($job->device, $job->port)
|
||||
or return error(sprintf "Unknown port name [%s] on device [%s]",
|
||||
$job->port, $job->device);
|
||||
|
||||
my $reconfig_check = port_reconfig_check($port);
|
||||
return error("Cannot alter port: $reconfig_check")
|
||||
if length $reconfig_check;
|
||||
|
||||
return _set_port_generic($job, 'up_admin');
|
||||
}
|
||||
|
||||
sub set_vlan {
|
||||
my ($self, $job) = @_;
|
||||
|
||||
my $port = get_port($job->device, $job->port)
|
||||
or return error(sprintf "Unknown port name [%s] on device [%s]",
|
||||
$job->port, $job->device);
|
||||
|
||||
my $port_reconfig_check = port_reconfig_check($port);
|
||||
return error("Cannot alter port: $port_reconfig_check")
|
||||
if length $port_reconfig_check;
|
||||
|
||||
my $vlan_reconfig_check = vlan_reconfig_check($port);
|
||||
return error("Cannot alter vlan: $vlan_reconfig_check")
|
||||
if length $vlan_reconfig_check;
|
||||
|
||||
return _set_port_generic($job, 'vlan');
|
||||
}
|
||||
|
||||
sub _set_port_generic {
|
||||
my ($job, $slot, $column) = @_;
|
||||
$column ||= $slot;
|
||||
|
||||
my $ip = $job->device;
|
||||
my $pn = $job->port;
|
||||
(my $data = $job->subaction) =~ s/-\w+//;
|
||||
|
||||
my $port = get_port($ip, $pn)
|
||||
or return error("Unknown port name [$pn] on device [$ip]");
|
||||
|
||||
# snmp connect using rw community
|
||||
my $info = snmp_connect($ip)
|
||||
or return error("Failed to connect to device [$ip] to control port");
|
||||
|
||||
my $iid = get_iid($info, $port)
|
||||
or return error("Failed to get port ID for [$pn] from [$ip]");
|
||||
|
||||
my $method = 'set_i_'. $slot;
|
||||
my $rv = $info->$method($data, $iid);
|
||||
|
||||
if (!defined $rv) {
|
||||
return error(sprintf 'Failed to set [%s] %s to [%s] on [%s]: %s',
|
||||
$pn, $slot, $data, $ip, ($info->error || ''));
|
||||
}
|
||||
|
||||
# confirm the set happened
|
||||
$info->clear_cache;
|
||||
my $check_method = 'i_'. $slot;
|
||||
my $state = ($info->$check_method($iid) || '');
|
||||
if (ref {} ne ref $state or $state->{$iid} ne $data) {
|
||||
return error("Verify of [$pn] $slot failed on [$ip]");
|
||||
}
|
||||
|
||||
# update netdisco DB
|
||||
$port->update({$column => $data});
|
||||
|
||||
return done("Updated [$pn] $slot status on [$ip] to [$data]");
|
||||
}
|
||||
|
||||
sub set_power {
|
||||
my ($self, $job) = @_;
|
||||
|
||||
my $port = get_port($job->device, $job->port)
|
||||
or return error(sprintf "Unknown port name [%s] on device [%s]",
|
||||
$job->port, $job->device);
|
||||
|
||||
return error("No PoE service on port [%s] on device [%s]")
|
||||
unless $port->power;
|
||||
|
||||
my $reconfig_check = port_reconfig_check($port);
|
||||
return error("Cannot alter port: $reconfig_check")
|
||||
if length $reconfig_check;
|
||||
|
||||
|
||||
my $ip = $job->device;
|
||||
my $pn = $job->port;
|
||||
(my $data = $job->subaction) =~ s/-\w+//;
|
||||
|
||||
# snmp connect using rw community
|
||||
my $info = snmp_connect($ip)
|
||||
or return error("Failed to connect to device [$ip] to control port");
|
||||
|
||||
my $powerid = get_powerid($info, $port)
|
||||
or return error("Failed to get power ID for [$pn] from [$ip]");
|
||||
|
||||
my $rv = $info->set_peth_port_admin($data, $powerid);
|
||||
|
||||
if (!defined $rv) {
|
||||
return error(sprintf 'Failed to set [%s] power to [%s] on [%s]: %s',
|
||||
$pn, $data, $ip, ($info->error || ''));
|
||||
}
|
||||
|
||||
# confirm the set happened
|
||||
$info->clear_cache;
|
||||
my $state = ($info->peth_port_admin($powerid) || '');
|
||||
if (ref {} ne ref $state or $state->{$powerid} ne $data) {
|
||||
return error("Verify of [$pn] power failed on [$ip]");
|
||||
}
|
||||
|
||||
# update netdisco DB
|
||||
$port->power->update({
|
||||
admin => $data,
|
||||
status => ($data eq 'false' ? 'disabled' : 'searching'),
|
||||
});
|
||||
|
||||
return done("Updated [$pn] power status on [$ip] to [$data]");
|
||||
}
|
||||
|
||||
1;
|
||||
15
Netdisco/lib/App/Netdisco/Daemon/Worker/Interactive/Util.pm
Normal file
15
Netdisco/lib/App/Netdisco/Daemon/Worker/Interactive/Util.pm
Normal file
@@ -0,0 +1,15 @@
|
||||
package App::Netdisco::Daemon::Worker::Interactive::Util;
|
||||
|
||||
# support utilities for Daemon Actions
|
||||
|
||||
use base 'Exporter';
|
||||
our @EXPORT = ();
|
||||
our @EXPORT_OK = qw/ done error /;
|
||||
our %EXPORT_TAGS = (
|
||||
all => [qw/ done error /],
|
||||
);
|
||||
|
||||
sub done { return ('done', shift) }
|
||||
sub error { return ('error', shift) }
|
||||
|
||||
1;
|
||||
123
Netdisco/lib/App/Netdisco/Daemon/Worker/Manager.pm
Normal file
123
Netdisco/lib/App/Netdisco/Daemon/Worker/Manager.pm
Normal file
@@ -0,0 +1,123 @@
|
||||
package App::Netdisco::Daemon::Worker::Manager;
|
||||
|
||||
use Dancer qw/:moose :syntax :script/;
|
||||
use Dancer::Plugin::DBIC 'schema';
|
||||
|
||||
use App::Netdisco::Util::DeviceProperties 'is_discoverable';
|
||||
use Try::Tiny;
|
||||
|
||||
use Role::Tiny;
|
||||
use namespace::clean;
|
||||
|
||||
sub worker_begin {
|
||||
my $self = shift;
|
||||
my $daemon = schema('daemon');
|
||||
|
||||
# deploy local db if not already done
|
||||
try {
|
||||
$daemon->storage->dbh_do(sub {
|
||||
my ($storage, $dbh) = @_;
|
||||
$dbh->selectrow_arrayref("SELECT * FROM admin WHERE 0 = 1");
|
||||
});
|
||||
}
|
||||
catch { $daemon->txn_do( $daemon->deploy ) };
|
||||
|
||||
$daemon->storage->disconnect;
|
||||
if ($daemon->get_db_version < $daemon->schema_version) {
|
||||
$daemon->txn_do( $daemon->upgrade );
|
||||
}
|
||||
|
||||
# on start, any jobs previously grabbed by a daemon on this host
|
||||
# will be reset to "queued", which is the simplest way to restart them.
|
||||
|
||||
my $rs = schema('netdisco')->resultset('Admin')->search({
|
||||
status => "running-$self->{nd_host}"
|
||||
});
|
||||
|
||||
if ($rs->count > 0) {
|
||||
$daemon->resultset('Admin')->delete;
|
||||
$rs->update({status => 'queued', started => undef});
|
||||
}
|
||||
}
|
||||
|
||||
sub worker_body {
|
||||
my $self = shift;
|
||||
|
||||
# get all pending jobs
|
||||
my $rs = schema('netdisco')->resultset('Admin')
|
||||
->search({status => 'queued'});
|
||||
|
||||
while (1) {
|
||||
while (my $job = $rs->next) {
|
||||
# filter for discover_*
|
||||
next unless is_discoverable($job->device);
|
||||
|
||||
# mark job as running
|
||||
next unless $self->lock_job($job);
|
||||
|
||||
# copy job to local queue
|
||||
$self->copy_job($job)
|
||||
or $self->revert_job($job->job);
|
||||
}
|
||||
|
||||
# reset iterator so ->next() triggers another DB query
|
||||
$rs->reset;
|
||||
$self->gd_sleep( setting('daemon_sleep_time') || 5 );
|
||||
}
|
||||
}
|
||||
|
||||
sub lock_job {
|
||||
my ($self, $job) = @_;
|
||||
my $happy = 1;
|
||||
|
||||
# lock db table, check job state is still queued, update to running
|
||||
try {
|
||||
my $status_updated = schema('netdisco')->txn_do(sub {
|
||||
my $row = schema('netdisco')->resultset('Admin')->find(
|
||||
{job => $job->job},
|
||||
{for => 'update'}
|
||||
);
|
||||
|
||||
$happy = 0 if $row->status ne 'queued';
|
||||
$row->update({
|
||||
status => "running-$self->{nd_host}",
|
||||
started => \'now()'
|
||||
});
|
||||
});
|
||||
|
||||
$happy = 0 if not $status_updated;
|
||||
}
|
||||
catch {
|
||||
warn "error locking job: $_\n";
|
||||
$happy = 0;
|
||||
};
|
||||
|
||||
return $happy;
|
||||
}
|
||||
|
||||
sub copy_job {
|
||||
my ($self, $job) = @_;
|
||||
|
||||
try {
|
||||
my %data = $job->get_columns;
|
||||
delete $data{$_} for qw/entered username userip/;
|
||||
|
||||
schema('daemon')->resultset('Admin')->update_or_create({
|
||||
%data, status => 'queued', started => undef,
|
||||
});
|
||||
}
|
||||
catch { warn "error copying job: $_\n" };
|
||||
}
|
||||
|
||||
sub revert_job {
|
||||
my ($self, $id) = @_;
|
||||
|
||||
try {
|
||||
schema('netdisco')->resultset('Admin')
|
||||
->find($id)
|
||||
->update({status => 'queued', started => undef});
|
||||
}
|
||||
catch { warn "error reverting job: $_\n" };
|
||||
}
|
||||
|
||||
1;
|
||||
151
Netdisco/lib/App/Netdisco/Util/Connect.pm
Normal file
151
Netdisco/lib/App/Netdisco/Util/Connect.pm
Normal file
@@ -0,0 +1,151 @@
|
||||
package App::Netdisco::Util::Connect;
|
||||
|
||||
use Dancer qw/:syntax :script/;
|
||||
use Dancer::Plugin::DBIC 'schema';
|
||||
|
||||
use SNMP::Info;
|
||||
use Try::Tiny;
|
||||
|
||||
use base 'Exporter';
|
||||
our @EXPORT = ();
|
||||
our @EXPORT_OK = qw/
|
||||
get_device get_port get_iid get_powerid snmp_connect
|
||||
/;
|
||||
our %EXPORT_TAGS = (
|
||||
all => [qw/
|
||||
get_device get_port get_iid get_powerid snmp_connect
|
||||
/],
|
||||
);
|
||||
|
||||
=head1 App::Netdisco::Util::Connect
|
||||
|
||||
A set of helper subroutines to support parts of the Netdisco application.
|
||||
|
||||
There are no default exports, however the C<:all> tag will export all
|
||||
subroutines.
|
||||
|
||||
=head2 get_device( $ip )
|
||||
|
||||
Given an IP address, returns a L<DBIx::Class::Row> object for the Device in
|
||||
the Netdisco database. The IP can be for any interface on the device.
|
||||
|
||||
Returns C<undef> if the device or interface IP is not known to Netdisco.
|
||||
|
||||
=cut
|
||||
|
||||
sub get_device {
|
||||
my $ip = shift;
|
||||
|
||||
my $alias = schema('netdisco')->resultset('DeviceIp')
|
||||
->search({alias => $ip})->first;
|
||||
return if not eval { $alias->ip };
|
||||
|
||||
return schema('netdisco')->resultset('Device')
|
||||
->find({ip => $alias->ip});
|
||||
}
|
||||
|
||||
=head2 get_port( $device, $portname )
|
||||
|
||||
=cut
|
||||
|
||||
sub get_port {
|
||||
my ($device, $portname) = @_;
|
||||
|
||||
# accept either ip or dbic object
|
||||
$device = get_device($device)
|
||||
if not ref $device;
|
||||
|
||||
my $port = schema('netdisco')->resultset('DevicePort')
|
||||
->find({ip => $device->ip, port => $portname});
|
||||
|
||||
return $port;
|
||||
}
|
||||
|
||||
=head2 get_iid( $info, $port )
|
||||
|
||||
=cut
|
||||
|
||||
sub get_iid {
|
||||
my ($info, $port) = @_;
|
||||
|
||||
# accept either port name or dbic object
|
||||
$port = $port->port if ref $port;
|
||||
|
||||
my $interfaces = $info->interfaces;
|
||||
my %rev_if = reverse %$interfaces;
|
||||
my $iid = $rev_if{$port};
|
||||
|
||||
return $iid;
|
||||
}
|
||||
|
||||
=head2 get_powerid( $info, $port )
|
||||
|
||||
=cut
|
||||
|
||||
sub get_powerid {
|
||||
my ($info, $port) = @_;
|
||||
|
||||
# accept either port name or dbic object
|
||||
$port = $port->port if ref $port;
|
||||
|
||||
my $iid = get_iid($info, $port)
|
||||
or return undef;
|
||||
|
||||
my $p_interfaces = $info->peth_port_ifindex;
|
||||
my %rev_p_if = reverse %$p_interfaces;
|
||||
my $powerid = $rev_p_if{$iid};
|
||||
|
||||
return $powerid;
|
||||
}
|
||||
|
||||
=head2 snmp_connect( $ip )
|
||||
|
||||
Given an IP address, returns an L<SNMP::Info> instance configured for and
|
||||
connected to that device. The IP can be any on the device, and the management
|
||||
interface will be connected to.
|
||||
|
||||
Returns C<undef> if the connection fails.
|
||||
|
||||
=cut
|
||||
|
||||
sub snmp_connect {
|
||||
my $ip = shift;
|
||||
|
||||
# get device details from db
|
||||
my $device = get_device($ip)
|
||||
or return ();
|
||||
|
||||
# TODO: really only supporing v2c at the moment
|
||||
my %snmp_args = (
|
||||
DestHost => $device->ip,
|
||||
Version => ($device->snmp_ver || setting('snmpver') || 2),
|
||||
Retries => (setting('snmpretries') || 2),
|
||||
Timeout => (setting('snmptimeout') || 1000000),
|
||||
MibDirs => [ _build_mibdirs() ],
|
||||
AutoSpecify => 1,
|
||||
IgnoreNetSNMPConf => 1,
|
||||
Debug => ($ENV{INFO_TRACE} || 0),
|
||||
);
|
||||
|
||||
my $info = undef;
|
||||
COMMUNITY: foreach my $c (@{ setting('community_rw') || []}) {
|
||||
try {
|
||||
$info = SNMP::Info->new(%snmp_args, Community => $c);
|
||||
last COMMUNITY if (
|
||||
$info
|
||||
and (not defined $info->error)
|
||||
and length $info->uptime
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
sub _build_mibdirs {
|
||||
# FIXME: make this cross-platform (Path::Class?)
|
||||
return map { setting('mibhome') .'/'. $_ }
|
||||
@{ setting('mibdirs') || [] };
|
||||
}
|
||||
|
||||
1;
|
||||
94
Netdisco/lib/App/Netdisco/Util/DeviceProperties.pm
Normal file
94
Netdisco/lib/App/Netdisco/Util/DeviceProperties.pm
Normal file
@@ -0,0 +1,94 @@
|
||||
package App::Netdisco::Util::DeviceProperties;
|
||||
|
||||
use Dancer qw/:syntax :script/;
|
||||
use Dancer::Plugin::DBIC 'schema';
|
||||
|
||||
use NetAddr::IP::Lite;
|
||||
|
||||
use base 'Exporter';
|
||||
our @EXPORT = ();
|
||||
our @EXPORT_OK = qw/
|
||||
is_discoverable
|
||||
is_vlan_interface port_has_phone
|
||||
/;
|
||||
our %EXPORT_TAGS = (
|
||||
all => [qw/
|
||||
is_discoverable
|
||||
is_vlan_interface port_has_phone
|
||||
/],
|
||||
);
|
||||
|
||||
=head1 App::Netdisco::Util::DeviceProperties;
|
||||
|
||||
A set of helper subroutines to support parts of the Netdisco application.
|
||||
|
||||
There are no default exports, however the C<:all> tag will export all
|
||||
subroutines.
|
||||
|
||||
=head2 is_discoverable( $ip )
|
||||
|
||||
Given an IP address, returns C<true> if Netdisco on this host is permitted to
|
||||
discover its configuration by the local configuration.
|
||||
|
||||
The configuration items C<discover_no> and C<discover_only> are checked
|
||||
against the given IP.
|
||||
|
||||
Returns false if the host is not permitted to discover the target device.
|
||||
|
||||
=cut
|
||||
|
||||
sub is_discoverable {
|
||||
my $ip = shift;
|
||||
|
||||
my $device = NetAddr::IP::Lite->new($ip) or return 0;
|
||||
my $discover_no = setting('discover_no') || [];
|
||||
my $discover_only = setting('discover_only') || [];
|
||||
|
||||
if (scalar @$discover_no) {
|
||||
foreach my $item (@$discover_no) {
|
||||
my $ip = NetAddr::IP::Lite->new($item) or return 0;
|
||||
return 0 if $ip->contains($device);
|
||||
}
|
||||
}
|
||||
|
||||
if (scalar @$discover_only) {
|
||||
my $okay = 0;
|
||||
foreach my $item (@$discover_only) {
|
||||
my $ip = NetAddr::IP::Lite->new($item) or return 0;
|
||||
++$okay if $ip->contains($device);
|
||||
}
|
||||
return 0 if not $okay;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
=head2 is_vlan_interface( $port )
|
||||
|
||||
=cut
|
||||
|
||||
sub is_vlan_interface {
|
||||
my $port = shift;
|
||||
|
||||
my $is_vlan = (($port->type and
|
||||
$port->type =~ /^(53|propVirtual|l2vlan|l3ipvlan|135|136|137)$/i)
|
||||
or ($port->port and $port->port =~ /vlan/i)
|
||||
or ($port->name and $port->name =~ /vlan/i)) ? 1 : 0;
|
||||
|
||||
return $is_vlan;
|
||||
}
|
||||
|
||||
=head2 port_has_phone( $port )
|
||||
|
||||
=cut
|
||||
|
||||
sub port_has_phone {
|
||||
my $port = shift;
|
||||
|
||||
my $has_phone = ($port->remote_type
|
||||
and $port->remote_type =~ /ip.phone/i) ? 1 : 0;
|
||||
|
||||
return $has_phone;
|
||||
}
|
||||
|
||||
1;
|
||||
74
Netdisco/lib/App/Netdisco/Util/Permissions.pm
Normal file
74
Netdisco/lib/App/Netdisco/Util/Permissions.pm
Normal file
@@ -0,0 +1,74 @@
|
||||
package App::Netdisco::Util::Permissions;
|
||||
|
||||
use Dancer qw/:syntax :script/;
|
||||
use Dancer::Plugin::DBIC 'schema';
|
||||
|
||||
use App::Netdisco::Util::DeviceProperties ':all';
|
||||
|
||||
use base 'Exporter';
|
||||
our @EXPORT = ();
|
||||
our @EXPORT_OK = qw/
|
||||
vlan_reconfig_check port_reconfig_check
|
||||
/;
|
||||
our %EXPORT_TAGS = (
|
||||
all => [qw/
|
||||
vlan_reconfig_check port_reconfig_check
|
||||
/],
|
||||
);
|
||||
|
||||
=head1 App::Netdisco::Util::Permissions
|
||||
|
||||
A set of helper subroutines to support parts of the Netdisco application.
|
||||
|
||||
There are no default exports, however the C<:all> tag will export all
|
||||
subroutines.
|
||||
|
||||
=head2 vlan_reconfig_check( $port )
|
||||
|
||||
=cut
|
||||
|
||||
sub vlan_reconfig_check {
|
||||
my $port = shift;
|
||||
my $ip = $port->ip;
|
||||
my $name = $port->port;
|
||||
|
||||
my $is_vlan = is_vlan_interface($port);
|
||||
|
||||
# vlan (routed) interface check
|
||||
return "forbidden: [$name] is a vlan interface on [$ip]"
|
||||
if $is_vlan;
|
||||
|
||||
return "forbidden: not permitted to change native vlan"
|
||||
if not setting('vlanctl');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
=head2 port_reconfig_check( $port )
|
||||
|
||||
=cut
|
||||
|
||||
sub port_reconfig_check {
|
||||
my $port = shift;
|
||||
my $ip = $port->ip;
|
||||
my $name = $port->port;
|
||||
|
||||
my $has_phone = port_has_phone($port);
|
||||
my $is_vlan = is_vlan_interface($port);
|
||||
|
||||
# uplink check
|
||||
return "forbidden: port [$name] on [$ip] is an uplink"
|
||||
if $port->remote_type and not $has_phone and not setting('allow_uplinks');
|
||||
|
||||
# phone check
|
||||
return "forbidden: port [$name] on [$ip] is a phone"
|
||||
if $has_phone and setting('portctl_nophones');
|
||||
|
||||
# vlan (routed) interface check
|
||||
return "forbidden: [$name] is a vlan interface on [$ip]"
|
||||
if $is_vlan and not setting('portctl_vlans');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
1;
|
||||
117
Netdisco/lib/App/Netdisco/Util/Web.pm
Normal file
117
Netdisco/lib/App/Netdisco/Util/Web.pm
Normal file
@@ -0,0 +1,117 @@
|
||||
package App::Netdisco::Util::Web;
|
||||
|
||||
use base 'Exporter';
|
||||
our @EXPORT = ();
|
||||
our @EXPORT_OK = qw/
|
||||
sort_port
|
||||
/;
|
||||
our %EXPORT_TAGS = (
|
||||
all => [qw/
|
||||
sort_port
|
||||
/],
|
||||
);
|
||||
|
||||
=head1 App::Netdisco::Util::Web
|
||||
|
||||
A set of helper subroutines to support parts of the Netdisco application.
|
||||
|
||||
There are no default exports, however the C<:all> tag will export all
|
||||
subroutines.
|
||||
|
||||
=head2 sort_port( $a, $b )
|
||||
|
||||
Sort port names of various types used by device vendors. Interface is as
|
||||
Perl's own C<sort> - two input args and an integer return value.
|
||||
|
||||
=cut
|
||||
|
||||
sub sort_port {
|
||||
my ($aval, $bval) = @_;
|
||||
|
||||
# hack for foundry "10GigabitEthernet" -> cisco-like "TenGigabitEthernet"
|
||||
$aval = "Ten$1" if $aval =~ qr/^10(GigabitEthernet.+)$/;
|
||||
$bval = "Ten$1" if $bval =~ qr/^10(GigabitEthernet.+)$/;
|
||||
|
||||
my $numbers = qr{^(\d+)$};
|
||||
my $numeric = qr{^([\d\.]+)$};
|
||||
my $dotted_numeric = qr{^(\d+)\.(\d+)$};
|
||||
my $letter_number = qr{^([a-zA-Z]+)(\d+)$};
|
||||
my $wordcharword = qr{^([^:\/.]+)[\ :\/\.]+([^:\/.]+)(\d+)?$}; #port-channel45
|
||||
my $netgear = qr{^Slot: (\d+) Port: (\d+) }; # "Slot: 0 Port: 15 Gigabit - Level"
|
||||
my $ciscofast = qr{^
|
||||
# Word Number slash (Gigabit0/)
|
||||
(\D+)(\d+)[\/:]
|
||||
# Groups of symbol float (/5.5/5.5/5.5), separated by slash or colon
|
||||
([\/:\.\d]+)
|
||||
# Optional dash (-Bearer Channel)
|
||||
(-.*)?
|
||||
$}x;
|
||||
|
||||
my @a = (); my @b = ();
|
||||
|
||||
if ($aval =~ $dotted_numeric) {
|
||||
@a = ($1,$2);
|
||||
} elsif ($aval =~ $letter_number) {
|
||||
@a = ($1,$2);
|
||||
} elsif ($aval =~ $netgear) {
|
||||
@a = ($1,$2);
|
||||
} elsif ($aval =~ $numbers) {
|
||||
@a = ($1);
|
||||
} elsif ($aval =~ $ciscofast) {
|
||||
@a = ($2,$1);
|
||||
push @a, split(/[:\/]/,$3), $4;
|
||||
} elsif ($aval =~ $wordcharword) {
|
||||
@a = ($1,$2,$3);
|
||||
} else {
|
||||
@a = ($aval);
|
||||
}
|
||||
|
||||
if ($bval =~ $dotted_numeric) {
|
||||
@b = ($1,$2);
|
||||
} elsif ($bval =~ $letter_number) {
|
||||
@b = ($1,$2);
|
||||
} elsif ($bval =~ $netgear) {
|
||||
@b = ($1,$2);
|
||||
} elsif ($bval =~ $numbers) {
|
||||
@b = ($1);
|
||||
} elsif ($bval =~ $ciscofast) {
|
||||
@b = ($2,$1);
|
||||
push @b, split(/[:\/]/,$3),$4;
|
||||
} elsif ($bval =~ $wordcharword) {
|
||||
@b = ($1,$2,$3);
|
||||
} else {
|
||||
@b = ($bval);
|
||||
}
|
||||
|
||||
# Equal until proven otherwise
|
||||
my $val = 0;
|
||||
while (scalar(@a) or scalar(@b)){
|
||||
# carried around from the last find.
|
||||
last if $val != 0;
|
||||
|
||||
my $a1 = shift @a;
|
||||
my $b1 = shift @b;
|
||||
|
||||
# A has more components - loses
|
||||
unless (defined $b1){
|
||||
$val = 1;
|
||||
last;
|
||||
}
|
||||
|
||||
# A has less components - wins
|
||||
unless (defined $a1) {
|
||||
$val = -1;
|
||||
last;
|
||||
}
|
||||
|
||||
if ($a1 =~ $numeric and $b1 =~ $numeric){
|
||||
$val = $a1 <=> $b1;
|
||||
} elsif ($a1 ne $b1) {
|
||||
$val = $a1 cmp $b1;
|
||||
}
|
||||
}
|
||||
|
||||
return $val;
|
||||
}
|
||||
|
||||
1;
|
||||
42
Netdisco/lib/App/Netdisco/Web.pm
Normal file
42
Netdisco/lib/App/Netdisco/Web.pm
Normal file
@@ -0,0 +1,42 @@
|
||||
package App::Netdisco::Web;
|
||||
|
||||
use Dancer ':syntax';
|
||||
use Dancer::Plugin::Ajax;
|
||||
|
||||
use Dancer::Plugin::DBIC;
|
||||
|
||||
use Socket6 (); # to ensure dependency is met
|
||||
use HTML::Entities (); # to ensure dependency is met
|
||||
use URI::QueryParam (); # part of URI, to add helper methods
|
||||
|
||||
use App::Netdisco::Web::AuthN;
|
||||
use App::Netdisco::Web::Search;
|
||||
use App::Netdisco::Web::Device;
|
||||
use App::Netdisco::Web::PortControl;
|
||||
use App::Netdisco::Web::Inventory;
|
||||
|
||||
hook 'before_template' => sub {
|
||||
my $tokens = shift;
|
||||
|
||||
# allow portable static content
|
||||
$tokens->{uri_base} = request->base->path
|
||||
if request->base->path ne '/';
|
||||
|
||||
# allow portable dynamic content
|
||||
$tokens->{uri_for} = \&uri_for;
|
||||
|
||||
# allow very long lists of ports
|
||||
$Template::Directive::WHILE_MAX = 10_000;
|
||||
};
|
||||
|
||||
get '/' => sub {
|
||||
template 'index';
|
||||
};
|
||||
|
||||
any qr{.*} => sub {
|
||||
var('notfound' => true);
|
||||
status 'not_found';
|
||||
template 'index';
|
||||
};
|
||||
|
||||
true;
|
||||
44
Netdisco/lib/App/Netdisco/Web/AuthN.pm
Normal file
44
Netdisco/lib/App/Netdisco/Web/AuthN.pm
Normal file
@@ -0,0 +1,44 @@
|
||||
package App::Netdisco::Web::AuthN;
|
||||
|
||||
use Dancer ':syntax';
|
||||
use Dancer::Plugin::DBIC;
|
||||
|
||||
use Digest::MD5 ();
|
||||
|
||||
hook 'before' => sub {
|
||||
if (! session('user') && request->path ne uri_for('/login')->path) {
|
||||
if (setting('no_auth')) {
|
||||
session(user => 'guest');
|
||||
}
|
||||
else {
|
||||
request->path_info('/');
|
||||
}
|
||||
}
|
||||
|
||||
if (session('user') && session->id) {
|
||||
var(user => schema('netdisco')->resultset('User')
|
||||
->find(session('user')));
|
||||
}
|
||||
};
|
||||
|
||||
post '/login' => sub {
|
||||
if (param('username') and param('password')) {
|
||||
my $user = schema('netdisco')->resultset('User')->find(param('username'));
|
||||
if ($user) {
|
||||
my $sum = Digest::MD5::md5_hex(param('password'));
|
||||
if ($sum and $sum eq $user->password) {
|
||||
session(user => $user->username);
|
||||
redirect uri_for('/inventory');
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
redirect uri_for('/', {failed => 1});
|
||||
};
|
||||
|
||||
get '/logout' => sub {
|
||||
session->destroy;
|
||||
redirect uri_for('/', {logout => 1});
|
||||
};
|
||||
|
||||
true;
|
||||
305
Netdisco/lib/App/Netdisco/Web/Device.pm
Normal file
305
Netdisco/lib/App/Netdisco/Web/Device.pm
Normal file
@@ -0,0 +1,305 @@
|
||||
package App::Netdisco::Web::Device;
|
||||
|
||||
use Dancer ':syntax';
|
||||
use Dancer::Plugin::Ajax;
|
||||
use Dancer::Plugin::DBIC;
|
||||
|
||||
use NetAddr::IP::Lite ':lower';
|
||||
use App::Netdisco::Util::Web (); # for sort_port
|
||||
|
||||
hook 'before' => sub {
|
||||
# list of port detail columns
|
||||
var('port_columns' => [
|
||||
{ name => 'c_admin', label => 'Port Control', default => '' },
|
||||
{ name => 'c_port', label => 'Port', default => 'on' },
|
||||
{ name => 'c_descr', label => 'Description', default => '' },
|
||||
{ name => 'c_type', label => 'Type', default => '' },
|
||||
{ name => 'c_duplex', label => 'Duplex', default => '' },
|
||||
{ name => 'c_lastchange', label => 'Last Change', default => '' },
|
||||
{ name => 'c_name', label => 'Name', default => 'on' },
|
||||
{ name => 'c_speed', label => 'Speed', default => '' },
|
||||
{ name => 'c_mac', label => 'Port MAC', default => '' },
|
||||
{ name => 'c_mtu', label => 'MTU', default => '' },
|
||||
{ name => 'c_vlan', label => 'Native VLAN', default => 'on' },
|
||||
{ name => 'c_vmember', label => 'Tagged VLANs', default => 'on' },
|
||||
{ name => 'c_power', label => 'PoE', default => '' },
|
||||
{ name => 'c_nodes', label => 'Connected Nodes', default => '' },
|
||||
{ name => 'c_neighbors', label => 'Connected Devices', default => 'on' },
|
||||
{ name => 'c_stp', label => 'Spanning Tree', default => '' },
|
||||
{ name => 'c_up', label => 'Status', default => '' },
|
||||
]);
|
||||
|
||||
# view settings for port connected devices
|
||||
var('connected_properties' => [
|
||||
{ name => 'n_age', label => 'Age Stamp', default => '' },
|
||||
{ name => 'n_ip', label => 'IP Address', default => 'on' },
|
||||
{ name => 'n_archived', label => 'Archived Data', default => '' },
|
||||
]);
|
||||
|
||||
# new searches will use these defaults in their sidebars
|
||||
var('device_ports' => uri_for('/device', {
|
||||
tab => 'ports',
|
||||
age_num => 3,
|
||||
age_unit => 'months',
|
||||
}));
|
||||
|
||||
foreach my $col (@{ var('port_columns') }) {
|
||||
next unless $col->{default} eq 'on';
|
||||
var('device_ports')->query_param($col->{name}, 'checked');
|
||||
}
|
||||
|
||||
foreach my $col (@{ var('connected_properties') }) {
|
||||
next unless $col->{default} eq 'on';
|
||||
var('device_ports')->query_param($col->{name}, 'checked');
|
||||
}
|
||||
|
||||
if (request->path eq uri_for('/device')->path
|
||||
or index(request->path, uri_for('/ajax/content/device')->path) == 0) {
|
||||
|
||||
foreach my $col (@{ var('port_columns') }) {
|
||||
next unless $col->{default} eq 'on';
|
||||
params->{$col->{name}} = 'checked'
|
||||
if not param('tab') or param('tab') ne 'ports';
|
||||
}
|
||||
|
||||
foreach my $col (@{ var('connected_properties') }) {
|
||||
next unless $col->{default} eq 'on';
|
||||
params->{$col->{name}} = 'checked'
|
||||
if not param('tab') or param('tab') ne 'ports';
|
||||
}
|
||||
|
||||
if (not param('tab') or param('tab') ne 'ports') {
|
||||
params->{'age_num'} = 3;
|
||||
params->{'age_unit'} = 'months';
|
||||
}
|
||||
|
||||
# for templates to link to same page with modified query but same options
|
||||
my $self_uri = uri_for(request->path, scalar params);
|
||||
$self_uri->query_param_delete('q');
|
||||
$self_uri->query_param_delete('f');
|
||||
var('self_options' => $self_uri->query_form_hash);
|
||||
}
|
||||
};
|
||||
|
||||
ajax '/ajax/content/device/:thing' => sub {
|
||||
return "<p>Hello, this is where the ". param('thing') ." content goes.</p>";
|
||||
};
|
||||
|
||||
ajax '/ajax/content/device/netmap' => sub {
|
||||
content_type('text/html');
|
||||
template 'ajax/device/netmap.tt', {}, { layout => undef };
|
||||
};
|
||||
|
||||
sub _get_name {
|
||||
my $ip = shift;
|
||||
my $domain = quotemeta( setting('domain_suffix') || '' );
|
||||
|
||||
(my $dns = (var('devices')->{$ip} || '')) =~ s/$domain$//;
|
||||
return ($dns || $ip);
|
||||
}
|
||||
|
||||
sub _add_children {
|
||||
my ($ptr, $childs) = @_;
|
||||
my @legit = ();
|
||||
|
||||
foreach my $c (@$childs) {
|
||||
next if exists var('seen')->{$c};
|
||||
var('seen')->{$c}++;
|
||||
push @legit, $c;
|
||||
push @{$ptr}, { name => _get_name($c), ip => $c };
|
||||
}
|
||||
|
||||
for (my $i = 0; $i < @legit; $i++) {
|
||||
$ptr->[$i]->{children} = [];
|
||||
_add_children($ptr->[$i]->{children}, var('links')->{$legit[$i]});
|
||||
}
|
||||
}
|
||||
|
||||
# d3 seems not to use proper json semantics, so get instead of ajax
|
||||
get '/ajax/data/device/netmap' => sub {
|
||||
my $start = param('q');
|
||||
return unless $start;
|
||||
|
||||
my @devices = schema->resultset('Device')->search({}, {
|
||||
result_class => 'DBIx::Class::ResultClass::HashRefInflator',
|
||||
columns => ['ip', 'dns'],
|
||||
})->all;
|
||||
var(devices => { map { $_->{ip} => $_->{dns} } @devices });
|
||||
|
||||
var(links => {});
|
||||
my $rs = schema->resultset('Virtual::DeviceLinks')->search({}, {
|
||||
result_class => 'DBIx::Class::ResultClass::HashRefInflator',
|
||||
});
|
||||
|
||||
while (my $l = $rs->next) {
|
||||
var('links')->{ $l->{left_ip} } ||= [];
|
||||
push @{ var('links')->{ $l->{left_ip} } }, $l->{right_ip};
|
||||
}
|
||||
|
||||
my %tree = (
|
||||
ip => $start,
|
||||
name => _get_name($start),
|
||||
children => [],
|
||||
);
|
||||
|
||||
var(seen => {$start => 1});
|
||||
_add_children($tree{children}, var('links')->{$start});
|
||||
|
||||
content_type('application/json');
|
||||
return to_json(\%tree);
|
||||
};
|
||||
|
||||
ajax '/ajax/data/device/alldevicelinks' => sub {
|
||||
my @devices = schema->resultset('Device')->search({}, {
|
||||
result_class => 'DBIx::Class::ResultClass::HashRefInflator',
|
||||
columns => ['ip', 'dns'],
|
||||
})->all;
|
||||
var(devices => { map { $_->{ip} => $_->{dns} } @devices });
|
||||
|
||||
my $rs = schema->resultset('Virtual::DeviceLinks')->search({}, {
|
||||
result_class => 'DBIx::Class::ResultClass::HashRefInflator',
|
||||
});
|
||||
|
||||
my %tree = ();
|
||||
while (my $l = $rs->next) {
|
||||
push @{ $tree{ _get_name($l->{left_ip} )} },
|
||||
_get_name($l->{right_ip});
|
||||
}
|
||||
|
||||
content_type('application/json');
|
||||
return to_json(\%tree);
|
||||
};
|
||||
|
||||
# device interface addresses
|
||||
ajax '/ajax/content/device/addresses' => sub {
|
||||
my $ip = param('q');
|
||||
return unless $ip;
|
||||
|
||||
my $set = schema('netdisco')->resultset('DeviceIp')
|
||||
->search({ip => $ip}, {order_by => 'alias'});
|
||||
return unless $set->count;
|
||||
|
||||
content_type('text/html');
|
||||
template 'ajax/device/addresses.tt', {
|
||||
results => $set,
|
||||
}, { layout => undef };
|
||||
};
|
||||
|
||||
# device ports with a description (er, name) matching
|
||||
ajax '/ajax/content/device/ports' => sub {
|
||||
my $ip = param('q');
|
||||
return unless $ip;
|
||||
|
||||
my $set = schema('netdisco')->resultset('DevicePort')
|
||||
->search({'me.ip' => $ip});
|
||||
|
||||
# refine by ports if requested
|
||||
my $q = param('f');
|
||||
if ($q) {
|
||||
if ($q =~ m/^\d+$/) {
|
||||
$set = $set->search({'me.vlan' => $q});
|
||||
return unless $set->count;
|
||||
}
|
||||
else {
|
||||
$q =~ s/\*/%/g if index($q, '*') >= 0;
|
||||
$q =~ s/\?/_/g if index($q, '?') >= 0;
|
||||
$q = { '-ilike' => $q };
|
||||
|
||||
if ($set->search({'me.port' => $q})->count) {
|
||||
$set = $set->search({'me.port' => $q});
|
||||
}
|
||||
else {
|
||||
$set = $set->search({'me.name' => $q});
|
||||
return unless $set->count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# filter for free ports if asked
|
||||
my $free_filter = (param('free') ? 'only_free_ports' : 'with_is_free');
|
||||
$set = $set->$free_filter({
|
||||
age_num => (param('age_num') || 3),
|
||||
age_unit => (param('age_unit') || 'months')
|
||||
});
|
||||
|
||||
# make sure query asks for formatted timestamps when needed
|
||||
$set = $set->with_times if param('c_lastchange');
|
||||
|
||||
# get number of vlans on the port to control whether to list them or not
|
||||
$set = $set->with_vlan_count if param('c_vmember');
|
||||
|
||||
# what kind of nodes are we interested in?
|
||||
my $nodes_name = (param('n_archived') ? 'nodes' : 'active_nodes');
|
||||
$nodes_name .= '_with_age' if param('c_nodes') and param('n_age');
|
||||
|
||||
# retrieve active/all connected nodes, if asked for
|
||||
$set = $set->search_rs({}, { prefetch => [{$nodes_name => 'ips'}] })
|
||||
if param('c_nodes');
|
||||
|
||||
# retrieve neighbor devices, if asked for
|
||||
$set = $set->search_rs({}, { prefetch => [{neighbor_alias => 'device'}] })
|
||||
if param('c_neighbors');
|
||||
|
||||
# sort ports (empty set would be a 'no records' msg)
|
||||
my $results = [ sort { &App::Netdisco::Util::Web::sort_port($a->port, $b->port) } $set->all ];
|
||||
return unless scalar @$results;
|
||||
|
||||
content_type('text/html');
|
||||
template 'ajax/device/ports.tt', {
|
||||
results => $results,
|
||||
nodes => $nodes_name,
|
||||
device => $ip,
|
||||
}, { layout => undef };
|
||||
};
|
||||
|
||||
# device details table
|
||||
ajax '/ajax/content/device/details' => sub {
|
||||
my $ip = param('q');
|
||||
return unless $ip;
|
||||
|
||||
my $device = schema('netdisco')->resultset('Device')
|
||||
->with_times()->find($ip);
|
||||
return unless $device;
|
||||
|
||||
content_type('text/html');
|
||||
template 'ajax/device/details.tt', {
|
||||
d => $device,
|
||||
}, { layout => undef };
|
||||
};
|
||||
|
||||
# support typeahead with simple AJAX query for device names
|
||||
ajax '/ajax/data/device/typeahead' => sub {
|
||||
my $q = param('query');
|
||||
my $set = schema('netdisco')->resultset('Device')->search_fuzzy($q);
|
||||
|
||||
content_type 'application/json';
|
||||
return to_json [map {$_->dns || $_->name || $_->ip} $set->all];
|
||||
};
|
||||
|
||||
get '/device' => sub {
|
||||
my $ip = NetAddr::IP::Lite->new(param('q'));
|
||||
if (! $ip) {
|
||||
redirect uri_for('/', {nosuchdevice => 1});
|
||||
return;
|
||||
}
|
||||
|
||||
my $device = schema('netdisco')->resultset('Device')->find($ip->addr);
|
||||
if (! $device) {
|
||||
redirect uri_for('/', {nosuchdevice => 1});
|
||||
return;
|
||||
}
|
||||
|
||||
# list of tabs
|
||||
var('tabs' => [
|
||||
{ id => 'details', label => 'Details' },
|
||||
{ id => 'ports', label => 'Ports' },
|
||||
{ id => 'modules', label => 'Modules' },
|
||||
{ id => 'netmap', label => 'Neighbors' },
|
||||
{ id => 'addresses', label => 'Addresses' },
|
||||
]);
|
||||
|
||||
params->{'tab'} ||= 'details';
|
||||
template 'device', { d => $device };
|
||||
};
|
||||
|
||||
true;
|
||||
18
Netdisco/lib/App/Netdisco/Web/Inventory.pm
Normal file
18
Netdisco/lib/App/Netdisco/Web/Inventory.pm
Normal file
@@ -0,0 +1,18 @@
|
||||
package App::Netdisco::Web::Inventory;
|
||||
|
||||
use Dancer ':syntax';
|
||||
use Dancer::Plugin::DBIC;
|
||||
|
||||
get '/inventory' => sub {
|
||||
my $models = schema('netdisco')->resultset('Device')->get_models();
|
||||
my $releases = schema('netdisco')->resultset('Device')->get_releases();
|
||||
|
||||
var(nav => 'inventory');
|
||||
|
||||
template 'inventory', {
|
||||
models => $models,
|
||||
releases => $releases,
|
||||
};
|
||||
};
|
||||
|
||||
true;
|
||||
72
Netdisco/lib/App/Netdisco/Web/PortControl.pm
Normal file
72
Netdisco/lib/App/Netdisco/Web/PortControl.pm
Normal file
@@ -0,0 +1,72 @@
|
||||
package App::Netdisco::Web::PortControl;
|
||||
|
||||
use Dancer ':syntax';
|
||||
use Dancer::Plugin::Ajax;
|
||||
use Dancer::Plugin::DBIC;
|
||||
use Try::Tiny;
|
||||
|
||||
ajax '/ajax/portcontrol' => sub {
|
||||
try {
|
||||
my $log = sprintf 'd:[%s] p:[%s] f:[%s]. a:[%s] v[%s]',
|
||||
param('device'), (param('port') || ''), param('field'),
|
||||
(param('action') || ''), (param('value') || '');
|
||||
|
||||
my %action_map = (
|
||||
'location' => 'location',
|
||||
'contact' => 'contact',
|
||||
'c_port' => 'portcontrol',
|
||||
'c_name' => 'portname',
|
||||
'c_vlan' => 'vlan',
|
||||
'c_power' => 'power',
|
||||
);
|
||||
|
||||
my $action = $action_map{ param('field') };
|
||||
my $subaction = ($action =~ m/^(?:power|portcontrol)/
|
||||
? (param('action') ."-other")
|
||||
: param('value'));
|
||||
|
||||
schema('netdisco')->resultset('Admin')->create({
|
||||
device => param('device'),
|
||||
port => param('port'),
|
||||
action => $action,
|
||||
subaction => $subaction,
|
||||
status => 'queued',
|
||||
username => session('user'),
|
||||
userip => request->remote_address,
|
||||
log => $log,
|
||||
});
|
||||
}
|
||||
catch {
|
||||
send_error('Failed to parse params or add DB record');
|
||||
};
|
||||
|
||||
content_type('application/json');
|
||||
to_json({});
|
||||
};
|
||||
|
||||
ajax '/ajax/userlog' => sub {
|
||||
my $user = session('user');
|
||||
send_error('No username') unless $user;
|
||||
|
||||
my $rs = schema('netdisco')->resultset('Admin')->search({
|
||||
username => $user,
|
||||
action => [qw/location contact portcontrol portname vlan power/],
|
||||
finished => { '>' => \"(now() - interval '5 seconds')" },
|
||||
});
|
||||
|
||||
my %status = (
|
||||
'done' => [
|
||||
map {s/\[\]/<empty>/; $_}
|
||||
$rs->search({status => 'done'})->get_column('log')->all
|
||||
],
|
||||
'error' => [
|
||||
map {s/\[\]/<empty>/; $_}
|
||||
$rs->search({status => 'error'})->get_column('log')->all
|
||||
],
|
||||
);
|
||||
|
||||
content_type('application/json');
|
||||
to_json(\%status);
|
||||
};
|
||||
|
||||
true;
|
||||
250
Netdisco/lib/App/Netdisco/Web/Search.pm
Normal file
250
Netdisco/lib/App/Netdisco/Web/Search.pm
Normal file
@@ -0,0 +1,250 @@
|
||||
package App::Netdisco::Web::Search;
|
||||
|
||||
use Dancer ':syntax';
|
||||
use Dancer::Plugin::Ajax;
|
||||
use Dancer::Plugin::DBIC;
|
||||
|
||||
use NetAddr::IP::Lite ':lower';
|
||||
use Net::MAC ();
|
||||
use List::MoreUtils ();
|
||||
|
||||
hook 'before' => sub {
|
||||
# view settings for node options
|
||||
var('node_options' => [
|
||||
{ name => 'stamps', label => 'Time Stamps', default => 'on' },
|
||||
]);
|
||||
# view settings for device options
|
||||
var('device_options' => [
|
||||
{ name => 'matchall', label => 'Match All Options', default => 'on' },
|
||||
]);
|
||||
|
||||
# new searches will use these defaults in their sidebars
|
||||
var('search_node' => uri_for('/search', {tab => 'node'}));
|
||||
var('search_device' => uri_for('/search', {tab => 'device'}));
|
||||
|
||||
foreach my $col (@{ var('node_options') }) {
|
||||
next unless $col->{default} eq 'on';
|
||||
var('search_node')->query_param($col->{name}, 'checked');
|
||||
}
|
||||
|
||||
foreach my $col (@{ var('device_options') }) {
|
||||
next unless $col->{default} eq 'on';
|
||||
var('search_device')->query_param($col->{name}, 'checked');
|
||||
}
|
||||
|
||||
if (request->path eq uri_for('/search')->path
|
||||
or index(request->path, uri_for('/ajax/content/search')->path) == 0) {
|
||||
|
||||
foreach my $col (@{ var('node_options') }) {
|
||||
next unless $col->{default} eq 'on';
|
||||
params->{$col->{name}} = 'checked'
|
||||
if not param('tab') or param('tab') ne 'node';
|
||||
}
|
||||
|
||||
foreach my $col (@{ var('device_options') }) {
|
||||
next unless $col->{default} eq 'on';
|
||||
params->{$col->{name}} = 'checked'
|
||||
if not param('tab') or param('tab') ne 'device';
|
||||
}
|
||||
|
||||
# used in the device search sidebar template to set selected items
|
||||
foreach my $opt (qw/model vendor os_ver/) {
|
||||
my $p = (ref [] eq ref param($opt) ? param($opt)
|
||||
: (param($opt) ? [param($opt)] : []));
|
||||
var("${opt}_lkp" => { map { $_ => 1 } @$p });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
# device with various properties or a default match-all
|
||||
ajax '/ajax/content/search/device' => sub {
|
||||
my $has_opt = List::MoreUtils::any {param($_)}
|
||||
qw/name location dns ip description model os_ver vendor/;
|
||||
my $set;
|
||||
|
||||
if ($has_opt) {
|
||||
$set = schema('netdisco')->resultset('Device')->search_by_field(scalar params);
|
||||
}
|
||||
else {
|
||||
my $q = param('q');
|
||||
return unless $q;
|
||||
|
||||
$set = schema('netdisco')->resultset('Device')->search_fuzzy($q);
|
||||
}
|
||||
return unless $set->count;
|
||||
|
||||
content_type('text/html');
|
||||
template 'ajax/search/device.tt', {
|
||||
results => $set,
|
||||
}, { layout => undef };
|
||||
};
|
||||
|
||||
# nodes matching the param as an IP or DNS hostname or MAC
|
||||
ajax '/ajax/content/search/node' => sub {
|
||||
my $node = param('q');
|
||||
return unless $node;
|
||||
content_type('text/html');
|
||||
|
||||
my $mac = Net::MAC->new(mac => $node, 'die' => 0, verbose => 0);
|
||||
my @active = (param('archived') ? () : (-bool => 'active'));
|
||||
|
||||
if (! $mac->get_error) {
|
||||
my $sightings = schema('netdisco')->resultset('Node')
|
||||
->search_by_mac({mac => $mac->as_IEEE, @active});
|
||||
|
||||
my $ips = schema('netdisco')->resultset('NodeIp')
|
||||
->search_by_mac({mac => $mac->as_IEEE, @active});
|
||||
|
||||
my $ports = schema('netdisco')->resultset('DevicePort')
|
||||
->search({mac => $mac->as_IEEE});
|
||||
|
||||
return unless $sightings->count
|
||||
or $ips->count
|
||||
or $ports->count;
|
||||
|
||||
template 'ajax/search/node_by_mac.tt', {
|
||||
ips => $ips,
|
||||
sightings => $sightings,
|
||||
ports => $ports,
|
||||
}, { layout => undef };
|
||||
}
|
||||
else {
|
||||
my $set;
|
||||
|
||||
if (my $ip = NetAddr::IP::Lite->new($node)) {
|
||||
# search_by_ip() will extract cidr notation if necessary
|
||||
$set = schema('netdisco')->resultset('NodeIp')
|
||||
->search_by_ip({ip => $ip, @active});
|
||||
}
|
||||
else {
|
||||
if (param('partial')) {
|
||||
$node = "\%$node\%";
|
||||
}
|
||||
elsif (setting('domain_suffix')) {
|
||||
$node .= setting('domain_suffix')
|
||||
if index($node, setting('domain_suffix')) == -1;
|
||||
}
|
||||
$set = schema('netdisco')->resultset('NodeIp')
|
||||
->search_by_dns({dns => $node, @active});
|
||||
}
|
||||
return unless $set and $set->count;
|
||||
|
||||
template 'ajax/search/node_by_ip.tt', {
|
||||
macs => $set,
|
||||
archive_filter => {@active},
|
||||
}, { layout => undef };
|
||||
}
|
||||
};
|
||||
|
||||
# devices carrying vlan xxx
|
||||
ajax '/ajax/content/search/vlan' => sub {
|
||||
my $q = param('q');
|
||||
return unless $q;
|
||||
my $set;
|
||||
|
||||
if ($q =~ m/^\d+$/) {
|
||||
$set = schema('netdisco')->resultset('Device')->carrying_vlan({vlan => $q});
|
||||
}
|
||||
else {
|
||||
$set = schema('netdisco')->resultset('Device')->carrying_vlan_name({name => $q});
|
||||
}
|
||||
return unless $set->count;
|
||||
|
||||
content_type('text/html');
|
||||
template 'ajax/search/vlan.tt', {
|
||||
results => $set,
|
||||
}, { layout => undef };
|
||||
};
|
||||
|
||||
# device ports with a description (er, name) matching
|
||||
ajax '/ajax/content/search/port' => sub {
|
||||
my $q = param('q');
|
||||
return unless $q;
|
||||
my $set;
|
||||
|
||||
if ($q =~ m/^\d+$/) {
|
||||
$set = schema('netdisco')->resultset('DevicePort')->search({vlan => $q});
|
||||
}
|
||||
else {
|
||||
$set = schema('netdisco')->resultset('DevicePort')->search({name => $q});
|
||||
}
|
||||
return unless $set->count;
|
||||
|
||||
content_type('text/html');
|
||||
template 'ajax/search/port.tt', {
|
||||
results => $set,
|
||||
}, { layout => undef };
|
||||
};
|
||||
|
||||
get '/search' => sub {
|
||||
my $q = param('q');
|
||||
if (not param('tab')) {
|
||||
if (not $q) {
|
||||
redirect uri_for('/');
|
||||
}
|
||||
|
||||
# pick most likely tab for initial results
|
||||
if ($q =~ m/^\d+$/) {
|
||||
params->{'tab'} = 'vlan';
|
||||
}
|
||||
else {
|
||||
my $s = schema('netdisco');
|
||||
if ($q =~ m{^[a-f0-9.:/]+$}i) {
|
||||
my $ip = NetAddr::IP::Lite->new($q);
|
||||
my $nd = $s->resultset('Device')->search_by_field({ip => $q});
|
||||
if ($ip and $nd->count) {
|
||||
if ($nd->count == 1) {
|
||||
# redirect to device details for the one device
|
||||
redirect uri_for('/device',
|
||||
{tab => 'details', q => $q, f => ''});
|
||||
}
|
||||
params->{'tab'} = 'device';
|
||||
}
|
||||
else {
|
||||
# this will match for MAC addresses
|
||||
# and partial IPs (subnets?)
|
||||
params->{'tab'} = 'node';
|
||||
}
|
||||
}
|
||||
else {
|
||||
my $nd = $s->resultset('Device')->search({dns => { '-ilike' => "\%$q\%" }});
|
||||
if ($nd->count) {
|
||||
if ($nd->count == 1) {
|
||||
# redirect to device details for the one device
|
||||
redirect uri_for('/device',
|
||||
{tab => 'details', q => $nd->first->ip, f => ''});
|
||||
}
|
||||
params->{'tab'} = 'device';
|
||||
}
|
||||
elsif ($s->resultset('DevicePort')
|
||||
->search({name => "\%$q\%"})->count) {
|
||||
params->{'tab'} = 'port';
|
||||
}
|
||||
}
|
||||
params->{'tab'} ||= 'node';
|
||||
}
|
||||
}
|
||||
|
||||
# used in the device search sidebar to populate select inputs
|
||||
var('model_list' => [
|
||||
schema('netdisco')->resultset('Device')->get_distinct_col('model')
|
||||
]);
|
||||
var('os_ver_list' => [
|
||||
schema('netdisco')->resultset('Device')->get_distinct_col('os_ver')
|
||||
]);
|
||||
var('vendor_list' => [
|
||||
schema('netdisco')->resultset('Device')->get_distinct_col('vendor')
|
||||
]);
|
||||
|
||||
# list of tabs
|
||||
var('tabs' => [
|
||||
{ id => 'device', label => 'Device' },
|
||||
{ id => 'node', label => 'Node' },
|
||||
{ id => 'vlan', label => 'VLAN' },
|
||||
{ id => 'port', label => 'Port' },
|
||||
]);
|
||||
|
||||
template 'search';
|
||||
};
|
||||
|
||||
true;
|
||||
Reference in New Issue
Block a user