File: cricket-genconf-sensor

package info (click to toggle)
libsnmp-session-perl 1.14~git20221124T101957-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,104 kB
  • sloc: perl: 11,920; ansic: 25; makefile: 15
file content (232 lines) | stat: -rwxr-xr-x 7,576 bytes parent folder | download | duplicates (3)
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
#!/usr/local/bin/perl -w
##
## cricket-genconf-sensor
##
## Generate Cricket configuration for sensor monitoring
##
## Author:        Simon Leinen  <simon@limmat.switch.ch>
## Date created:  21-Dec-2006
##
## This script generates Cricket configuration files for
## SNMP-monitorable sensors in a set of routers.  It does this on the
## basis of a RANCID configuration file repository.  For each router
## in that directory that seems to have monitorable sensors, the
## script calls the `entls' script to generate Cricket configuration.
##
## The script puts newly generated configuration files into a
## temporary directory, and then installs some "safe" configuration
## changes by itself.  For other configuration changes, the user is
## presented with "diff" output and has to decide how to apply them.

use strict;
use warnings;

use Cisco::Abbrev;

my $testing = 0;

### Prototypes
sub read_router_configurations ($ );
sub has_sensors_p ($ );
sub postprocess_router_config ($$);
sub maybe_install_new_configuration ($ );
sub install_new_configuration ($ );

my $rancid_directory = '/usr/local/rancid/backbone/configs';

my @routers = read_router_configurations ($rancid_directory);

my $cricket_config_dir = '/home/cricket/cricket-config';
my $old_config_dir = $cricket_config_dir.'/'.'transceiver-monitoring';

-d $old_config_dir or die "cannot find existing configuration $old_config_dir";

my $new_config_dir = '/tmp'.'/foo/';
-d $new_config_dir
    or mkdir $new_config_dir
    or die "Cannot create $new_config_dir: $!";

my (@unchanged, @installed, @unresolved);
foreach my $router (@routers) {
    my $routername = $router->{name};
    ## For testing, only look at one router
    next if $testing and $routername ne 'swiix2';
    next unless has_sensors_p ($router);
    my $rdir = $new_config_dir.'/'.$routername;
    -d $rdir or mkdir $rdir or die "cannot create directory $rdir: $!";
    my $retval = system ('perl -Ilib test/entls -t hctiws@'
			 .$routername.':::::2:v4only > '
			 .$rdir.'/'.$routername);
    if ($retval) {
	warn "failed to generate configuration for $routername";
    } else {
	postprocess_router_config ($rdir.'/'.$routername, $router);
	maybe_install_new_configuration ($router);
    }
}
print "Unchanged: ",join (", ", map { $_->{name} } @unchanged),"\n";
print "Installed: ",join (", ", map { $_->{name} } @installed),"\n";
print "Unresolved: ",join (", ", map { $_->{name} } @unresolved),"\n";
1;

sub postprocess_router_config ($$) {
    my ($file, $router) = @_;
    my ($pre, $sd, $post, $long, $desc);
    open IN, $file or die "Cannot open configuration file $file: $!";
    open OUT, ">$file.post" or die "Cannot open configuration file $file.post: $!";
    while (<IN>) {
	if (/^(\s*display-name\s*=\s*")(.*)("\s*)$/) {
	} elsif (/^(\s*long-desc\s*=\s*")(.*)("\s*)$/) {
	} elsif (/^(\s*short-desc\s*=\s*")(.*)("\s*)$/) {
	    ($pre, $sd, $post) = ($1, $2, $3);
	    $sd =~ s/^transceiver //i;
	    $long = cisco_long_int ($sd);
	    $sd = $long if defined $long;
	    if (defined $long) {
		$desc = $long;
		$sd = $desc = $router->{ifdesc}->{$long}
		if exists $router->{ifdesc}->{$long};
	    } else {
		$long = $desc = $sd;
	    }
	    chomp $post;
	    print OUT "$pre$sd$post\n";
	    print OUT "\tlong-desc\t = \"<h3>$long - $desc</h3>\"\n";
	    print OUT "\tdisplay-name\t = \"%router% - $long\"\n";
	} else {
	    print OUT $_;
	}
    }
    close IN or die "Cannot close configuration file $file: $!";
    close OUT or die "Cannot close configuration file $file.post: $!";
    rename $file, "$file.pre" or unlink $file;
    rename "$file.post", $file or rename "$file.pre", $file;
    unlink "$file.pre";
    return 1;
}

