# # Copyright (c) 2001-2016 NetApp, Inc., All Rights Reserved # Any use, modification, or distribution is prohibited # without prior written consent from NetApp, Inc. # ## @summary Mix-in for common functionality for Snapmirror-related CS files ## @author dl-nacl-dev@netapp.com ## @status shared ## @pod here package NACL::CS::_Mixins::Snapmirror; use strict; use warnings; use feature 'state'; use NATE::Log qw(log_global); my $Log = log_global(); my $may_enter = $Log->may_enter(); my $may_exit = $Log->may_exit(); use Params::Validate qw(:all); BEGIN { use Exporter qw(import); our @EXPORT_OK = qw( _non_iter_check_cs _hash_map_translations_type _hash_map_translations_group_type _hash_map_translations_status _apply_filter ); our %EXPORT_TAGS = ('all' => \@EXPORT_OK); } sub _non_iter_check_cs { $Log->enter(); my ($pkg, %opts) = @_; my %filter = %{$opts{filter}}; # -get ZAPI will work only if the destination-path can be constructed $pkg->_construct_single_path(params => \%filter, type => 'destination'); $pkg->_non_iter_check( 'destination-path' => $filter{'destination-path'}, %opts ); $Log->exit(); } # After the call to SUPER::_fetch_cmode_zapi, the value of the "type" attribute # will be the ZAPI value. Map it to the CLI value. sub _hash_map_translations_type { $Log->enter(); my $pkg = $_[0]; my %type_map = $pkg->_type_val_map(); my %reverse_type_map = reverse %type_map; # This is output-only, so is not present in the map we get from the mix-in $reverse_type_map{extended_data_protection} = 'XDP'; $Log->exit(); return ( type => { fields_to_translate => [qw(type)], hash_map => {%reverse_type_map}, } ); } sub _hash_map_translations_group_type { my %map = ( 'none' => 'None', 'vserver' => 'Vserver', 'infinitevol' => 'InfiniteVol', 'cg' => 'CG', 'consistencygroup' => 'ConsistencyGroup', 'flexgroup' => 'FlexGroup' ); return ( group_type => { fields_to_translate => [qw(group-type)], hash_map => {%map}, } ); } sub _hash_map_translations_status { my $pkg = $_[0]; return ( status => { fields_to_translate => [qw(status)], hash_map => {$pkg->_status_zapi_cli_map()}, } ); } sub _apply_filter { $Log->enter(); my ($pkg, @args) = @_; # Validate only the options used here state $spec = { filter => {type => HASHREF}, state_objs => {type => ARRAYREF}, }; my %opts = validate_with( params => \@args, spec => $spec, # Allow through any options the base-class _apply_filter accepts allow_extra => 1, ); my $state_objs = $opts{state_objs}; # The path can be provided in any of the following formats: # clustername://vs/vol # vs:vol # We normalize the path on the input (i.e. whatever is specified in the # filter) and on the output (i.e. in the CS object) to the "vs:vol" format state $path_regex = qr(.*://(.*)); my $normalize_path = sub { my ($path) = @_; if ($path =~ $path_regex) { $path = $1; } $path =~ s/\//:/; return $path; }; my $dest_path = $opts{filter}{'destination-path'}; my ($need_to_filter_path, $has_src, $has_dest); if (defined $dest_path) { if (ref $dest_path ne 'Regexp') { if (!$pkg->_check_relational_regex_filter(filter_value => $dest_path)) { # Normalize the path only if it's not a Perl regex and does # not contain any wildcard characters $need_to_filter_path = 1; $has_dest = 1; $dest_path = $normalize_path->($dest_path); } } } my $src_path = $opts{filter}{'source-path'}; if (defined $src_path) { if (ref $src_path ne 'Regexp') { if (!$pkg->_check_relational_regex_filter(filter_value => $src_path)) { $need_to_filter_path = 1; $has_src = 1; $src_path = $normalize_path->($src_path); } } } if ($need_to_filter_path) { my %filter = %{$opts{filter}}; delete $filter{'source-path'} if $has_src; delete $filter{'destination-path'} if $has_dest; $opts{filter} = \%filter; my $matches_filter = sub { my ($state_obj) = @_; if ($has_src) { my $cs_src_path = $state_obj->source_path(); $cs_src_path = $normalize_path->($cs_src_path); if ($cs_src_path ne $src_path) { return 0; } } if ($has_dest) { my $cs_dst_path = $state_obj->destination_path(); $cs_dst_path = $normalize_path->($cs_dst_path); if ($cs_dst_path ne $dest_path) { return 0; } } return 1; }; @{$state_objs} = grep($matches_filter->($_), @{$state_objs}); } $pkg->_super_apply_filter(%opts); $Log->exit(); } 1;