# # Copyright (c) 2001-2010 NetApp, Inc., All Rights Reserved # Any use, modification, or distribution is prohibited # without prior written consent from NetApp, Inc. # ## @summary Vfiler ComponentState Module ## @author madhav.shekar@netapp.com, dl-nacl-dev@netapp.com ## @status shared ## @pod here =head1 NAME NACL::CS::Vfiler =head1 DESCRIPTION C is a derived class of L. It represents the state of an ONTAP vfiler. A related class is L, which represents access to an ONTAP Vfiler. =head1 ATTRIBUTES The individual pieces of data that are part of the state of the Vfiler element are the elements of the Vfiler ComponentState. =over =item C<< vfiler >> The name of the vfiler being represented. =item C<< status >> The status of the vfiler (could be either running or stopped) =item C<< protocols_allowed >> The communication protocols (like rsh, ssh etc) allowed on the vfiler. =item C<< protocols_disallowed >> (Array) The communication protocols (like rsh, ssh etc) disallowed on the vfiler. =item C<< number_of_protocols_allowed >> (Array) The number of communication protocols allowed on the vfiler. =item C<< number_of_protocols_disallowed >> The number of communication protocols disallowed on the vfiler. =item C<< ipspace >> =item C<< storage_units_paths >> (Array) Paths to the storage units (which could be volumes and/or qtrees) hosted on the vfiler. =item C<< uuid >> The Universal Unique Identifier of the vfiler. =item C<< configuration_directory >> =item C<< ip_address_configuration >> (Arrayref) Contains configuration details of the IP addresses assigned to the vfiler. These details include the interface and IP address. It is an arrayref, which contains a hashref for each IP address assigned to the vfiler. An example of the data structure of this would be: [ { interface => 'e0b', ip_address => '1.2.3.4' }, { ... }, ... ] =back =head1 DEPRECATED ATTRIBUTES The following attributes are related to the details returned by the "vfiler limit" command. While these attributes will still be populated in the CS object, they are deprecated. The new way to get these values would be: my $limit_obj = NACL::C::Vfiler->limit(command_interface => $ci); # Access attributes in the same way my $curr_limit = $limit_obj->current_limit(); =item C<< platform_hard_limit >> The maximum number of vfilers allowed on the hosting filer. =item C<< current_limit >> The current vfiler limit of the hosting filer. =item C<< current_in_use >> The number of vfilers currently on the hosting filer. =back =cut package NACL::CS::Vfiler; use strict; use warnings; use base 'NACL::CS::ComponentState::ONTAP'; use Params::Validate qw(validate validate_pos SCALAR); use NATE::Log qw(log_global); my $Log = log_global(); my $may_enter = $Log->may_enter(); my $may_exit = $Log->may_exit(); use NATE::BaseException qw(:try); use Class::MethodMaker [ scalar => 'vfiler', scalar => 'status', array => 'protocols_allowed', array => 'protocols_disallowed', scalar => 'number_of_protocols_disallowed', scalar => 'number_of_protocols_allowed', scalar => 'ipspace', array => 'storage_units_paths', scalar => 'uuid', scalar => 'configuration_directory', array => 'ip_address_configuration', ]; my @Limit_Fields = (qw(platform_hard_limit current_limit current_in_use)); # This section is to log a warning if any of the "vfiler limit" related # deprecated attributes are used. # Unfortunately we can't use -read_cb for MethodMaker because that ends # up getting invoked while storing the value as well (so would result # in one warning per row containing this field). Hence, we need to create # new methods that mimic MethodMaker. # For every scalar field 'foo' defined in MethodMaker, the following methods # get installed: "foo" (in get/set context); "foo_isset"; "foo_reset"; "foo_clear" no strict 'refs'; foreach my $removed_field (@Limit_Fields) { *{$removed_field} = sub { my ($self, $value) = @_; # Method is invoked with a package name to determine the data-type. # Simply returned if invoked without an object instance. return unless ref $self; if ($value) { $self->{$removed_field} = $value; return $value; } else { $self->_warn_for_deprecated_field_accessor($removed_field); return $self->{$removed_field}; } }; *{"${removed_field}_isset"} = sub { exists $_[0]->{$removed_field} }; *{"${removed_field}_reset"} = sub { delete $_[0]->{$removed_field} }; *{"${removed_field}_clear"} = sub { $_[0]->{$removed_field} = undef }; } use strict 'refs'; =head1 METHODS =head2 fetch my $vfiler_state = NACL::CS::Vfiler->fetch(command_interface => $ci, ...); my @vfiler_states = NACL::CS::Vfiler->fetch(command_interface => $ci, ...); See L. Uses a 7Mode CLI APISet. =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, choices => [ { method => '_fetch_7mode_cli', interface => 'CLI', set => '7Mode', }, ], exception_text => 'No matching vfiler(s) found' ); $Log->exit() if $may_exit; return wantarray ? @state_objs : $state_objs[0]; } sub _fetch_7mode_cli { $Log->enter() if $may_enter; my ($pkg, @args) = @_; my %opts = validate @args, $pkg->_fetch_backend_validate_spec(); my $apiset = $opts{apiset}; # Remove all special characters from the filter. my @requested_fields = @{$opts{requested_fields}}; my %filter = %{$opts{filter}}; my %req_field_filter = ( filter => \%filter, requested_fields => \@requested_fields ); $pkg->_remove_relational_regex_filters(%req_field_filter); my %vfilerstatus_args; # Run with "-a" only if any of the following fields are required if ($pkg->_want_any_field_of( %req_field_filter, fields_filled_by_api => [qw(protocols_allowed protocols_disallowed number_of_protocols_disallowed number_of_protocols_allowed ipspace storage_units_paths uuid configuration_directory ip_address_configuration)] ) ) { $vfilerstatus_args{'all-details'} = 1; } # The only server-side filtering possible in 7-mode is if the # caller limits to one vfiler name, then we can get info on just # that vfiler. Otherwise, we get info on all vfilers and # filter out undesired entries somewhere below. if (defined $filter{vfiler}) { $vfilerstatus_args{vfiler} = $filter{vfiler}; } my ($response, $caught_exception); try { $response = $apiset->vfiler_status(%vfilerstatus_args); } catch NACL::APISet::Exceptions::InvalidParamValueException with { # Indicates that the vfiler doesn't exist. $caught_exception = 1; }; if ($caught_exception) { $Log->exit() if $may_exit; return; } my $output = $response->get_parsed_output(); # Keeping this behind for backwards compatibility. The way to do this # from now on is to use NACL::C::Vfiler->limit(). my $vfiler_limit_row = {}; if ($pkg->_want_any_field_of(%req_field_filter, fields_filled_by_api => \@Limit_Fields)) { my $response2 = $apiset->vfiler_limit(); my $output2 = $response2->get_parsed_output(); # It always has only one hash. $vfiler_limit_row = $output2->[0]; } my @state_objs; foreach my $row (@$output) { my $obj = $pkg->new(command_interface => $opts{command_interface}); # The parsed output contains certain fields whose names aren't very # descriptive. Here, we'll rename them to clearer names. $pkg->_hash_move( source => $row, target => $row, map => { "protocols_disallowed" => "number_of_protocols_disallowed", "protocols_allowed" => "number_of_protocols_allowed", "allowed" => "protocols_allowed", "disallowed" => "protocols_disallowed", "path" => "storage_units_paths", }, ); $obj->_set_fields(row => $row); $obj->_set_fields(row => $vfiler_limit_row); push @state_objs, $obj; } $Log->exit() if $may_exit; return @state_objs; } sub _warn_for_deprecated_field_accessor { $Log->enter() if $may_enter; my ($self, @opts) = @_; my ($field) = validate_pos(@opts, { type => SCALAR }); $Log->warn("The attribute '$field' was accessed from the NACL::CS::Vfiler " . 'object. This attribute is now deprecated. The new way to get this ' . "value is by using NACL::C::Vfiler->limit:\n\t" . 'my $limit_obj = NACL::C::Vfiler->limit(command_interface => $ci);' . "\n\t" . 'my $' . $field . ' = $limit_obj->' . $field . '();' ); $Log->exit() if $may_exit; } 1;