###
### Copyright 2000-2007 University of Illinois Board of Trustees
### All rights reserved.
###
### swatch.pm - swatch module for psgconf
###
### Campus Information Technologies and Educational Services
### University of Illinois at Urbana-Champaign
###
package PSGConf::Control::swatch;
use strict;
use PSGConf::Action::GenerateFile::Literal;
use PSGConf::Data::Boolean;
use PSGConf::Data::List;
use PSGConf::Data::String;
use PSGConf::Control::Packages qw(_add_pkgs);
###############################################################################
### policy methods
###############################################################################
###
### WARNING: Needs to be called after syslog_default_dir policy is called,
### because syslog_dir may get prepended there.
###
sub _policy_add_crontab
{
my ($self, $psgconf) = @_;
my ($cmd);
return
if ( ! -f $psgconf->data_obj('swatch_cmd')->get() ||
$psgconf->data_obj('swatch_enable')->equals('false'));
$cmd = $psgconf->data_obj('swatch_cmd')->get()
. ' -c /usr/local/etc/swatchrc -f '
. $psgconf->data_obj('syslog_dir')->get()
. '/messages > /dev/null 2>&1';
$psgconf->data_obj('crontabs')->insert(
{'root' => [{
hour => $psgconf->data_obj('swatch_hour')->get(),
minute => $psgconf->data_obj('swatch_minute')->get(),
command => $cmd
}]
}
);
}
###
### WARNING: This is a fix because Solaris systems complain about a host
### being our address, when you look into the MAC address it reports, that
### is the same host's MAC address.
###
sub _policy_add_swatch_rule
{
my ($self, $psgconf) = @_;
my (@mac, @ip, $i, @res, $line, $tmp);
### If we are not running swatch nor on Solaris, just return
return
if ( ! $psgconf->data_obj('platform')->match('solaris') ||
$psgconf->data_obj('swatch_enable')->equals('false'));
### find all the IP/MAC pairs that we are currently using
$i=-1;
@res = `/sbin/ifconfig -au`;
foreach $line ( @res ) {
if ( $line =~ /^\s+inet / ) {
$i++;
$tmp=$line;
$tmp =~ s/^\s*inet //;
$tmp =~ s/\s.*$//;
$ip[$i] = &_format_addr($tmp, 'IP');
}
if ( $line =~ /^\s+ether / ) {
my ($tmp) = $line;
$tmp =~ s/^\s*ether //;
$mac[$i] = &_format_addr($tmp, 'MAC');
}
}
### Now assemble the swatch configuration for all the IP/MAC pairs
$line=undef;
for ($i = 0; $i < scalar (@ip); $i++) {
$line .= "ignore / WARNING: IP: Hardware address "
. $mac[$i]
. " trying to be our address "
. $ip[$i]
. "!/\n"
if ( defined $ip[$i] && defined $mac[$i] );
}
$psgconf->data_obj('swatch_config')->add(
"# Ignore warnings reported between my IP and MAC address\n"
. $line
. " continue"
) if ( defined $line );
}
sub _format_addr {
my ($str, $type) = @_;
my ($res, @addr, $sep, $cnt, $t, $digits);
if ( $type eq 'IP' ) {
$sep = '.'; $cnt = 4; $digits = 3; $t = 'd';
} elsif ( $type eq 'MAC' ) {
$sep = ':'; $cnt = 6; $digits = 2; $t = 'x';
} else {
return undef;
}
@addr = split (/\Q$sep\E/, $str);
return undef
if ( $cnt != scalar (@addr) );
$res = undef;
for (my $i = 0; $i < scalar (@addr); $i++) {
$res .= $sep if ( defined $res );
$res .= sprintf "%${digits}.${digits}$t",
($type eq 'MAC')
? hex($addr[$i])
: $addr[$i];
}
return $res;
};
###############################################################################
### Constructor
###############################################################################
sub new
{
my ($class, $psgconf) = @_;
my ($self);
$self = {};
bless($self, $class);
$self->{name} = 'swatch';
$self->{enable} = $self->{name} . '_enable';
$self->{packages} = $self->{name} . '_packages';
$psgconf->register_data(
swatch_enable => PSGConf::Data::Boolean->new(
value => 'false'
),
swatch_config => PSGConf::Data::List->new(),
swatch_cmd => PSGConf::Data::String->new(
'value_abspath' => 1,
value => '/usr/local/bin/swatch'
),
swatch_mailto => PSGConf::Data::String->new(
value => 'root'
),
swatch_hour => PSGConf::Data::String->new(
value => '23'
),
swatch_minute => PSGConf::Data::String->new(
value => '58'
),
swatch_packages => PSGConf::Data::List->new()
);
$psgconf->register_policy($self,
swatch_add_packages => '_add_pkgs',
swatch_add_crontab => '_policy_add_crontab',
swatch_add_rule => '_policy_add_swatch_rule'
);
return $self;
}
##############################################################################
### decide() method
###############################################################################
sub decide
{
my ($self, $psgconf) = @_;
return
if ($psgconf->data_obj('swatch_enable')->equals('false'));
$psgconf->register_actions(
PSGConf::Action::GenerateFile::Literal->new(
name => '/usr/local/etc/swatchrc',
mode => 0640,
description => 'Swatch Configuration File',
content => join ("\n\n",
@{$psgconf->data_obj('swatch_config')->get()})
. "\n\nwatchfor /.*/\n\tmail addresses="
. $psgconf->data_obj('swatch_mailto')->get()
. ",subject=Message from Swatch on "
. $psgconf->data_obj('hostname')->get()
. ",keep_open=1\n"
)
);
}
###############################################################################
### documentation
###############################################################################
1;
__END__
=head1 NAME
PSGConf::Control::swatch - psgconf control class for swatch syslog reporting
=head1 SYNOPSIS
In F</etc/psgconf_modules>:
Control PSGConf::Control::swatch
=head1 DESCRIPTION
The B<PSGConf::Control::swatch> module provides a B<psgconf> control object
for configuring swatch syslog reporting. It supports the following methods:
=over 4
=item new()
The constructor. Its parameter is a reference to the B<PSGConf>
object. It registers the following data objects:
=over 4
=item I<swatch_enable>
A B<PSGConf::Data::Boolean> object, indicating whether swatch should
be configured. The default is no.
=item I<swatch_packages>
A B<PSGConf::Data::List> object containing a list of packages to install.
=item I<swatch_config>
A B<PSGConf::Data::List> object containing a list of swatch actions to
put into the F<swatchrc> file.
=item I<swatch_mailto>
A B<PSGConf::Data::String> object containing an email address
to send the results of the C<swatch> command to.
=item I<swatch_cmd>
A B<PSGConf::Data::String> object containing the full command to the
F<swatch> binary. Defaults to F</usr/local/bin/swatch>.
=item I<swatch_hour>
A B<PSGConf::Data::String> object containing which hour or hours
to run F<swatch>. Defaults to C<23>.
=item I<swatch_minute>
A B<PSGConf::Data::String> object containing which minute or minutes
to run F<swatch>. Defaults to C<58>.
=back
The constructor also registers the following policy methods:
=over 4
=item I<swatch_add_packages>
If I<swatch_enable> is true, adds the B<swatch> package and its
requirements to the I<pkg_install_list> Data object (provided by
B<PSGConf::Control::Packages>).
=item I<bass_add_crontab>
If I<swatch_enable> is true, adds an entry for the I<swatch> nightly
to I<root>'s I<crontab> Data object (provided by B<PSGConf::Control::cron>).
=item decide()
Does the following:
If I<swatch_enable> is true, creates the F</usr/local/etc/swatchrc>
config file for the C<swatch> command to use.
=back
=back
=head1 SEE ALSO
L<perl>
L<PSGConf>
L<PSGConf::Action::GenerateFile::Literal>
L<PSGConf::Control::cron>
L<PSGConf::Control::Packages>
L<PSGConf::Data::Boolean>
L<PSGConf::Data::List>
L<PSGConf::Data::String>
L<psgconf-intro>
=cut
syntax highlighted by Code2HTML, v. 0.9.1