# # Copyright (c) 2001-2013 NetApp, Inc., All Rights Reserved # Any use, modification, or distribution is prohibited # without prior written consent from NetApp, Inc. # ## @summary AntivirusOnDemand Task Module ## @author swati.bajaj@netapp.com, dl-nacl-dev@netapp.com ## @status shared ## @pod here package NACL::STask::AntivirusOnDemand; use strict; use warnings; use base qw(NACL::C::AntivirusOnDemand NACL::STask::STask); use NACL::C::AntivirusOnDemandReport; use NATE::Log qw(log_global); my $Log = log_global(); my $may_enter = $Log->may_enter(); my $may_exit = $Log->may_exit(); use Params::Validate qw(validate SCALAR BOOLEAN SCALARREF); use NATE::Exceptions::Argument qw(:try); use NACL::APISet::Exceptions::ResponseException (); =head1 NAME NACL::STask::AntivirusOnDemand =head1 DESCRIPTION C provides a number of well-defined but potentially complex or multi-step methods related to AntivirusOnDemand in ONTAP. It builds on top of, and is a derived class of C, and so it also provides methods that are more in the scope of individual AntivirusOnDemand-related commands. See C for details. This also means that a C object may generally be used in place of a component object. =head1 ATTRIBUTES =head2 command_interface (Required) A component object that represents the host to which to send commands. =head1 METHODS =head2 schedule NACL::STask::AntivirusOnDemand->schedule( command_interface => $command_interface, command => $command_name, schedule => $schedule, nacltask_verify => 0|1 # defaults to 0, %other_options ); (Class method) This method is used to schedule On-Demand Scan. Also verify that the on-demand command has been scheduled if C is set to 1. =over =item C<< nacltask_verify => 0|1 >> (Optional, defaults to 0) When set to 1, the on-demand schedule is verified. When set to 0, verification is not performed. =item C<< nacltask_if_scheduled => 'pass' | 'die' >> (Optional, defaults to "die") This arguments specifies what should be done if the scan has already been scheduled. "pass" means that the exception should be suppressed, a value of "die" will result in the exception being propagated. =item other options See L for all the other options accepted by this method. =back =over =item Exceptions =over =item C This type of exception is thrown when an attempt is made to schedule antivirus ondemand when it is already scheduled. =item C This type of exception is thrown when verification fails to find any scheduled antivirus ondemand command. =back =cut sub schedule { $Log->enter() if $may_enter; my ( $pkg, @args ) = @_; my %opts = $pkg->_common_validate_with( params => \@args, additional_spec => { nacltask_verify => { type => SCALAR, default => 0 }, nacltask_if_scheduled => $pkg->_if_action_completed_already_validate_spec( name => 'nacltask_if_scheduled' ), }, allow_extra => 1, ); my $command_interface = $opts{command_interface}; my $verify = delete $opts{nacltask_verify}; my $if_scheduled = delete $opts{nacltask_if_scheduled}; my $already_scheduled; # Execute the Component schedule method try { $pkg->SUPER::schedule(%opts); } catch NACL::C::Exceptions::AntivirusOnDemand::AlreadyScheduled with { my $exception = shift; $already_scheduled = 1; if ( $if_scheduled =~ /die/i ) { $Log->exit() if $may_exit; $exception->throw(); } }; # Verify that the AntivirusOnDemandCommand was scheduled if ( $verify && !$already_scheduled ) { my $od_state = NACL::CS::AntivirusOnDemand->fetch( 'command_interface' => $command_interface, 'filter' => { name => $opts{command}, schedule => $opts{schedule}, }, allow_empty => 1, ); if ( !defined $od_state ) { $Log->exit() if $may_exit; NACL::Exceptions::VerifyFailure->throw( "Failed to schedule on-demand command"); } } $Log->exit() if $may_exit; } =head2 run NACL::STask::AntivirusOnDemand->run( command_interface => $command_interface, command => $command_name, nacltask_verify => 0|1 # defaults to 0, %other_options ); (Class method) This method is used to run On-Demand Scan. Also verify that the on-demand command has started the run if C is set to 1. =over =item C<< nacltask_verify => 0|1 >> (Optional, defaults to 0) When set to 1, the on-demand run is verified. When set to 0, verification is not performed. =item other options See L<"NACL::C::AntivirusOnDemand-\>run"|lib-NACL-C-AntivirusOnDemand-pm/run> for all the other options accepted by this method. =back =over =item Exceptions =over =item C This type of exception is thrown when an attempt is made to delete antivirus ondemand report. =item C This type of exception is thrown when verification fails to find any antivirus on-demand report. =back =cut sub run { $Log->enter() if $may_enter; my $pkg = shift; my %opts = $pkg->_common_validate_with( params => \@_, additional_spec => { nacltask_verify => { type => SCALAR, default => 0 }, }, allow_extra => 1, ); my $command_interface = $opts{command_interface}; my $verify = delete $opts{nacltask_verify}; # Empty the report history before we start the run if we # need to verify the run later. my %od_report_delete = ( command_interface => $opts{command_interface}, id => "all", ); $od_report_delete{vserver} = $opts{vserver} if (exists $opts{vserver}); if ($verify) { try { NACL::C::AntivirusOnDemandReport->delete( %od_report_delete, ); } catch NACL::APISet::Exceptions::CommandFailedException with { my $ex = shift; if ( $ex->text() =~ /There are no entries matching your query/ ) { $Log->debug("There are no old reports to be deleted"); # Continue further } else { $Log->exit() if $may_exit; $ex->throw(); } }; } $pkg->SUPER::run(%opts); # Verify whether the avod was run if 'nacltask_verify' is set to 1 if ($verify) { # It takes a couple of seconds for the report to be generated after # the command is run. So let us add some snooze to verify Tharn::snooze(10); # Once the command is run, it generates a report. This can # be used to verify whether the on-demand command was run. my $od_report = NACL::CS::AntivirusOnDemandReport->fetch( command_interface => $command_interface, filter => { 'command' => $opts{'command'} }, allow_empty => 1 ); unless ($od_report) { $Log->exit() if $may_exit; NACL::Exceptions::VerifyFailure->throw( "Failed to run on-demand command"); } } $Log->exit() if $may_exit; } =head2 unschedule NACL::STask::AntivirusOnDemand->unschedule( command_interface => $command_interface, vserver => $vs_name, id => $jobid, nacltask_wait => 0|1 # defaults to 1, %other_options ); (Class method) This method is used to unschedule On-Demand Scan. Defaults to waiting for the scan to be unscheduled. =over =item Options =over =item C<< nacltask_wait => 0|1 >> (Optional, defaults to 1) When set to 1 waits for the scan to be unscheduled. It is also possible to wait later by invoking the L method. =item other options See L for all the other options accepted by this method. =back =back =cut sub unschedule { $Log->enter() if $may_enter; my ( $pkg, @args ) = @_; my %opts = $pkg->_common_validate_with( params => \@args, additional_spec => { nacltask_wait => { type => SCALAR, default => 1 }, }, allow_extra => 1 ); my $wait = delete $opts{nacltask_wait}; $pkg->SUPER::unschedule(%opts); $pkg->wait_for_unschedule(%opts) if ($wait); $Log->exit() if $may_exit; } =head2 wait_for_unschedule NACL::STask::AntivirusOnDemand->wait_for_unschedule( command_interface => $ci, vserver => $vserver_name, id => $jobid, %other_opts ); Waits for the unschedule to complete. Defaults to waiting for 300 seconds. If the unschedule is not complete within 300 seconds, then a C is thrown. =over =item Options =over =item C<< command_interface => $command_interface >> (Mandatory) The command interface on which to run the commands. =item C<< vserver => $vs_name >> The vserver on which the scan had been initiated. =item C<< id => $jobid >> The ID of the scan which is being unscheduled. =item C<< 'method-timeout' => $time >> (Optional, defaults to 300s) The time for which to wait for the unschedule to complete. =item C<< polling_interval => $interval >> (Optional, defaults to 10s) The interval at which to poll for whether the unschedule command completed. =back =back =cut sub wait_for_unschedule { $Log->enter() if $may_enter; my ( $pkg, @args ) = @_; my %opts = $pkg->_common_validate_with( params => \@args, additional_spec => { id => { type => SCALAR } }, ); # The field in the "show" output is "jobid", but for unschedule it's # called "id" $opts{jobid} = delete $opts{id}; $pkg->wait_for_deletion( 'method-timeout' => 300, %opts ); $Log->exit() if $may_exit; } 1;