mirror of
https://github.com/xcat2/xcat-core.git
synced 2025-05-22 03:32:04 +00:00
770 lines
23 KiB
Perl
Executable File
770 lines
23 KiB
Perl
Executable File
#!/usr/bin/env perl
|
|
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
|
|
|
package xCAT_plugin::switchdiscover;
|
|
BEGIN
|
|
{
|
|
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
|
|
}
|
|
use lib "$::XCATROOT/lib/perl";
|
|
|
|
use Getopt::Long;
|
|
use xCAT::Usage;
|
|
use xCAT::NodeRange;
|
|
use xCAT::Utils;
|
|
use XML::Simple;
|
|
no strict;
|
|
use Data::Dumper;
|
|
|
|
#global variables for this module
|
|
my %globalopt;
|
|
my @filternodes;
|
|
my @iprange;
|
|
my %global_scan_type = (
|
|
lldp => "lldp_scan",
|
|
nmap => "nmap_scan",
|
|
snmp => "snmp_scan"
|
|
);
|
|
|
|
#-------------------------------------------------------------------------------
|
|
=head1 xCAT_plugin:switchdiscover
|
|
=head2 Package Description
|
|
Handles switch discovery functions. It uses lldp, nmap or snmap to scan
|
|
the network to find out the switches attached to the network.
|
|
=cut
|
|
#-------------------------------------------------------------------------------
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 send_msg
|
|
Invokes the callback with the specified message
|
|
Arguments:
|
|
request: request structure for plguin calls
|
|
ecode: error code. 0 for succeful.
|
|
msg: messages to be displayed.
|
|
Returns:
|
|
none
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub send_msg {
|
|
|
|
my $request = shift;
|
|
my $ecode = shift;
|
|
my $msg = shift;
|
|
my %output;
|
|
|
|
#################################################
|
|
# Called from child process - send to parent
|
|
#################################################
|
|
if ( exists( $request->{pipe} )) {
|
|
my $out = $request->{pipe};
|
|
|
|
$output{errorcode} = $ecode;
|
|
$output{data} = \@_;
|
|
print $out freeze( [\%output] );
|
|
print $out "\nENDOFFREEZE6sK4ci\n";
|
|
}
|
|
#################################################
|
|
# Called from parent - invoke callback directly
|
|
#################################################
|
|
elsif ( exists( $request->{callback} )) {
|
|
my $callback = $request->{callback};
|
|
$output{errorcode} = $ecode;
|
|
$output{data} = $msg;
|
|
$callback->( \%output );
|
|
}
|
|
}
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 handled_commands
|
|
It returns a list of commands handled by this plugin.
|
|
Arguments:
|
|
none
|
|
Returns:
|
|
a list of commands.
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub handled_commands {
|
|
return( {switchdiscover=>"switchdiscover"} );
|
|
}
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 parse_args
|
|
Parse the command line options and operands.
|
|
Arguments:
|
|
request: the request structure for plugin
|
|
Returns:
|
|
Usage string or error message.
|
|
0 if no user promp needed.
|
|
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub parse_args {
|
|
|
|
my $request = shift;
|
|
my $args = $request->{arg};
|
|
my $cmd = $request->{command};
|
|
my %opt;
|
|
|
|
#############################################
|
|
# Responds with usage statement
|
|
#############################################
|
|
local *usage = sub {
|
|
my $usage_string = xCAT::Usage->getUsage($cmd);
|
|
return( [$_[0], $usage_string] );
|
|
};
|
|
#############################################
|
|
# No command-line arguments - use defaults
|
|
#############################################
|
|
if ( !defined( $args )) {
|
|
return(0);
|
|
}
|
|
#############################################
|
|
# Checks case in GetOptions, allows opts
|
|
# to be grouped (e.g. -vx), and terminates
|
|
# at the first unrecognized option.
|
|
#############################################
|
|
@ARGV = @$args;
|
|
$Getopt::Long::ignorecase = 0;
|
|
Getopt::Long::Configure( "bundling" );
|
|
|
|
#############################################
|
|
# Process command-line flags
|
|
#############################################
|
|
if (!GetOptions( \%opt,
|
|
qw(h|help V|Verbose v|version x z w r n range=s s=s))) {
|
|
return( usage() );
|
|
}
|
|
|
|
#############################################
|
|
# Check for node range
|
|
#############################################
|
|
if ( scalar(@ARGV) eq 1 ) {
|
|
my @nodes = xCAT::NodeRange::noderange( @ARGV );
|
|
foreach (@nodes) {
|
|
push @filternodes, $_;
|
|
}
|
|
unless (@filternodes) {
|
|
return(usage( "Invalid Argument: $ARGV[0]" ));
|
|
}
|
|
if ( exists( $opt{range} )) {
|
|
return(usage( "--range flag cannot be used with noderange." ));
|
|
}
|
|
} elsif ( scalar(@ARGV) > 1 ) {
|
|
return(usage( "Invalid flag, please check and retry." ));
|
|
}
|
|
|
|
#############################################
|
|
# Option -V for verbose output
|
|
#############################################
|
|
if ( exists( $opt{V} )) {
|
|
$globalopt{verbose} = 1;
|
|
}
|
|
|
|
#############################################
|
|
# Check for mutually-exclusive formatting
|
|
#############################################
|
|
if ( (exists($opt{r}) + exists($opt{x}) + exists($opt{z}) ) > 1 ) {
|
|
return( usage() );
|
|
}
|
|
|
|
#############################################
|
|
# Check for unsupported scan types
|
|
#############################################
|
|
if ( exists( $opt{s} )) {
|
|
my @stypes = split ',', $opt{s};
|
|
my $error;
|
|
foreach my $st (@stypes) {
|
|
if (! exists($global_scan_type{$st})) {
|
|
$error = $error . "Invalide scan type: $st\n";
|
|
}
|
|
}
|
|
if ($error) {
|
|
return usage($error);
|
|
}
|
|
$globalopt{scan_types} = \@stypes;
|
|
}
|
|
|
|
#############################################
|
|
# Check the --range ip range option
|
|
#############################################
|
|
if ( exists( $opt{range} )) {
|
|
$globalopt{range} = $opt{range};
|
|
my @ips = split /,/, $opt{range};
|
|
foreach (@ips) {
|
|
push @iprange, $_;
|
|
}
|
|
}
|
|
|
|
#############################################
|
|
# write to the database
|
|
#############################################
|
|
if ( exists( $opt{w} )) {
|
|
$globalopt{w} = 1;
|
|
}
|
|
|
|
#############################################
|
|
# list the raw information
|
|
#############################################
|
|
if ( exists( $opt{r} )) {
|
|
$globalopt{r} = 1;
|
|
}
|
|
|
|
#############################################
|
|
# list the xml formate data
|
|
#############################################
|
|
if ( exists( $opt{x} )) {
|
|
$globalopt{x} = 1;
|
|
}
|
|
|
|
#############################################
|
|
# list the stanza formate data
|
|
#############################################
|
|
if ( exists( $opt{z} )) {
|
|
$globalopt{z} = 1;
|
|
}
|
|
|
|
|
|
#########################################################
|
|
# only list the nodes that discovered for the first time
|
|
#########################################################
|
|
if ( exists( $opt{n} )) {
|
|
$globalopt{n} = 1;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 preprocess_request
|
|
Parse the arguments and display the usage or the version string.
|
|
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub preprocess_request {
|
|
my $req = shift;
|
|
if ($req->{_xcatpreprocessed}->[0] == 1) { return [$req]; }
|
|
my $callback=shift;
|
|
my $command = $req->{command}->[0];
|
|
my $extrargs = $req->{arg};
|
|
my @exargs=($req->{arg});
|
|
if (ref($extrargs)) {
|
|
@exargs=@$extrargs;
|
|
}
|
|
my $usage_string=xCAT::Usage->parseCommand($command, @exargs);
|
|
if ($usage_string) {
|
|
$callback->({data=>[$usage_string]});
|
|
$req = {};
|
|
return;
|
|
}
|
|
|
|
my @result = ();
|
|
my $mncopy = {%$req};
|
|
push @result, $mncopy;
|
|
return \@result;
|
|
}
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 process_request
|
|
Pasrse the arguments and call the correspondent functions
|
|
to do switch discovery.
|
|
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub process_request {
|
|
my $req = shift;
|
|
my $callback = shift;
|
|
my $sub_req = shift;
|
|
|
|
###########################################
|
|
# Build hash to pass around
|
|
###########################################
|
|
my %request;
|
|
$request{arg} = $req->{arg};
|
|
$request{callback} = $callback;
|
|
$request{command} = $req->{command}->[0];
|
|
|
|
####################################
|
|
# Process command-specific options
|
|
####################################
|
|
my $result = parse_args( \%request );
|
|
|
|
|
|
####################################
|
|
# Return error
|
|
####################################
|
|
if ( ref($result) eq 'ARRAY' ) {
|
|
send_msg( \%request, 1, @$result );
|
|
return(1);
|
|
}
|
|
|
|
# call the relavant functions to start the scan
|
|
my @scan_types = ("lldp");
|
|
if (exists($globalopt{scan_types})) {
|
|
@scan_types = @{$globalopt{scan_types}};
|
|
}
|
|
|
|
my $all_result;
|
|
foreach my $st (@scan_types) {
|
|
no strict;
|
|
my $fn = $global_scan_type{$st};
|
|
my $tmp_result = &$fn(\%request, $callback);
|
|
$all_result->{$st} = $tmp_result;
|
|
}
|
|
|
|
#consolidate the results by merging the swithes with the same ip
|
|
my $result;
|
|
foreach my $st (keys %$all_result) {
|
|
my $tmp_result = $all_result->{$st};
|
|
foreach my $key (keys %$tmp_result) {
|
|
if (! exists($result->{$key})) {
|
|
$result->{$key} = $tmp_result->{$key};
|
|
} else {
|
|
if (exists($tmp_result->{$key}->{name})) {
|
|
$result->{$key}->{name} = $tmp_result->{$key}->{name};
|
|
}
|
|
if (exists($tmp_result->{$key}->{mac})) {
|
|
$result->{$key}->{mac} = $tmp_result->{$key}->{mac};
|
|
}
|
|
if (exists($tmp_result->{$key}->{vendor})) {
|
|
$result->{$key}->{vendor} .= $tmp_result->{$key}->{vendor};
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
my $display_done = 0;
|
|
if (exists($globalopt{r})) {
|
|
#do nothing since is done by the scan functions.
|
|
$display_done = 1;
|
|
}
|
|
|
|
if (exists($globalopt{x})) {
|
|
send_msg( \%request, 0, format_xml( $result ));
|
|
$display_done = 1;
|
|
}
|
|
|
|
if (exists($globalopt{z})) {
|
|
|
|
my $stanza_output = format_stanza( $result );
|
|
send_msg( \%request, 0, $stanza_output );
|
|
$display_done = 1;
|
|
}
|
|
|
|
if (!$display_done) {
|
|
#display header
|
|
$format = "%-12s\t%-18s\t%-20.20s\t%-12s";
|
|
$header = sprintf $format, "ip", "name","vendor", "mac";
|
|
send_msg(\%request, 0, $header);
|
|
my $sep = "------------";
|
|
send_msg(\%request, 0, sprintf($format, $sep, $sep, $sep, $sep ));
|
|
|
|
#display switches one by one
|
|
foreach my $key (keys(%$result)) {
|
|
my $mac = " ";
|
|
my $vendor = " ";
|
|
my $name = get_hostname($result->{$key}->{name}, $key);
|
|
if (exists($result->{$key}->{mac})) {
|
|
$mac = $result->{$key}->{mac};
|
|
}
|
|
if (exists($result->{$key}->{vendor})) {
|
|
$vendor = $result->{$key}->{vendor};
|
|
}
|
|
my $msg = sprintf $format, $key, $name, $vendor, $mac;
|
|
send_msg(\%request, 0, $msg);
|
|
}
|
|
}
|
|
|
|
|
|
# writes the data into xCAT db
|
|
if (exists($globalopt{w})) {
|
|
send_msg(\%request, 0, "Writing the data into xCAT DB....");
|
|
xCATdB($result, \%request, $sub_req);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 lldp_scan
|
|
Use lldpd to scan the subnets to do switch discovery.
|
|
Arguments:
|
|
request: request structure with callback pointer.
|
|
Returns:
|
|
A hash containing the swithes discovered.
|
|
Each element is a hash of switch attributes. For examples:
|
|
{
|
|
"1.2.3.5" =>{name=>"switch1", vendor=>"ibm", mac=>"AABBCCDDEEFA"},
|
|
"1.2.4.6" =>{name=>"switch2", vendor=>"cisco", mac=>"AABBCCDDEEFF"}
|
|
}
|
|
returns 1 if there are errors occurred.
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub lldp_scan {
|
|
my $request = shift;
|
|
|
|
send_msg($request, 0, "Discovering switches using lldpd...");
|
|
|
|
# get the PID of the currently running lldpd if it is running.
|
|
# If it is not running start it up.
|
|
my $pid;
|
|
chomp($pid= `ps -ef | grep lldpd | grep -v grep | awk '{print \$2}'`);
|
|
unless($pid){
|
|
my $dcmd = "lldpd -c -s -e -f";
|
|
my $outref = xCAT::Utils->runcmd($dcmd, 0);
|
|
if ($::RUNCMD_RC != 0)
|
|
{
|
|
send_msg($request, 1, "Could not start lldpd process. The command was: $dcmd" );
|
|
return 1;
|
|
}
|
|
# TODO: how to determin if the lldpd has done all the scanning or not?
|
|
xCAT::Utils->runcmd("sleep 30");
|
|
}
|
|
|
|
#now run the lldpcli to collect the data
|
|
my $ccmd = "lldpcli show neighbors -f xml";
|
|
my $result = xCAT::Utils->runcmd($ccmd, 0);
|
|
if ($::RUNCMD_RC != 0)
|
|
{
|
|
send_msg($request, 1, "Could not start lldpd process. The command was: $ccmd" );
|
|
return 1;
|
|
}
|
|
|
|
#display the raw output
|
|
if (exists($globalopt{r})) {
|
|
my $ccmd = "lldpcli show neighbors";
|
|
my $raw_result = xCAT::Utils->runcmd($ccmd, 0);
|
|
if ($::RUNCMD_RC == 0)
|
|
{
|
|
send_msg($request, 0, "$raw_result\n\n");
|
|
}
|
|
}
|
|
|
|
my $result_ref = XMLin($result, KeyAttr => 'interface', ForceArray => 1);
|
|
my $switches;
|
|
if ($result_ref) {
|
|
if (exists($result_ref->{interface})) {
|
|
my $ref1 = $result_ref->{interface};
|
|
foreach my $interface (@$ref1) {
|
|
if (exists($interface->{chassis})) {
|
|
my $chassis = $interface->{chassis}->[0];
|
|
my $ip = $chassis->{'mgmt-ip'}->[0]->{content};
|
|
if ($ip) {
|
|
my $name = $chassis->{name}->[0]->{content};
|
|
my $id = $chassis->{id}->[0]->{content};
|
|
my $desc = $chassis->{descr}->[0]->{content};
|
|
$switches->{$ip}->{name} = $name;
|
|
$switches->{$ip}->{mac} = $id;
|
|
$switches->{$ip}->{vendor} = $desc;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return $switches
|
|
}
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 nmap_scan
|
|
Use nmap to scan the subnets to do switch discovery.
|
|
Arguments:
|
|
request: request structure with callback pointer.
|
|
Returns:
|
|
A hash containing the swithes discovered.
|
|
Each element is a hash of switch attributes. For examples:
|
|
{
|
|
"1.2.3.5" =>{name=>"switch1", vendor=>"ibm", mac=>"AABBCCDDEEFA"},
|
|
"1.2.4.6" =>{name=>"switch2", vendor=>"cisco", mac=>"AABBCCDDEEFF"}
|
|
}
|
|
returns 1 if there are errors occurred.
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub nmap_scan {
|
|
my $request = shift;
|
|
|
|
my $ccmd;
|
|
|
|
send_msg($request, 0, "Discovering switches using nmap...");
|
|
#################################################
|
|
# If --range options, take iprange, otherwise
|
|
# use noderange to discover switches.
|
|
##################################################
|
|
if ( scalar(@filternodes) eq 0)
|
|
{
|
|
$ccmd = "/usr/bin/nmap -sn -oX - @iprange";
|
|
} else {
|
|
$ccmd = "/usr/bin/nmap -sn -oX - @filternodes";
|
|
}
|
|
print $ccmd;
|
|
my $result = xCAT::Utils->runcmd($ccmd, 0);
|
|
if ($::RUNCMD_RC != 0)
|
|
{
|
|
send_msg($request, 1, "Could not process this command: $ccmd" );
|
|
return 1;
|
|
}
|
|
|
|
#################################################
|
|
#display the raw output
|
|
#################################################
|
|
if (exists($globalopt{r})) {
|
|
send_msg($request, 0, "$result\n" );
|
|
}
|
|
|
|
#################################################
|
|
#compose the switch hash
|
|
#################################################
|
|
my $result_ref = XMLin($result, ForceArray => 1);
|
|
my $switches;
|
|
if ($result_ref) {
|
|
if (exists($result_ref->{host})) {
|
|
my $host_ref = $result_ref->{host};
|
|
foreach my $host ( @$host_ref ) {
|
|
my $ip;
|
|
if (exists($host->{address})) {
|
|
my $addr_ref = $host->{address};
|
|
foreach my $addr ( @$addr_ref ) {
|
|
my $type = $addr->{addrtype};
|
|
if ( $type ne "mac" ) {
|
|
$ip = $addr->{addr};
|
|
}
|
|
if ($addr->{vendor}) {
|
|
$switches->{$ip}->{mac} = $addr->{addr};
|
|
$switches->{$ip}->{vendor} = $addr->{vendor};
|
|
$switches->{$ip}->{name} = $host->{hostname};
|
|
|
|
}
|
|
} #end for each address
|
|
}
|
|
} #end for each host
|
|
}
|
|
}
|
|
|
|
return $switches
|
|
}
|
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 snmp_scan
|
|
Use lldpd to scan the subnets to do switch discovery.
|
|
Arguments:
|
|
request: request structure with callback pointer.
|
|
Returns:
|
|
A hash containing the swithes discovered.
|
|
Each element is a hash of switch attributes. For examples:
|
|
{
|
|
"1.2.3.5" =>{name=>"switch1", vendor=>"ibm", mac=>"AABBCCDDEEFA"},
|
|
"1.2.4.6" =>{name=>"switch2", vendor=>"cisco", mac=>"AABBCCDDEEFF"}
|
|
}
|
|
returns 1 if there are errors occurred.
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub snmp_scan {
|
|
my $request = shift;
|
|
|
|
send_msg($request, 0, "Discovering switches using snmp...");
|
|
my $switches = {
|
|
"1.2.3.5" => { name=>"switch1", vendor=>"ibm", mac=>"AABBCCDDEEFA" },
|
|
"1.2.4.6" => { name=>"switch2", vendor=>"cisco", mac=>"AABBCCDDEEFF" }
|
|
};
|
|
return $switches
|
|
}
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 get_hostname
|
|
return hostname for the switch discovered
|
|
Arguments:
|
|
host: hostname passed by the switch after scan
|
|
ip : IP address passed by the switch after scan
|
|
Returns:
|
|
hose: hostname of the switch
|
|
if host is empty, format hostname as switch and ip combination
|
|
ex: switch-9-114-5-6
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub get_hostname {
|
|
my $host = shift;
|
|
my $ip = shift;
|
|
|
|
if ( !$host ) {
|
|
my $ip_str = $ip;
|
|
$ip_str =~ s/\./\-/g;
|
|
$host = "switch-$ip_str";
|
|
}
|
|
return $host;
|
|
}
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 get_switchtype
|
|
determine the switch type based on the switch vendor
|
|
Arguments:
|
|
vendor: switch vendor
|
|
Returns:
|
|
stype: type of switch, supports JUN, Cisco, BNT and MellanoxIB
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub get_switchtype {
|
|
my $vendor = shift;
|
|
my $stype;
|
|
|
|
if ($vendor =~ "Juniper") {
|
|
$stype = "JUN";
|
|
} elsif ($vendor =~ "Cisco") {
|
|
$stype = "Cisco";
|
|
} elsif ($vendor =~ "BNT") {
|
|
$stype = "BNT";
|
|
} elsif ($vendor =~ "Mellanox") {
|
|
$stype = "MellanoxIB";
|
|
} else {
|
|
$stype = $vendor;
|
|
}
|
|
|
|
return $stype;
|
|
}
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 xCATdB
|
|
Write discovered switch information to xCAT database.
|
|
Arguments:
|
|
outhash: A hash containing the swithes discovered.
|
|
request: The request structure for plugin.
|
|
sub_req: The request structure for runxcmd.
|
|
Returns:
|
|
none
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub xCATdB {
|
|
my $outhash = shift;
|
|
my $request = shift;
|
|
my $sub_req = shift;
|
|
my $ret;
|
|
|
|
#################################################
|
|
# write each switch to xcat database
|
|
##################################################
|
|
foreach my $ip ( keys %$outhash ) {
|
|
my $mac = $outhash->{$ip}->{mac};
|
|
my $vendor = $outhash->{$ip}->{vendor};
|
|
|
|
#Get hostname and switch type
|
|
my $host = get_hostname($outhash->{$ip}->{name}, $ip);
|
|
my $stype = get_switchtype($vendor);
|
|
|
|
#################################################
|
|
# use lsdef command to check if this switch is
|
|
# already in the switch table
|
|
# if it is, use chdef to update it's attribute
|
|
# otherwise, use mkdef to add this switch to
|
|
# switch table
|
|
##################################################
|
|
$ret = xCAT::Utils->runxcmd( { command => ['lsdef'], arg => ['-t','switch','-o',$host] }, $sub_req, 0, 1);
|
|
if ($::RUNCMD_RC == 0)
|
|
{
|
|
$ret = xCAT::Utils->runxcmd({ command => ['chdef'], arg => ['-t','switch','-o',$host,"ip=$ip","comments=$vendor","switchtype=$stype"] }, $sub_req, 0, 1);
|
|
} else {
|
|
$ret = xCAT::Utils->runxcmd( { command => ['mkdef'], arg => ['-t','switch','-o',$host,'groups=switch',"ip=$ip","comments=$vendor",'nodetype=switch','mgt=switch',"switchtype=$stype"] }, $sub_req, 0, 1);
|
|
}
|
|
if ($::RUNCMD_RC != 0)
|
|
{
|
|
send_msg($request, 0, "$$ret[0]");
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 format_stanza
|
|
list the stanza format for swithes
|
|
Arguments:
|
|
outhash: a hash containing the switches discovered
|
|
Returns:
|
|
result: return lists as stanza format for swithes
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub format_stanza {
|
|
my $outhash = shift;
|
|
my $result;
|
|
|
|
#####################################
|
|
# Write attributes
|
|
#####################################
|
|
foreach my $ip ( keys %$outhash ) {
|
|
my $mac = $outhash->{$ip}->{mac};
|
|
my $vendor = $outhash->{$ip}->{vendor};
|
|
|
|
#Get hostname and switch type
|
|
my $host = get_hostname($outhash->{$ip}->{name}, $ip);
|
|
my $stype = get_switchtype($vendor);
|
|
|
|
$result .= "$host:\n\tobjtype=switch\n";
|
|
$result .= "\tcomments=$vendor\n";
|
|
$result .= "\tgroups=switch\n";
|
|
$result .= "\tip=$ip\n";
|
|
$result .= "\tmac=$mac\n";
|
|
$result .= "\tmgt=switch\n";
|
|
$result .= "\tnodetype=switch\n";
|
|
$result .= "\tswitchtype=$stype\n";
|
|
}
|
|
return ($result);
|
|
}
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 format_xml
|
|
list the xml format for swithes
|
|
Arguments:
|
|
outhash: a hash containing the switches discovered
|
|
Returns:
|
|
result: return lists as xml format for swithes
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub format_xml {
|
|
my $outhash = shift;
|
|
my $xml;
|
|
|
|
#####################################
|
|
# Write attributes
|
|
#####################################
|
|
foreach my $ip ( keys %$outhash ) {
|
|
my $result;
|
|
my $mac = $outhash->{$ip}->{mac};
|
|
my $vendor = $outhash->{$ip}->{vendor};
|
|
|
|
#Get hostname and switch type
|
|
my $host = get_hostname($outhash->{$ip}->{name}, $ip);
|
|
my $stype = get_switchtype($vendor);
|
|
|
|
$result .= "hostname=$host\n";
|
|
$result .= "objtype=switch\n";
|
|
$result .= "comments=$vendor\n";
|
|
$result .= "groups=switch\n";
|
|
$result .= "ip=$ip\n";
|
|
$result .= "mac=$mac\n";
|
|
$result .= "mgt=switch\n";
|
|
$result .= "nodetype=switch\n";
|
|
$result .= "switchtype=$stype\n";
|
|
|
|
my $href = {
|
|
Switch => { }
|
|
};
|
|
my @attr = split '\\n', $result;
|
|
for (my $i = 0; $i < scalar(@attr); $i++ ){
|
|
if( $attr[$i] =~ /(\w+)\=(.*)/){
|
|
$href->{Switch}->{$1} = $2;
|
|
}
|
|
}
|
|
$xml.= XMLout($href,
|
|
NoAttr => 1,
|
|
KeyAttr => [],
|
|
RootName => undef );
|
|
}
|
|
return ($xml);
|
|
|
|
}
|
|
|
|
1;
|
|
|