# Copyright (c) 2001-2014 NetApp, Inc., All Rights Reserved # Any use, modification, or distribution is prohibited # without prior written consent from NetApp, Inc. # ## @summary VserverFcpInitiator ComponentState Module (auto-generated by CGT) ## @author dl-nacl-dev@netapp.com ## @status shared ## @pod here =head1 NAME NACL::CS::VserverFcpInitiator =head1 DESCRIPTION C is a derived class of L. It represents the state of an ONTAP VserverFcpInitiator. A related class is L, which represents access to an ONTAP VserverFcpInitiator. =head1 ATTRIBUTES The individual pieces of data that are part of the state of the VserverFcpInitiator element are the attributes of the VserverFcpInitiator ComponentState. Additionally, the command_interface used to obtain the ComponentState object is also an attribute of the object. This makes it easier to obtain the component object corresponding to the CS object, using L. =over =item command_interface The command_interface with which the CS object was obtained. (Available in all CS objects regardless of requested_fields and the mode/interface) =item C<< port_address >> Port Address Filled in for CMode CLI/ZAPI. Maps to: CMode ZAPI: For "requested_fields", "filter" and Output mapping: =item C<< vserver >> Vserver Filled in for CMode CLI/ZAPI. Maps to: CMode ZAPI: For "requested_fields", "filter" and Output mapping: =item C<< wwpn >> Initiator WWPN Filled in for CMode CLI/ZAPI. Maps to: CMode ZAPI: For "requested_fields", "filter" and Output mapping: =item C<< node >> Hosting Node Filled in for CMode CLI. =item C<< igroup >> Igroup Name (Array) Note that for array fields, the accessor method can be invoked in either scalar or list context. my $igroup = $obj->igroup(); # $igroup contains a reference to the array of values my @igroup = $obj->igroup(); # @igroup contains the array of values If this field needs to be passed to the filter hash, the value for this field should be passed in as an arrayref # filter => { igroup = [ value1, value2...] } Filled in for CMode CLI/ZAPI. Maps to: CMode ZAPI: For "requested_fields", "filter" and Output mapping: =item C<< wwnn >> Initiator WWNN Filled in for CMode CLI/ZAPI. Maps to: CMode ZAPI: For "requested_fields", "filter" and Output mapping: =item C<< vserver_uuid >> Vserver UUID Filled in for CMode CLI. =item C<< lif_uuid >> Logical Interface UUID Filled in for CMode CLI. =item C<< alias >> Initiator WWPN Alias (Array) Note that for array fields, the accessor method can be invoked in either scalar or list context. my $alias = $obj->alias(); # $alias contains a reference to the array of values my @alias = $obj->alias(); # @alias contains the array of values If this field needs to be passed to the filter hash, the value for this field should be passed in as an arrayref # filter => { alias = [ value1, value2...] } Filled in for CMode CLI/ZAPI. Maps to: CMode ZAPI: For "requested_fields", "filter" and Output mapping: =item C<< lif >> Logical Interface Filled in for CMode CLI/ZAPI. Maps to: CMode ZAPI: For "requested_fields", "filter" and Output mapping: =back =cut package NACL::CS::VserverFcpInitiator; use strict; use warnings; use Params::Validate qw(validate); use NATE::Log qw(log_global); use Storable qw(dclone); use NACL::Exceptions::NoElementsFound qw(:try); use NACL::CS::ComponentState::ZapiSkip qw(make_zapi_skip); use NACL::CS::ComponentState::ZapiArray qw(make_zapi_array); use base 'NACL::CS::ComponentState::ONTAP'; use Class::MethodMaker [ scalar => 'port_address', scalar => 'vserver', scalar => 'wwpn', scalar => 'node', array => 'igroup', scalar => 'wwnn', scalar => 'vserver_uuid', scalar => 'lif_uuid', array => 'alias', scalar => 'lif', ]; my $Log = log_global(); my $may_enter = $Log->may_enter(); my $may_exit = $Log->may_exit(); =head1 METHODS =head2 fetch my $VserverFcpInitiator_state = NACL::CS::VserverFcpInitiator->fetch(command_interface => $ci, ...); my @VserverFcpInitiator_states = NACL::CS::VserverFcpInitiator->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. Uses CMode CLI/ZAPI. Invokes fcp-initiator-get-iter API for CMode ZAPI. =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. =back =back =cut sub fetch { $Log->enter() if $may_enter; my ($pkg, @args) = @_; my @state_objs = $pkg->SUPER::fetch( @args, show_cmd =>'vserver fcp initiator show', choices => [ { method => '_fetch_cmode_cli', interface => 'CLI', set => 'CMode' }, { method => '_fetch_cmode_zapi', interface => 'ZAPI', set => 'CMode', }, ], exception_text => 'No matching vserver fcp initiator(s) found', frontend => 'NACL::CS::VserverFcpInitiator::fetch', ); $Log->exit() if $may_exit; return wantarray ? @state_objs : $state_objs[0]; } sub _fetch_cmode_cli { $Log->enter() if $may_enter; my ($pkg, @args) = @_; my @state_objs = $pkg->SUPER::_fetch_cmode_cli(@args, api => 'vserver_fcp_initiator_show',); $Log->exit() if $may_exit; return @state_objs; } sub _fetch_cmode_zapi { $Log->enter() if $may_enter; my ($pkg, %opts) = @_; my $requested_fields = $opts{requested_fields}; my $filter = $opts{filter}; my @orig_state_objs = $pkg->SUPER::_fetch_cmode_zapi( %opts, api => 'fcp-initiator-get-iter', # The mapping for these fields cannot be handled by make_zapi_array # and make_zapi_skip, so they have been handled through "fix_api_opts" # and "fix_response" (see below). Hence, help_xml look-up for mapping # of these fields should be disabled. inapplicable_for_help_xml => [qw(igroup alias)], # CLI returns one row per vserver+lif+wwpn combination, but ZAPI # returns one record per vserver+lif combination, so the base-class # will set array values for many fields which are actually scalars. # The code after the call to _fetch_cmode_zapi normalizes this. suppress_type_warning => 1, copy => [qw(vserver)], map => { 'lif' => 'adapter', wwnn => [ make_zapi_array('fcp-connected-initiators'), make_zapi_skip('fcp-connected-initiator-info'), 'node-name', ], wwpn => [ make_zapi_array('fcp-connected-initiators'), make_zapi_skip('fcp-connected-initiator-info'), 'port-name', ], 'port-address' => [ make_zapi_array('fcp-connected-initiators'), make_zapi_skip('fcp-connected-initiator-info'), 'port-address', ], }, # Handle input mapping for "igroup" and "alias" fix_api_opts => sub { my %fix_api_args = @_; my $api_opts = $fix_api_args{api_opts}; my %req_field_hash = map {$_ => 1} @$requested_fields; if (exists $req_field_hash{'igroup'}) { $api_opts->{'desired-attributes'}{'fcp-connected-initiators'} [0]{'initiator-group-list'} = ['']; } if (exists $req_field_hash{'alias'}) { $api_opts->{'desired-attributes'}{'fcp-connected-initiators'} [0]{'portname-alias-list'} = ['']; } if (exists $filter->{igroup}) { $api_opts->{'query'}{'fcp-connected-initiators'} [0]{'initiator-group-list'} = $filter->{igroup}; } if (exists $filter->{alias}) { $api_opts->{'query'}{'fcp-connected-initiators'} [0]{'portname-alias-list'} = $filter->{alias}; } }, # Handle output mapping for "igroup" and "alias" fix_response => sub { my %opts = @_; my $zapi = $opts{zapi}; my $cli = $opts{cli}; my $initiator_arr = $zapi->{'fcp-connected-initiators'}[0] {'fcp-connected-initiator-info'}; my (@all_igroups, @all_aliases); foreach my $initiator_hash (@$initiator_arr) { if (exists $initiator_hash->{'initiator-group-list'}) { my $ig_arr = $initiator_hash->{'initiator-group-list'} [0]{'initiator-group-list-info'}; my @igroups_for_row; foreach my $ig_hash (@$ig_arr) { push @igroups_for_row, $ig_hash->{'initiator-group-name'}; } push @all_igroups, \@igroups_for_row; } if (exists $initiator_hash->{'portname-alias-list'}) { my $alias_arr = $initiator_hash->{'portname-alias-list'} [0]{'portname-alias-name'}; my @alias_for_row; foreach my $alias_hash (@$alias_arr) { push @alias_for_row, $alias_hash->{'portname-alias'}; } push @all_aliases, \@alias_for_row; } } $cli->{igroup} = \@all_igroups if (@all_igroups); $cli->{alias} = \@all_aliases if (@all_aliases); }, ); # ZAPI will return one object per lif+vserver combination, but that needs # to be converted to the CLI form of one object per lif+vserver+wwpn # combination. For example, the object returned above might be of the form: # { # lif => 'lif_name', # vserver => 'vs_name', # wwpn => ['wwpn1', 'wwpn2'] # } # # This should then be converted into two CS objects: # { # lif => 'lif_name', # vserver => 'vs_name', # wwpn => 'wwpn1', # }, # { # lif => 'lif_name', # vserver => 'vs_name', # wwpn => 'wwpn2', # }, # # The piece of code below expands these objects my @state_objs; foreach my $orig_state_obj (@orig_state_objs) { my @fields_to_expand = (qw(wwnn wwpn port-address)); my %fields_to_expand_hash; foreach my $field (@fields_to_expand) { $fields_to_expand_hash{$field} = $orig_state_obj->$field(); # Remove original values from the object my $reset_method = "${field}_reset"; $orig_state_obj->$reset_method(); } my @array_fields_to_expand = (qw(igroup alias)); my %array_fields_to_expand_hash; foreach my $arr_field (@array_fields_to_expand) { $array_fields_to_expand_hash{$arr_field} = $orig_state_obj->$arr_field(); # Remove original values from the object my $reset_method = "${arr_field}_reset"; $orig_state_obj->$reset_method(); } my $wwpn_ref = $fields_to_expand_hash{wwpn}; # To be able to dclone the CS object, the command_interface # needs to be removed from the CS object. Store its value and remove. my $ci = $orig_state_obj->command_interface(); $orig_state_obj->command_interface_reset(); for (my $i = 0; $i < scalar @$wwpn_ref; $i++) { # Easiest way to copy over all the data is to make a deep-copy # of the object. my $state_obj = dclone ($orig_state_obj); $state_obj->command_interface($ci); foreach my $field (@fields_to_expand) { my $val = $fields_to_expand_hash{$field}->[$i]; $state_obj->$field($val) if (defined $val); } foreach my $arr_field (@array_fields_to_expand) { my $val = $array_fields_to_expand_hash{$arr_field}->[$i]; $state_obj->$arr_field(@$val) if (defined $val); } push @state_objs, $state_obj; } } $Log->exit() if $may_exit; return @state_objs; } 1;