# $Id: $ # # Copyright (c) 2001-2012 NetApp, Inc., All Rights Reserved # Any use, modification, or distribution is prohibited # without prior written consent from NetApp, Inc. # ## @summary SystemLicense ComponentState Module ## @author dheeraj@netapp.com, dl-nacl-dev@netapp.com, benjaram@netapp.com ## @status public ## @pod here =head1 NAME NACL::CS::SystemLicense =head1 DESCRIPTION C is a derived class of L. It represents the state of an ONTAP SystemLicense. A related class is L, which represents access to an ONTAP SystemLicense. =head1 ATTRIBUTES The individual pieces of data that are part of the state of the SystemLicense element are the attributes of the SystemLicense ComponentState. =over =item C<< license_code >> The feature code of the SystemLicense element whose state is being represented. =item C<< feature >> =item C<< package >> =item C<< description >> =item C<< serial_number >> =item C<< limit >> =item C<< expiration_date >> =item C<< count >> =item C<< is_licensed >> =item C<< is_expired >> =item C<< is_site >> =item C<< is_demo >> =item C<< length >> =item C<< node_count >> =item C<< installation_timestamp >> =item C<< expiration_timestamp >> =item C<< owner >> Filled in for CMode CLI. =item C<< customer_id >> Filled in for CMode CLI. =item C<< legacy >> Filled in for CMode CLI. =item C<< expiration >> Filled in for CMode CLI. =item C<< type >> Filled in for CMode CLI. =item C<< package >> Filled in for CMode CLI. =item C<< grace_expiration >> Grace Period Expiration Date Filled in for CMode CLI. =item C<< grace_period >> Grace Period possible value(s) are, yes,no Filled in for CMode CLI. =item C<< is_in_grace_period >> Grace Period possible value(s) are, yes,no Filled in for CMode CLI. =item C<< grace_period_expiration >> Grace Period Expiration Date Filled in for CMode CLI. =back =cut package NACL::CS::SystemLicense; use strict; use warnings; use Params::Validate qw(validate); use NACL::ComponentUtils qw(Dumper); use NATE::Log qw(log_global); my $Log = log_global(); my $may_enter = $Log->may_enter(); my $may_exit = $Log->may_exit(); use NACL::C::_Mixins::SystemLicense qw(_map_feature_to_package _is_v2_7m_zapi); use base qw(NACL::CS::ComponentState::ONTAP); use Class::MethodMaker [ scalar => 'feature', scalar => 'package', scalar => 'license_code', scalar => 'description', scalar => 'serial_number', scalar => 'limit', scalar => 'expiration_date', scalar => 'state', scalar => 'max_capacity', scalar => 'current_capacity', # Zapi 7-mode specific options. scalar => 'count', scalar => 'is_licensed', scalar => 'is_expired', scalar => 'is_site', scalar => 'is_demo', scalar => 'length', scalar => 'node_count', scalar => 'installation_timestamp', scalar => 'expiration_timestamp', scalar => 'owner', scalar => 'customer_id', scalar => 'legacy', scalar => 'expiration', scalar => 'type', scalar => 'grace_expiration', scalar => 'grace_period', scalar => 'is_in_grace_period', scalar => 'grace_period_expiration', ]; sub isa { $Log->enter() if $may_enter; my ($pkg_or_obj, $kind) = @_; my $isa = $pkg_or_obj->_build_isa( kind => $kind, alias => 'NACL::CS::License' ); $Log->exit() if $may_exit; return $isa; } =head1 METHODS =head2 fetch my $license_state = NACL::CS::SystemLicense->fetch(command_interface=>$ci,...); my @license_states = NACL::CS::SystemLicense->fetch(command_interface=>$ci,...); see L Uses a CMode CLI/ZAPI or 7Mode CLI or Nodescope CLI or 7Mode ZAPI 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 = shift; my @state_objs = $pkg->SUPER::fetch( @_, choices => [ { method => '_fetch_cmode_cli', interface => 'CLI', set => 'CMode', }, { method => '_fetch_cmode_zapi_v1', interface => 'ZAPI', set => 'CMode', check => '_is_v1', }, { method => '_fetch_zapi_v2', interface => 'ZAPI', set => 'CMode', check => '_is_v2', }, { method => '_fetch_7mode_cli_v2', interface => 'CLI', set => '7Mode|Nodescope', check => '_is_v2' }, { method => '_fetch_7mode_cli_v1', interface => 'CLI', set => '7Mode|Nodescope', check => '_is_v1' }, { method => '_fetch_7mode_zapi_v1', interface => 'ZAPI', set => '7Mode', check => '_is_v1' }, { method => '_fetch_zapi_v2', interface => 'ZAPI', set => '7Mode', check => '_is_v2_7m_zapi' }, ], exception_text => 'No matching system license(s) found', show_cmd => 'system license show', ); $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, %opts) = @_; my $v2 = $opts{command_interface} ->is_feature_supported(feature => 'license_v2'); if ($v2) { _map_feature_to_package(hashref_or_arrayref => $opts{filter}); _map_feature_to_package( hashref_or_arrayref => $opts{requested_fields}); } my @state_objs = $pkg->SUPER::_fetch_cmode_cli(%opts, api => 'system_license_show'); $Log->exit() if $may_exit; return @state_objs; } ## end sub _fetch_cmode_cli sub _fetch_7mode_cli_v1 { $Log->enter() if $may_enter; my $pkg = shift; my %opts = validate @_, $pkg->_fetch_backend_validate_spec(); my $apiset = delete $opts{apiset}; my $requested_fields = delete $opts{requested_fields}; my @state_objs; my $response = $apiset->license('connectrec-timeout' => 1200); my $output = $response->get_parsed_output(); # 7 Mode has below output. # { 'is_demo' => 'false', # 'license_code' => '', # 'is_site' => 'false', # 'is_licensed' => 'false', # 'service' => 'multistore', # 'multistore' => 'not licensed' # }, foreach my $row (@$output) { my $obj = $pkg->new(command_interface => $opts{command_interface}); my $row_modified = $pkg->_hash_copy( source => $row, copy => [qw(is_demo license_code is_site is_licensed)], map => {'service' => 'feature'}, ); $obj->_set_fields(row => $row_modified); push @state_objs, $obj; } ## end foreach my $row (@$output) $Log->exit() if $may_exit; return @state_objs; } ## end sub _fetch_7mode_cli_v1 sub _fetch_7mode_cli_v2 { $Log->enter() if $may_enter; my $pkg = shift; my %opts = validate @_, $pkg->_fetch_backend_validate_spec(); my $apiset = delete $opts{apiset}; my $requested_fields = delete $opts{requested_fields}; my @state_objs; _map_feature_to_package(hashref_or_arrayref => \%opts); _map_feature_to_package(hashref_or_arrayref => $requested_fields); my $response = $apiset->license('connectrec-timeout' => 1200); my $output = $response->get_parsed_output(); foreach my $row (@$output) { my $licenses = $row->{licenses}; my $row_modified = $pkg->_hash_copy( source => $row, copy => [qw(owner serial_number)], ); foreach my $license_attr (@$licenses) { my $obj = $pkg->new(command_interface => $opts{command_interface}); my %constructed_row = %$row_modified; foreach my $key (keys %$license_attr) { $constructed_row{$key} = $license_attr->{$key}; } $obj->_set_fields(row => \%constructed_row); push @state_objs, $obj; } } ## end foreach my $row (@$output) $Log->exit() if $may_exit; return @state_objs; } ## end sub _fetch_7mode_cli_v2 sub _fetch_cmode_zapi_v1 { $Log->enter() if $may_enter; my $pkg = shift; my %opts = validate @_, $pkg->_fetch_backend_validate_spec(); my $apiset = $opts{apiset}; my $system_license_response; my @state_objs; $system_license_response = $apiset->interim_license_list_get(); my $system_license_output = $system_license_response->get_parsed_output(); foreach my $row ( @{ $system_license_output->[0]{'licenses'}[0] {'interim-license-cluster-info'} } ) { my $state_fields = $pkg->_zapi_hash_copy( source => $row, copy => [qw( serial-number description expiration-date limit )], map => [ "service" => "feature", "code" => "license-code", ], ); my $obj = $pkg->new(command_interface => $opts{command_interface},); $obj->_set_fields(row => $state_fields); push @state_objs, $obj; } ## end foreach my $row ( @{ $netport_output... $Log->exit() if $may_exit; return @state_objs; } ## end sub _fetch_cmode_zapi_v1 sub _fetch_zapi_v2 { $Log->enter() if $may_enter; my $pkg = shift; my %opts = validate @_, $pkg->_fetch_backend_validate_spec(); my $apiset = $opts{apiset}; my $ci = $opts{command_interface}; my $system_license_response; my @state_objs; # map the option 'feature' to 'package' for V2 _map_feature_to_package(hashref_or_arrayref => \%opts); # CMode License V2 ZAPI returns package name in lower case. # # 1-80-000000 # NFS License # no # cluster-2 # nfs # 1-80-000011 # site # if ($ci->is_cmode() && defined $opts{filter}->{package}) { $opts{filter}->{package} = lc $opts{filter}->{package}; } my $api; my $response_attribute; my $desc = $opts{filter}->{'description'} if(defined $opts{filter}->{'description'}); if (defined($desc) && $desc =~ /capacity/i) { $api = 'license_v2_capacity_get_iter'; $response_attribute = 'license-v2-capacity-info'; delete($opts{filter}->{'description'}); @state_objs = $pkg->SUPER::_fetch_cmode_zapi( %opts, api => $api, copy => [qw( owner state package max-capacity current-capacity serial-number )],); } else { $api = 'license_v2_list_info'; $response_attribute = 'license-v2-info'; $system_license_response = $apiset->$api(); my $system_license_output = $system_license_response->get_parsed_output(); foreach my $row ( @{$system_license_output->[0]{'licenses'}[0]{$response_attribute}}) { my $state_fields = $pkg->_zapi_hash_copy( source => $row, copy => [ qw( serial-number description package type owner customer-id legacy limit ) ], map => ['expiration-date' => ['expiration-time'],], ); my $obj = $pkg->new(command_interface => $opts{command_interface},); $obj->_set_fields(row => $state_fields); push @state_objs, $obj; } ## end foreach my $row ( @{ $netport_output... } $Log->exit() if $may_exit; return @state_objs; } ## end sub _fetch_zapi_v2 sub _fetch_7mode_zapi_v1 { $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 @state_objs; my $response = $apiset->license_list_info(); my $output = $response->get_parsed_output(); foreach my $row (@{$output->[0]->{licenses}->[0]->{'license-info'}}) { my $obj = $pkg->new(command_interface => $opts{command_interface}); my $row_modified = $pkg->_hash_copy( source => $row, copy => [ qw(length count node-count is-licensed is-expired is-site is-demo) ], map => { 'code' => 'license-code', 'service' => 'feature' }, ); $obj->_set_fields(row => $row_modified); push @state_objs, $obj; } ## end foreach my $row ( @{ $output... $Log->exit() if $may_exit; return @state_objs; } ## end sub _fetch_7mode_zapi_v1 sub _is_v1 { $Log->enter() if $may_enter; my ($pkg_or_obj, %opts) = @_; require NACL::C::SystemLicense; my $ret = NACL::C::SystemLicense->_is_v1(%opts); $Log->exit() if $may_exit; return $ret; } ## end sub _is_v1 sub _is_v2 { $Log->enter() if $may_enter; my ($pkg_or_obj, %opts) = @_; require NACL::C::SystemLicense; my $ret = NACL::C::SystemLicense->_is_v2(%opts); $Log->exit() if $may_exit; return $ret; } ## end sub _is_v2 sub _case_insensitive_attributes { $Log->enter() if $may_enter; $Log->exit() if $may_exit; return [qw(license-code package feature)]; } 1;