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

Last change on this file since 1470 was 1436, checked in by nanardon, 9 years ago

Cname don't have to be uniq

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