source: trunk/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Sql/Nethost.pm @ 2116

Last change on this file since 2116 was 2113, checked in by nanardon, 7 years ago

Revert computing of zone matching: too costly

File size: 10.6 KB
RevLine 
[861]1package LATMOS::Accounts::Bases::Sql::Nethost;
2
3use 5.010000;
4use strict;
5use warnings;
6
7use base qw(LATMOS::Accounts::Bases::Sql::objects);
8use LATMOS::Accounts::Log;
[1551]9use LATMOS::Accounts::I18N;
[1419]10use Net::IP;
[861]11
12our $VERSION = (q$Rev: 2104 $ =~ /^Rev: (\d+) /)[0];
13
14=head1 NAME
15
[1023]16LATMOS::Accounts::Bases::Sql::Nethost - A Network Host entry
[861]17
18=cut
19
[1014]20sub _object_table { 'nethost' }
[861]21
[1014]22sub _key_field { 'name' }
[861]23
[1014]24sub _has_extended_attributes { 1 }
[861]25
26sub _get_attr_schema {
27    my ($class, $base) = @_;
28
29    $class->SUPER::_get_attr_schema($base,
30        {
31            name    => { ro => 1, inline => 1, },
32            cn      => { ro => 1, inline => 1, iname => 'name' },
33            date    => { ro => 1, inline => 1, },
34            create  => { ro => 1, inline => 1, },
[1737]35            expire    => {
36                inline => 1,
37                formtype => 'DATE',
38                label => l('Expire'),
39            },
[2097]40            endOfWarranty => {
41                formtype => 'DATE',
42                label => l('End of warranty'),
43            },
[861]44            ip      => {
[1297]45                monitored => 1,
[861]46                multiple => 1,
47                uniq => 1,
48                input => sub {
[1420]49                    my $ip = $_[0] or return;
[861]50                    $ip =~ s/(\D|^)0+/$1/g;
[1419]51                    $ip =~ s:/.*$::;
[861]52                    $ip
53                },
[1419]54                checkinputformat => sub {
55                    my ($value) = @_;
[1420]56                    $value or return;
[1419]57                    my $ip = Net::IP->new($value);
58                    $ip or return;
59                    $ip->prefixlen() == ($ip->version == 4 ? 32 : 128) or do {
60                        $base->log(LA_ERR, "Wrong prefix len for IP %s: %d (ip version %d)",
61                            $ip->print, $ip->prefixlen, $ip->version);
62                        return undef;
63                    };
[1550]64                },
65                label => l('Ip'),
[861]66            },
67            ipFrom  => {
68                multiple => 1, 
69                managed => 1,
[1420]70                delayed => 1,
[861]71                can_values => sub {
72                    $base->search_objects('netzone', 'type=dhcp')
73                },
[1315]74                set => sub {
75                    my ($self, $data) = @_;
[1420]76                    my $count = 0;
[1315]77                    foreach (ref $data ? @{$data} : $data) {
78                        my $zone = $self->base->get_object('netzone', $_)
79                            or next;
80                        my @freeips = $zone->get_attributes('freeIP') or next;
81                        my $idx = rand(scalar(@freeips));
82                        $self->object->_addAttributeValue('ip', $freeips[$idx]);
83                        $self->base->log(LA_NOTICE, "Assigning ip %s to host %s",
84                            $freeips[$idx], $self->object->id);
[1420]85                        $count++;
[1315]86                    }
[1420]87                    return $count;
[1315]88                },
[1550]89                label => l('Ip from...'),
[861]90            },
91            macaddr => {
[1297]92                monitored => 1,
[861]93                multiple => 1,
94                uniq => 1,
95                input => sub {
[1420]96                    $_[0] or return;
[1685]97                    $_[0] =~ /^([0-9a-f]{2}([:-]|$)){6}$/i or return $_[0];
[1224]98                    my @elem = split(/[:-]/, $_[0]);
[1685]99                    return join(':', map { sprintf("%02x", hex($_)) || $_ } @elem);
[861]100                },
[1415]101                checkinputformat => sub {
[1420]102                    $_[0] or return;
[1329]103                    return $_[0] =~ /^([0-9a-f]{2}([:-]|$)){6}$/i ? 1 : undef;
104                },
[1550]105                label => l('Hardware address'),
[861]106            },
107            cname   => {
[1297]108                monitored => 1,
[1436]109                multiple => 1,
[1550]110                input => sub { lc($_[0]) },
111                label => l('Aliases'),
[861]112            },
[1302]113            related   => {
114                multiple => 1, uniq => 1,
115                reference => 'nethost',
[1550]116                label => l('Related'),
[1302]117            },
[1280]118            owner   => {
[1297]119                monitored => 1,
[861]120                reference => 'user',
121                delayed => 1,
[1550]122                label => l('Owner'),
[861]123            },
[920]124            user    => {
125                reference => 'user',
126                delayed => 1,
[1550]127                label => l('User'),
[920]128            },
[861]129            netZone => {
130                multiple => 1, ro => 1, managed => 1,
131                reference => 'netzone',
[2113]132                get => sub {
133                    my ($self) = @_;
134                    my $find = $self->base->db->prepare_cached(q{
135                        select name from netzone where ikey in
136                        (
137                        select netzone_attributes.okey from netzone_attributes join
138                        nethost_attributes_ips on netzone_attributes.attr='net'
139                            and
140                        nethost_attributes_ips.value::inet <<=
141                        netzone_attributes.value::inet
142                        where nethost_attributes_ips.okey = $1
143                        except
144                        select netzone_attributes.okey from netzone_attributes join
145                        nethost_attributes_ips on netzone_attributes.attr='netExclude'
146                            and nethost_attributes_ips.value::inet <<= netzone_attributes.value::inet
147                        where nethost_attributes_ips.okey = $1
148                        )
149                        order by name
150                        });
151                    $find->execute($self->object->get_attributes('ikey'));
152                    my @zones;
153                    while (my $res = $find->fetchrow_hashref) {
154                        push(@zones, $res->{name});
155                    }
156                    return @zones ? [ @zones ] : undef;
157                },
[1552]158                label => l('NetZones'),
[861]159            },
[1550]160            puppetClass => {
161                multiple => 1,
162                label => l('Puppet Class'),
163            },
[861]164            netZoneExclude => {
165                multiple => 1, ro => 1, managed => 1,
166                reference => 'netzone',
[1315]167                get => sub {
168                    my ($self) = @_;
169                    my $find = $self->base->db->prepare_cached(q{
170                        select name from netzone where ikey in
171                        (
172                        select netzone_attributes.okey from netzone_attributes join
173                        nethost_attributes_ips on netzone_attributes.attr='netExclude'
174                            and
175                        nethost_attributes_ips.value::inet <<=
176                        netzone_attributes.value::inet
177                        where nethost_attributes_ips.okey = $1
178                        )
179                            order by name
180                        });
181                    $find->execute($self->object->get_attributes('ikey'));
182                    my @zones;
183                    while (my $res = $find->fetchrow_hashref) {
184                        push(@zones, $res->{name});
185                    }
186                    return @zones ? [ @zones ] : undef;
187                },
[861]188            },
189            noDynamic => { 
190                formtype => 'CHECKBOX',
[1557]191                label => l('No dynamic IP'),
[861]192            },
193            exported => { formtype => 'CHECKBOX', },
[1550]194            noInheritPuppet => {
195                formtype => 'CHECKBOX',
[1557]196                label => l('No puppet'),
[1550]197            },
[861]198            otherName => {
199                multiple => 1,
200                input => sub { lc($_[0]) },
[1550]201                label => l('Other name'),
[861]202            },
[1550]203            sshfp => {
204                multiple => 1,
205                label => l('SSH finger print'),
206            },
[1374]207            ip6 => { },
[1225]208            sshfpUpdate  => {
209                managed => 1,
[1315]210                iname => 'sshfp',
211                input => sub {
212                    my ($self, $data) = @_;
[1419]213                    $data or return;
[1315]214                    open(my $h, '<', $data) or return;
215                    my @sshfps;
216                    while (my $line = <$h>) {
217                        my ($type, $mode, $key) = $line =~ /^\S+\s+IN\s+SSHFP\s+(\d)\s+(\d)\s+(\S+)/i
218                            or do {
219                            la_log(LA_ERR, "Seems to not be a ssh-keygen line: %s", $line);
220                            return;
221                        };
222                        la_log(LA_DEBUG, "found sshfp %s %s %s", $type, $mode, $key);
223                        push(@sshfps, "$type $mode $key");
224                    }
225                    close($h);
226                    \@sshfps;
227                }
[1225]228            },
[1550]229            comment => {
230                label => l('Comment'),
231            },
232            description => {
233                label => l('Description'),
234            },
[2097]235            hostType => {
236                label => l('Host\'s type'),
237            },
[1550]238            encryptKey => {
239                label => l('Encrypted key'),
240            },
241            reverse => {
242                label => l('Reverse name'),
243            },
244            serialNumber => {
245                label => l('Serial number'),
246            },
[2054]247            inventoryNumber => {
248                label => l('Inventory number'),
249            },
[2100]250            site => {
251                reference => 'site',
252                label => l('Site'),
253            },
[861]254        }
255    )
256}
257
258sub set_fields {
259    my ($self, %data) = @_;
260
[1302]261    my $res = $self->SUPER::set_fields(%data);
262
[1315]263    # Post update related
[1302]264    if (exists $data{related}) {
265        my %exists;
266        if ($data{related}) {
267            my @related = ref $data{related} ? @{$data{related}} : $data{related};
268            foreach (@related) {
269                my $obj = $self->base->get_object('nethost', $_) or next;
270                $exists{$obj->id} = 1; 
271                my @current = grep { $_ } $obj->get_attributes('related');
272                grep { $_ eq $self->id } @current and next;
273                $obj->set_c_fields('related' => [ $self->id, @current ]);
274
275            }
276        }
277        foreach ($self->base->search_objects('nethost', 'related=' . $self->id)) {
278            my $obj = $self->base->get_object('nethost', $_) or next;
279            $exists{$_} and next;
280            my @current = grep { $_ eq $self->id } $obj->get_attributes('related');
281            $obj->set_c_fields('related' => [ @current ]);
282        }
283    }
284
285    $res
[861]286}
287
2881;
289
290__END__
291
292=head1 SEE ALSO
293
[1023]294L<LATMOS::Accounts::Bases::Sql::Netzones>, L<LATMOS::Accounts::Bases::Sql>
295
[861]296=head1 AUTHOR
297
298Olivier Thauvin, E<lt>olivier.thauvin@latmos.ipsl.frE<gt>
299
300=head1 COPYRIGHT AND LICENSE
301
[1023]302Copyright (C) 2008, 2009, 2010, 2011, 2012 CNRS SA/CETP/LATMOS
[861]303
304This library is free software; you can redistribute it and/or modify
305it under the same terms as Perl itself, either Perl version 5.10.0 or,
306at your option, any later version of Perl 5 you may have available.
307
308
309=cut
Note: See TracBrowser for help on using the repository browser.