# # Copyright (c) 2001-2013 NetApp, Inc., All Rights Reserved # Any use, modification, or distribution is prohibited # without prior written consent from NetApp, Inc. # ## @summary VserverCifsShare ComponentState Module ## @author dl-nacl-dev@netapp.com ## @status shared ## @pod here =head1 NAME NACL::CS::VserverCifsShare =head1 DESCRIPTION C is a derived class of L. It represents the state of a Vserver Cifs Share. A related class is L, which represents access to ONTAP Vserver Cifs Share. =head1 ATTRIBUTES The individual pieces of data that are part of the state of the element are the attributes of the ComponentState. =over =item C<< vserver >> Filled in for CMode CLI/ZAPI. =item C<< share_name >> Filled in for CMode CLI/ZAPI. Maps to: CM ZAPI: $value =item C<< path >> Filled in for CMode CLI/ZAPI. Maps to: CM ZAPI: $value =item C<< share_properties >> Filled in for CMode CLI/ZAPI. Maps to: CM ZAPI: @values =item C<< symlink_properties >> Filled in for CMode CLI/ZAPI. Maps to: CM ZAPI: @values =item C<< file_umask >> Filled in for CMode CLI/ZAPI. Maps to: CM ZAPI: $value =item C<< dir_umask >> Filled in for CMode CLI/ZAPI. Maps to: CM ZAPI: $value =item C<< comment >> Filled in for CMode CLI/ZAPI. Maps to: CM ZAPI: $value =item C<< acl >> Filled in for CMode CLI/ZAPI. Maps to: CM ZAPI: @values =item C<< cifs_server >> Filled in for CMode CLI/ZAPI. Maps to: CM ZAPI: $value =item C<> Filled in for CMode CLI. =item C<>, Filled in for CMode CLI. =item C<> Filled in for CMode CLI. =item C<> Filled in for CMode CLI. =item C<> Filled in for CMode CLI. =item C<>, Filled in for CMode CLI. =item C<> Filled in for CMode CLI. =item C<> Filled in for CMode CLI. =item C<> Filled in for CMode CLI. =item C<> Filled in for CMode CLI. =item C<> Filled in for CMode CLI. =item C<< attribute_cache_ttl >> Filled in for CMode CLI/ZAPI. =item C<< volume >> Filled in for CMode CLI/ZAPI. =item C<< offline_files >> Offline Files Filled in for CMode CLI/ZAPI. =item C<< is_browse >> Filled in for CMode CLI. =item C<< vscan_fileop_profile >> Vscan File-Operations Profile possible value(s) are, no_scan,standard,strict,writes_only Filled in for CMode CLI/ZAPI. =item C<< max_connections_per_share >> Maximum tree-connect on share Filled in for CMode CLI. =item C<< force_group_for_create >> UNIX Group for File Create Filled in for CMode CLI. =item C<< is_path_validation_enabled >> Enable/Disable the CIFS share path validation possible value(s) are, true,false Filled in for CMode CLI. =back =cut package NACL::CS::VserverCifsShare; use strict; use warnings; use NACL::C::VserverCifsShare; use NACL::Exceptions::InvalidChoice qw(:try); use Params::Validate qw/validate/; use NATE::Log qw(log_global); my $Log = log_global(); my $may_enter = $Log->may_enter(); my $may_exit = $Log->may_exit(); 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 [ # These fields are from the C Mode "vserver cifs share show" scalar => 'vserver', scalar => 'share_name', scalar => 'path', array => 'share_properties', array => 'symlink_properties', scalar => 'file_umask', scalar => 'dir_umask', scalar => 'comment', array => 'acl', scalar => 'cifs_server', scalar => 'forcegroup', scalar => 'is_access_based_enum', scalar => 'is_browse', scalar => 'is_namespace_caching_allowed', scalar => 'is_symlink_strict_security', scalar => 'is_vol_offline', scalar => 'is_vscan', scalar => 'is_vscanread', scalar => 'is_widelink', scalar => 'maxusers', scalar => 'umask', scalar => 'caching', scalar => 'attribute_cache_ttl', scalar => 'volume', scalar => 'offline_files', scalar => 'vscan_fileop_profile', scalar => 'max_connections_per_share', scalar => 'force_group_for_create', scalar => 'is_path_validation_enabled', ]; =head1 METHODS =head2 fetch my $share_state = NACL::CS::VserverCifsShare->fetch(command_interface=>$ci,...); my @share_states = NACL::CS::VserverCifsShare->fetch(command_interface=>$ci,...); see L Supports CMode CLI/ZAPI. Invokes "cifs-share-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 = shift; my @state_objs = $pkg->SUPER::fetch( @_, show_cmd => 'vserver cifs share show', choices => [ { method => '_fetch_cmode_cli', interface => 'CLI', set => 'CMode', }, { method => '_fetch_cmode_zapi', interface => 'ZAPI', set => 'CMode', check => '_generic_zapi_check' }, { method => '_fetch_7mode_cli', interface => 'CLI', set => '7Mode', }, { method => '_fetch_7mode_zapi', interface => 'ZAPI', set => '7Mode', }, ], exception_text => 'No matching vserver cifs share(s) found' ); $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 => 'vserver_cifs_share_show'); $Log->exit() if $may_exit; return @state_objs; } ## end sub _fetch_cmode_cli 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 $requested_fields = $opts{requested_fields}; my $filter = $opts{filter}; my (%hash, $caught, $response); if (defined $filter->{'share-name'}) { $hash{sharename} = $filter->{'share-name'}; } try { $response = $apiset->cifs_shares(%hash); } catch NACL::APISet::Exceptions::InvalidParamValueException with { $caught = 1; }; if ($caught) { $Log->exit() if $may_exit; return; } my $output = $response->get_parsed_output(); my (@state_objs, $hashref, @acl); foreach my $hashref (@$output) { my $state_base_field_settings = $pkg->_hash_copy( source => $hashref, map => { "Name" => "share-name", "Mount Point" => "path", "Description" => "comment" }, ); # acl information will be present in other_settings and will # have a "/" in it foreach (@{$hashref->{other_settings}}) { if ($_ =~ /\//) { push @acl, $_; $_ = ""; } } ## end foreach ( @{ $hashref->{other_settings... my %messages_key_map = ( 'widelinks supported' => sub { $state_base_field_settings->{'is-widelink'} = 'true' }, 'virus scanning disabled$' => sub { $state_base_field_settings->{'is-vscan'} = 'false' }, 'user limit=(.+)' => sub { $state_base_field_settings->{maxusers} = $1 }, '^([a-z]+)=(.+)\s*' => sub { $state_base_field_settings->{$1} = $2 }, '(\w+_\w+)=(.+)\s*' => sub { my ($key, $value) = ($1, $2); $key =~ s/_/-/; $state_base_field_settings->{$key} = $value; }, 'not visible to browsers' => sub { delete $state_base_field_settings->{'share-properties'}; }, 'namespace caching enabled' => sub { $state_base_field_settings->{'is-namespace-caching-allowed'} = 'true'; }, 'access based enum supported' => sub { $state_base_field_settings->{'is-access-based-enum'} = 'true'; }, 'strict symlink security disabled' => sub { $state_base_field_settings->{'is-symlink-strict-security'} = 'false'; }, 'virus scanning disabled for read access' => sub { $state_base_field_settings->{'is-vscanread'} = 'false'; }, 'client side caching disabled' => sub { $state_base_field_settings->{caching} = "no_caching"; }, 'automatic (.+) caching enabled' => sub { $state_base_field_settings->{caching} = "auto_$1_caching"; }, ); # fill in the default values - for share-properties, the default is # ['browsable'] $state_base_field_settings->{'share-properties'} = ['browsable']; foreach my $string (@{$hashref->{other_settings}}) { foreach (keys %messages_key_map) { if ($string =~ /$_/) { &{$messages_key_map{$_}}; last; } } ## end foreach ( keys %messages_key_map) } ## end foreach my $string ( @{ $hashref... $state_base_field_settings->{acl} = \@acl; my $obj = $pkg->new(command_interface => $opts{command_interface}); $obj->_set_fields(row => $state_base_field_settings); push @state_objs, $obj; } ## end foreach my $hashref (@$output) $Log->exit() if $may_exit; return @state_objs; } ## end sub _fetch_7mode_cli sub _fetch_7mode_zapi { $Log->enter() if $may_enter; my $pkg = shift; my %opts = validate @_, $pkg->_fetch_backend_validate_spec(); my $apiset = $opts{apiset}; my $requested_fields = $opts{requested_fields}; my $filter = $opts{filter}; my (%iter_filter_args, $caught, $response); # this is for obtaining records that match the filter # (share-name is the only filter) $iter_filter_args{'share-name'} = $filter->{'share-name'} if (defined $filter->{'share-name'}); # the zapi invocation is as follows # Execute cifs_share_list_iter_start with the filter parameters to get the # number of matching records and the tag # Then execute cifs-share-list-iter-next passing in the tag obtained in the # previous step and the maximum number of records to obtain in one go # We'll obtain all the records in one go # Lastly, execute cifs-share-list-iter-end which will # terminate the list iteration and clean up any saved info. try { my $info = $apiset->cifs_share_list_iter_start(%iter_filter_args) ->get_parsed_output(); $response = $apiset->cifs_share_list_iter_next( maximum => $info->[0]->{records}, tag => $info->[0]->{tag} ); $apiset->cifs_share_list_iter_end(tag => $info->[0]->{tag}); } ## end try catch NACL::APISet::Exceptions::ResponseException with { # there were no matching records found. $caught = 1; }; if ($caught) { $Log->exit() if $may_exit; return; } my $output = $response->get_parsed_output(); my @state_objs; # to get the information about cifs shares, we have to look at the # arrayref located at $output->[0]->{'cifs-shares'}->[0]->{'cifs-share-info'} foreach (@{$output->[0]->{'cifs-shares'}->[0]->{'cifs-share-info'}}) { my $state_base_field_settings = $pkg->_hash_copy( source => $_, map => { "mount-point" => "path", "description" => "comment", }, # dir_umask and file_umask should be replaced with their hyphenated # forms once burt 511946 is fixed copy => [ qw(share-name forcegroup is-access-based-enum is-namespace-caching-allowed is-symlink-strict-security is-vol-offline is-vscan is-vscanread is-widelink maxusers umask dir_umask file_umask) ], ); # to have compatibility with CMode $state_base_field_settings->{'share-properties'} = ['browsable']; if (defined $_->{'is-browse'}) { delete $state_base_field_settings->{'share-properties'}; } my $obj = $pkg->new(command_interface => $opts{command_interface}); $obj->_set_fields(row => $state_base_field_settings); push @state_objs, $obj; } ## end foreach ( @{ $output->[0]->... $Log->exit() if $may_exit; return @state_objs; } ## end sub _fetch_7mode_zapi sub _fetch_cmode_zapi { $Log->enter() if $may_enter; my $pkg = shift; my @state_objs = $pkg->SUPER::_fetch_cmode_zapi( @_, api => 'cifs-share-get-iter', map => { "acl" => [make_zapi_array('acl'), make_zapi_skip('string')], 'share-properties' => [ make_zapi_array('share-properties'), make_zapi_skip('cifs-share-properties') ], 'symlink-properties' => [ make_zapi_array('symlink-properties'), make_zapi_skip('cifs-share-symlink-properties') ], 'offline-files' => 'offline-files-mode', }, copy => [ qw(vserver share-name cifs-server path comment dir-umask file-umask attribute-cache-ttl volume vscan-fileop-profile ) ] ); $Log->exit() if $may_exit; return @state_objs; } ## end sub _fetch_cmode_zapi # Re-use the _generic_zapi_check defined in NACL::C::VserverCifsShare sub _generic_zapi_check { $Log->enter() if $may_enter; my $pkg = shift; NACL::C::VserverCifsShare->_generic_zapi_check(@_); $Log->exit() if $may_exit; } ## end sub _generic_zapi_check sub _update_state_objs_cmode_zapi { $Log->enter() if $may_enter; my ($pkg, @args) = @_; $pkg->SUPER::_update_state_objs_cmode_zapi( @args, zapi_field_translations => { decimal_to_octal => [qw(dir-umask file-umask)], }, ); $Log->exit() if $may_exit; } 1;