# # Copyright (c) 2001-2015 NetApp, Inc., All Rights Reserved # Any use, modification, or distribution is prohibited # without prior written consent from NetApp, Inc. # # ## @summary Mount ComponentState Module ## @author osgood@netapp.com, dl-nacl-dev@netapp.com ## @status shared ## @pod here ################################################################################ =head1 NAME NACL::CS::Client::Mount =head1 DESCRIPTION C is a derived class of L. It represents the state of Mount element. A related class is L, which represents access to a Mount element. =head1 ATTRIBUTES The individual pieces of data that are part of the state of the Mount element are the individual attributes of the Mount ComponentState =over =item C<< "path" >> The path of the export point on the server which contains it =item C<< "server" >> The server which contains the export point =item C<< "source_path" >> The server and path of the mounted filesystem =item C<< "mount_point" >> The directory of the mounted filesytem =item C<< type >> Either C or C. Default is C. =item C<< options >> The options for the mount =item C<< network >> The network name =item C<< status >> The current status of the mount =back =cut ################### # Package package NACL::CS::Client::Mount; ################### # Everytime use strict; use warnings; ################### # Module includes use Params::Validate qw (validate); use NACL::ComponentUtils qw (_dump_one); use NACL::Exceptions::NoElementsFound qw(:try); use NACL::APISet::Exceptions::InvalidParamValueException qw(:try); use Net::IP qw(:PROC); use NACL::Util::IPv6 qw(convert_ipv6_address_format); use base 'NACL::CS::ComponentState::Client'; use Class::MethodMaker [ scalar => "source_path", scalar => "path", scalar => "mount_point", scalar => "type", scalar => "options", scalar => "server", # Windows specific scalar => 'network', scalar => 'status', scalar => 'share_name', scalar => 'resource_type', scalar => 'opens', scalar => 'connections', scalar => 'drive' ]; =head1 METHODS =head2 fetch my $mount_state = NACL::CS::Client::Mount->fetch(command_interface=>$ci,...); my @mount_states = NACL::CS::Client::Mount->fetch(command_interface=>$ci,...); see L =cut sub fetch { my ($pkg, @args) = @_; my %opts = validate @args, $pkg->_fetch_validate_spec(); my $filter = $opts{filter}; $filter->{share_name} = delete $filter->{share}; # server option if provided in filter needs to get converted to ipv6 format #burt896038 if ( ($opts{command_interface}->type() =~ /windows/) && ( defined $filter->{server} ) ){ if ( Net::IP::ip_is_ipv6( $filter->{server} ) ) { $filter->{server} = convert_ipv6_address_format( ipv6_address => $filter->{server}, client_type => $opts{command_interface}->type(), ); } ## end if ( Net::IP::ip_is_ipv6...) } my @state_objs = $pkg->SUPER::fetch( %opts, choices => [ { method => "_fetch_windows_cli", interface => "CLI", set => "Windows" }, { method => "_fetch_linux_cli", interface => "CLI", set => 'Linux' }, { method => "_fetch_solaris_cli", interface => "CLI", set => 'Solaris' }, ], exception_text => 'No matching mountpoints found' ); return wantarray ? @state_objs : $state_objs[0]; } sub _fetch_linux_cli { my $pkg = shift; my %opts = validate @_, $pkg->_fetch_backend_validate_spec(); my $apiset = $opts{apiset}; my @state_objs; my $response = $apiset->mount(); my $output = $response->get_parsed_output(); foreach my $row (@$output) { my $obj = $pkg->new( command_interface => $opts{command_interface} ); # path is the location on the server where the export point is located # server is the server name or ip if ( $row->{source_path} =~ /(.*):(\/.*)/ ) { $row->{server} = $1; $row->{path} = $2; } $obj->_set_fields( row => $row ); push @state_objs, $obj; } ## end foreach my $row (@$output) return @state_objs; } sub _fetch_solaris_cli { my $pkg = shift; my %opts = validate @_, $pkg->_fetch_backend_validate_spec(); my $apiset = delete $opts{apiset}; my $filter = delete $opts{filter}; my $requested_fields = $opts{requested_fields}; my @state_objs; my %api_opts; # type indicates the filesytem type for a particular mount point # Example : # Output of 'mount' : /t/10.227.71.55/vol_vol0 on 10.227.71.55:/vol/vol0 remote/read/write/setuid/devices/hard/intr/noquota/xattr/dev=510002a # The above output doesn't contain the filesystem type # Output of 'mount -v' : 10.227.71.55:/vol/vol0 on /t/10.227.71.55/vol_vol0 type nfs remote/read/write/setuid/devices/hard/intr/noquota/xattr/dev=510002b # Here the type of filesystem is nfs. # When the filter is applied for specific mount point, then mount -v is executed, from which filesystem type can be fetched. # if ($pkg->_want_any_field_of( requested_fields => $requested_fields, filter => $filter, fields_filled_by_api => [ qw(type) ] ) ) { $api_opts{verbose} = 1; } my $response = $apiset->mount(%api_opts); my $output = $response->get_parsed_output(); foreach my $row (@$output) { my $obj = $pkg->new( command_interface => $opts{command_interface} ); # path is the location on the server where the export point is located # server is the server name or ip if ( $row->{source_path} =~ /(.*):(\/.*)/ ) { $row->{server} = $1; $row->{path} = $2; } $obj->_set_fields( row => $row ); push @state_objs, $obj; } ## end foreach my $row (@$output) return @state_objs; } sub _fetch_windows_cli { my $pkg = shift; my %opts = validate @_, $pkg->_fetch_backend_validate_spec(); my $apiset = $opts{apiset}; my $filter = $opts{filter}; my $requested_fields = $opts{requested_fields}; my ( @state_objs, $output, $caught_exception ); my %api_args; if ( defined $filter->{mount_point} && !($pkg->_want_any_field_of( requested_fields => $requested_fields, filter => $filter, fields_filled_by_api => [qw(status network)]))){ $api_args{devicename} = $filter->{mount_point}; } try { my $response = $apiset->net_use(%api_args); $output = $response->get_parsed_output(); } catch NACL::APISet::Exceptions::InvalidParamValueException with { $caught_exception = 1; } catch NACL::APISet::Exceptions::CommandFailedException with { ## As per burt 834899 net use command reported a non-zero errorlevel ## So even though the command passed but it reported an error $caught_exception = 1; }; return if $caught_exception; foreach my $row (@$output) { my $obj = $pkg->new( command_interface => $opts{command_interface} ); my $new_row = {}; $pkg->_hash_copy( source => $row, target => $new_row, copy => [qw(network status resource_type opens connections)], map => { local => 'mount_point', remote => 'share_name', } ); $new_row->{drive} = $new_row->{mount_point} ; if ( $new_row->{mount_point} eq '' ) { $new_row->{mount_point} = $new_row->{share_name}; } $new_row->{path} = $new_row->{share_name}; if ( $new_row->{share_name} =~ s/\\\\(.+)?\\// ) { $new_row->{server} = $1; } $new_row->{type} = "CIFS"; $obj->_set_fields( row => $new_row ); push @state_objs, $obj; } ## end foreach my $row (@$output) return @state_objs; } 1;