sub read_router_configurations ($ ) {
    my ($dir) = @_;
    my @routers = ();
    opendir CONFIG, $dir
	or die "open directory $dir: $!";
    foreach my $file (readdir CONFIG) {
	next if $testing and $file ne 'swiix2';
	next unless -f $dir.'/'.$file;
	push @routers, { name => $file };
    }
    closedir CONFIG
	or die "close directory $dir: $!";
    @routers;
}

sub has_sensors_p ($ ) {
    my ($router) = @_;
    my $routername = $router->{name};
    my $have_sensor_p = 0;
    my ($ifname, %ifdesc);
    open (CONFIG, $rancid_directory.'/'.$routername)
	or die "open configuration file for $routername: $!";
    while (<CONFIG>) {
	if (/Receive Power Sensor/) {
	    $have_sensor_p = 1;
	} elsif (/^interface (.*)/) {
	    $ifname = $1;
	} elsif (/^ description (.*)$/
		 and defined $ifname) {
	    $ifdesc{$ifname} = $1;
	} elsif (/^ /) {
	} else {
	    $ifname = undef;
	}
    }
    close CONFIG or die "close configuration file for $routername: $!";
    ## foreach my $ifname (sort keys %ifdesc) {
    ## 	printf "%-20s %s\n", $ifname, $ifdesc{$ifname};
    ## }
    $router->{ifdesc} = \%ifdesc;
    return $have_sensor_p;
}

## maybe_install_new_configuration ROUTER
##
## Check whether the newly generated Cricket configuration file for
## router ROUTER has to/can be installed.
##
## If the file doesn't exist in the current configuration, we can
## safely install the new one.
##
## If the newly generated file is identical to the old one, we don't
## have to do anything.
##
## The the newly generated file differs from the old one, we output
## the diff and don't install anything.
##
## TODO: Apply the diffs.  This is not totally trivial, however.  As
## long as the diff consists in only added lines, the new file can be
## safely installed over the current one.  But when configuration is
## lost (i.e. sensors are removed), we should deactivate the lost
## targets using "collect = 0", rather than removing them entirely, to
## make sure that history is kept.
##
## There is an additional case, namely that a file exists in the
## current configuration that was not generated in the new run.  We
## don't handle this situation currently.
##
## TODO: Check the existing configuration for files that were lost in
## the new generation run, and deactivate collection in these files.
##
## Actual installation of configurations is performed by
## install_new_configuration().
##
sub maybe_install_new_configuration ($ ) {
    my ($router) = @_;
    my $routername = $router->{name};
    my $old_file = $old_config_dir.'/'.$routername.'/'.$routername;
    my $new_file = $new_config_dir.'/'.$routername.'/'.$routername;

    if (! -f $old_file) {
	print "NEW: $routername\n";
	if (install_new_configuration ($router)) {
	    push @installed, $router;
	} else {
	    push @unresolved, $router;
	}
    } else {
	my $retval = system ("diff", "-uw", $old_file, $new_file);
	if ($retval) {
	    ##warn "TESTING:\n";
	    ##$retval = system "diff -w $old_file $new_file | egrep -v '\^>'";
	    ##warn "TESTING END: $retval\n";
	    print "DIFFER: $routername\n";
	    push @unresolved, $router;
	} else {
	    push @unchanged, $router;
	    unlink $new_file;
	}
    }
}

## install_new_configuration ROUTER
##
## Install the newly generated configuration file for router ROUTER in
## the active directory tree.  The containing directory is created if
## needed.
##
sub install_new_configuration ($ ) {
    my ($router) = @_;
    my $routername = $router->{name};
    my $old_file = $old_config_dir.'/'.$routername.'/'.$routername;
    my $new_file = $new_config_dir.'/'.$routername.'/'.$routername;
    my $old_dir = $old_config_dir.'/'.$routername;

    unless (-d $old_dir || mkdir $old_dir) {
	warn "Cannot create $old_dir: $!";
	return undef;
    }
    if (system ("mv", $new_file, $old_file)) {
	warn "Failed to move $new_file to $old_file";
	return undef;
    }
    return 1;
}