/usr/share/perl5/Zabbix/API/CRUDE.pm is in libzabbix-api-perl 0.009-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 | package Zabbix::API::CRUDE;
use strict;
use warnings;
use 5.010;
use Carp;
sub new {
my ($class, %args) = @_;
my $self = \%args;
bless $self, $class;
return $self;
}
sub id {
croak 'Class '.(ref shift).' does not implement required mutator id()';
}
sub node_id {
my ($self, $value) = @_;
if (defined $value) {
croak 'Accessor node_id() called as mutator';
}
return unless $self->id;
return unless $self->id > 100000000000000;
# this is how Zabbix operates, don't blame me
return int($self->id/100000000000000);
}
sub prefix {
croak 'Class '.(ref shift).' does not implement required method prefix()';
}
sub extension {
croak 'Class '.(ref shift).' does not implement required method extension()';
}
sub name {
croak 'Class '.(ref shift).' does not implement required method name()';
}
sub data {
## accessor for data
my ($self, $value) = @_;
if (defined $value) {
croak 'Accessor data() called as mutator';
} else {
$self->{data} = {} unless exists $self->{data};
return $self->{data};
}
}
sub pull {
my ($self, $data) = @_;
if (defined $data) {
$self->{data} = $data;
} else {
croak sprintf('Cannot pull data from server into a %s without ID', $self->prefix)
unless $self->id;
$self->{data} = $self->{root}->query(method => $self->prefix('.get'),
params => {
$self->prefix('ids') => [ $self->id ],
$self->extension
})->[0];
}
return $self;
}
sub created {
my $self = shift;
return $self->id if $self->{root}->{lazy};
return @{$self->{root}->query(method => $self->prefix('.get'),
params => {
$self->prefix('ids') => [$self->id],
$self->extension
})};
}
sub collides {
croak 'Class '.(ref shift).' does not implement required method collides()';
}
sub push {
my ($self, $data) = @_;
$data //= $self->data;
my @colliders;
if ($self->id and $self->created) {
say sprintf('Updating %s %s', $self->prefix, $self->id)
if $self->{root}->{verbosity};
$self->{root}->query(method => $self->prefix('.update'),
params => $data);
$self->pull unless $self->{root}->{lazy};
} elsif ($self->id) {
croak sprintf('%s has a %s but does not exist on server', $self->id, $self->prefix('id'));
} elsif (@colliders = $self->collides and $colliders[0]) {
say sprintf('Updating %s (match by collisions)', $self->prefix)
if $self->{root}->{verbosity};
if (@colliders > 1) {
croak sprintf('Cannot push %s: too many possible targets', $self->prefix);
}
my $class = ref $self;
# not referenced! and that's the way we want it
my $collider = $class->new(root => $self->{root}, data => $colliders[0]);
$self->id($collider->id);
$self->push;
} else {
say 'Creating '.$self->prefix
if $self->{root}->{verbosity};
my $id = $self->{root}->query(method => $self->prefix('.create'),
params => $data)->{$self->prefix('ids')}->[0];
$self->id($id);
$self->pull unless $self->{root}->{lazy};
}
return $self;
}
sub delete {
my $self = shift;
if ($self->id) {
say sprintf('Deleting %s %s', $self->prefix, $self->id)
if $self->{root}->{verbosity};
$self->{root}->query(method => $self->prefix('.delete'),
params => [ $self->id ]);
} else {
carp sprintf(q{Useless call of delete() on a %s that does not have a %s}, $self->prefix, $self->prefix('id'));
}
return $self;
}
1;
__END__
=pod
=head1 NAME
Zabbix::API::CRUDE -- Base abstract class for most Zabbix::API::* objects
=head1 SYNOPSIS
package Zabbix::API::Unicorn;
use parent qw/Zabbix::API::CRUDE/;
# now override some virtual methods so that it works for the specific case of
# unicorns
sub id { ... }
sub prefix { ... }
sub extension { ... }
=head1 DESCRIPTION
This module handles most aspects of pushing, pulling and deleting the various
types of Zabbix objects. You do not want to use this directly; a few abstract
methods need to be implemented by a subclass.
=head2 WHY "CRUDE"?
=over 4
=item 1
On top of Create, Read, Update and Delete, the Zabbix API also implements an
Exists operation.
=item 2
It I<was> written in a hurry.
=back
=head1 METHODS
=over 4
=item new([DATA]) (constructor)
This is the standard, boilerplate Perl OO constructor. It returns a blessed
hashref with the contents of C<DATA>, which should be a hash.
=item id([NEWID]) (abstract method)
This method must implement a mutator for the relevant unique Zabbix ID (e.g. for
hosts, C<hostid>). What this means is, it must accept zero or one argument; if
zero, return the current ID or undef; if one, set the current ID in the raw data
hash (see the C<data()> method) and return it.
=item node_id()
This method returns the current object's node ID, for distributed
setups. For objects in non-distributed setups, whose IDs do not
include a node ID, and objects that have never been pushed to the
server, this method will return false.
=item prefix([SUFFIX]) (abstract method)
This method must return a string that corresponds to its type (e.g. C<host>).
It should accept one optional argument to concatenate to the type; this kludge
is necessary for types that have a different name depending on where they are
used (e.g. graph items -- not currently implemented as such -- have a
C<graphitemid> but are referred to as C<gitems> elsewhere).
This is a class and instance method (and it returns the same thing in both cases
so far). Warning: do not rely too much on this returning the correct compound
name for any SUFFIX, as I have implemented only those special cases that were of
interest for the rest of the distribution.
=item extension() (abstract method)
This method must return a list that contains the various parameters necessary to
fetch more data. (Returning an empty hash means that in most cases, only the
IDs will be sent by the server.) E.g. for hosts, this is C<< return (output =>
'extend') >>.
=item name() (abstract method)
This method must return a preferably unique human-readable identifier. For
instance, hosts return the C<host> attribute.
=item data()
This is a standard accessor for the raw data as fetched from Zabbix and
converted into a hashref. You can use C<pull()> as a mutator on the same (but
not for long).
=item pull([DATA])
Without an argument, fetches the raw data from the Zabbix server and updates the
Perl object appropriately. Calling C<pull> on objects that do not have an ID
set (they have not been fetched from the server, have never been pushed, or you
have removed the ID yourself for obscure reasons) throws an exception.
With a hashref argument, sets the raw data on the object directly, although this
will change in a future version.
In any case, this does not save your modifications for you. If you have changed
the object's data in any way and not pushed the modifications to the server,
they will be overwritten.
=item created()
This checks that the server knows about the object (has an object of the same
type with the same ID).
=item collides() (abstract method)
This method must return a list of objects (hashrefs of data, not instances of
C<Zabbix::API>!) that would cause the Zabbix server to reply "... already
exists" if the invocant were created (as with a push).
=item push()
Create the object on the server if it doesn't exist, update it if it does. This
distinction means that an object which has an ID, but not a server
representation, is in an illegal state; calling C<push> on such an object throws
an exception. Some classes (e.g. C<Screen>) override this to ensure that other
objects they depend on are created before they are.
=item delete()
Deletes the object on the server and the local index (if you fetch it again it
will be a different object from the one you're "holding").
=back
=head1 SEE ALSO
L<Zabbix::API>, the Zabbix API documentation at
L<http://www.zabbix.com/documentation/start>.
=head1 AUTHOR
Fabrice Gabolde <fabrice.gabolde@uperto.com>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2011 SFR
This library is free software; you can redistribute it and/or modify it under
the terms of the GPLv3.
=cut
|