1use utf8;
2package App::Netdisco::DB::Result::Node;
3
4
5use strict;
6use warnings;
7
8use NetAddr::MAC;
9
10use base 'App::Netdisco::DB::Result';
11__PACKAGE__->table("node");
12__PACKAGE__->add_columns(
13  "mac",
14  { data_type => "macaddr", is_nullable => 0 },
15  "switch",
16  { data_type => "inet", is_nullable => 0 },
17  "port",
18  { data_type => "text", is_nullable => 0 },
19  "active",
20  { data_type => "boolean", is_nullable => 1 },
21  "oui",
22  { data_type => "varchar", is_nullable => 1, is_serializable => 0, size => 8 },
23  "time_first",
24  {
25    data_type     => "timestamp",
26    default_value => \"current_timestamp",
27    is_nullable   => 1,
28    original      => { default_value => \"now()" },
29  },
30  "time_recent",
31  {
32    data_type     => "timestamp",
33    default_value => \"current_timestamp",
34    is_nullable   => 1,
35    original      => { default_value => \"now()" },
36  },
37  "time_last",
38  {
39    data_type     => "timestamp",
40    default_value => \"current_timestamp",
41    is_nullable   => 1,
42    original      => { default_value => \"now()" },
43  },
44  "vlan",
45  { data_type => "text", is_nullable => 0, default_value => '0' },
46);
47__PACKAGE__->set_primary_key("mac", "switch", "port", "vlan");
48
49
50
51=head1 RELATIONSHIPS
52
53=head2 device
54
55Returns the single C<device> to which this Node entry was associated at the
56time of discovery.
57
58The JOIN is of type LEFT, in case the C<device> is no longer present in the
59database but the relation is being used in C<search()>.
60
61=cut
62
63__PACKAGE__->belongs_to( device => 'App::Netdisco::DB::Result::Device',
64  { 'foreign.ip' => 'self.switch' }, { join_type => 'LEFT' } );
65
66=head2 device_port
67
68Returns the single C<device_port> to which this Node entry was associated at
69the time of discovery.
70
71The JOIN is of type LEFT, in case the C<device> is no longer present in the
72database but the relation is being used in C<search()>.
73
74=cut
75
76# device port may have been deleted (reconfigured modules?) but node remains
77__PACKAGE__->belongs_to( device_port => 'App::Netdisco::DB::Result::DevicePort',
78  { 'foreign.ip' => 'self.switch', 'foreign.port' => 'self.port' },
79  { join_type => 'LEFT' }
80);
81
82=head2 wireless_port
83
84Returns the single C<wireless_port> to which this Node entry was associated at
85the time of discovery.
86
87The JOIN is of type LEFT, in case the C<device> is no longer present in the
88database but the relation is being used in C<search()>.
89
90=cut
91
92__PACKAGE__->belongs_to(
93    wireless_port => 'App::Netdisco::DB::Result::DevicePortWireless',
94    { 'foreign.ip' => 'self.switch', 'foreign.port' => 'self.port' },
95    { join_type    => 'LEFT' }
96);
97
98=head2 ips
99
100Returns the set of C<node_ip> entries associated with this Node. That is, the
101IP addresses which this MAC address was hosting at the time of discovery.
102
103Note that the Active status of the returned IP entries will all be the same as
104the current Node's.
105
106=cut
107
108__PACKAGE__->has_many( ips => 'App::Netdisco::DB::Result::NodeIp',
109  { 'foreign.mac' => 'self.mac', 'foreign.active' => 'self.active' } );
110
111=head2 ip4s
112
113Same as C<ips> but for IPv4 only.
114
115=cut
116
117__PACKAGE__->has_many( ip4s => 'App::Netdisco::DB::Result::Virtual::NodeIp4',
118  { 'foreign.mac' => 'self.mac', 'foreign.active' => 'self.active' } );
119
120=head2 ip6s
121
122Same as C<ips> but for IPv6 only.
123
124=cut
125
126__PACKAGE__->has_many( ip6s => 'App::Netdisco::DB::Result::Virtual::NodeIp6',
127  { 'foreign.mac' => 'self.mac', 'foreign.active' => 'self.active' } );
128
129=head2 netbios
130
131Returns the C<node_nbt> entry associated with this Node if one exists. That
132is, the NetBIOS information of this MAC address at the time of discovery.
133
134=cut
135
136__PACKAGE__->might_have( netbios => 'App::Netdisco::DB::Result::NodeNbt',
137  { 'foreign.mac' => 'self.mac' } );
138
139=head2 wireless
140
141Returns the set of C<node_wireless> entries associated with this Node. That
142is, the SSIDs and wireless statistics associated with this MAC address
143at the time of discovery.
144
145=cut
146
147__PACKAGE__->has_many( wireless => 'App::Netdisco::DB::Result::NodeWireless',
148  { 'foreign.mac' => 'self.mac' } );
149
150=head2 oui
151
152Returns the C<oui> table entry matching this Node. You can then join on this
153relation and retrieve the Company name from the related table.
154
155The JOIN is of type LEFT, in case the OUI table has not been populated.
156
157=cut
158
159__PACKAGE__->belongs_to( oui => 'App::Netdisco::DB::Result::Oui', 'oui',
160  { join_type => 'LEFT' } );
161
162=head1 ADDITIONAL COLUMNS
163
164=head2 time_first_stamp
165
166Formatted version of the C<time_first> field, accurate to the minute.
167
168The format is somewhat like ISO 8601 or RFC3339 but without the middle C<T>
169between the date stamp and time stamp. That is:
170
171 2012-02-06 12:49
172
173=cut
174
175sub time_first_stamp { return (shift)->get_column('time_first_stamp') }
176
177=head2 time_last_stamp
178
179Formatted version of the C<time_last> field, accurate to the minute.
180
181The format is somewhat like ISO 8601 or RFC3339 but without the middle C<T>
182between the date stamp and time stamp. That is:
183
184 2012-02-06 12:49
185
186=cut
187
188sub time_last_stamp  { return (shift)->get_column('time_last_stamp')  }
189
190=head2 net_mac
191
192Returns the C<mac> column instantiated into a L<NetAddr::MAC> object.
193
194=cut
195
196sub net_mac { return NetAddr::MAC->new(mac => ((shift)->mac || '')) }
197
1981;
199