package SM;
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Copyright (C) 2010-2011 Stormons, Sarl. #
# #
# This program is free software; you can redistribute it and/or #
# modify it under the terms of the GNU General Public License #
# as published by the Free Software Foundation; either version 3 #
# of the License, or (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
#-------------------------------------------------------------------------#
# Stormons : The Storage Monitoring Software #
#-------------------------------------------------------------------------#
# This code is designed,written,and maintained by the Stormons Group. See #
# about.cgi and/or the AUTHORS file for specific developer information. #
#-------------------------------------------------------------------------#
# http://www.stormons.com/ #
#-------------------------------------------------------------------------#
# Thanks to Larry Wall and all who have made Perl possible. #
# Particular thanks to Didier Brun, Frank Bounds and Norton. #
#-------------------------------------------------------------------------#
# SM.pm : Stormons library #
# #
#-------------------------------------------------------------------------#
#------------------------------------------------------------------
# external libraries
#------------------------------------------------------------------
use lib '../lib';
use threads;
use threads::shared;
use Time::Local;
use XML::LibXML::Simple qw(XMLin);
use Clone qw(clone);
use Sys::Hostname;
use Cwd;
use Crypt::CBC;
#------------------------------------------------------------------
# stormons libraries
#------------------------------------------------------------------
use SMfile;
use SMconstant;
#------------------------------------------------------------------
# dev libraries
#------------------------------------------------------------------
use strict;
use warnings;
use diagnostics;
use 5.012;
#------------------------------------------------------------------
# Versioning
#------------------------------------------------------------------
our $VERSION = '1.3.0 B2';
#------------------------------------------------------------------
sub Version {return $VERSION}
#------------------------------------------------------------------
#--------------------------------------------------------------------------
# Constructor: new
#--------------------------------------------------------------------------
sub new {
my $package = shift; # Package name comes in as first parameter
my %options = @_; # Remaining args end up in options hash
# my %args : shared;
my %args;
my $self = \%args; # Hashref that will become "the object"
bless $self, $package;
$self->{hostname} = hostname;
$self->{current_array} = 'none';
$self->{begin_working_dir} = cwd();
# Class Variables (passed in from object instantiation)
$self->{sm_config_file} = ESMAPI_CONFIG_FILE;
$self->{sm_catalog_file} = ESMAPI_CATALOG_FILE;
$self->{error_cfg_file} = 1;
$self->{error_cfg_file_mess} = '';
$self->{debuglevel} = 'Disabled';
$self->{sm_env_error} = 0b00000000;
# 0b-------1 => unable to write to error file
# Contacts
$self->{contact_name} = 'N/A';
$self->{contact_mail} = 'N/A';
$self->{contact_phone} = 'N/A';
# Advertising
$self->{advertising} = '';
# Demo
$self->{demo} = FALSE;
# Enabled Settings Class in Aggregate and RaidGroup Report
$self->{settings_class} = FALSE;
$self->{storage_class} = ();
# Fonts
$self->{graph_font_name} = '';
$self->{sparkline_font_size} = 11;
# RRDtool options
$self->{rrdtool_font_size} = 8;
$self->{rrdtool_font_render_mode} = 'normal';
$self->{rrdtool_slope_mode} = 'on';
# HTTP
$self->{base_url} = 'http://localhost/stormons/';
$self->{sparkline_url} = 'http://localhost/smtrend/';
# Path
$self->{site_path} = '';
$self->{rrdtool_cmd} = '';
$self->{repository_path} = '';
$self->{tmp_path} = '';
$self->{alert_dir} = 'Alerts';
$self->{rrd_dir} = 'rrd';
$self->{sparklines_dir} = 'smtrend';
$self->{cx_disk_ref_file} = '../config/cx_disk_ref.xml';
$self->{sm_disk_ref_file} = '../config/sm_disk_ref.xml';
$self->{na_disk_ref_file} = '../config/na_disk_ref.xml';
$self->{wwn_ref_file} = '../config/wwn_ref.xml';
# marker http
$self->{html_marker_file} = 'marker.html';
# Cache
$self->{force_repository_update} = FALSE;
$self->{cache_ttl} = 3600;
$self->{maintain_cache_limit} = 6500;
# Web
$self->{web_longname_enabled} = FALSE;
# Pooler
$self->{poller_archive_enabled} = TRUE;
$self->{poller_use_thread} = TRUE;
$self->{poller_max_thread} = 5;
$self->{poller_timeout} = 300;
$self->{poller_array_timeout} = 300;
$self->{poller_smtp_out_enabled} = FALSE;
$self->{poller_smtp_out_to} = '';
$self->{poller_smtp_out_hours} = '0,1,4,8,12,16';
$self->{poller_smtp_zipfile} = 'stormons_smtp.zip';
$self->{poller_smtp_subject} = 'Stormons Automatic Storage';
# Log
$self->{log_path} = '';
$self->{log_file} = 'stormons.log';
$self->{max_log_size} = 300000;
$self->{verbose} = FALSE;
# Threshold
$self->{threshold_miror} = 80;
$self->{treshold_major} = 90;
$self->{threshold_critical} = 95;
# EMC navicli
$self->{navicli_cmd} = '';
$self->{javacli_cmd} = '';
$self->{naviseccli_cmd} = '';
$self->{navisecfilepath} = '';
$self->{naviseccli_timeout} = 60;
# EMC symcli
$self->{symcli_home} = '';
# Alerte
$self->{capacity_alert} = 300;
# SMTP out
$self->{smtp_out_server} = '';
$self->{smtp_out_port} = 25;
$self->{smtp_out_user} = '';
$self->{smtp_out_passwd} = '';
$self->{smtp_out_from} = 'stormons@localhost';
$self->{smtp_out_timeout} = 15;
$self->{smtp_out_auth_enabled} = 0;
# SMTP entering
$self->{smtp_ent_server} = '';
$self->{smtp_ent_port} = 110;
$self->{smtp_ent_timeout} = 60;
$self->{smtp_ent_user} = '';
$self->{smtp_ent_passwd} = '';
$self->{smtp_ent_auth_enabled} = 0;
# Email Alert
$self->{alert_email_enabled} = 0;
# Graph
$self->{ds_use_thread} = TRUE;
$self->{ds_max_thread} = 5;
$self->{ds_timeout} = 300;
$self->{ds_array_timeout} = 300;
$self->{ds_update_rrd_files} = TRUE;
$self->{ds_update_sparklines} = TRUE;
$self->{ds_update_catalog} = TRUE;
$self->{graph_list_size} = '300x100';
$self->{graph_view_size} = '600x200';
$self->{graph_zoom_size} = '600x200';
# undef is necessary in SMsmtp library !
$self->{alert_email_to} = '';
$self->{alert_email_cc} = '';
$self->{alert_email_subject} = 'Stormons Alert';
$self->{alert_critical_send_interval} = '24';
$self->{alert_major_send_interval} = '24';
$self->{alert_minor_send_interval} = '24';
$self->{alert_info_send_interval} = '24';
$self->{alert_critical_send_enabled} = TRUE;
$self->{alert_major_send_enabled} = FALSE;
$self->{alert_minor_send_enabled} = FALSE;
$self->{alert_info_send_enabled} = FALSE;
# *** Threads Shared Var ***
$self->{alert_list} = shared_clone({});
# *** Threads Shared Var ***
$self->{alert_recycling} = 20;
# Array List
$self->{na_lst} = ();
$self->{cx_lst} = ();
$self->{ns_lst} = ();
$self->{sym_lst} = ();
$self->{array_datetime_lst} = ();
$self->{updated_array_lst} = ();
# NetApp default backup files
$self->{na_backup_file} = "/vol/vol0/etc/exports,/vol/vol0/etc/hosts,/vol/vol0/etc/rc,/vol/vol0/etc/snapmirror.conf,/vol/vol0/etc/resolv.conf";
# SSH Timeout
$self->{ssh_timeout} = 15;
# SSH Read buffer size
$self->{ssh_buffer_size} = 512;
# Update specific values
$self->specific_os_values();
# read config file
$self->read_config_file();
# Instance SMFILE
$self->{smfile} = new SMfile(cacheage=>$self->{cache_ttl});
return $self;
}
#--------------------------------------------------------------------------
# specific_os_values
# Purpose: Set specific OS values
# Required parameters: sm,record,filename
# Returns:
#--------------------------------------------------------------------------
sub specific_os_values{
my ( $self, %options ) = @_;
my $os = $^O;
given($os) {
when(/Win/i) {
$self->{repository_path} = 'c:/Program Files/Stormons/' . ESMAPI_VERSION_PATH . '/repository';
$self->{log_path} = 'c:/Program Files/Stormons/' . ESMAPI_VERSION_PATH . '/logs';
$self->{graph_font_name} = 'c:/windows/fonts/arial.ttf';
$self->{navicli_cmd} = 'c:/Program Files/EMC/navicli.exe';
$self->{javacli_cmd} = 'c:/Program Files/EMC/javacli.exe';
$self->{naviseccli_cmd} = 'c:/Program Files/EMC/naviseccli.exe';
$self->{tmp_path} = 'c:/temp';
}
default {
# Unix
$self->{repository_path} = '/usr/local/stormons/' . ESMAPI_VERSION_PATH . '/repository';
$self->{log_path} = '/usr/local/stormons/' . ESMAPI_VERSION_PATH . '/logs';
$self->{graph_font_name} = '/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf';
$self->{navicli_cmd} = '/opt/EMC/navicli.exe';
$self->{javacli_cmd} = '/opt/EMC/javacli.exe';
$self->{naviseccli_cmd} = '/opt/EMC/naviseccli.exe';
$self->{tmp_path} = '/tmp';
}
}
}
#--------------------------------------------------------------------------
# conv_path
# Purpose:
# Required parameters:
# Returns:
#--------------------------------------------------------------------------
sub conv_path{
my $path = shift;
if ( defined $path ) {
$path =~ s/\\\\/\//g;
$path =~ s/\\/\//g;
}
else {
return(undef);
}
return $path;
}
#--------------------------------------------------------------------------
# SMset
# Purpose:
# Required parameters:
# Returns:
#--------------------------------------------------------------------------
sub SMset {
# $_[0] value
# $_[1] set
return $_[0] if ( defined($_[0]) && ( ref(\$_[0]) eq 'SCALAR' ) );
return $_[1];
}
#--------------------------------------------------------------------------
# SMset2
# Purpose:
# Required parameters:
# Returns:
#--------------------------------------------------------------------------
sub SMset2 {
# $_[0] value1
# $_[1] value2
# $_[2] set
return $_[0] if ( defined($_[0]) && ( ref(\$_[0]) eq 'SCALAR' ) );
return $_[1] if ( defined($_[1]) && ( ref(\$_[1]) eq 'SCALAR' ) );
return $_[2];
}
#--------------------------------------------------------------------------
# init_var
# Purpose:
# Required parameters:
# Returns:
#--------------------------------------------------------------------------
sub init_var {
my ($pt_var,$pt_value) = @_;
if ( defined($$pt_value) && ( ref($pt_value) eq 'SCALAR' ) ) {
$$pt_var = $$pt_value;
} else {
$$pt_value = $$pt_var;
}
}
#--------------------------------------------------------------------------
# read_config_file
# Purpose:
# Required parameters:
# Returns:
#--------------------------------------------------------------------------
sub read_config_file {
my ( $self, %options ) = @_;
# is it necessary to define %config here ,
# if the config file do not exist,
# SMSettings working and update %config before create file
my %config;
$self->{CONFIG_HASH} = \%config;
unless ( -e ESMAPI_CONFIG_FILE ) {
$self->{error_cfg_file}=ESMAPI_FILE_NOT_FOUND;
return;
}
unless ( -r ESMAPI_CONFIG_FILE ) {
$self->{error_cfg_file}=ESMAPI_FILE_OPEN_FAILED;
return;
}
my $config_ref = eval{XMLin(ESMAPI_CONFIG_FILE);};
if ($@) {
$self->{error_cfg_file}=ESMAPI_FILE_BAD_STRUCTURE;
$@ =~ m/line\s(\d+),/;
$self->{error_cfg_file_mess}="line $@";
return;
}
%config = %$config_ref;
$self->{error_cfg_file}=0;
$self->{CONFIG_HASH} = $config_ref;
#print Dumper(%config);
############################## User Parameters ########################################
#
# Example to use xml <debuglevel>10</debuglevel> in stormons.xml file
#
## Debug Level ( Disabled, Enable, Verbose, Smtp, Ssh, Clariion, NetApp, Celerra, Symmetrix, All )
init_var(\$self->{debuglevel},\$config{debuglevel});
## Contact Name for the Pooler
init_var(\$self->{contact_name},\$config{contact_name});
## Contact Email for the Pooler
init_var(\$self->{contact_mail},\$config{contact_mail});
## Contact Phone for the Pooler
init_var(\$self->{contact_phone},\$config{contact_phone});
## Home Directory of Stormons
$self->{site_path} = conv_path(cwd);
## Settings Class
init_var(\$self->{settings_class},\$config{settings_class});
## Directory of XML Files
init_var(\$self->{repository_path},\$config{repository_path});
$self->{repository_path} = conv_path($self->{repository_path});
## rrdtool binary
init_var(\$self->{rrdtool_cmd},\$config{rrdtool_cmd});
$self->{rrdtool_cmd} = conv_path($self->{rrdtool_cmd});
## set font
init_var(\$self->{graph_font_name},\$config{graph_font_name});
init_var(\$self->{sparkline_font_size},\$config{sparkline_font_size});
## RRDtool options
init_var(\$self->{rrdtool_font_size},\$config{rrdtool_font_size});
init_var(\$self->{rrdtool_font_render_mode},\$config{rrdtool_font_render_mode});
init_var(\$self->{rrdtool_slope_mode},\$config{rrdtool_slope_mode});
## Temporary Directory
init_var(\$self->{tmp_path},\$config{path_tmp});
$self->{tmp_path} = conv_path($self->{tmp_path});
## Enable or Disable Cache ( 0 => Disable ; 1 => Enable ; Default 1)
init_var(\$self->{force_repository_update},\$config{force_repository_update});
## Maximum Cache Age for the Console ( in second ; Default 7200 )
init_var(\$self->{cache_ttl},\$config{cache_ttl});
## Maximum Cache Age for the Pooler ( in second ; Default 6000 )
## To avoid latency on console set maintain_cache_limit below the cacheage value
init_var(\$self->{maintain_cache_limit},\$config{maintain_cache_limit});
## Enable or Disable LongName in Report ( 0 => Disable ; 1 => Enable ; Default 0)
init_var(\$self->{web_longname_enabled},\$config{web_longname_enabled});
## Enable or Disable Multi-Thread Pooler ( 0 => Disable ; 1 => Enable )
init_var(\$self->{poller_use_thread},\$config{poller_use_thread});
## Set max thread ( default 5 )
init_var(\$self->{poller_max_thread},\$config{poller_max_thread});
## Directory of Log files
init_var(\$self->{log_path},\$config{log_path});
$self->{log_path} = conv_path($self->{log_path});
## Temp Directory
init_var(\$self->{tmp_path},\$config{tmp_path});
$self->{tmp_path} = conv_path($self->{tmp_path});
## Set max log size ( in byte ; Default 300000 )
init_var(\$self->{max_log_size},\$config{max_log_size});
## Set Minor Threshold ( Default 80 )
init_var(\$self->{threshold_miror},\$config{threshold_minor});
## Set Major Threshold ( Default 90 )
init_var(\$self->{treshold_major},\$config{threshold_major});
## Set Critical Threshold ( Default 95 )
init_var(\$self->{threshold_critical},\$config{threshold_critical});
## Set Navicli path ( Default c:\Program Files\EMC\navicli.exe )
init_var(\$self->{navicli_cmd},\$config{navicli_cmd});
$self->{navicli_cmd} = conv_path($self->{navicli_cmd});
## Set Javacli path ( Default c:\Program Files\EMC\javacli.exe )
init_var(\$self->{javacli_cmd},\$config{javacli_cmd});
$self->{navicli_cmd} = conv_path($self->{navicli_cmd});
## Set Navicli path ( Default c:\Program Files\EMC\naviseccli.exe )
init_var(\$self->{naviseccli_cmd},\$config{naviseccli_cmd});
$self->{naviseccli_cmd} = conv_path($self->{naviseccli_cmd});
## Set Navisecfile path ( Default '' )
### cannot make conv_path for this path
init_var(\$self->{navisecfilepath},\$config{navisecfile_path});
## Set Navicli timeout( Default 60 seconds )
init_var(\$self->{naviseccli_timeout},\$config{naviseccli_timeout});
## Set Symcli path
## HTTP URL
init_var(\$self->{base_url},\$config{base_url});
init_var(\$self->{sparkline_url},\$config{sparkline_url});
### cannot make conv_path for this path
init_var(\$self->{symcli_home},\$config{symcli_home});
## Set Capacity Alert limit ( Default 300GB ) [ Using in Capacity Reports ]
init_var(\$self->{capacity_alert},\$config{capacity_alert});
## Enable or Disable Poolre SMTP Outgoing ( 0 => Disable ; 1 => Enable )
init_var(\$self->{poller_smtp_out_enabled},\$config{poller_smtp_out_enabled});
## Enable or Disable Poolre Archive ( 0 => Disable ; 1 => Enable )
init_var(\$self->{poller_archive_enabled},\$config{poller_archive_enabled});
## Set outgoing Pooler SMTP Recipient Address
init_var(\$self->{poller_smtp_out_to},\$config{poller_smtp_out_to});
## Set Pooler Timeout ( in second ; Default 300 )
init_var(\$self->{poller_timeout},\$config{poller_timeout});
## Set Pooler array Timeout ( in second ; Default 300 )
init_var(\$self->{poller_array_timeout},\$config{poller_array_timeout});
## Set Outgoing SMTP Server
init_var(\$self->{smtp_out_server},\$config{smtp_out_server});
## Set Outgoing SMTP Port number ( Default 25 )
init_var(\$self->{smtp_out_port},\$config{smtp_out_port});
## Set Outgoing SMTP Timeout ( Default 25 )
init_var(\$self->{smtp_out_timeout},\$config{smtp_out_timeout});
## Enable or Disable SMTP User/Password Authentication
init_var(\$self->{smtp_out_auth_enabled},\$config{smtp_out_auth_enabled});
## Set Outgoing SMTP User
init_var(\$self->{smtp_out_user},\$config{smtp_out_user});
## Set Outgoing SMTP Password
$self->{smtp_out_passwd} = $self->decrypt(key=>PASSWD_CRYPT_KEY,code=>$config{smtp_out_passwd});
## Set Ougoing SMTP Sender Name
init_var(\$self->{smtp_out_from},\$config{smtp_out_from});
## Enable or Disable POP3 Incoming ( 0 => Disable ; 1 => Enable )
init_var(\$self->{smtp_ent_user},\$config{smtp_ent_user});
## Set Incoming PO3 Server
init_var(\$self->{smtp_ent_server},\$config{smtp_ent_server});
## Set Incoming POP3 Port
# Actual lib NET::POP3 do not support Port Number and ssl
init_var(\$self->{smtp_ent_port},\$config{smtp_ent_port});
## Set Incoming POP3 TIMEOUT
init_var(\$self->{smtp_ent_timeout},\$config{smtp_ent_timeout});
## Enable or Disable POOP3 User/Password Authentication
init_var(\$self->{smtp_ent_auth_enabled},\$config{smtp_ent_auth_enabled});
## Set Incoming POP3 User
init_var(\$self->{smtp_ent_user},\$config{smtp_ent_user});
## Set Incoming POP3 Password
$self->{smtp_ent_passwd} = $self->decrypt(key=>PASSWD_CRYPT_KEY,code=>$config{smtp_ent_passwd});
## SSH Timeout ( Default 15 seconds )
init_var(\$self->{ssh_timeout},\$config{ssh_timeout});
## Enable or Disable Mail Alert ( 0 => Disable ; 1 => Enable )
init_var(\$self->{alert_email_enabled},\$config{alert_email_enabled});
# Set outgoing Alert Recipient Address
init_var(\$self->{alert_email_to},\$config{alert_email_to});
# Set outgoing Alert Recipient CC Address
init_var(\$self->{alert_email_cc},\$config{alert_email_cc});
## Critical Alert Email Enabled
init_var(\$self->{alert_critical_send_enabled},\$config{alert_critical_send_enabled});
## Major Alert Email Enabled
init_var(\$self->{alert_major_send_enabled},\$config{alert_major_send_enabled});
## Minor Alert Email Enabled
init_var(\$self->{alert_minor_send_enabled},\$config{alert_minor_send_enabled});
## Information Alert Enabled
init_var(\$self->{alert_info_send_enabled},\$config{alert_info_send_enabled});
## Critical Alert Email Interval in Hours ( Default 1 )
init_var(\$self->{alert_critical_send_interval},\$config{alert_critical_send_interval});
## Major Alert Email Interval in Hours ( Default 1 )
init_var(\$self->{alert_major_send_interval},\$config{alert_major_send_interval});
## Minor Alert Email Interval in Hours ( Default 1 )
init_var(\$self->{alert_minor_send_interval},\$config{alert_minor_send_interval});
## Information Alert Email Interval in Hours ( Default 1 )
init_var(\$self->{alert_info_send_interval},\$config{alert_info_send_interval});
## Recycling alert after n call of poller( Default 20 )
init_var(\$self->{alert_recycling},\$config{alert_recycling});
## Graph enable
init_var(\$self->{graph_list_size},\$config{graph_list_size});
init_var(\$self->{graph_view_size},\$config{graph_view_size});
init_var(\$self->{graph_zoom_size},\$config{graph_zoom_size});
## Enable or Disable Multi-Thread Daily Stat ( 0 => Disable ; 1 => Enable )
init_var(\$self->{ds_use_thread},\$config{ds_use_thread});
## Set max thread ( default 5 )
init_var(\$self->{ds_max_thread},\$config{ds_max_thread});
## Set Daily Stat Timeout ( in second ; Default 300 )
init_var(\$self->{ds_timeout},\$config{ds_timeout});
## Set Daily Stat array Timeout ( in second ; Default 300 )
init_var(\$self->{ds_array_timeout},\$config{ds_array_timeout});
############################## Shadow Parameters ###################################
#
## Message in the header or SMC ( Bêta test for example )
init_var(\$self->{advertising},\$config{advertising});
## Set Demo mode ( 0 => Disable ; 1 => Enable )
init_var(\$self->{demo},\$config{demo_mode});
## Name of pooler zip file ( default => stormon_zipfile.zip )
init_var(\$self->{poller_smtp_zipfile},\$config{poller_smtp_zipfile});
## Subject of Pooler mail ( default => SMC Automatic Storage )
init_var(\$self->{poller_smtp_subject},\$config{poller_smtp_subject});
## Subject of Alert mail ( default => SMC Alert )
init_var(\$self->{alert_email_subject},\$config{alert_email_subject});
## Name of the log file ( Default => stormon.log )
init_var(\$self->{log_path},\$config{log_file});
## SSH Buffer Size ( Default 512 Bytes )
init_var(\$self->{ssh_buffer_size},\$config{ssh_buffer_size});
## Column Sort Config
# [A,B],[C,D],ttdd
# => Tri sur la colonne A ( première colonne = 0 )
# => Ordre du tri B ( 0 => ascendant, 1 => descendant )
# => Puis tri sur la colonne C ( Ordre D ... )
# => ttdd => colonne 0 et 1 au format text
# => ttdd => colonne 2 et 3 au format numérique
# $self->{sort_list}{AGTInfo} = "[0,0]:tttttddttd";
# $self->{sort_list}{BILLCX} = '';
# $self->{sort_list}{BILLNA} = '';
# $self->{sort_list}{BILLSYM} = '';
# $self->{sort_list}{CAPCX} = "[2,0],[4,0],[5,0]:tdddttddd;[0,1],[1,0]:ttdtdff";
# $self->{sort_list}{CAPNA}
#
####################################################################################
# Create a user on the filer(s) to be monitored that has api and http privileges
#
# useradmin role add ontapi -c OnTapi -a api-*,login-http-admin
# useradmin group add apionly -c OnTapi -r ontapi
# useradmin user add stormons -c OnTapi -g apionly
# New password: {your password here}
#
#### NetApp List ####
my %netapp_list=();
if ( defined $config{netapp} ) {
eval { %netapp_list = %{$config{netapp}};};
foreach my $array (keys %netapp_list) {
$self->add_array_netapp(\%{$netapp_list{$array}},$array);
}
}
#### Clariion List ####
my %clariion_list=();
if ( ( defined $config{clariion} ) ) {
eval { %clariion_list = %{$config{clariion}};};
foreach my $array (keys %clariion_list) {
$self->add_array_cx(\%{$clariion_list{$array}},$array);
}
}
#### Celerra List ####
my %celerra_list=();
if ( defined $config{celerra} ) {
eval { %celerra_list = %{$config{celerra}};};
foreach my $array (keys %celerra_list) {
$self->add_array_ns(\%{$celerra_list{$array}},$array);
}
}
#### Symmetrix List ####
my %symmetrix_list=();
if ( defined $config{symmetrix} ) {
eval { %symmetrix_list = %{$config{symmetrix}};};
foreach my $array (keys %symmetrix_list) {
$self->add_array_sym(\%{$symmetrix_list{$array}},$array);
}
}
#### Storage Class List ####
my %storage_class_list=();
if ( defined $config{storage_class} ) {
eval { %storage_class_list = %{$config{storage_class}};};
foreach my $array (keys %storage_class_list) {
foreach my $info_group ( split(/;/, $config{storage_class}{$array} ) ) {
my ($group,$class) = split(/,/,$info_group);
$self->{storage_class}{$array}{$group} = $class;
}
}
}
if ( defined $config{sort_list} ) {
foreach my $appli (sort keys %{$config{sort_list}}) {
$self->{sort_list}{$appli} = $config{sort_list}->{$appli};
}
}
}
#--------------------------------------------------------------------------
# decrypt
# Purpose: decrypt password entries
# Required parameters:
# Returns:
#--------------------------------------------------------------------------
sub decrypt {
my ( $self, %options ) = @_;
my $key = $options{key} // '';
my $code = $options{code} // '';
my $cipher = Crypt::CBC->new( -key => $key,-cipher => 'Blowfish' );
my $ciphertext = eval {$cipher->decrypt_hex($code)};
if ( $@ ) {
return('');
}
return($ciphertext);
}
#--------------------------------------------------------------------------
# crypt
# Purpose: crypt password entries
# Required parameters:
# Returns:
#--------------------------------------------------------------------------
sub crypt {
my ( $self, %options ) = @_;
my $key = $options{key} // '';
my $tocrypt = $options{tocrypt} // '';
my $cipher = Crypt::CBC->new( -key => $key,-cipher => 'Blowfish' );
my $cryptcode = eval {$cipher->encrypt_hex($tocrypt)};
if ( $@ ) {
return('');
}
return($cryptcode);
}
#--------------------------------------------------------------------------
# add_array_netapp
# Purpose: load netapp Array from config file
# Required parameters:
# Returns:
#--------------------------------------------------------------------------
sub add_array_netapp {
my ( $self, $pconfig, $array ) = @_;
my %ptconf = %$pconfig;
my $alias;
my $rand = int(rand(1000));
$self->{na_lst}{$array}{'alias'} = SMset($ptconf{'alias'},$array);
$self->{na_lst}{$array}{'head'} = SMset($ptconf{'head'},'A');
$self->{na_lst}{$array}{'partner'} = SMset($ptconf{'partner'},'none');
$self->{na_lst}{$array}{'hostname'} = SMset($ptconf{'hostname'},'');
$self->{na_lst}{$array}{'login'} = SMset($ptconf{'login'},'');
$self->{na_lst}{$array}{'password'} = $self->decrypt(key=>PASSWD_CRYPT_KEY,code=>$ptconf{'password'});
$self->{na_lst}{$array}{'mode'} = SMset($ptconf{'mode'},0);
$self->{na_lst}{$array}{'api_major'} = SMset($ptconf{'api_major'},ESMAPI_ONTAPI_VERSION_MAJOR);
$self->{na_lst}{$array}{'api_minor'} = SMset($ptconf{'api_minor'},ESMAPI_ONTAPI_VERSION_MINOR);
$self->{na_lst}{$array}{'dualattach'} = SMset($ptconf{'dualattach'},0);
$self->{na_lst}{$array}{'forward'} = SMset($ptconf{'forward'},0);
$self->{na_lst}{$array}{'datetime'} = SMset($ptconf{'datetime'},time);
$self->{na_lst}{$array}{'backupfile'} = SMset($ptconf{'backupfile'},$self->{na_backup_file});
$self->{array_datetime_lst}{'na'}{$array} = 1;
}
#--------------------------------------------------------------------------
# get_netapp_partner
# Purpose:
# Required parameters:
# Returns:
#--------------------------------------------------------------------------
sub get_netapp_partner {
my ( $self, $array ) = @_;
return($self->{na_lst}{$array}{'partner'} // 'none');
}
#--------------------------------------------------------------------------
# add_array_cx
# Purpose: load clariion Array from config file
# Required parameters:
# Returns:
#--------------------------------------------------------------------------
sub add_array_cx {
my ( $self, $pconfig, $array ) = @_;
my %ptconf = %$pconfig;
$self->{cx_lst}{$array}{'alias'} = SMset($ptconf{'alias'},"$array");
$self->{cx_lst}{$array}{'spa'} = SMset($ptconf{'spa'},'');
$self->{cx_lst}{$array}{'spb'} = SMset($ptconf{'spb'},'');
$self->{cx_lst}{$array}{'mode'} = SMset($ptconf{'mode'},0);
$self->{cx_lst}{$array}{'forward'} = SMset($ptconf{'forward'},0);
$self->{cx_lst}{$array}{'celerra'} = SMset($ptconf{'celerra'},'');
$self->{cx_lst}{$array}{'celerra_sg'} = SMset($ptconf{'celerra_sg'},'');
$self->{cx_lst}{$array}{'datetime'} = SMset($ptconf{'datetime'},time);
$self->{array_datetime_lst}{'cx'}{$array} = 1;
}
#--------------------------------------------------------------------------
# add_array_ns
# Purpose: load celerra Array from config file
# Required parameters:
# Returns:
#--------------------------------------------------------------------------
sub add_array_ns {
my ( $self, $pconfig, $array ) = @_;
my %ptconf = %$pconfig;
$self->{ns_lst}{$array}{'alias'} = SMset($ptconf{'alias'},"$array");
$self->{ns_lst}{$array}{'cs'} = SMset($ptconf{'cs'},'');
$self->{ns_lst}{$array}{'port'} = SMset($ptconf{'ssh_port'},22);
$self->{ns_lst}{$array}{'login'} = SMset($ptconf{'login'},'nasadmin');
$self->{ns_lst}{$array}{'password'} = $self->decrypt(key=>PASSWD_CRYPT_KEY,code=>$ptconf{'password'});
$self->{ns_lst}{$array}{'mode'} = SMset($ptconf{'mode'},0);
$self->{ns_lst}{$array}{'forward'} = SMset($ptconf{'forward'},0);
$self->{ns_lst}{$array}{'datetime'} = SMset($ptconf{'datetime'},time);
$self->{array_datetime_lst}{'ns'}{$array} = 1;
}
#--------------------------------------------------------------------------
# add_array_sym
# Purpose: load symmetrix Array from config file
# Required parameters:
# Returns:
#--------------------------------------------------------------------------
sub add_array_sym {
my ( $self, $pconfig, $array ) = @_;
my %ptconf = %$pconfig;
$self->{sym_lst}{$array}{'alias'} = SMset($ptconf{'alias'},"$array");
$self->{sym_lst}{$array}{'hostagent'} = SMset($ptconf{'hostagent'},'');
$self->{sym_lst}{$array}{'port'} = SMset($ptconf{'ssh_port'},22);
$self->{sym_lst}{$array}{'sid'} = SMset($ptconf{'sid'},'');
$self->{sym_lst}{$array}{'login'} = SMset($ptconf{'login'},'');
$self->{sym_lst}{$array}{'password'} = $self->decrypt(key=>PASSWD_CRYPT_KEY,code=>$ptconf{'password'});
$self->{sym_lst}{$array}{'mode'} = SMset($ptconf{'mode'},0);
$self->{sym_lst}{$array}{'forward'} = SMset($ptconf{'forward'},0);
$self->{sym_lst}{$array}{'datetime'} = SMset($ptconf{'datetime'},time);
$self->{array_datetime_lst}{'sym'}{$array} = 1;
}
#--------------------------------------------------------------------------
# get_type
# Purpose:
# Required parameters:
# Returns:
#--------------------------------------------------------------------------
sub get_type {
my ( $self, $array ) = @_;
return('na') if ( $self->{na_lst}{$array} );
return('ns') if ( $self->{ns_lst}{$array} );
return('cx') if ( $self->{cx_lst}{$array} );
return('sym') if ( $self->{sym_lst}{$array} );
}
#--------------------------------------------------------------------------
# get_list
# Purpose:
# Required parameters:
# Returns:
#--------------------------------------------------------------------------
sub get_list {
my ( $self, $type ) = @_;
my @list;
@list = sort keys %{$self->{updated_array_lst}} if ( $type eq 'updated' );
@list = sort keys %{$self->{na_lst}} if ( $type eq 'na' );
@list = sort keys %{$self->{ns_lst}} if ( $type eq 'ns' );
@list = sort keys %{$self->{cx_lst}} if ( $type eq 'cx' );
@list = sort keys %{$self->{sym_lst}} if ( $type eq 'sym' );
@list = (sort keys %{$self->{na_lst}},sort keys %{$self->{ns_lst}},sort keys %{$self->{cx_lst}}) if ( $type eq 'all' );
if ( scalar(@list) eq 0 ) {
@list = ();
}
return @list;
}
#--------------------------------------------------------------------------
# get_param
# Purpose:
# Required parameters:
# Returns:
#--------------------------------------------------------------------------
sub get_param {
my ( $self, $type, $param, $array ) = @_;
my $result;
$result = $self->{na_lst}{$array}{$param} if ( $type eq 'na' );
$result = $self->{cx_lst}{$array}{$param} if ( $type eq 'cx' );
$result = $self->{ns_lst}{$array}{$param} if ( $type eq 'ns' );
$result = $self->{sym_lst}{$array}{$param} if ( $type eq 'sym' );
$result = $self->{$param} if ( $type eq 'global' );
return $result;
}
#--------------------------------------------------------------------------
# get_class
# Purpose:
# Required parameters:
# Returns:
#--------------------------------------------------------------------------
sub get_class {
my ( $self, $array, $group ) = @_;
my $result;
$result = $self->{storage_class}{$array}{$group} // 'undef';
return $result;
}
#--------------------------------------------------------------------------
# set_current_array
# Purpose:
# Required parameters:
# Returns:
#--------------------------------------------------------------------------
sub set_current_array {
my ( $self, $array ) = @_;
$self->{current_array} = $array;
}
1;