#!/usr/bin/perl -w
#
# Copyright (c) 2016 VMware, Inc.  All rights reserved.

use strict;
use warnings;

use FindBin;
use lib "$FindBin::Bin/../";

use VMware::VIRuntime;
use VMware::VIMRuntime;

use VsanapiUtils;

$SIG{__DIE__} = sub{Util::disconnect()};
$SIG{INT} = sub{on_interrupt();};

$Util::script_version = "1.0";

my %opts = (
   cluster_name => {
      type => "=s",
      help => "Cluster name",
      required => 0,
   },
);

#Assuming the binding files are in the same directory
#of this script.
load_vsanmgmt_binding_files("./VIM25VsanmgmtStub.pm",
                            "./VIM25VsanmgmtRuntime.pm");
Opts::add_options(%opts);
Opts::parse();
Opts::validate();
Util::connect();
main();
Util::disconnect();

sub on_interrupt {
   Util::disconnect();
   exit;
}
sub trim($)
{
   my $string = shift;
   $string =~ s/^\s+//;
   $string =~ s/\s+$//;
   return $string;
}

sub onTaskUpdated {
   my $progress = shift @_;
   Util::trace(0, "Task updated with progress($progress%)\n");
}

sub main {
   Util::trace(0, "\nConnection Successful\n");
   my $service_content = Vim::get_service_content();
   my $apiType = $service_content->about->apiType;

   my $cluster_name = Opts::get_option("cluster_name");
   my $cluster_view = undef;
   if (not defined($cluster_name)) {
      croak "Please provide the cluster name for \
VC connection(option --cluster_name).";
   }
   $cluster_view = Vim::find_entity_view(
                         view_type => 'ClusterComputeResource',
                         filter => { 'name' => $cluster_name },
                         properties => ['name']);
   if ($cluster_view) {
      Util::trace(0, "cluster name: ".$cluster_view->name."\n");
   }
   if (not $cluster_view) {
      croak "Cannot get the cluster. \
Please check if the cluster name or id is correct.";
   }

   my %vc_mos = get_vsan_vc_mos();

   # The VSAN iSCSI service and cluster configuration service should be fetched
   # for iSCSI service status toggle, and target/lun creation.
   my $vit_system_view = $vc_mos{'vsan-cluster-iscsi-target-system'};
   my $cluster_config_system_view = $vc_mos{'vsan-cluster-config-system'};

   # Enable iSCSI service with the cluster configuration API.
   my $vsan_config_spec = VsanIscsiTargetServiceDefaultConfigSpec->new(
                                networkInterface => "vmk0",
                                port => 2300);
   my $enable_spec = VsanIscsiTargetServiceSpec->new(
                           defaultConfig => $vsan_config_spec,
                           enabled => "true");
   my $reconfig_spec = VimVsanReconfigSpec->new(
                           iscsiSpec => $enable_spec,
                           modify => "true");
   my $iscsi_enable_task = $cluster_config_system_view->VsanClusterReconfig(
                                 cluster => $cluster_view,
                                 vsanReconfigSpec => $reconfig_spec);
   $cluster_view->waitForTask($iscsi_enable_task, \&onTaskUpdated);
   Util::trace(0, "Enable vSAN iSCSI service task completed.\n");

   # Create a target and an associated 1GB LUN.
   my $target_alias_name = "targetAlias";
   my $target_spec = VsanIscsiTargetSpec->new(
                           alias => $target_alias_name,
                           iqn => "iqn.2015-08.com.vmware:vit.target");
   my $target_create_task = $vit_system_view->VsanVitAddIscsiTarget(
                                 cluster => $cluster_view,
                                 targetSpec => $target_spec);
   $cluster_view->waitForTask($target_create_task, \&onTaskUpdated);
   Util::trace(0, "Create vSAN iSCSI target task completed.\n");

   my $lun_size = 1 * 1024 * 1024 * 1024;
   my $lun_spec = VsanIscsiLUNSpec->new(
                              lunId=>0,
                              lunSize=>$lun_size);
   my $lun_create_task = $vit_system_view->VsanVitAddIscsiLUN(
                              cluster => $cluster_view,
                              targetAlias => $target_alias_name,
                              lunSpec => $lun_spec);
   $cluster_view->waitForTask($lun_create_task, \&onTaskUpdated);
   Util::trace(0, "Create vSAN iSCSI LUN task completed.\n");

   # Remove a LUN
   my $lun_remove_task = $vit_system_view->VsanVitRemoveIscsiLUN(
                              cluster => $cluster_view,
                              targetAlias => $target_alias_name,
                              lunId => 0);
   $cluster_view->waitForTask($lun_remove_task, \&onTaskUpdated);
   Util::trace(0, "Remove vSAN iSCSI LUN task completed.\n");

   # Remove a target
   my $target_remove_task = $vit_system_view->VsanVitRemoveIscsiTarget(
                              cluster => $cluster_view,
                              targetAlias => $target_alias_name);
   $cluster_view->waitForTask($target_remove_task, \&onTaskUpdated);
   Util::trace(0, "Remove vSAN iSCSI target task completed.\n");

   # Disable vSAN iSCSI target service.
   my $disable_spec = VsanIscsiTargetServiceSpec->new(enabled=>"false");
   $reconfig_spec = VimVsanReconfigSpec->new(
                        iscsiSpec=>$disable_spec,
                        modify => "true");
   my $iscsi_disable_task = $cluster_config_system_view->VsanClusterReconfig(
                                 cluster => $cluster_view,
                                 vsanReconfigSpec => $reconfig_spec);
   $cluster_view->waitForTask($iscsi_disable_task, \&onTaskUpdated);
   Util::trace(0, "Disable vSAN iSCSI service task completed.\n");
}
__END__

=head1 NAME

vsaniscsisample.pl - Connects to and disconnects from a VirtualCenter server,
                     and demostrate vSAN iSCSI target serviec API.
=head1 SYNOPSIS

 vsaniscsisample.pl [options]

=head1 DESCRIPTION

This VI Perl command-line utility connects to aVirtualCenter server,
- Demostrate sample code for how to enable/disable the vSAN iSCSI target
  service, and create iSCSI target and LUN based using this service.

=head1 EXAMPLES

VC:
 vsaniscsisample.pl --url https://<host>:<port>/sdk/vimService
            --username myuser --password mypassword --cluster_name mycluster
 vsaniscsisample.pl --url https://<host>:<port>/sdk/vimService
            --username myuser --password mypassword --cluster_moid cluster_id

=head1 SUPPORTED PLATFORMS

All operations work with VMware VirtualCenter and ESX 6.5 or later.

