# Copyright (c) 2013 NetApp, Inc., All Rights Reserved # Any use, modification, or distribution is prohibited # without prior written consent from NetApp, Inc. # # ## @summary Iscsi ComponentState Module ## @author Vishwanath.Rawat@netapp.com, dl-nacl-dev@netapp.com ## @status shared ## @pod here ################################################################################ =head1 NAME NACL::CS::Client::Iscsi =head1 DESCRIPTION C is a derived class of L. It represents the state of Iscsi element. A related class is L, which represents access to a Iscsi element. =head1 ATTRIBUTES The individual pieces of data that are part of the state of the Iscsi element are the individual attributes of the Iscsi ComponentState =over =item C<< "tpgt" >> Filled in for Linux and Solaris CLI. Maps to: Linux and Solaris CLI: For 'filter': Applicable, Filtering will be done by Components. For 'requested_fields', Not applicable, but the field will be populated in the CS object. =item C<< "ipaddress" >> Filled in for Linux and Solaris CLI. Maps to: Linux and Solaris CLI: For 'filter': Applicable, Filtering will be done by Components. For 'requested_fields', Not applicable, but the field will be populated in the CS object. =item C<< "iqn" >> Filled in for Linux and Solaris CLI. Maps to: Linux and Solaris CLI: For 'filter': Applicable, Filtering will be done by Components. For 'requested_fields', Not applicable, but the field will be populated in the CS object. =item C<< "ip_port" >> Filled in for Linux and Solaris CLI. Maps to: Linux and Solaris CLI: For 'filter': Applicable, Filtering will be done by Components. For 'requested_fields', Not applicable, but the field will be populated in the CS object. =item C<< "discovery_type" >> Filled in for Linux CLI. Maps to: Linux CLI: For 'filter': Applicable, Filtering will be done by Components. For 'requested_fields', Not applicable, but the field will be populated in the CS object. =item C<< "target" >> Filled in for Linux CLI. Maps to: Linux CLI: For 'filter': Applicable, Filtering will be done by Components. For 'requested_fields', Not applicable, but the field will be populated in the CS object. =item C<< "status" >> Filled in for Linux CLI. Maps to: Linux CLI: For 'filter': Applicable, Filtering will be done by Components. For 'requested_fields', Not applicable, but the field will be populated in the CS object. =item C<< "iface" >> Filled in for Linux CLI. Maps to: Linux CLI: For 'filter': Applicable, Filtering will be done by Components. For 'requested_fields', Not applicable, but the field will be populated in the CS object. =item C<< "portal" >> Filled in for Linux CLI. Maps to: Linux CLI: For 'filter': Applicable, Filtering will be done by Components. For 'requested_fields', Not applicable, but the field will be populated in the CS object. =item C<< "send_targets" >> Filled in for Solaris CLI. Maps to: Solaris CLI: For 'filter': Applicable, Filtering will be done by Components. For 'requested_fields', Not applicable, but the field will be populated in the CS object. =item C<< "static" >> Filled in for Solaris CLI. Maps to: Solaris CLI: For 'filter': Applicable, Filtering will be done by Components. For 'requested_fields', Not applicable, but the field will be populated in the CS object. =item C<< "connections" >> Filled in for Solaris CLI. Maps to: Solaris CLI: For 'filter': Applicable, Filtering will be done by Components. For 'requested_fields', Not applicable, but the field will be populated in the CS object. =item C<< "isid" >> Filled in for Solaris CLI. Maps to: Solaris CLI: For 'filter': Applicable, Filtering will be done by Components. For 'requested_fields', Not applicable, but the field will be populated in the CS object. =item C<< "alias" >> Filled in for Solaris CLI. Maps to: Solaris CLI: For 'filter': Applicable, Filtering will be done by Components. For 'requested_fields', Not applicable, but the field will be populated in the CS object. =item C<< "configured_sessions" >> Filled in for Solaris CLI. Maps to: Solaris CLI: For 'filter': Applicable, Filtering will be done by Components. For 'requested_fields', Not applicable, but the field will be populated in the CS object. =item C<< "radius_access" >> Filled in for Solaris CLI. Maps to: Solaris CLI: For 'filter': Applicable, Filtering will be done by Components. For 'requested_fields', Not applicable, but the field will be populated in the CS object. =item C<< "radius_server" >> Filled in for Solaris CLI. Maps to: Solaris CLI: For 'filter': Applicable, Filtering will be done by Components. For 'requested_fields', Not applicable, but the field will be populated in the CS object. =item C<< "authentication_type" >> Filled in for Solaris CLI. Maps to: Solaris CLI: For 'filter': Applicable, Filtering will be done by Components. For 'requested_fields', Not applicable, but the field will be populated in the CS object. =item C<< "login_parameters" >> Filled in for Solaris CLI. Maps to: Solaris CLI: For 'filter': Applicable, Filtering will be done by Components. For 'requested_fields', Not applicable, but the field will be populated in the CS object. =item C<< "tunable_parameters" >> Filled in for Solaris CLI. Maps to: Solaris CLI: For 'filter': Applicable, Filtering will be done by Components. For 'requested_fields', Not applicable, but the field will be populated in the CS object. =item C<< "isns" >> Filled in for Solaris CLI. Maps to: Solaris CLI: For 'filter': Applicable, Filtering will be done by Components. For 'requested_fields', Not applicable, but the field will be populated in the CS object. =item C<< "initiator_node" >> Filled in for Solaris CLI. Maps to: Solaris CLI: For 'filter': Applicable, Filtering will be done by Components. For 'requested_fields', Not applicable, but the field will be populated in the CS object. =back =cut ################### # Package package NACL::CS::Client::Iscsi; ################### # Everytime use strict; use warnings; ################### # Module includes use Params::Validate qw (validate SCALAR); use NACL::ComponentUtils qw (_optional_scalars); use NATE::Log qw(log_global); my $Log = log_global(); my $may_enter = $Log->may_enter(); my $may_exit = $Log->may_exit(); use base 'NACL::CS::ComponentState::Client'; use NACL::Exceptions::NoElementsFound qw(:try); use NACL::APISet::Exceptions::CommandFailedException; use Class::MethodMaker [ # Common components scalar => "ipaddress", scalar => "iqn", scalar => "ip_port", scalar => "tpgt", # Linux specific scalar => "discovery_type", scalar => "target", scalar => "status", scalar => "iface", scalar => "portal", # Solaris specific scalar => "isns", scalar => "send_targets", scalar => "static", scalar => "connections", scalar => "isid", scalar => "alias", scalar => "configured_sessions", scalar => "radius_access", scalar => "radius_server", scalar => "authentication_type", array => "login_parameters", array => "tunable_parameters", array => "initiator_node", ]; =head1 METHODS =head2 fetch my $iscsi_state = NACL::CS::Client::Iscsi->fetch(command_interface=>$ci,mode => "session"); my @iscsi_state = NACL::CS::Client::Iscsi->fetch(command_interface=>$ci, mode=> "session"); my @iscsi_state = NACL::CS::Client::Iscsi->fetch(command_interface=>$ci, mode=> "node"); my @iscsi_state = NACL::CS::Client::Iscsi->fetch(command_interface=>$ci, mode=> "discovery"); see L Supports Linux CLI. Invokes "iscsiadm" command for Linux CLI. =over =item Additional Options =over =item C<< "mode" >> (Required) This is special param that will be passed to Cfetch()>. This option will determines with which options iscsiadm will run. Applicable for Linux and Solaris CLI. Valid values for Linux are: session, node, discovery. Examples: if mode => "session" is passed Command executed will be "iscsiadm -m session" if mode => "node" is passed Command executed will be "iscsiadm -m node" if mode => "discovery" is passed Command executed will be "iscsiadm -m discovery" Valid values for Solaris are: initiator-node, static-config, discovery, target, target-param, discovery-address, isns-server. Examples: if mode => "initiator-node" is passed Command executed will be "iscsiadm list initiator-node" if mode => "static-config" is passed Command executed will be "iscsiadm list static-config" if mode => "discovery" is passed Command executed will be "iscsiadm list discovery" =back =back =cut sub fetch { $Log->enter(); my ($pkg, @opts) = @_; my @state_objs = $pkg->SUPER::fetch( @opts, choices => [ { method => "_fetch_linux_cli", interface => "CLI", set => 'Linux' }, { method => "_fetch_solaris_cli", interface => "CLI", set => 'Solaris' }, ], exception_text => 'No node/session found', allow_empty => 1, ); $Log->exit(); return wantarray ? @state_objs : $state_objs[0]; } sub _fetch_linux_cli { $Log->enter(); my ($pkg, @opts) = @_; my %opts = validate @opts, $pkg->_fetch_backend_validate_spec(); my $apiset = $opts{apiset}; my $command_interface = delete $opts{command_interface}; my ( @state_objs ); my %opts_hash = (mode => 1); $opts_hash{$opts{mode}} = 1; my $parsed_output = []; try { my $resp = $apiset->iscsiadm(%opts_hash); $parsed_output = $resp->get_parsed_output(); } catch NACL::APISet::Exceptions::CommandFailedException with { my $ex = shift; if ($ex->text() !~ /(no\s+records\s+found)|(No\s+active\s+sessions)/i) { $ex->throw(); } }; foreach my $row (@$parsed_output) { my $obj = $pkg->new( command_interface => $command_interface ); $obj->_set_fields( row => $row ); push @state_objs, $obj; } $Log->exit(); return @state_objs; } sub _fetch_solaris_cli { $Log->enter(); my ($pkg, @opts) = @_; my %opts = validate @opts, $pkg->_fetch_backend_validate_spec(); my $apiset = $opts{apiset}; my $command_interface = delete $opts{command_interface}; my ( @state_objs ); my $parsed_output = []; try { my $resp = $apiset->iscsiadm_list('direct-object' => $opts{mode}); $parsed_output = $resp->get_parsed_output(); } catch NACL::APISet::Exceptions::CommandFailedException with { my $ex = shift; if ($ex->text() !~ /(no\s+records\s+found)|(No\s+active\s+sessions)/i) { $ex->throw(); } }; foreach my $row (@$parsed_output) { my $obj = $pkg->new( command_interface => $command_interface ); $obj->_set_fields( row => $row ); push @state_objs, $obj; } $Log->exit(); return @state_objs; } sub _fetch_validate_spec { my $pkg = shift; my $validate_spec = $pkg->SUPER::_fetch_validate_spec(); $validate_spec->{'mode'} = { type => SCALAR }; return $validate_spec; } ## end sub _fetch_validate_spec sub _fetch_backend_validate_spec { my $pkg = shift; my $validate_spec = $pkg->SUPER::_fetch_backend_validate_spec; $validate_spec->{'mode'} = { type => SCALAR }; return $validate_spec; } ## end sub _fetch_backend_validate_spec 1;