# $Id$ # # Copyright (c) 2001-2013 NetApp, Inc., All Rights Reserved # Any use, modification, or distribution is prohibited # without prior written consent from NetApp, Inc. # ## @summary LunMaxsize ComponentState Module ## @author anbumozh@netapp.com dl-nacl-dev@netapp.com ## @status shared ## @pod here =head1 NAME NACL::CS::LunMaxsize =head1 DESCRIPTION C is a derived class of L. A related class is L =head1 ATTRIBUTES This module does not represent the state of any element, but is an object repesentation of the output obtained when the lun maxsize is queried =over =item C<< "qtree" >> Filled in for CMode CLI/ZAPI , 7Mode CLI. Maps to: CM ZAPI: Input: For "filter": This input along with 'volume' is used to construct the 'path' input. For "requested_fields": Not applicable, but this field will be filled in the CS object. Output mapping: The value will be same as what was specified to 'qtree' option in the filter. Or it will be obtained from the 'path' input specified to the filter 7M CLI: For "filter" : This input along with 'volume' is used to construct the 'path' input. For "requested_fields" : Not applicable, but this field will be filled in the CS object. =item C<< "volume" >> Filled in for CMode CLI/ZAPI , 7Mode CLI. Maps to: CM ZAPI: Input: For "filter": This input along with 'qtree'(optional) is used to construct the 'path' input. For "requested_fields": Not applicable, but this field will be filled in the CS object. Output mapping: The value will be same as what was specified to 'volume' option in the filter. Or it will be obtained from the 'path' input specified to the filter 7M CLI: For "filter" : This input along with 'qtree'(optional) is used to construct the 'path' input. For "requested_fields" : Not applicable, but this field will be filled in the CS object. =item C<< "vserver" >> Filled in for CMode CLI/ZAPI. Maps to: CM ZAPI: For "filter" : Invoked in the context of the specified vserver For "requested_fields" : Not applicable, but this field will be filled in the CS object. Output mapping: The name of the vserver in whose context, the ZAPI is invoked will be filled in the CS object =item C<< "path" >> Filled in for CMode CLI/ZAPI. Maps to: CM ZAPI: Input: For "filter": $value For "requested_fields" : Not applicable, but this field will be filled in the CS object. Output mapping: The value will be same as what was specified to 'path' or volume , qtree(optional) in the filter 7M CLI: Input: For "filter": Maps to path (Programmatic option : path) For "requested_fields" : Not applicable, but this field will be filled in the CS object. =item C<< "ostype" >> Filled in for CMode CLI/ZAPI. Maps to: CM ZAPI: Input: For "filter": $value For "requested_fields": Not applicable, but this field will be filled in the CS object. Output mapping: The value will be same as what was specified to 'ostype' in the filter. =item C<< "complete_ss_reserve" >> Filled in for CMode CLI/ZAPI, 7Mode CLI. Maps to: CM ZAPI: Input: For "filter" : Applicable, Filtering will be done by Components. For "requested_fields": Not applicable, but this field will be filled in the CS object. Output mapping: $value 7M CLI : For "filter": Applicable, Filtering will be done by Components. For "requested_fields" : Not applicable, but this field will be filled in the CS object. =item C<< "ss_reserve" >> Filled in for CMode CLI/ZAPI, 7Mode CLI. Maps to: CM ZAPI: For "filter" : Applicable, Filtering will be done by Components. For "requested_fields": Not applicable, but this field will be filled in the CS object. Output mapping: $value 7M CLI : For "filter": Applicable, Filtering will be done by Components. For "requested_fields" : Not applicable, but this field will be filled in the CS object. =item C<< "without_ss_reserve" >> Filled in for CMode CLI/ZAPI, 7Mode CLI. Maps to: CM ZAPI: For "filter" : Applicable, Filtering will be done by Components. For "requested_fields": Not applicable, but this field will be filled in the CS object. Output mapping: $value 7M CLI : For "filter": Applicable, Filtering will be done by Components. For "requested_fields" : Not applicable, but this field will be filled in the CS object. =back =cut package NACL::CS::LunMaxsize; use strict; use warnings; use Params::Validate qw(validate); use NACL::ComponentUtils qw(_dump_one Dumper); use NATE::Log qw(log_global); my $Log = log_global(); my $may_enter = $Log->may_enter(); my $may_exit = $Log->may_exit(); use NACL::Exceptions::NoElementsFound qw(:try); use NATE::Exceptions::Argument qw(:try); use base 'NACL::CS::ComponentState::ONTAP'; use Class::MethodMaker [ scalar => 'vserver', scalar => 'path', scalar => [ { '-default_ctor' => sub { my $self = $_[0]; if ($self->path()) { my $path = $self->path(); $path =~ /\/vol\/(\w+)/; return $1; } }, }, 'volume' ], scalar => [ { '-default_ctor' => sub { my $self = $_[0]; if ($self->path()) { my $path = $self->path(); if ($path =~ /\/vol\/\S+\/(\S+)/) { return $1; } else { return ""; } } }, }, 'qtree' ], scalar => 'ostype', scalar => 'complete_ss_reserve', scalar => 'ss_reserve', scalar => 'without_ss_reserve' ]; =head1 METHODS =head2 fetch my $LunMaxsize_state = NACL::CS::LunMaxsize->fetch(command_interface => $ci, ...); my @LunMaxsize_states = NACL::CS::LunMaxsize->fetch(command_interface => $ci, ...); (Class method) Discovers which elements are present and returns their state in ComponentState objects. Called in scalar context it returns only one state object, in list context it returns all state objects. See L for a more detailed description along with a complete explanation of the options it accepts. =over =item Exceptions =over =item C When there are no elements matching the query specified or elements of that type doesn't exist, then this exception will be thrown. =item C When apiset_must choice for interface is provided as 'ZAPI' and if the method is invoked without specifying 'path' (or volume and qtree (optional)) or ostype then this exception will be thrown. When path is not specified and qtree is specified without specifying the volume , then this exception is thrown. =item C when path is specified and also volume or qtree is provided ,then this exception is thrown. =back =back =cut sub fetch { $Log->enter() if $may_enter; my $pkg = shift; my @state_objs = $pkg->SUPER::fetch( @_, choices => [ { method => '_fetch_cmode_cli', interface => 'CLI', set => 'CMode' }, { method => '_fetch_cmode_zapi', interface => 'ZAPI', set => 'CMode', check => '_fetch_zapi_check' }, { method => '_fetch_7mode_cli', interface => 'CLI', set => '7Mode' }, ], exception_text => 'No matching lun maxsize(s) found', show_cmd => 'lun maxsize', ); $Log->exit() if $may_exit; return wantarray ? @state_objs : $state_objs[0]; } ## end sub fetch sub _fetch_cmode_cli { $Log->enter() if $may_enter; my $pkg = shift; my @state_objs = $pkg->SUPER::_fetch_cmode_cli(@_, api => 'lun_maxsize'); $Log->exit() if $may_exit; return @state_objs; } ## end sub _fetch_cmode_cli sub _fetch_cmode_zapi { $Log->enter() if $may_enter; my $pkg = shift; my %opts = validate @_, $pkg->_fetch_backend_validate_spec(); my $apiset = $opts{apiset}; my %copy_filter = %{$opts{filter}}; my $filter = \%copy_filter; my $lun_get_args; if ($filter->{path} && ($filter->{volume} || $filter->{qtree})) { $Log->exit() if $may_exit; NATE::Exceptions::Argument->throw( "Pass only either of path or volume (and qtree) in the filter"); } if (($filter->{volume} || $filter->{qtree}) && (!$filter->{path})) { $lun_get_args->{path} = &_construct_path(%{$filter}); } else { $lun_get_args->{path} = $filter->{path}; } $lun_get_args->{type} = $filter->{ostype}; my $lun_response; # find all the lun present. my $vserver = $pkg->_handle_zapi_vserver_context( api_opts => \%$lun_get_args, vserver => $filter->{vserver}, command_interface => $opts{command_interface} ); $lun_response = $apiset->lun_get_maxsize(%$lun_get_args); my $lun_output = $lun_response->get_parsed_output(); my @state_objs; foreach my $row (@{$lun_output}) { my $state_fields = $pkg->_zapi_hash_copy( source => $row, source_has_extra_arrays => 1, copy => [qw(path)], map => [ "type" => "ostype", "with-complete-snapshot-reserve" => "complete-ss-reserve", "with-snapshot-reserve" => "ss-reserve", "without-snapshot-reserve" => "without-ss-reserve" ], ); my $obj = $pkg->new(command_interface => $opts{command_interface}); $state_fields->{vserver} = $vserver; $state_fields->{path} = $lun_get_args->{path}; $state_fields->{ostype} = $lun_get_args->{type}; $obj->_set_fields(row => $state_fields); push @state_objs, $obj; } ## end foreach my $row ( @{$lun_output... $Log->exit() if $may_exit; return @state_objs; } ## end sub _fetch_cmode_zapi sub _fetch_7mode_cli { $Log->enter() if $may_enter; my $pkg = shift; my %opts = validate @_, $pkg->_fetch_backend_validate_spec(); my $apiset = $opts{apiset}; my %copy_filter = %{$opts{filter}}; my @copy_requested_fields = @{$opts{requested_fields}}; my $deleted_filter = $pkg->_remove_relational_regex_filters( filter => \%copy_filter, requested_fields => \@copy_requested_fields ); my $filter = \%copy_filter; my $requested_fields = \@copy_requested_fields; my $lun_response; my %lun_get_args; if ($filter->{path} && ($filter->{volume} || $filter->{qtree})) { $Log->exit() if $may_exit; NATE::Exceptions::Argument->throw( "Pass only either of path or volume (and qtree) in the filter"); } if (($filter->{volume} || $filter->{qtree}) && (!$filter->{path})) { $lun_get_args{'path'} = &_construct_path(%{$filter}); } else { $lun_get_args{'path'} = $filter->{'path'}; } # find all the lun present. $lun_response = $apiset->lun_maxsize(%lun_get_args); my $lun_output = $lun_response->get_parsed_output(); my @state_objs; foreach my $row (@{$lun_output}) { foreach my $os (@{$row->{'ostype'}}) { my $state_fields = $pkg->_hash_copy( source => $row, map => { "with_complete_snapshot_reserve" => "complete-ss-reserve", "with_snapshot_reserve" => "ss-reserve", "without_snapshot_reserve" => "without-ss-reserve" }, ); $$state_fields{'ostype'} = $os; $$state_fields{'path'} = $lun_get_args{'path'}; $$state_fields{'command_interface'} = $opts{'command_interface'}; my $obj = $pkg->new(command_interface => $opts{command_interface}); $obj->_set_fields(row => $state_fields); push @state_objs, $obj; } ## end foreach my $os ( @{ $row->{... } ## end foreach my $row ( @{$lun_output... $Log->exit() if $may_exit; return @state_objs; } ## end sub _fetch_7mode_cli sub _construct_path { $Log->enter() if $may_enter; my %opts = @_; my $path; if ($opts{volume}) { if ($opts{qtree}) { $path = '/vol/' . $opts{volume} . '/' . $opts{qtree}; } else { $path = '/vol/' . $opts{volume}; } } else { $Log->exit() if $may_exit; NATE::Exceptions::Argument->throw( 'Either volume(and qtree optional) or path needs to be passed as parameter' ); } $Log->exit() if $may_exit; return $path; } sub _fetch_zapi_check { $Log->enter() if $may_enter; my ($pkg, %opts) = @_; my $path; my $filter = \%{$opts{filter}}; if (!$filter->{path} && $filter->{volume}) { $path = &_construct_path(%$filter); } else { $path = $filter->{path}; } unless ($opts{filter}->{ostype} && $path) { $Log->exit() if $may_exit; NACL::Exceptions::InvalidChoice->throw( 'ZAPI needs path (or volume +(qtree)) and ostype as mandatory inputs.' . 'Since atleast one of them is missing in the filter,' . 'ZAPI interface cannot be selected'); } $Log->exit() if $may_exit; } 1;