# # Copyright (c) 2001-2011 NetApp, Inc., All Rights Reserved # Any use, modification, or distribution is prohibited # without prior written consent from NetApp, Inc. # ## @summary FreeDataPort Module ## @author dl-nacl-dev@netapp.com ## @status shared ## @pod here package NACL::MTask::FreeDataPort; use base qw(NACL::MTask::MTask); use NATE::Log qw(log_global); my $Log = log_global(); my $may_enter = $Log->may_enter(); my $may_exit = $Log->may_exit(); use Data::Dumper; use NACL::C::Component; use NACL::CS::NetworkPort; use NACL::CS::NetworkPortVlan; use NACL::CS::NetworkInterface; use NACL::CS::NetworkPortIfgrp; =head1 NAME NACL::MTask::FreeDataPort =head1 DESCRIPTION This module is to be used to find free data ports present in the filer. The method implemented is discovery, which checks existing ifgrp, interface and vlan to find used network ports and based on that, try to find the available free data ports. # use the module use NACL::MTask::FreeDataPort; ... my $port_finder = NACL::MTask::FreeDataPort->new( command_interface => $ci ); $port_finder->discovery(); =head1 ATTRIBUTES =head2 command_interface (Required isa NACL::C::CommandInterface) A component object that represents the host to which to send commands. =head1 METHODS =head2 discovery my $port_obj = NACL::MTask::FreeDataPort->discovery( command_interface => $ci ); (Class method) It checks the available data ports and existing ifgrps, data interfaces and vlans for used ports and based on that determines the available data ports. In an array context it returns the list of network port component objects. In a scalar context it returns a component object for just one element. my $port_obj = NACL::MTask::FreeDataPort->discovery( command_interface => $ci ); $port_obj->modify(..); or my @port_objs = NACL::MTask::FreeDataPort->discovery( command_interface => $ci ); foreach my $port_object (@port_objs) { ... $port_object->modify(..); } =over =item command_interface (Required) As NACL::C::Node. A component object that represents the host to which to send commands. =back =cut sub discovery { $Log->enter() if $may_enter; my $pkg = shift; my %opts = NACL::C::Component->_common_validate_with( params => \@_, ignore_primary_keys => 1, only_static_method => 1 ); my @free_p_ports; my $ci = delete $opts{command_interface}; my $node_name = $ci->name(); # Find all the physical data ports my @port_cs = NACL::CS::NetworkPort->fetch( command_interface => $ci, filter => { node => $node_name, type => 'physical', role => 'data', link => 'up' }, requested_fields => ['port'], allow_empty => 1, %opts ); my @physical_ports; push( @physical_ports, map { $_->port() } @port_cs ); my @used_ports; # Check for vlan ports my @vlan_cs = NACL::CS::NetworkPortVlan->fetch( command_interface => $ci, filter => { node => $node_name }, requested_fields => ['port'], allow_empty => 1, %opts ); push( @used_ports, map { $_->port() } @vlan_cs ); # Check for interface current port. my @interface_cs = NACL::CS::NetworkInterface->fetch( command_interface => $ci, filter => { role => 'data', 'curr-node' => $node_name }, requested_fields => ['curr-port'], allow_empty => 1 ); push( @used_ports, map { $_->curr_port() } @interface_cs ); # Check for interface home port. @interface_cs = NACL::CS::NetworkInterface->fetch( command_interface => $ci, filter => { role => 'data', 'home-node' => $node_name }, requested_fields => ['home-port'], allow_empty => 1, %opts ); push( @used_ports, map { $_->home_port() } @interface_cs ); # Check for Ifgrp ports # Since ZAPI doesn't support net-port-ifgrp-get-iter # CLI interface is used here. my @ifgrp_cs = NACL::CS::NetworkPortIfgrp->fetch( command_interface => $ci, filter => { node => $node_name }, requested_fields => ['ports'], allow_empty => 1, %opts, apiset_must => { interface => "CLI" } ); foreach my $obj (@ifgrp_cs) { next if ( $obj->ports() =~ m[-] ); my @ports = split( /,/, $obj->ports() ); foreach (@ports) { push( @used_ports, $_ ); } } ## end foreach my $obj (@ifgrp_cs) my $allowed_port; foreach my $p_port (@physical_ports) { $allowed_port = 1; foreach my $u_port (@used_ports) { if ( $p_port eq $u_port ) { $allowed_port = 0; } } if ($allowed_port) { push( @free_p_ports, $p_port ); } } ## end foreach my $p_port (@physical_ports) $Log->debug( "Free ports " . Dumper( \@free_p_ports ) ); my @free_p_port_objects; foreach my $portname (@free_p_ports) { my $port_obj = NACL::C::NetworkPort->new( command_interface => $ci, node => $node_name, port => $portname ); push @free_p_port_objects, $port_obj; } ## end foreach my $portname (@free_p_ports) $Log->exit() if $may_exit; return wantarray ? @free_p_port_objects : $free_p_port_objects[0]; } ## end sub discovery 1;