Hide Show 27 lines of Pod
use
5.010001;
our
$VERSION
=0.11;
use
constant
RESULT_CLASS
=>
'Net::SolarWinds::Result'
;
Hide Show 10 lines of Pod
our
$JSON
=JSON->new->allow_nonref->utf8;
Hide Show 6 lines of Pod
sub
get_json {
return
$JSON
; }
Hide Show 6 lines of Pod
our
$UA
=LWP::UserAgent->new;
$UA
->ssl_opts(
SSL_verify_mode
=> IO::Socket::SSL::SSL_VERIFY_NONE,
SSL_hostname
=>
''
,
verify_hostname
=> 0
);
Hide Show 6 lines of Pod
sub
get_ua {
return
$UA
; }
Hide Show 18 lines of Pod
use
constant
DEFAULT_SERVER
=>
'SolarWindsServer'
;
use
constant
LOG_CLASS
=>
'Net::SolarWinds::Log'
;
Hide Show 22 lines of Pod
sub
new {
my
(
$class
,
%args
)=
@_
;
foreach
my
$key
(
qw(USER PASS SERVER PORT PROTO)
) {
my
$method
=
"DEFAULT_$key"
;
next
if
exists
$args
{
$key
};
$args
{
$key
}=
$class
->
$method
;
}
my
$self
=
$class
->SUPER::new(
%args
);
$self
->{header}=[
Authorization
=>
'Basic '
.MIME::Base64::encode_base64(
$self
->{USER} .
':'
.
$self
->{PASS}),
'Content-Type'
=>
'application/json'
,
];
return
$self
;
}
Hide Show 6 lines of Pod
sub
build_request {
my
(
$self
,
$method
,
$path
,
$data
)=
@_
;
my
$uri
=
sprintf
$self
->BASE_URI,@{
$self
}{
qw(PROTO SERVER PORT )
},
$path
;
my
$content
=
undef
;
my
$headers
=[@{
$self
->{header}}];
if
(
defined
(
$data
)) {
$content
=
$self
->get_json->encode(
$data
);
push
@{
$headers
},
'Content-Length'
=>
length
(
$content
);
}
my
$request
=HTTP::Request->new(
$method
,
$uri
,
$headers
,
$content
);
$self
->log_debug(
$request
->as_string);
return
$request
;
}
Hide Show 8 lines of Pod
sub
run_request {
my
(
$self
,
$request
)=
@_
;
$self
->log_debug(
"Sending: "
,
$request
->as_string);
my
$response
=
$self
->get_ua->request(
$request
);
$self
->log_debug(
"Got back"
,
$response
->as_string);
my
$content
=
$response
->decoded_content;
if
(
$response
->is_success) {
if
(
$content
=~ /^\s*[\[\{]/s) {
my
$data
=
eval
{
$self
->get_json->decode(
$content
)};
if
($@) {
return
$self
->RESULT_CLASS->new_false(
"Code: ["
.
$response
->code.
"] JSON Decode error [$@] Content: $content"
,
$response
);
}
else
{
return
$self
->RESULT_CLASS->new_true(
$data
,
$response
);
}
}
else
{
return
$self
->RESULT_CLASS->new_true(
$content
,
$response
);
}
}
else
{
return
$self
->RESULT_CLASS->new_false(
"Code: ["
.
$response
->code.
"] http error ["
.
$response
->status_line.
"] Content: $content"
,
$response
);
}
}
Hide Show 6 lines of Pod
sub
DiscoverInterfacesOnNode {
my
(
$self
,
$nodeId
)=
@_
;
$nodeId
.=
''
;
my
$request
=
$self
->build_request(
'POST'
,
'Invoke/Orion.NPM.Interfaces/DiscoverInterfacesOnNode'
,[
$nodeId
]);
my
$result
=
$self
->run_request(
$request
);
return
$result
;
}
Hide Show 9 lines of Pod
sub
DiscoverInterfaceMap {
my
(
$self
,
$node_id
)=
@_
;
$self
->log_info(
"starting node_id: $node_id"
);
my
$result
=
$self
->DiscoverInterfacesOnNode(
$node_id
);
$self
->log_info(
"stopping"
);
return
$self
->build_interface_result_map(
$result
);
}
Hide Show 6 lines of Pod
sub
build_interface_result_map {
my
(
$self
,
$result
)=
@_
;
$self
->log_info(
"starting"
);
unless
(
$result
) {
$self
->log_error(
"failed to build interface map error was: $result"
);
$self
->log_info(
"stopping"
);
return
$result
;
}
my
$list
=
$result
->get_data->{DiscoveredInterfaces};
my
$map
={};
foreach
my
$int
(@{
$list
}) {
my
$caption
=
$int
->{Caption};
my
@list
=
$self
->InterfaceCaptionTranslation(
$caption
);
foreach
my
$ifname
(
@list
) {
$map
->{
$ifname
}=
$int
;
}
}
$self
->log_info(
"stopping"
);
return
$self
->RESULT_CLASS->new_true(
$map
,
$list
);
}
Hide Show 6 lines of Pod
sub
InterfaceCaptionTranslation {
my
(
$self
,
$caption
)=
@_
;
$self
->log_info(
"starting"
);
my
@list
;
if
(
$caption
=~ s/\s\\x\{b7\}.*$//s > 0) {
push
@list
,
$caption
;
}
else
{
push
@list
,
split
/\s+-\s+/,
$caption
;
}
$self
->log_info(
"stopping"
);
return
@list
;
}
Hide Show 7 lines of Pod
sub
NodeInterfaceAddDefaultPollers {
my
(
$self
,
$nodeId
,
$data
)=
@_
;
$self
->log_info(
"starting"
);
$nodeId
.=
''
;
my
$request
=
$self
->build_request(
'POST'
,
'Invoke/Orion.NPM.Interfaces/AddInterfacesOnNode'
,[
$nodeId
,
$data
,
'AddDefaultPollers'
]);
my
$result
=
$self
->run_request(
$request
);
$self
->log_info(
"stopping"
);
return
$result
;
}
Hide Show 6 lines of Pod
sub
NodeAddInterface {
my
(
$self
,
$node_id
,
$data
)=
@_
;
$self
->log_info(
"starting"
);
my
$request
=
$self
->build_request(
'POST'
,
'Invoke/Orion.NPM.Interfaces/AddInterfacesOnNode'
,[
$node_id
,
$data
,
'AddNoPollers'
]);
my
$result
=
$self
->run_request(
$request
);
$self
->log_info(
"stopping"
);
return
$result
;
}
Hide Show 7 lines of Pod
sub
NodeInterfaceCustomProperties {
my
(
$self
,
$nodeId
,
$interfaceId
,
$data
)=
@_
;
my
$request
;
$self
->log_info(
"starting"
);
if
(
$data
) {
}
else
{
}
my
$result
=
$self
->run_request(
$request
);
$self
->log_info(
"stopping"
);
return
$result
;
}
Hide Show 6 lines of Pod
sub
query_lookup {
my
(
$self
,
@args
)=
@_
;
my
$hash
=
$self
->LOG_CLASS->lookback(2);
my
$method
=
$hash
->{
sub
};
$method
=~ s/^.*::([^:]+)/$1/s;
$self
->log_debug(
"Starting look up of query: $method"
);
my
$query
=
$self
->get_query(
$method
);
$self
->log_debug(
"Finished look up of query: $method"
);
$self
->log_debug(
"Preparing query: $method Args: ["
,
join
(
','
,
map
{
defined
(
$_
) ?
qq{"$_"}
:
'""'
}
@args
),
']'
);
my
$swql
=
$self
->prepare_query(
$query
,
@args
);
$self
->log_debug(
"Preparing query: $method Looks like: $swql"
);
return
$swql
;
}
Hide Show 6 lines of Pod
sub
prepare_query {
my
(
$self
,
$query
,
@args
)=
@_
;
return
sprintf
$query
,
@args
;
}
Hide Show 6 lines of Pod
sub
get_query {
my
(
$self
,
$method
)=
@_
;
my
$constant
=
"SWQL_$method"
;
return
'QUERY NOT FOUND'
unless
$self
->can(
$constant
);
return
$self
->
$constant
;
}
Hide Show 9 lines of Pod
sub
getInterfacesOnNode {
my
(
$self
,
$node_id
)=
@_
;
my
$query
=
$self
->query_lookup(
$node_id
);
$self
->log_info(
"starting $node_id"
);
my
$result
=
$self
->Query(
$query
);
return
$result
unless
$result
;
my
$list
=
$result
->get_data->{results};
my
$ints
={};
foreach
my
$int
(@{
$list
}) {
my
@list
=
$self
->InterfaceCaptionTranslation(
$int
->{Caption});
foreach
my
$ifname
(
@list
) {
$ints
->{
$ifname
}=
$int
;
}
}
$self
->log_info(
"stopping"
);
return
$self
->RESULT_CLASS->new_true(
$ints
);
}
Hide Show 7 lines of Pod
sub
NodeCustomProperties {
my
(
$self
,
$nodeId
,
$data
)=
@_
;
my
$request
;
if
(
$data
) {
$self
->log_info(
"starting node_id: $nodeId mode: POST"
);
}
else
{
$self
->log_info(
"starting node_id: $nodeId mode: GET"
);
}
my
$result
=
$self
->run_request(
$request
);
$self
->log_info(
"stopping"
);
return
$result
;
}
Hide Show 7 lines of Pod
sub
Query {
my
(
$self
,
$sql
)=
@_
;
$self
->log_info(
"starting"
);
$self
->log_debug(
"$sql"
);
my
$path
=
'Query?query='
.uri_encode(
$sql
);
my
$request
=
$self
->build_request(
'GET'
,
$path
);
my
$result
=
$self
->run_request(
$request
);
$self
->log_info(
"stopping"
);
return
$result
;
}
Hide Show 7 lines of Pod
sub
getNodesByIp {
my
(
$self
,
$ip
)=
@_
;
$self
->log_info(
"starting $ip"
);
my
$query
=
$self
->query_lookup(
$ip
);
my
$result
=
$self
->Query(
$query
);
$self
->log_info(
"stopping"
);
return
$result
;
}
Hide Show 7 lines of Pod
sub
getNodesByDisplayName {
my
(
$self
,
$ip
)=
@_
;
$self
->log_info(
"starting $ip"
);
my
$query
=
$self
->query_lookup(
$ip
,
$ip
);
my
$result
=
$self
->Query(
$query
);
$self
->log_info(
"stopping"
);
return
$result
;
}
Hide Show 6 lines of Pod
sub
getNodesByID {
my
(
$self
,
$id
)=
@_
;
$self
->log_info(
"starting"
);
my
$query
=
$self
->query_lookup(
$id
);
my
$result
=
$self
->Query(
$query
);
$self
->log_info(
"stopping"
);
return
$result
;
Hide Show 7 lines of Pod
}
sub
createNode {
my
(
$self
,
%args
)=
@_
;
$self
->log_info(
"starting"
);
%args
=(
qw(
ObjectSubType SNMP
EntityType Orion.Nodes
DynamicIP false
EngineID 1
Status 1
UnManaged false
Allow64BitCounters true
ObjectSubType SNMP
SNMPVersion 2
Community public
VendorIcon 8072.gif
NodeDescription Hardware
)
,
IOSImage
=>
""
,
IOSVersion
=>
""
,
Pollinterval
=>60,
SysObjectID
=>
"1.3.6.1.4.1.8072.3.2.10"
,
MachineType
=>
"net-snmp - Linux"
,
StatCollection
=>10,
CPULoad
=>
"-2"
,
MemoryUsed
=>
"-2"
,
PercentMemoryUsed
=>
"-2"
,
BufferNoMemThisHour
=>
"0"
,
BufferNoMemToday
=>
"0"
,
BufferSmMissThisHour
=>
"0"
,
BufferSmMissToday
=>
"0"
,
BufferMdMissThisHour
=>
"0"
,
BufferMdMissToday
=>
"0"
,
BufferBgMissThisHour
=>
"0"
,
BufferBgMissToday
=>
"0"
,
BufferLgMissThisHour
=>
"0"
,
BufferLgMissToday
=>
"0"
,
BufferHgMissThisHour
=>
"0"
,
BufferHgMissToday
=>
"0"
,
%args
);
unless
(
exists
$args
{IPAddress}) {
$self
->log_error(
"IPAddress must be set"
);
$self
->log_info(
"stopping"
);
return
$self
->RESULT_CLASS->new_false(
"IPAddress must be set"
);
}
$args
{IPAddressGUID}=
$self
->ip_to_gui(
$args
{IPAddress})
unless
exists
$args
{IPAddressGUID};
$args
{Caption}=
$self
->ip_to_reverse_hex(
$args
{IPAddress})
unless
exists
$args
{Caption};
my
$path
=
'Create/Orion.Nodes'
;
my
$request
=
$self
->build_request(
'POST'
,
$path
,{
%args
});
my
$result
=
$self
->run_request(
$request
);
unless
(
$result
) {
$self
->log_error(
"Failed to create node error was: $result"
);
$self
->log_info(
"stopping"
);
return
$result
;
}
my
$swis
=
$result
->get_data;
$swis
=~ s/(?:^
"|"
$)//sg;
my
(
$node_id
)=
$swis
=~ /(\d+)$/s;
$self
->log_info(
"stopping"
);
return
$self
->RESULT_CLASS->new_true({
Uri
=>
$swis
,
NodeID
=>
$node_id
});
}
Hide Show 7 lines of Pod
sub
getNodeUri {
my
(
$self
,
$node_id
)=
@_
;
$self
->log_info(
"starting"
);
my
$query
=
$self
->query_lookup(
$node_id
);
my
$result
=
$self
->Query(
$query
);
unless
(
$result
) {
$self
->log_error(
"could not get node uri error was: $result"
);
$self
->log_info(
"stopping"
);
return
$result
;
}
unless
($
$self
->log_error(
"NodeId: $node_id not found!"
);
$self
->log_info(
"stopping"
);
return
$self
->RESULT_CLASS->new_false(
"NodeId: $node_id not found!"
)
}
$self
->log_info(
"stopping"
);
return
$self
->RESULT_CLASS->new_true(
$result
->get_data->{results}->[0]->{Uri});
}
Hide Show 6 lines of Pod
sub
deleteSwis {
my
(
$self
,
$uri
)=
@_
;
$self
->log_info(
"starting"
);
my
$request
=
$self
->build_request(
'DELETE'
,
$uri
);
my
$result
=
$self
->run_request(
$request
);
$self
->log_info(
"stopping"
);
return
$result
;
}
Hide Show 6 lines of Pod
sub
deleteNode {
my
(
$self
,
$node_id
)=
@_
;
my
$path
;
$self
->log_info(
"starting"
);
if
(
my
$result
=
$self
->getNodeUri(
$node_id
)) {
$path
=
$result
->get_data;
}
else
{
$self
->log_error(
"Failed to delete node: $node_id error was: $result"
);
$self
->log_info(
"stopping"
);
return
$result
;
}
my
$request
=
$self
->build_request(
'DELETE'
,
$path
);
my
$result
=
$self
->run_request(
$request
);
$self
->log_info(
"stopping"
);
return
$result
;
}
Hide Show 6 lines of Pod
sub
getApplicationTemplate {
my
(
$self
,
@names
)=
@_
;
$self
->log_info(
"starting"
);
my
$append
=
join
' OR '
,
map
{
sprintf
q{Name='%s'}
,
$_
}
@names
;
my
$query
=
$self
->query_lookup(
$append
);
my
$result
=
$self
->Query(
$query
);
$self
->log_info(
"stopping"
);
return
$result
;
}
Hide Show 9 lines of Pod
sub
addTemplateToNode {
my
(
$self
,
$node_id
,
$template_id
,
$cred_id
)=
@_
;
$cred_id
=-4
unless
defined
(
$cred_id
);
$self
->log_info(
"starting node_id: $node_id template_id: $template_id credential_id: $cred_id"
);
my
$request
=
$self
->build_request(
'POST'
,
'Invoke/Orion.APM.Application/CreateApplication'
,
[
$node_id
,
$template_id
,
$cred_id
,JSON::true]
);
my
$result
=
$self
->run_request(
$request
);
unless
(
$result
) {
$self
->log_error(
"Failed to addTemplateToNode error was: $result"
);
$self
->log_info(
"stopping"
);
return
$result
;
}
if
(
$result
->get_data == -1) {
my
$msg
=
"TemplateID: $template_id all ready exists on node"
;
$self
->log_error(
$msg
);
$self
->log_info(
"stopping"
);
return
$self
->RESULT_CLASS->new_false(
$msg
);
}
$self
->log_info(
"stopping"
);
return
$result
;
}
Hide Show 8 lines of Pod
sub
getTemplatesOnNode {
my
(
$self
,
$node_id
)=
@_
;
$self
->log_info(
"starting"
);
my
$query
=
$self
->query_lookup(
$node_id
);
my
$result
=
$self
->Query(
$query
);
unless
(
$result
) {
$self
->log_error(
"failed to getTemplatesOnNode"
);
$self
->log_info(
"stopping"
);
return
$result
;
}
$self
->log_info(
"stopping"
);
return
$self
->RESULT_CLASS->new_true(
$result
->get_data->{results});
}
Hide Show 6 lines of Pod
sub
UpdateNodeProps {
my
(
$self
,
$nodeID
,
%args
)=
@_
;
$self
->log_info(
"starting node_id: $nodeID"
);
my
$request
;
if
(
scalar
(
keys
(
%args
))==0) {
$self
->log_info(
"called in Read mode"
);
$request
=
$self
->build_request(
'GET'
,
$uri
);
}
else
{
$self
->log_info(
"called in Write mode"
);
$request
=
$self
->build_request(
'POST'
,
$uri
,{
%args
});
}
my
$result
=
$self
->run_request(
$request
);
$self
->log_info(
"stopping $nodeID"
);
return
$result
;
}
Hide Show 6 lines of Pod
sub
AddPollerToNode {
my
(
$self
,
$node_id
,
$poller
)=
@_
;
$self
->log_info(
"starting node_id: $node_id poller: $poller"
);
my
$result
=
$self
->add_poller(
$node_id
,
'N'
,
$poller
);
$self
->log_info(
"stopping node_id: $node_id poller: $poller"
);
return
$result
;
}
Hide Show 6 lines of Pod
sub
add_poller {
my
(
$self
,
$node_id
,
$t
,
$poller
)=
@_
;
$self
->log_info(
"starting object_id: $node_id type: $t poller: $poller"
);
my
$json
={
PollerType
=>
$poller
,
NetObjectType
=>
$t
,
NetObject
=>
$t
.
':'
.
$node_id
,
NetObjectID
=>
$node_id
,
};
my
$request
=
$self
->build_request(
'POST'
,
'Create/Orion.Pollers'
,
$json
);
my
$result
=
$self
->run_request(
$request
);
unless
(
$result
) {
$self
->log_error(
"failed to add poller to node_id: $node_id type: $t poller: $poller error was: $result"
);
$self
->log_info(
"stopping"
);
return
$result
;
}
my
$url
=
$result
->get_data;
$url
=~ s/(?:^
"|"
$)//g;
$self
->log_info(
"stopping"
);
return
$self
->RESULT_CLASS->new_true(
$url
);
}
Hide Show 10 lines of Pod
sub
add_volume {
my
(
$self
,
%args
)=
@_
;
$self
->log_info(
"starting"
);
my
$json
={
VolumeIndex
=>2,
Caption
=>
"/"
,
VolumeDescription
=>
"/"
,
Status
=>1,
VolumeType
=>
"Fixed Disk"
,
VolumeTypeIcon
=>
"FixedDisk.gif"
,
VolumeSpaceAvailable
=>0,
VolumeSize
=>0,
VolumePercentUsed
=>0,
VolumeSpaceUsed
=>0,
VolumeTypeID
=>4,
PollInterval
=>240,
StatCollection
=>15,
RediscoveryInterval
=>30,
,
%args
};
my
$request
=
$self
->build_request(
'POST'
,
'Create/Orion.Volumes'
,
$json
);
my
$result
=
$self
->run_request(
$request
);
$self
->log_info(
"stopping"
);
return
$result
;
}
Hide Show 8 lines of Pod
sub
getVolumeTypeMap {
my
(
$self
)=
@_
;
$self
->log_info(
"starting"
);
my
$query
=
$self
->SWQL_getNodesByIp;
my
$result
=
$self
->Query(
$query
);
unless
(
$result
) {
$self
->log_error(
"Failed to get getVolumeTypeMap error was: $result"
);
$self
->log_info(
"stopping"
);
return
$result
;
}
my
$list
=
$result
->get_data->{results};
my
$map
={};
foreach
my
$type
(@{
$list
}) {
$map
->{
$type
->{VolumeType}}=
$type
;
}
$self
->log_info(
"stopping"
);
return
$self
->RESULT_CLASS->new_true(
$map
);
}
Hide Show 8 lines of Pod
sub
getEngines {
my
(
$self
)=
@_
;
my
$result
=
$self
->Query(
$self
->SWQL_getEngines);
return
$result
;
}
Hide Show 10 lines of Pod
sub
getEngine {
my
(
$self
,
$engine
)=
@_
;
my
$result
=
$self
->Query(
$self
->query_lookup(
$engine
,
$engine
));
return
$result
unless
$result
;
Hide Show 8 lines of Pod
}
sub
getVolumeMap {
my
(
$self
,
$node_id
)=
@_
;
$self
->log_info(
"starting"
);
my
$query
=
$self
->query_lookup(
$node_id
);
my
$result
=
$self
->Query(
$query
);
unless
(
$result
) {
$self
->log_error(
"Failed to get getVolumeMap for node_id: $node_id error was: $result"
);
$self
->log_info(
"stopping"
);
return
$result
;
}
my
$list
=
$result
->get_data->{results};
my
$map
={};
my
$MaxVolumeIndex
=$
foreach
my
$vol
(@{
$list
}) {
$map
->{
$vol
->{Caption}}=
$vol
;
}
$self
->log_info(
"stopping"
);
return
$self
->RESULT_CLASS->new_true({
'map'
=>
$map
,
MaxVolumeIndex
=>
$MaxVolumeIndex
});
}
Hide Show 8 lines of Pod
sub
getSwisProps {
my
(
$self
,
$uri
)=
@_
;
$self
->log_info(
"starting"
);
my
$request
=
$self
->build_request(
'GET'
,
$uri
);
my
$result
=
$self
->run_request(
$request
);
$self
->log_info(
"stopping"
);
return
$result
;
}
Hide Show 6 lines of Pod
sub
GetNodePollers {
my
(
$self
,
$node_id
,
$type
)=
@_
;
$type
=
'N'
unless
defined
(
$type
);
$self
->log_info(
"starting node_id: $node_id type: $type"
);
my
$query
=
$self
->query_lookup(
$node_id
,
$type
);
my
$result
=
$self
->Query(
$query
);
unless
(
$result
) {
$self
->log_error(
"Failed to GetNodePollers on node_id: $node_id type: $type"
);
$self
->log_info(
"stopping"
);
return
$result
;
}
my
$list
=
$result
->get_data->{results};
my
$pollers
=[];
foreach
my
$poller
(@{
$list
}) {
return
unless
$result
;
push
@{
$pollers
},
$result
->get_data;
}
$self
->log_info(
"stopping"
);
return
$self
->RESULT_CLASS->new_true(
$pollers
);
}
Hide Show 6 lines of Pod
sub
UpdateUri {
my
(
$self
,
$uri
,
%args
)=
@_
;
$self
->log_info(
"starting Uri: $uri"
);
my
$request
;
if
(
scalar
(
keys
(
%args
))==0) {
$self
->log_info(
"called in Read mode"
);
$request
=
$self
->build_request(
'GET'
,
$uri
);
}
else
{
$self
->log_info(
"called in Write mode"
);
$request
=
$self
->build_request(
'POST'
,
$uri
,{
%args
});
}
my
$result
=
$self
->run_request(
$request
);
$self
->log_info(
"stopping Uri $uri"
);
return
$result
;
}
Hide Show 20 lines of Pod
1;