mirror of
https://github.com/xcat2/xcat-core.git
synced 2025-06-12 17:30:19 +00:00
Merge pull request #817 from cxhong/swdiscover
Find switch vendor using snmpwalk command
This commit is contained in:
@ -5,7 +5,7 @@ Use switchdiscover command to discover the switches that are attached to the nei
|
||||
|
||||
switchdiscover [noderange|--range ip_ranges][-s scan_methods][-r|-x|-z][-w]
|
||||
|
||||
where the scan_methods can be **nmap** . The default is **nmap**. (**nmap** comes from most os distribution.)
|
||||
where the scan_methods can be **nmap**, **snmp", or **lldp** . The default is **nmap**. (**nmap** comes from most os distribution.)
|
||||
|
||||
To discover switches over the IP range 10.4.25.0/24 and 192.168.0.0/24, use the following command: ::
|
||||
|
||||
|
@ -23,12 +23,14 @@ DESCRIPTION
|
||||
***********
|
||||
|
||||
|
||||
The switchdiscover command scans the subnets and discovers all the swithches on the subnets. The command takes a list of subnets as input. The default subnets are the ones that the xCAT management node is on. It uses nmap command to discover the switches. However, you can specify other discovery methods such as lldp with \ **-s**\ flag. You can write the discovered switches into xCAT database with \ **-w**\ flag. This command supports may output formats such as xml(\ **-x**\ ), raw(\ **-r**\ ) and stanza(\ **-z**\ ) in addition to the default format.
|
||||
The switchdiscover command scans the subnets and discovers all the swithches on the subnets. The command takes a list of subnets as input. The default subnets are the ones that the xCAT management node is on. It uses nmap command as default to discover the switches. However, you can specify other discovery methods such as lldp or snmp with \ **-s**\ flag. You can write the discovered switches into xCAT database with \ **-w**\ flag. This command supports may output formats such as xml(\ **-x**\ ), raw(\ **-r**\ ) and stanza(\ **-z**\ ) in addition to the default format.
|
||||
|
||||
To view all the switches defined in the xCAT databasee use \ **lsdef -w "nodetype=switch"**\ command.
|
||||
|
||||
For lldp method, please make sure that lldpd package is installed and lldpd is running on the xCAT management node. lldpd comes from xcat-dep packge or you can get it from http://vincentbernat.github.io/lldpd/installation.html.
|
||||
|
||||
For snmp method, please make sure that snmpwalk command is installed and snmp is enabled for switches. To install snmpwalk, "yum install net-snmp-utils" for redhat and sles, "apt-get install snmp" for Ubuntu.
|
||||
|
||||
|
||||
*******
|
||||
OPTIONS
|
||||
@ -59,7 +61,7 @@ OPTIONS
|
||||
|
||||
Specify one or more IP ranges. Each can be an ip address (10.1.2.3) or an ip range (10.1.2.0/24). If the range is huge, for example, 192.168.1.1/8, the switch discover may take a very long time to scan. So the range should be exactly specified.
|
||||
|
||||
For nmap scan method, it accepts multiple formats. For example, 192.168.1.1/24, 40-41.1-2.3-4.1-100.
|
||||
For nmap and snmp scan method, it accepts multiple formats. For example: 192.168.1.1/24, 40-41.1-2.3-4.1-100.
|
||||
|
||||
If the range is not specified, the command scans all the subnets that the active network interfaces (eth0, eth1) are on where this command is issued.
|
||||
|
||||
@ -74,7 +76,7 @@ OPTIONS
|
||||
\ **-s**\
|
||||
|
||||
It is a comma separated list of methods for switch discovery.
|
||||
The possible switch scan methods are: lldp and nmap. The default is nmap.
|
||||
The possible switch scan methods are: lldp, nmap or snmp. The default is nmap.
|
||||
|
||||
|
||||
|
||||
|
@ -16,12 +16,14 @@ B<switchdiscover> [I<noderange> | B<--range> I<ip_ranges>] B<[-V] [-w][-r|-x|-z]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The switchdiscover command scans the subnets and discovers all the swithches on the subnets. The command takes a list of subnets as input. The default subnets are the ones that the xCAT management node is on. It uses nmap command to discover the switches. However, you can specify other discovery methods such as lldp with B<-s> flag. You can write the discovered switches into xCAT database with B<-w> flag. This command supports may output formats such as xml(B<-x>), raw(B<-r>) and stanza(B<-z>) in addition to the default format.
|
||||
The switchdiscover command scans the subnets and discovers all the swithches on the subnets. The command takes a list of subnets as input. The default subnets are the ones that the xCAT management node is on. It uses nmap command as default to discover the switches. However, you can specify other discovery methods such as lldp or snmp with B<-s> flag. You can write the discovered switches into xCAT database with B<-w> flag. This command supports may output formats such as xml(B<-x>), raw(B<-r>) and stanza(B<-z>) in addition to the default format.
|
||||
|
||||
To view all the switches defined in the xCAT databasee use B<lsdef -w "nodetype=switch"> command.
|
||||
|
||||
For lldp method, please make sure that lldpd package is installed and lldpd is running on the xCAT management node. lldpd comes from xcat-dep packge or you can get it from http://vincentbernat.github.io/lldpd/installation.html.
|
||||
|
||||
For snmp method, please make sure that snmpwalk command is installed and snmp is enabled for switches. To install snmpwalk, "yum install net-snmp-utils" for redhat and sles, "apt-get install snmp" for Ubuntu.
|
||||
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
@ -46,7 +48,7 @@ Display usage message.
|
||||
|
||||
Specify one or more IP ranges. Each can be an ip address (10.1.2.3) or an ip range (10.1.2.0/24). If the range is huge, for example, 192.168.1.1/8, the switch discover may take a very long time to scan. So the range should be exactly specified.
|
||||
|
||||
For nmap scan method, it accepts multiple formats. For example, 192.168.1.1/24, 40-41.1-2.3-4.1-100.
|
||||
For nmap and snmp scan method, it accepts multiple formats. For example: 192.168.1.1/24, 40-41.1-2.3-4.1-100.
|
||||
|
||||
If the range is not specified, the command scans all the subnets that the active network interfaces (eth0, eth1) are on where this command is issued.
|
||||
|
||||
@ -57,7 +59,7 @@ Display Raw responses.
|
||||
=item B<-s>
|
||||
|
||||
It is a comma separated list of methods for switch discovery.
|
||||
The possible switch scan methods are: lldp and nmap. The default is nmap.
|
||||
The possible switch scan methods are: lldp, nmap or snmp. The default is nmap.
|
||||
|
||||
=item B<-v|--version>
|
||||
|
||||
|
@ -30,11 +30,17 @@ my %global_scan_type = (
|
||||
|
||||
my %global_switch_type = (
|
||||
Juniper => "Juniper",
|
||||
juniper => "Juniper",
|
||||
Cisco => "Cisco",
|
||||
BNT => "BNT",
|
||||
Mellanox => "Mellanox"
|
||||
Mellanox => "Mellanox",
|
||||
mellanox => "Mellanox",
|
||||
MLNX => "Mellanox",
|
||||
MELLAN => "Mellanox",
|
||||
IBM => "BNT",
|
||||
);
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
=head1 xCAT_plugin:switchdiscover
|
||||
=head2 Package Description
|
||||
@ -417,7 +423,7 @@ sub process_request {
|
||||
|
||||
if (!$display_done) {
|
||||
#display header
|
||||
$format = "%-12s\t%-18s\t%-20.20s\t%-12s";
|
||||
$format = "%-12s\t%-15s\t%-40.50s\t%-12s";
|
||||
$header = sprintf $format, "ip", "name","vendor", "mac";
|
||||
send_msg(\%request, 0, $header);
|
||||
my $sep = "------------";
|
||||
@ -660,12 +666,8 @@ sub nmap_scan {
|
||||
#################################################
|
||||
#display the raw output
|
||||
#################################################
|
||||
if (exists($globalopt{r})) {
|
||||
if (defined($globalopt{r}) || defined($globalopt{verbose})) {
|
||||
send_msg($request, 0, "$result\n" );
|
||||
} else {
|
||||
if (exists($globalopt{verbose})) {
|
||||
send_msg($request, 0, "$result\n" );
|
||||
}
|
||||
}
|
||||
|
||||
#################################################
|
||||
@ -695,15 +697,16 @@ sub nmap_scan {
|
||||
$mac="nomac_nmap_$counter";
|
||||
$counter++;
|
||||
}
|
||||
if ($addr->{vendor}) {
|
||||
my $vendor = $addr->{vendor};
|
||||
if ($vendor) {
|
||||
my $search_string = join '|', keys(%global_switch_type);
|
||||
if ($addr->{vendor} =~ /($search_string)/) {
|
||||
if ($vendor =~ /($search_string)/) {
|
||||
$switches->{$mac}->{ip} = $ip;
|
||||
$switches->{$mac}->{vendor} = $addr->{vendor};
|
||||
$switches->{$mac}->{vendor} = $vendor;
|
||||
$switches->{$mac}->{name} = $host->{hostname};
|
||||
$found = 1;
|
||||
if (exists($globalopt{verbose})) {
|
||||
send_msg($request, 0, "FOUND Switch: ip=$ip, mac=$mac, vendor=$addr->{vendor}\n");
|
||||
send_msg($request, 0, "FOUND Switch: ip=$ip, mac=$mac, vendor=$vendor\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -782,7 +785,7 @@ sub nmap_scan {
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 snmp_scan
|
||||
Use lldpd to scan the subnets to do switch discovery.
|
||||
Use snmp to scan the subnets to do switch discovery.
|
||||
Arguments:
|
||||
request: request structure with callback pointer.
|
||||
Returns:
|
||||
@ -797,15 +800,190 @@ sub nmap_scan {
|
||||
#--------------------------------------------------------------------------------
|
||||
sub snmp_scan {
|
||||
my $request = shift;
|
||||
my $ccmd;
|
||||
my $switches;
|
||||
my $counter = 0;
|
||||
|
||||
send_msg($request, 0, "Discovering switches using snmp is not supported yet.");
|
||||
my $switches = {
|
||||
"AABBCCDDEEFA" =>{name=>"switch1", vendor=>"ibm", ip=>"10.1.2.3"},
|
||||
"112233445566" =>{name=>"switch2", vendor=>"cisco", ip=>"11.4.5.6"}
|
||||
};
|
||||
return 1;
|
||||
# snmpwalk command has to be available for snmp_scan
|
||||
if (-x "/usr/bin/snmpwalk" ){
|
||||
send_msg($request, 0, "Discovering switches using snmpwalk.....");
|
||||
} else {
|
||||
send_msg($request, 0, "snmpwalk is not available, please install snmpwalk command first");
|
||||
return 1;
|
||||
}
|
||||
|
||||
#################################################
|
||||
# If --range options, take iprange, if noderange is defined
|
||||
# us the ip addresses of the nodes. If none is define, use the
|
||||
# subnets for all the interfaces.
|
||||
##################################################
|
||||
my $ranges = get_ip_ranges($request);
|
||||
|
||||
#use nmap to find if snmp port is enabled
|
||||
$ccmd = "/usr/bin/nmap -P0 -v -sU -p 161 -oA snmp_scan @$ranges | grep 'open port 161' ";
|
||||
if (exists($globalopt{verbose})) {
|
||||
send_msg($request, 0, "Process command: $ccmd\n");
|
||||
}
|
||||
|
||||
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 (defined($globalopt{r}) || defined($globalopt{verbose})) {
|
||||
send_msg($request, 0, "$result\n" );
|
||||
}
|
||||
my @lines = split /\n/, $result;
|
||||
|
||||
# each line like this: "Discovered open port 161/udp on 10.4.25.1"
|
||||
# only open port will be scan
|
||||
foreach my $line (@lines) {
|
||||
my @array = split / /, $line;
|
||||
my $ip = $array[5];
|
||||
if (exists($globalopt{verbose})) {
|
||||
send_msg($request, 0, "Run snmpwalk command to get information for $ip");
|
||||
}
|
||||
|
||||
my $vendor = get_snmpvendorinfo($request, $ip);
|
||||
if ($vendor) {
|
||||
my $mac = get_snmpmac($request, $ip);
|
||||
if (!$mac) {
|
||||
$mac="nomac_nmap_$counter";
|
||||
$counter++;
|
||||
}
|
||||
my $hostname = get_snmphostname($request, $ip);
|
||||
my $stype = get_switchtype($vendor);
|
||||
$switches->{$mac}->{ip} = $ip;
|
||||
$switches->{$mac}->{vendor} = $vendor;
|
||||
$switches->{$mac}->{name} = $hostname;
|
||||
if (exists($globalopt{verbose})) {
|
||||
send_msg($request, 0, "found switch: $hostname, $ip, $stype, $vendor");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $switches;
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 get_snmpvendorinfo
|
||||
return vendor info from snmpwalk command
|
||||
Arguments:
|
||||
ip : IP address passed by the switch after scan
|
||||
Returns:
|
||||
vendor: vendor info of the switch
|
||||
=cut
|
||||
#--------------------------------------------------------------------------------
|
||||
sub get_snmpvendorinfo {
|
||||
my $request = shift;
|
||||
my $ip = shift;
|
||||
my $snmpwalk_vendor;
|
||||
|
||||
|
||||
my $ccmd = "snmpwalk -Os -v1 -c public $ip sysDescr.0";
|
||||
if (exists($globalopt{verbose})) {
|
||||
send_msg($request, 0, "Process command: $ccmd\n");
|
||||
}
|
||||
|
||||
my $result = xCAT::Utils->runcmd($ccmd, 0);
|
||||
if ($::RUNCMD_RC != 0)
|
||||
{
|
||||
if (exists($globalopt{verbose})) {
|
||||
send_msg($request, 1, "Could not process this command: $ccmd" );
|
||||
}
|
||||
return $snmpwalk_vendor;
|
||||
}
|
||||
|
||||
my ($desc,$model) = split /: /, $result;
|
||||
|
||||
if (exists($globalopt{verbose})) {
|
||||
send_msg($request, 0, "switch model = $model\n" );
|
||||
}
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 get_snmpmac
|
||||
return mac address from snmpwalk command
|
||||
Arguments:
|
||||
ip : IP address passed by the switch after scan
|
||||
Returns:
|
||||
mac: mac address of the switch
|
||||
=cut
|
||||
#--------------------------------------------------------------------------------
|
||||
sub get_snmpmac {
|
||||
my $request = shift;
|
||||
my $ip = shift;
|
||||
my $mac;
|
||||
|
||||
my $ccmd = "snmpwalk -Os -v1 -c public $ip ipNetToMediaPhysAddress | grep $ip";
|
||||
if (exists($globalopt{verbose})) {
|
||||
send_msg($request, 0, "Process command: $ccmd\n");
|
||||
}
|
||||
|
||||
my $result = xCAT::Utils->runcmd($ccmd, 0);
|
||||
if ($::RUNCMD_RC != 0)
|
||||
{
|
||||
if (exists($globalopt{verbose})) {
|
||||
send_msg($request, 1, "Could not process this command: $ccmd" );
|
||||
}
|
||||
return $mac;
|
||||
}
|
||||
|
||||
my ($desc,$mac) = split /: /, $result;
|
||||
|
||||
if (exists($globalopt{verbose})) {
|
||||
send_msg($request, 0, "switch mac = $mac\n" );
|
||||
}
|
||||
|
||||
return $mac;
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 get_snmphostname
|
||||
return hostname from snmpwalk command
|
||||
Arguments:
|
||||
ip : IP address passed by the switch after scan
|
||||
Returns:
|
||||
mac: hostname of the switch
|
||||
=cut
|
||||
#--------------------------------------------------------------------------------
|
||||
sub get_snmphostname {
|
||||
my $request = shift;
|
||||
my $ip = shift;
|
||||
my $hostname;
|
||||
|
||||
my $ccmd = "snmpwalk -Os -v1 -c public $ip sysName";
|
||||
if (exists($globalopt{verbose})) {
|
||||
send_msg($request, 0, "Process command: $ccmd\n");
|
||||
}
|
||||
|
||||
my $result = xCAT::Utils->runcmd($ccmd, 0);
|
||||
if ($::RUNCMD_RC != 0)
|
||||
{
|
||||
if (exists($globalopt{verbose})) {
|
||||
send_msg($request, 1, "Could not process this command: $ccmd" );
|
||||
}
|
||||
return $hostname;
|
||||
}
|
||||
|
||||
my ($desc,$hostname) = split /: /, $result;
|
||||
|
||||
if (exists($globalopt{verbose})) {
|
||||
send_msg($request, 0, "switch hostname = $hostname\n" );
|
||||
}
|
||||
|
||||
return $hostname;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 get_hostname
|
||||
return hostname for the switch discovered
|
||||
@ -822,6 +1000,10 @@ sub get_hostname {
|
||||
my $host = shift;
|
||||
my $ip = shift;
|
||||
|
||||
if ($host) {
|
||||
return $host;
|
||||
}
|
||||
|
||||
if ( !$host ) {
|
||||
$host = gethostbyaddr( inet_aton($ip), AF_INET );
|
||||
if ( !$host ) {
|
||||
@ -897,10 +1079,10 @@ sub xCATdB {
|
||||
$ret = xCAT::Utils->runxcmd( { command => ['lsdef'], arg => ['-t','node','-o',$host] }, $sub_req, 0, 1);
|
||||
if ($::RUNCMD_RC == 0)
|
||||
{
|
||||
$ret = xCAT::Utils->runxcmd({ command => ['chdef'], arg => ['-t','node','-o',$host,"ip=$ip",'nodetype=switch','mgt=switch',"switchtype=$stype","usercomment=$vendor"] }, $sub_req, 0, 1);
|
||||
$ret = xCAT::Utils->runxcmd({ command => ['chdef'], arg => ['-t','node','-o',$host,"ip=$ip","mac=$mac",'nodetype=switch','mgt=switch',"switchtype=$stype","usercomment=$vendor"] }, $sub_req, 0, 1);
|
||||
$ret = xCAT::Utils->runxcmd({ command => ['chdef'], arg => ['-t','node','-o',$host,'-p','groups=switch'] }, $sub_req, 0, 1);
|
||||
} else {
|
||||
$ret = xCAT::Utils->runxcmd( { command => ['mkdef'], arg => ['-t','node','-o',$host,'groups=switch',"ip=$ip",'nodetype=switch','mgt=switch',"switchtype=$stype","usercomment=$vendor"] }, $sub_req, 0, 1);
|
||||
$ret = xCAT::Utils->runxcmd( { command => ['mkdef'], arg => ['-t','node','-o',$host,'groups=switch',"ip=$ip","mac=$mac",'nodetype=switch','mgt=switch',"switchtype=$stype","usercomment=$vendor"] }, $sub_req, 0, 1);
|
||||
}
|
||||
if ($::RUNCMD_RC != 0)
|
||||
{
|
||||
|
Reference in New Issue
Block a user