diff --git a/recipes/go/storage/AIRAPIs/AIRAPIs.go b/recipes/go/storage/AIRAPIs/AIRAPIs.go index deac305..a3b371b 100644 --- a/recipes/go/storage/AIRAPIs/AIRAPIs.go +++ b/recipes/go/storage/AIRAPIs/AIRAPIs.go @@ -67,4 +67,19 @@ func main() { os.Exit(0) } storageHelper.DeleteReplicationTargets(*nbmaster, httpClient, jwt, stsName, tarId) + + + // TODO: (KEEP THIS OR NOT) Create Storage Unit and DP/DV + //if ( storageHelper.CreateMSDPDiskPool(*nbmaster, httpClient, jwt) != 201 ) { + // panic("CreateMSDPDiskPool Failed. Exiting.\n") + //} + + // TODO: (KEEP THIS OR NOT) Create Storage Unit and DP/DV + //if ( storageHelper.CreateMSDPStorageUnit(*nbmaster, httpClient, jwt) != 201 ) { + // panic("CreateMSDPStorageUnit Failed. Exiting.\n") + //} + + if ( storageHelper.AddReplicationTargetToDV(*nbmaster, httpClient, jwt, stsName) != 201 ) { + panic("AddReplicationTarget Failed. Exiting.\n") + } } diff --git a/recipes/go/storage/README.txt b/recipes/go/storage/README.txt index b76e2a8..8156474 100644 --- a/recipes/go/storage/README.txt +++ b/recipes/go/storage/README.txt @@ -12,4 +12,5 @@ The script can also create new MSDP storage server (with creds as a/a) depending Further lists the replication candidates based on the no of trusted master servers and storage server (MSDP and CC) on them. User need to select one of the replication candidate to create AIR relationship on the earlier created MSDP/CC sts or existing one. User can delete any existing AIR relationship as well. +User can also add replication targets on diskvolume level and manage the entitiy with desired ADD/GET/GET ALL/DELETE operations. diff --git a/recipes/go/storage/StorageHelper/StorageHelper.go b/recipes/go/storage/StorageHelper/StorageHelper.go index 1e25a6c..bb3bca5 100644 --- a/recipes/go/storage/StorageHelper/StorageHelper.go +++ b/recipes/go/storage/StorageHelper/StorageHelper.go @@ -41,13 +41,16 @@ type DataArray struct { var mediaServerName string const ( - port = "1556" - storageUri = "storage/" + port = "1556" + storageUri = "storage/" storageServerUri = "storage-servers/" - storageUnitUri = "storage-units" - contentType = "application/vnd.netbackup+json;version=3.0" + storageUnitUri = "storage-units" + diskPoolUri = "disk-pools" + contentType = "application/vnd.netbackup+json;version=4.0" replicationTargetsUri = "/replication-targets" replicationCandidatesUri = "/target-storage-servers" + diskVolumeUri = "disk-volumes/" + ) //############################################################## @@ -379,3 +382,351 @@ func DeleteReplicationTargets(nbmaster string, httpClient *http.Client, jwt stri } return response.StatusCode; } + +//####################################################################### +// Create a MSDP Disk Pool +//####################################################################### +func CreateMSDPDiskPool(nbmaster string, httpClient *http.Client, jwt string)(int, string) { + fmt.Printf("\nSending a POST request to create with defaults...\n") + if strings.Compare(apiUtil.TakeInput("Want to create new MSDP storage Pool?(Or you can use existing)(Yes/No):"), "Yes") != 0 { + dpName := apiUtil.TakeInput("Enter MSDP Disk Pool Name for other operations:") + return 201, dpName; + } + + dpName := apiUtil.TakeInput("Enter Disk Pool Name:") + + // Creating Disl Pool with rest of the parameters with default settings, you may choose to change them as per use. + + MSDPstorageUnit := map[string]interface{}{ + "data": map[string]interface{}{ + "type": "diskPool", + "attributes": map[string]interface{}{ + "name":dpName, + "diskVolumes":map[string]interface{}[, + { + "name":"PureDiskVolume" + } + ], + "maximumIoStreams": map[string]interface{}{ + "limitIoStreams": true, + "streamsPerVolume": 2 + } + }, + "relationships": map[string]interface{}{ + "storageServers": map[string]interface{}{ + "data": map[string]interface{}{ + "type": "storageServer", + "id": "PureDisk" + ":" + stsName + } + } + } + } + } + + + stsRequest, _ := json.Marshal(MSDPstorageUnit) + + uri := "https://" + nbmaster + ":" + port + "/netbackup/" + storageUri + diskPoolUri + + request, _ := http.NewRequest(http.MethodPost, uri, bytes.NewBuffer(stsRequest)) + request.Header.Add("Content-Type", contentType); + request.Header.Add("Authorization", jwt); + + response, err := httpClient.Do(request) + + if err != nil { + fmt.Printf("The HTTP request failed with error: %s\n", err) + panic("Unable to create storage unit.\n") + } else { + if response.StatusCode != 201 { + responseBody, _ := ioutil.ReadAll(response.Body) + fmt.Printf("%s\n", responseBody) + panic("Unable to create MSDP storage unit.\n") + } else { + fmt.Printf("%s created successfully.\n", stuName); + //responseDetails, _ := httputil.DumpResponse(response, true); + apiUtil.AskForResponseDisplay(response.Body) + } + } + + return response.StatusCode, stuName; +} + + +//####################################################################### +// Create a MSDP Storage Unit +//####################################################################### +func CreateMSDPStorageUnit(nbmaster string, httpClient *http.Client, jwt string)(int, string) { + fmt.Printf("\nSending a POST request to create with defaults...\n") + if strings.Compare(apiUtil.TakeInput("Want to create new MSDP storage Unit?(Or you can use existing)(Yes/No):"), "Yes") != 0 { + stuName := apiUtil.TakeInput("Enter MSDP/CloudCatalyst Storage Unit Name for other operations:") + return 201, stuName; + } + + stuName := apiUtil.TakeInput("Enter Storage Unit Name:") + if strings.Compare(apiUtil.TakeInput("Want to create new MSDP Disk Pool?(Or you can use existing)(Yes/No):"), "Yes") != 0 { + dpName := apiUtil.TakeInput("Enter MSDP/CloudCatalyst Disk Pool Name for other operations:") + } else { + dpName := apiUtil.TakeInput("Enter Disk Pool Name:") + CreateMSDPDiskPool(); + } + + // Creating Storage Unit with rest of the parameters with default settings, you may choose to change them as per use. + + MSDPstorageUnit := map[string]interface{}{ + "data": map[string]interface{}{ + "type": "storageUnit", + "id": stuName, + "attributes": map[string]interface{}{ + "name":stuName, + "useAnyAvailableMediaServer": true, + "maxFragmentSizeMegabytes": 50000, + "maxConcurrentJobs": 10, + "onDemandOnly": true + }, + "relationships": map[string]interface{}{ + "diskPool": map[string]interface{}{ + "data": map[string]interface{}{ + "type": "diskPool", + "id": "PureDisk" + ":" + dpName + } + } + } + } + } + + + stsRequest, _ := json.Marshal(MSDPstorageUnit) + + uri := "https://" + nbmaster + ":" + port + "/netbackup/" + storageUri + storageUnitUri + + request, _ := http.NewRequest(http.MethodPost, uri, bytes.NewBuffer(stsRequest)) + request.Header.Add("Content-Type", contentType); + request.Header.Add("Authorization", jwt); + + response, err := httpClient.Do(request) + + if err != nil { + fmt.Printf("The HTTP request failed with error: %s\n", err) + panic("Unable to create storage unit.\n") + } else { + if response.StatusCode != 201 { + responseBody, _ := ioutil.ReadAll(response.Body) + fmt.Printf("%s\n", responseBody) + panic("Unable to create MSDP storage unit.\n") + } else { + fmt.Printf("%s created successfully.\n", stuName); + //responseDetails, _ := httputil.DumpResponse(response, true); + apiUtil.AskForResponseDisplay(response.Body) + } + } + + return response.StatusCode, stuName; +} + + +//####################################################################### +// Add replication target to MSDP Disk Volume +//####################################################################### +func AddReplicationTargetToDV(nbmaster string, httpClient *http.Client, jwt string, stsName string)(int) { + fmt.Printf("\nSending a POST request to create with defaults...\n") + + + candId := apiUtil.TakeInput("Enter target storage server Id:") + IdSlice := strings.Split(candId, ":") + + candId := apiUtil.TakeInput("Enter target storage disk volume name:") + dvName := strings.Split(diskVolumeId, ":"); + username := apiUtil.TakeInput("Enter target storage server username:") + password := apiUtil.TakeInput("Enter target storage server password:") + + replicationtarget := map[string]interface{}{ + "data": map[string]interface{}{ + "type": "volumeReplicationTarget", + "attributes": map[string]interface{}{ + "operationType": "SET_REPLICATION", + "targetVolumeName": dvName, + "targetStorageServerDetails": map[string]interface{}{ + "masterServerName": IdSlice[3], + "storageServerName": IdSlice[1], + "storageServerType": IdSlice[0], + "mediaServerName": IdSlice[2]}, + "credentials": map[string]interface{}{ + "userName": username, + "password": password + }}}} + + + + stsRequest, _ := json.Marshal(replicationtarget) + + uri := "https://" + nbmaster + ":" + port + "/netbackup/" + storageUri + storageServerUri + "PureDisk:" + stsName + diskVolumeUri + diskVolumeId + replicationTargetsUri + + request, _ := http.NewRequest(http.MethodPost, uri, bytes.NewBuffer(stsRequest)) + request.Header.Add("Content-Type", contentType); + request.Header.Add("Authorization", jwt); + + fmt.Println ("Firing request: POST: " + uri) + response, err := httpClient.Do(request) + + if err != nil { + fmt.Printf("The HTTP request failed with error: %s\n", err) + panic("Unable to add replication target.\n") + } else { + if response.StatusCode != 204 { + responseBody, _ := ioutil.ReadAll(response.Body) + fmt.Printf("%s\n", responseBody) + panic("Unable to add replication target.\n") + } else { + fmt.Printf("%s created successfully.\n", ""); + //responseDetails, _ := httputil.DumpResponse(response, true); + apiUtil.AskForResponseDisplay(response.Body) + } + } + + return response.StatusCode; +} + +//####################################################################### +// Get all replication targets on MSDP Disk Volume +//####################################################################### +func GetAllReplicationTargetsToDV(nbmaster string, httpClient *http.Client, jwt string, stsName string)(int) { + fmt.Printf("\nSending a POST request to delete with defaults...\n") + + + candId := apiUtil.TakeInput("Enter target storage server Id:") + IdSlice := strings.Split(candId, ":") + + candId := apiUtil.TakeInput("Enter target storage disk volume name:") + dvName := strings.Split(diskVolumeId, ":"); +username := apiUtil.TakeInput("Enter target storage server username:") + password := apiUtil.TakeInput("Enter target storage server password:") + + + stsRequest, _ := json.Marshal(replicationtarget) + + uri := "https://" + nbmaster + ":" + port + "/netbackup/" + storageUri + storageServerUri + "PureDisk:" + stsName + diskVolumeUri + diskVolumeId + replicationTargetsUri + + request, _ := http.NewRequest(http.MethodGet, uri, nil) + request.Header.Add("Content-Type", contentType); + request.Header.Add("Authorization", jwt); + + fmt.Println ("Firing request: GET: " + uri) + response, err := httpClient.Do(request) + + if err != nil { + fmt.Printf("The HTTP request failed with error: %s\n", err) + panic("Unable to get replication targets for disk volume.\n") + } else { + if response.StatusCode == 200 { + responseBody, _ := ioutil.ReadAll(response.Body) + fmt.Printf("%s\n", responseBody) + } + } + + return response.StatusCode; +} + +//####################################################################### +// Get replication target by ID on MSDP Disk Volume +//####################################################################### +func GetReplicationTargetByIdToDV(nbmaster string, httpClient *http.Client, jwt string, stsName string)(int) { + fmt.Printf("\nSending a POST request to delete with defaults...\n") + + candId := apiUtil.TakeInput("Enter target storage server Id:") + IdSlice := strings.Split(candId, ":") + + candId := apiUtil.TakeInput("Enter target storage disk volume name:") + dvName := strings.Split(diskVolumeId, ":"); + username := apiUtil.TakeInput("Enter target storage server username:") + password := apiUtil.TakeInput("Enter target storage server password:") + + repTargetId := apiUtil.TakeInput("Enter replication target ID:") + + stsRequest, _ := json.Marshal(replicationtarget) + + uri := "https://" + nbmaster + ":" + port + "/netbackup/" + storageUri + storageServerUri + "PureDisk:" + stsName + + diskVolumeUri + diskVolumeId + replicationTargetsUri + repTargetId + + request, _ := http.NewRequest(http.MethodGet, uri, nil) + request.Header.Add("Content-Type", contentType); + request.Header.Add("Authorization", jwt); + + fmt.Println ("Firing request: GET: " + uri) + response, err := httpClient.Do(request) + + if err != nil { + fmt.Printf("The HTTP request failed with error: %s\n", err) + panic("Unable to get replication targets for disk volume.\n") + } else { + if response.StatusCode == 200 { + responseBody, _ := ioutil.ReadAll(response.Body) + fmt.Printf("%s\n", responseBody) + } + } + return response.StatusCode; +} + +//####################################################################### +// Delete replication target on MSDP Disk Volume +//####################################################################### +func DeleteReplicationTargetToDV(nbmaster string, httpClient *http.Client, jwt string, stsName string)(int) { + fmt.Printf("\nSending a POST request to delete with defaults...\n") + + + candId := apiUtil.TakeInput("Enter target storage server Id:") + IdSlice := strings.Split(candId, ":") + + candId := apiUtil.TakeInput("Enter target storage disk volume name:") + dvName := strings.Split(diskVolumeId, ":"); + username := apiUtil.TakeInput("Enter target storage server username:") + password := apiUtil.TakeInput("Enter target storage server password:") + + replicationtarget := map[string]interface{}{ + "data": map[string]interface{}{ + "type": "volumeReplicationTarget", + "attributes": map[string]interface{}{ + "operationType": "DELETE_REPLICATION", + "targetVolumeName": dvName, + "targetStorageServerDetails": map[string]interface{}{ + "masterServerName": IdSlice[3], + "storageServerName": IdSlice[1], + "storageServerType": IdSlice[0], + "mediaServerName": IdSlice[2]}, + "credentials": map[string]interface{}{ + "userName": username, + "password": password + }}}} + + + + stsRequest, _ := json.Marshal(replicationtarget) + + uri := "https://" + nbmaster + ":" + port + "/netbackup/" + storageUri + storageServerUri + "PureDisk:" + stsName + diskVolumeUri + diskVolumeId + replicationTargetsUri + + request, _ := http.NewRequest(http.MethodPost, uri, bytes.NewBuffer(stsRequest)) + request.Header.Add("Content-Type", contentType); + request.Header.Add("Authorization", jwt); + + fmt.Println ("Firing request: POST: " + uri) + response, err := httpClient.Do(request) + + if err != nil { + fmt.Printf("The HTTP request failed with error: %s\n", err) + panic("Unable to delete replication target.\n") + } else { + if response.StatusCode != 204 { + responseBody, _ := ioutil.ReadAll(response.Body) + fmt.Printf("%s\n", responseBody) + panic("Unable to add replication target.\n") + } else { + fmt.Printf("%s deleted successfully.\n", ""); + //responseDetails, _ := httputil.DumpResponse(response, true); + apiUtil.AskForResponseDisplay(response.Body) + } + } + + return response.StatusCode; +} + + diff --git a/recipes/perl/storage/README.md b/recipes/perl/storage/README.md index 9dadd15..fe38a4b 100644 --- a/recipes/perl/storage/README.md +++ b/recipes/perl/storage/README.md @@ -15,3 +15,4 @@ These scripts are only meant to be used as a reference. If you intend to use the Use the following commands to run the perl samples. - `perl configure_storage_unit_cloud_end_to_end.pl -nbmaster -username -password -sts_payload -dp_payload -stu_payload [-domainName ] [-domainType ]` +- `perl replication_target_operations_end_to_end.pl -nbmaster -username -password -sts_payload -dp_payload -stu_payload -add_reptarget_payload -delete_reptarget_payload [-domainname ] [-domaintype ]` diff --git a/recipes/perl/storage/replication_target_on_dv_operations_end_to_end.pl b/recipes/perl/storage/replication_target_on_dv_operations_end_to_end.pl new file mode 100644 index 0000000..e9be1b4 --- /dev/null +++ b/recipes/perl/storage/replication_target_on_dv_operations_end_to_end.pl @@ -0,0 +1,132 @@ +#!/usr/bin/env perl + +use LWP::UserAgent; +use LWP::Protocol::https; +print "LWP::UserAgent: ".LWP::UserAgent->VERSION,"\n"; +print "LWP::Protocol::https: ".LWP::Protocol::https->VERSION,"\n"; +use JSON; +use Getopt::Long qw(GetOptions); +use storage; + +# This script consists of the helper functions to excute NetBackup APIs to create storage unit. +# 1) Login to Netbackup +# 2) Create storage server +# 3) Create disk Pool +# 4) Create storage unit + +# +# The token is the key to the NetBackup AuthN/AuthZ scheme. You must login and get a token +# and use this token in your Authorization header for all subsequent requests. Token validity +# is fixed at 24 hours +# +my $token; + +my $protocol = "https"; +my $port = "1556"; +my $nbmaster; +my $username; +my $password; +my $sts_payload; +my $dp_payload; +my $stu_payload; +my $domainName; +my $domainType; +my $base_url; + + +# subroutines for printing usage and library information required to run the script. +sub print_usage { + print("\n\nUsage:"); + print("\nperl replication_target_operations_end_to_end.pl -nbmaster -username -password -sts_payload -dp_payload -stu_payload -add_reptarget_payload -delete_reptarget_payload [-domainname ] [-domaintype ]\n\n\n") +} + +sub print_disclaimer { + print("--------------------------------------------------------\n"); + print("-- This script requires Perl 5.20.2 or later --\n"); + print("--------------------------------------------------------\n"); + print("Executing this library requires some additional libraries like \n\t'LWP' \n\t'JSON'\ \n\t'Getopt'\ \n\n"); + print("You can specify the 'nbmaster', 'username', 'password', 'sts_payload', 'dp_payload', 'stu_payload', 'add_reptarget_payload', '-delete_reptarget_payload', 'domainName' and 'domainType' as command-line parameters\n"); + print_usage(); +} + +# subroutine to process user input +sub user_input { + GetOptions( + 'nbmaster=s' => \$nbmaster, + 'username=s' => \$username, + 'password=s' => \$password, + 'sts_payload=s' => \$sts_payload, + 'dp_payload=s' => \$dp_payload, + 'stu_payload=s' => \$stu_payload, + 'add_reptarget_payload=s' => \$add_reptarget_payload, + 'delete_reptarget_payload=s' => \$delete_reptarget_payload, + 'domainName=s' => \$domainName, + 'domainType=s' => \$domainType, + ) or die print_usage(); + + if ($nbmaster eq "") { + print("Please provide the value for 'nbmaster'"); + exit; + } + + if ($username eq "") { + print("Please provide the value for 'username'"); + exit; + } + + if ($password eq "") { + print("Please provide the value for 'password'"); + exit; + } + if ($sts_payload eq "") { + print("Please provide the value for 'sts_payload'"); + exit; + } + + if ($dp_payload eq "") { + print("Please provide the value for 'dp_payload'"); + exit; + } + + if ($stu_payload eq "") { + print("Please provide the value for 'stu_payload'"); + exit; + } + + if ($add_reptarget_payload eq "") { + print("Please provide the value for 'add_reptarget_payload'"); + exit; + } + + if ($delete_reptarget_payload eq "") { + print("Please provide the value for 'delete_reptarget_payload'"); + exit; + } + + $base_url = "$protocol://$nbmaster:$port/netbackup"; +} + +sub storage_api_automation { + my $token = storage::perform_login($nbmaster, $username, $password, $domain_name, $domain_type); + my $response_sts = storage::post_storage_server($nbmaster, $token, $sts_payload); + my $response_dp = storage::post_disk_pool($nbmaster, $token, $dp_payload); + storage::post_storage_unit($nbmaster, $token, $stu_payload); + + # Get the stsid from response_sts, dvid from response_dp. + my $stsid = $response_sts->{data}->{id} + my $dvid = $response_dp->{data}->{attributes}->{diskVolumes}[0]->{name} + + storage::post_add_replication_target_on_dv($nbmaster, $token, $stsid, $dvid, $add_reptarget_payload) + my $response_reptarget = storage::get_all_replication_targets($nbmaster, $token, $stsid, $dvid) + my $reptargetid = $response_reptarget->{data}[0]->{id} + + storage::get_replication_targets_by_id($nbmaster, $token, $stsid, $dvid, $reptargetid) + + storage::post_delete_replication_target_on_dv($nbmaster, $token, $stsid, $dvid, $delete_reptarget_payload) +} + +print_disclaimer(); + +user_input(); + +storage_api_automation(); diff --git a/recipes/perl/storage/storage.pm b/recipes/perl/storage/storage.pm index caec679..2e62005 100644 --- a/recipes/perl/storage/storage.pm +++ b/recipes/perl/storage/storage.pm @@ -240,5 +240,149 @@ sub post_disk_pool { } } +# Add a replication target on a disk volume +sub post_add_replication_target_on_dv { + my $arguments_count = scalar(@_); + if ($arguments_count != 5) { + print "ERROR :: Incorrect number of arguments passed to post_add_replication_target_on_dv()\n"; + print "Usage : post_add_replication_target_on_dv( , , ) \n"; + return; + } + + my $master_server = $_[0]; + my $token = $_[1]; + my $stsid = $_[2]; + my $dvid = $_[3]; + my $filename = $_[4]; + + my @dvid_split = @split /:/, $dvid + my $dvid_hex = sprintf "0x%02x", hex $dvid_hex[0]; + my $url = "$PROTOCOL$master_server:$NB_PORT/netbackup/storage/storage-servers/".$stsid."/disk-volumes/".$dvid_hex."/replication-targets"; + open(my $fh, '<:encoding(UTF-8)', $filename) + or die "Could not open file '$filename' $!"; + + my $payload = ""; + while (my $row = <$fh>) { + chomp $row; + $payload .= $row; + } + print "payload: $payload\n"; + + my $json = send_http_request($url, "POST", $token, $payload, undef, $CONTENT_TYPE); + + if (defined $json) { + print "Successfully completed POST Storage Server Request.\n"; + + my $pretty = JSON->new->pretty->encode($json); + return $pretty; + } + else { + print "ERROR :: Add replication target Request Failed!\n"; + } +} + +# Delete a replication target on a disk volume +sub post_delete_replication_target_on_dv { + my $arguments_count = scalar(@_); + if ($arguments_count != 5) { + print "ERROR :: Incorrect number of arguments passed to post_delete_replication_target_on_dv()\n"; + print "Usage : post_delete_replication_target_on_dv( , , ) \n"; + return; + } + + my $master_server = $_[0]; + my $token = $_[1]; + my $stsid = $_[2]; + my $dvid = $_[3]; + my $filename = $_[4]; + + my @dvid_split = @split /:/, $dvid + my $dvid_hex = sprintf "0x%02x", hex $dvid_hex[0]; + my $url = "$PROTOCOL$master_server:$NB_PORT/netbackup/storage/storage-servers/".$stsid."/disk-volumes/".$dvid_hex."/replication-targets"; + open(my $fh, '<:encoding(UTF-8)', $filename) + or die "Could not open file '$filename' $!"; + + my $payload = ""; + while (my $row = <$fh>) { + chomp $row; + $payload .= $row; + } + print "payload: $payload\n"; + + my $json = send_http_request($url, "POST", $token, $payload, undef, $CONTENT_TYPE); + + if (defined $json) { + print "Successfully completed POST Storage Server Request.\n"; + + my $pretty = JSON->new->pretty->encode($json); + return $pretty; + } + else { + print "ERROR :: Delete replication target Request Failed!\n"; + } +} + +sub get_replication_targets_by_id { + my $arguments_count = scalar(@_); + if ($arguments_count != 5) { + print "ERROR :: Incorrect number of arguments passed to get_replication_targets_by_id()\n"; + print "Usage : get_replication_targets_by_id( , , ) \n"; + return; + } + + my $master_server = $_[0]; + my $token = $_[1]; + my $stsid = $_[2]; + my $dvid = $_[3]; + my $reptargetid = $_[4]; + + my @dvid_split = @split /:/, $dvid + my $dvid_hex = sprintf "0x%02x", hex $dvid_hex[0]; + my $url = "$PROTOCOL$master_server:$NB_PORT/netbackup/storage/storage-servers/".$stsid."/disk-volumes/".$dvid_hex."/replication-targetsi/".$reptargetid; + + my $json = send_http_request($url, "GET", $token, undef, undef, $CONTENT_TYPE); + + if (defined $json) { + print "Successfully completed GET replication target by id Request.\n"; + + my $pretty = JSON->new->pretty->encode($json); + return $pretty; + } + else { + print "ERROR :: GET replication target by id Request Failed!\n"; + } +} + +sub get_all_replication_targets { + my $arguments_count = scalar(@_); + if ($arguments_count != 4) { + print "ERROR :: Incorrect number of arguments passed to get_all_replication_targets()\n"; + print "Usage : post_add_replication_target_on_dv( , , ) \n"; + return; + } + + my $master_server = $_[0]; + my $token = $_[1]; + my $stsid = $_[2]; + my $dvid = $_[3]; + + my @dvid_split = @split /:/, $dvid + my $dvid_hex = sprintf "0x%02x", hex $dvid_hex[0]; + my $url = "$PROTOCOL$master_server:$NB_PORT/netbackup/storage/storage-servers/".$stsid."/disk-volumes/".$dvid_hex."/replication-targets"; + + my $json = send_http_request($url, "GET", $token, undef, undef, $CONTENT_TYPE); + + if (defined $json) { + print "Successfully completed GET all replication targets Request.\n"; + + my $pretty = JSON->new->pretty->encode($json); + return $pretty; + } + else { + print "ERROR :: GET all replication targets Request Failed!\n"; + } +} + + 1; diff --git a/recipes/powershell/storage/README.md b/recipes/powershell/storage/README.md index 99015e9..3fbb30f 100644 --- a/recipes/powershell/storage/README.md +++ b/recipes/powershell/storage/README.md @@ -15,3 +15,4 @@ Pre-requisites: Use the following commands to run the PowerShell samples. - `.\configure_storage_unit_end_to_end.ps1 -nbmaster -username -password [-domainName -domainType ]` +- `.\replication_target_on_dv_operations_end_to_end.ps1 -nbmaster -username -password [-domainName -domainType ]` diff --git a/recipes/powershell/storage/replication_target_on_dv_operations_end_to_end.ps1 b/recipes/powershell/storage/replication_target_on_dv_operations_end_to_end.ps1 new file mode 100644 index 0000000..dd44bc9 --- /dev/null +++ b/recipes/powershell/storage/replication_target_on_dv_operations_end_to_end.ps1 @@ -0,0 +1,429 @@ +#! /usr/bin/pwsh +<# +.SYNOPSIS +This sample script demonstrates the use of NetBackup Storage management REST APIs for replication target operations. +.DESCRIPTION +This script can be run using NetBackup 8.2.1 and higher. +It demonstrate how to add/remove and get/get all replication targets on disk volume by specifying json payload string in each specified function. +.EXAMPLE +./replication_target_on_dv_operations_end_to_end.ps1 -nbmaster -username -password [-domainName -domainType ] +#> + +#Requires -Version 4.0 + +Param ( + [string]$nbmaster = $(Throw "Please specify the name of the NetBackup Master Server using the -nbmaster parameter."), + [string]$username = $(Throw "Please specify the user name using the -username parameter."), + [string]$password = $(Throw "Please specify the password using the -password parameter."), + [string]$domainName, + [string]$domainType +) + +#################### +# Global Variables +#################### + +$port = 1556 +$baseUri = "https://" + $nbmaster + ":" + $port + "/netbackup/" +$contentType = "application/vnd.netbackup+json;version=3.0" + +############################################################### +# Setup to allow self-signed certificates and enable TLS v1.2 +############################################################### +Function Setup() +{ + # Allow self-signed certificates + if ([System.Net.ServicePointManager]::CertificatePolicy -notlike 'TrustAllCertsPolicy') + { + Add-Type -TypeDefinition @" + using System.Net; + using System.Security.Cryptography.X509Certificates; + public class TrustAllCertsPolicy : ICertificatePolicy { + public bool CheckValidationResult( + ServicePoint srvPoint, X509Certificate certificate, + WebRequest request, int certificateProblem) { + return true; + } + } +"@ + [System.Net.ServicePointManager]::CertificatePolicy = New-Object -TypeName TrustAllCertsPolicy + } + + # Force TLS v1.2 + try { + if ([Net.ServicePointManager]::SecurityProtocol -notcontains 'Tls12') { + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + } + } + catch { + Write-Host "`n"$_.Exception.InnerException.Message + } +} + +###################################### +# Login to the NetBackup webservices +###################################### + +Function Login() +{ + $uri = $baseUri + "login" + + $body = @{ + userName=$username + password=$password + } + if ($domainName -ne "") { + $body.add("domainName", $domainName) + } + if ($domainType -ne "") { + $body.add("domainType", $domainType) + } + Write-Host "`nSending a POST request to login to the NetBackup webservices..." + + $response = Invoke-WebRequest ` + -Uri $uri ` + -Method POST ` + -Body (ConvertTo-Json -InputObject $body) ` + -ContentType $contentType + + if ($response.StatusCode -ne 201) + { + throw "Unable to connect to the NetBackup Master Server" + } + + Write-Host "Login successful.`n" + $response = (ConvertFrom-Json -InputObject $response) + return $response +} + + +################################################# +# Create a cloud storage server +################################################# +Function CreateStorageServer() +{ + $sts_uri = $baseUri + "/storage/storage-servers" + + $sts_cloud_json = '{ + "data": { + "type": "storageServer", + "attributes": { + "name": "amazonstss.com", + "storageCategory": "CLOUD", + "mediaServerDetails": { + "name": "MEDIA_SERVER" + }, + "cloudAttributes": { + "providerId": "amazon", + "compressionEnabled": true, + "s3RegionDetails": [ + { + "serviceHost": "SERVICE-HOST", + "regionName": "REGION_NAME", + "regionId": "REGION_ID" + } + ], + "cloudCredentials": { + "authType": "ACCESS_KEY", + "accessKeyDetails": { + "userName": "USER_ID", + "password": "PASSWORD" + } + } + } + } + } + } + + + ' + + $response_create_sts = Invoke-WebRequest ` + -Uri $sts_uri ` + -Method POST ` + -Body ($sts_cloud_json) ` + -ContentType $contentType ` + -Headers $headers + + if ($response_create_sts.StatusCode -ne 201) + { + throw "Unable to create storage server." + } + + Write-Host "storage server created successfully.`n" + echo $response_create_sts + Write-Host $response_create_sts + + $response_create_sts = (ConvertFrom-Json -InputObject $response_create_sts) + return $response_create_sts +} + +################################################# +# Create a disk pool for cloud storage server +################################################# +Function CreateDiskPool() +{ + + $dp_uri = $baseUri + "/storage/disk-pools" + + $dp_cloud_json = '{ + "data": { + "type": "diskPool", + "attributes": { + "name": "disk-pool1", + "diskVolumes": [ + { + "name": "VOLUME_NAME" + } + ], + "maximumIoStreams": { + "limitIoStreams": true, + "streamsPerVolume": 4 + } + }, + "relationships": { + "storageServers": { + "data": [ + { + "type": "storageServer", + "id": "STORAGE_SERVER_ID" + } + ] + } + } + } + } + + + ' + + $response_create_dp = Invoke-WebRequest ` + -Uri $dp_uri ` + -Method POST ` + -Body ($dp_cloud_json) ` + -ContentType $contentType ` + -Headers $headers + + if ($response_create_dp.StatusCode -ne 201) + { + throw "Unable to create Disk Pool." + } + + Write-Host "Disk Pool created successfully.`n" + echo $response_create_dp + Write-Host $response_create_dp + + $response_create_dp = (ConvertFrom-Json -InputObject $response_create_dp) + return $response_create_dp +} + +#################################################################################### +# Create a storage unit for cloud torage server +#################################################################################### +Function CreateStorageUnit() +{ + $stu_uri = $baseUri + "/storage/storage-units" + + $stu_cloud_json = '{ + "data": { + "type": "storageUnit", + "attributes": { + "name": "cloud-stu", + "useAnyAvailableMediaServer": true, + "maxFragmentSizeMegabytes": 50000, + "maxConcurrentJobs": 10, + "onDemandOnly": true + }, + "relationships": { + "diskPool": { + "data" : { + "type": "diskPool", + "id": "STORAGE_SERVER_ID" + } + } + } + } + } + ' + + $response_create_stu = Invoke-WebRequest ` + -Uri $stu_uri ` + -Method POST ` + -Body ($stu_cloud_json) ` + -ContentType $contentType ` + -Headers $headers + + if ($response_create_stu.StatusCode -ne 201) + { + throw "Unable to create storage unit." + } + + Write-Host "storage unit created successfully.`n" + echo $response_create_stu + Write-Host $response_create_stu + + $response_create_stu = (ConvertFrom-Json -InputObject $response_create_stu) +} + +################################################# +# Add replication target details +################################################# +Function AddReplicationTargets([string]$stsid, [string]$dvid) +{ + $add_rep_tgt_uri = $baseUri + "/storage/storage-servers" + $stsid + "/disk-volumes/" + $dvid | Format-Hex + "/replication-targets" + + $add_rep_tgt_json = '{ + { + "data": { + "type": "volumeReplicationTarget", + "attributes": { + "operationType": "SET_REPLICATION", + "targetVolumeName": "DISK_VOLUME_NAME", + "targetStorageServerDetails": { + "masterServerName": "TARGET_MASTER_SERVER", + "mediaServerName": "TARGET_MEDIA_SERVER", + "storageServerName": "TARGET_STORAGE_SERVER_NAME", + "storageServerType": "TARGET_STORAGE_SERVER_TYPE", + "credentials": { + "userName": "TARGET_USERID", + "password": "TARGET_PASSWORD" + } + } + } + } + } + } + ' + + $response_add_rep_target = Invoke-WebRequest ` + -Uri $add_rep_tgt_uri ` + -Method POST ` + -Body ($add_rep_tgt_json) ` + -ContentType $contentType ` + -Headers $headers + + if ($response_add_rep_target.StatusCode -ne 204) + { + throw "Unable to add replication target." + } + + Write-Host "replication target added successfully.`n" + echo $response_add_rep_target + Write-Host $response_add_rep_target + + $response_add_rep_target = (ConvertFrom-Json -InputObject $response_add_rep_target) + retrun $response_add_rep_target +} + +################################################# +# Get all replication target details +################################################# +Function GetAllReplicationTargets([string]$stsid, [string]$dvid) +{ + $get_rep_tgt_uri = $baseUri + "/storage/storage-servers" + $stsid + "/disk-volumes/" + $dvid | Format-Hex + "/replication-targets" + + $response_get_rep_target = Invoke-WebRequest ` + -Uri $get_rep_tgt_uri ` + -Method GET ` + -ContentType $contentType ` + -Headers $headers + + if ($response_get_rep_target.StatusCode -ne 200) + { + throw "Unable to get replication targets." + } + + Write-Host "replication target information recieved successfully.`n" + echo $response_get_rep_target + Write-Host $response_get_rep_target + + $response_get_rep_target = (ConvertFrom-Json -InputObject $response_get_rep_target) +} + +################################################# +# Get all replication target details for a specific replication target +################################################# +Function GetReplicationTargetById([string]$stsid, [string]$dvid, [string]$reptargetid) +{ + $get_rep_tgt_uri = $baseUri + "/storage/storage-servers" + $stsid + "/disk-volumes/" + $dvid | Format-Hex + "/replication-targets/" + reptargetid + + $response_get_rep_target = Invoke-WebRequest ` + -Uri $get_rep_tgt_uri ` + -Method GET ` + -ContentType $contentType ` + -Headers $headers + + if ($response_get_rep_target.StatusCode -ne 200) + { + throw "Unable to get replication targets." + } + + Write-Host "replication target information recieved successfully.`n" + echo $response_get_rep_target + Write-Host $response_get_rep_target + + $response_get_rep_target = (ConvertFrom-Json -InputObject $response_get_rep_target) +} + +################################################# +# Delete replication target details +################################################# +Function DeleteReplicationTargets([string]$stsid, [string]$dvid) +{ + $del_rep_tgt_uri = $baseUri + "/storage/storage-servers" + $stsid + "/disk-volumes/" + $dvid | Format-Hex + "/replication-targets" + + $del_rep_tgt_json = '{ + { + "data": { + "type": "volumeReplicationTarget", + "attributes": { + "operationType": "DELETE_REPLICATION", + "targetVolumeName": "DISK_VOLUME_NAME", + "targetStorageServerDetails": { + "masterServerName": "TARGET_MASTER_SERVER", + "mediaServerName": "TARGET_MEDIA_SERVER", + "storageServerName": "TARGET_STORAGE_SERVER_NAME", + "storageServerType": "TARGET_STORAGE_SERVER_TYPE", + "credentials": { + "userName": "TARGET_USERID", + "password": "TARGET_PASSWORD" + } + } + } + } + } + } + ' + + $response_del_rep_target = Invoke-WebRequest ` + -Uri $del_rep_tgt_uri ` + -Method POST ` + -Body ($del_rep_tgt_json) ` + -ContentType $contentType ` + -Headers $headers + + if ($response_del_rep_target.StatusCode -ne 204) + { + throw "Unable to delete replication target." + } + + Write-Host "replication target deleted successfully.`n" + echo $response_del_rep_target + Write-Host $response_del_rep_target + + $response_del_rep_target = (ConvertFrom-Json -InputObject $response_del_rep_target) +} + + +Setup +$loginResponse = Login +$headers = @{"Authorization" = $loginResponse.token} +$created_sts = CreateStorageServer +$created_dp = CreateDiskPool +CreateStorageUnit + +$reptarget = AddReplicationTargets($created_sts.data.id, $created_dp.data.attributes.diskVolumes[0].name) +GetReplicationTargetById($created_sts.data.id, $created_dp.data.attributes.diskVolumes[0].name, $reptarget.data[0].id) +GetAllReplicationTargets($created_sts.data.id, $created_dp.data.attributes.diskVolumes[0].name) +DeleteReplicationTargets($created_sts.data.id, $created_dp.data.attributes.diskVolumes[0].name, $reptarget.data[0].id) + diff --git a/recipes/python/storage/README.md b/recipes/python/storage/README.md index a709199..0c24101 100644 --- a/recipes/python/storage/README.md +++ b/recipes/python/storage/README.md @@ -16,3 +16,5 @@ Pre-requisites: Use the following commands to run the python samples. - `python -W ignore configure_storage_unit_end_to_end.py -nbmaster -username -password -sts_payload -dp_payload -stu_payload [-domainname ] [-domaintype ]` + +- `python -W ignore replication_target_operations_end_to_end.py -nbmaster -username -password -sts_payload -dp_payload -stu_payload -add_reptarget_payload -delete_reptarget_payload [-domainname ] [-domaintype ]` diff --git a/recipes/python/storage/replication_target_on_dv_operations_end_to_end.py b/recipes/python/storage/replication_target_on_dv_operations_end_to_end.py new file mode 100644 index 0000000..1c06d16 --- /dev/null +++ b/recipes/python/storage/replication_target_on_dv_operations_end_to_end.py @@ -0,0 +1,124 @@ +import sys +import storage +import json +import texttable as tt + +# This script consists of the helper functions to excute NetBackup APIs to create storage unit. +# 1) Login to Netbackup +# 2) Create storage server +# 3) Create disk Pool +# 4) Create storage unit + +protocol = "https" +nbmaster = "" +username = "" +password = "" +domainname = "" +domaintype = "" + +port = 1556 + +def print_usage(): + print("Example:") + print("python -W ignore replication_target_operations_end_to_end.py -nbmaster -username -password -sts_payload -dp_payload -stu_payload -add_reptarget_payload -delete_reptarget_payload [-domainname ] [-domaintype ]\n\n\n") + +def read_command_line_arguments(): + if len(sys.argv)%2 == 0: + print_usage() + exit() + + global nbmaster + global username + global password + global domainname + global domaintype + global sts_payload + global dp_payload + global stu_payload + global add_reptarget_payload + global delete_reptarget_payload + global stsid + global dvid + global reptargetid + + for i in range(1, len(sys.argv), 2): + if sys.argv[i] == "-nbmaster": + nbmaster = sys.argv[i + 1] + elif sys.argv[i] == "-username": + username = sys.argv[i + 1] + elif sys.argv[i] == "-password": + password = sys.argv[i + 1] + elif sys.argv[i] == "-sts_payload": + sts_payload = sys.argv[i + 1] + elif sys.argv[i] == "-dp_payload": + dp_payload = sys.argv[i + 1] + elif sys.argv[i] == "-stu_payload": + stu_payload = sys.argv[i + 1] + elif sys.argv[i] == "-add_reptarget_payload": + add_reptarget_payload = sys.argv[i + 1] + elif sys.argv[i] == "-delete_reptarget_payload": + delete_reptarget_payload = sys.argv[i + 1] + elif sys.argv[i] == "-domainname": + domainname = sys.argv[i + 1] + elif sys.argv[i] == "-domaintype": + domaintype = sys.argv[i + 1] + else: + print_usage() + exit() + + if nbmaster == "": + print("Please provide the value for 'nbmaster'") + exit() + elif username == "": + print("Please provide the value for 'username'") + exit() + elif password == "": + print("Please provide the value for 'password'") + exit() + elif sts_payload == "": + print("Please provide the value for 'sts_payload'") + exit() + elif dp_payload == "": + print("Please provide the value for 'dp_payload'") + exit() + elif stu_payload == "": + print("Please provide the value for 'stu_payload'") + exit() + elif add_reptarget_payload == "": + print("Please provide the value for 'add_reptarget_payload'") + elif delete_reptarget_payload == "": + print("Please provide the value for 'delete_reptarget_payload'") + + +read_command_line_arguments() + +base_url = protocol + "://" + nbmaster + ":" + str(port) + "/netbackup" + +jwt = storage.perform_login(username, password, base_url, domainname, domaintype) + +response_sts = storage.create_storage_server(jwt, base_url, sts_payload) +print(response_sts) + +response_dp = storage.create_disk_pool(jwt, base_url, dp_payload) +print(response_dp) + +response_stu = storage.create_storage_unit(jwt, base_url, stu_payload) +print(response_stu) + +# Get the stsid from response_sts, dvid from response_dp. + +stsid = response_sts['data']['id'] +dvid = response_dp['data']['attributes']['diskVolumes'][0]['name'] + +storage.add_replication_target_on_diskvolume(jwt, base_url, add_reptarget_payload, stsid, dvid) + +response_reptarget = storage.get_all_replication_targets_on_diskvolume(jwt, base_url, stsid, dvid) +print(response_reptarget) + +# get reptargetid from response_reptarget +reptargetid = response_reptarget['data'][0]['id'] +response_reptarget = storage.get_replication_target_by_id_on_diskvolume(jwt, base_url, stsid, dvid, reptargetid) +print(response_reptarget) + +storage.delete_replication_target_on_diskvolume(jwt, base_url, delete_reptarget_payload, stsid, dvid) + diff --git a/recipes/python/storage/storage.py b/recipes/python/storage/storage.py index 9e34c53..5fba99d 100644 --- a/recipes/python/storage/storage.py +++ b/recipes/python/storage/storage.py @@ -1,6 +1,6 @@ import requests -content_type = "application/vnd.netbackup+json; version=3.0" +content_type = "application/vnd.netbackup+json; version=4.0" def perform_login(username, password, base_url, domain_name, domain_type): @@ -30,7 +30,7 @@ def get_storage_units(jwt, base_url): # "filter": "jobType eq 'RESTORE'" #This adds a filter to only show RESTORE Jobs } - print("performing GET on {}\n".format(url)) + print("performing GET on {}\n".format(url)) resp = requests.get(url, headers=headers, params=query_params, verify=False) @@ -66,7 +66,7 @@ def create_storage_server(jwt, base_url, file_name): req_body = open(path, 'r').read() - print("performing POST on {}\n".format(url), req_body) + print("performing POST on {}\n".format(url)) resp = requests.post(url, headers=headers, data=req_body, verify=False) @@ -137,7 +137,7 @@ def create_disk_pool(jwt, base_url, file_name): req_body = open(path, 'r').read() - print("performing POST on {}\n".format(url), req_body) + print("performing POST on {}\n".format(url)) resp = requests.post(url, headers=headers, data=req_body, verify=False) @@ -281,4 +281,78 @@ def delete_disk_pools(jwt, base_url, dpid): if resp.status_code != 204: raise Exception('DELETE DP with specific ID failed with status code {} and {}'.format(resp.status_code, resp.json())) - print("\nThe DP is deleted with status code: {}\n".format(resp.status_code)) \ No newline at end of file + print("\nThe DP is deleted with status code: {}\n".format(resp.status_code)) + +def add_replication_target_on_diskvolume(jwt, base_url, file_name, stsid, dvid): + # add and delete replication target has same URI, just that the operationType parameter is DELETE_REPLICATION in case of add. + dvid = dvid.split(":",1)[0].encode('utf-8') + url = base_url + "/storage/storage-servers/" + stsid + "/disk-volumes/" + dvid.hex() + "/replication-targets" + + headers = {'Content-Type': content_type, 'Authorization': jwt} + + path = file_name + + req_body = open(path, 'r').read() + + print("performing POST on {}\n".format(url), req_body) + + resp = requests.post(url, headers=headers, data=req_body, verify=False) + + if resp.status_code != 204: + raise Exception('Add replication target on diskvolume API failed with status code {}'.format(resp.status_code)) + + print("\nThe replication target is added with status code: {}\n".format(resp.status_code)) + +def get_all_replication_targets_on_diskvolume(jwt, base_url, stsid, dvid): + dvid = dvid.split(":",1)[0].encode('utf-8') + url = base_url + "/storage/storage-servers/" + stsid + "/disk-volumes/" + dvid.hex() + "/replication-targets" + headers = {'Content-Type': content_type, 'Authorization': jwt} + query_params = { + "page[limit]": 100, #This changes the default page size to 100 + } + + print("performing GET on {}\n".format(url)) + + resp = requests.get(url, headers=headers, params=query_params, verify=False) + + if resp.status_code != 200: + raise Exception('Get all replication targets on a diskvolume API failed with status code {} and {}'.format(resp.status_code, resp.json())) + + return resp.json() + +def get_replication_target_by_id_on_diskvolume(jwt, base_url, stsid, dvid, reptargetid): + dvid = dvid.split(":",1)[0].encode('utf-8') + url = base_url + "/storage/storage-servers/" + stsid + "/disk-volumes/" + dvid.hex() + "/replication-targets/" + reptargetid + headers = {'Content-Type': content_type, 'Authorization': jwt} + query_params = { + } + + print("performing GET on {}\n".format(url)) + + resp = requests.get(url, headers=headers, params=query_params, verify=False) + + if resp.status_code != 200: + raise Exception('Get replication target by specific id on a diskvolume API failed with status code {} and {}'.format(resp.status_code, resp.json())) + + return resp.json() + +def delete_replication_target_on_diskvolume(jwt, base_url, file_name, stsid, dvid): + # add and delete replication target has same URI, just that the operationType parameter is DELETE_REPLICATION in case of add. + dvid = dvid.split(":",1)[0].encode('utf-8') + url = base_url + "/storage/storage-servers/" + stsid + "/disk-volumes/" + dvid.hex() + "/replication-targets" + + headers = {'Content-Type': content_type, 'Authorization': jwt} + + path = file_name + + req_body = open(path, 'r').read() + + print("performing POST on {}\n".format(url), req_body) + + resp = requests.post(url, headers=headers, data=req_body, verify=False) + + if resp.status_code != 204: + raise Exception('Delete replication target on diskvolume API failed with status code {}'.format(resp.status_code)) + + print("\nThe replication target is deleted with status code: {}\n".format(resp.status_code)) + diff --git a/snippets/perl/storage/README.md b/snippets/perl/storage/README.md index d217d30..b01a420 100644 --- a/snippets/perl/storage/README.md +++ b/snippets/perl/storage/README.md @@ -77,4 +77,14 @@ Delete Disk Pool: Use the following command to create the disk pool on NetBackup Master server: - perl delete_storage_unit.pl -nbmaster -username -password -dpid [-domainname ] [-domaintype ] +Add replication target on diskvolume + - perl post_add_replication_target_on_dv.pl -nbmaster -username -password -stsid -dvid -payload [-domainname ] [-domaintype ] +Get all replication targets on diskvolume + - perl get_all_replication_targets_on_dv.pl -nbmaster -username -password -stsid -dvid -payload [-domainname ] [-domaintype ]; + +Get replication target on diskvolume with specific replication target id + - perl get_replication_target_by_id_on_dv.pl -nbmaster -username -password -stsid -dvid -payload [-domainname ] [-domaintype ]; + +Delete replication target on diskvolume + - perl post_delete_replication_target_on_dv.pl -nbmaster -username -password -stsid -dvid -payload [-domainname ] [-domaintype ]; diff --git a/snippets/perl/storage/get_all_replication_targets_on_dv.pl b/snippets/perl/storage/get_all_replication_targets_on_dv.pl new file mode 100644 index 0000000..ea20849 --- /dev/null +++ b/snippets/perl/storage/get_all_replication_targets_on_dv.pl @@ -0,0 +1,39 @@ +#Load module netbackup.pm from current directory +use lib"../."; + +use gateway; +use storage::storage; +use Getopt::Long qw(GetOptions); +sub printUsage { + print "\nUsage : perl get_all_replication_targets_on_dv.pl -nbmaster -username -password -stsid -dvid -payload [-domainname ] [-domaintype ]\n\n"; + die; +} + +my $master_server; +my $username; +my $password; +my $payload_file; +my $domainname; +my $domaintype; + +GetOptions( +'nbmaster=s' => \$master_server, +'username=s' => \$username, +'password=s' => \$password, +'stsid=s' => \$stsid, +'dvid=s' => \$dvid, +'payload=s' => \$payload_file, +'domainname=s' => \$domain_name, +'domaintype=s' => \$domain_type, +) or printUsage(); + +if (!$master_server || !$username || !$password || !$stsid || !$dvid) { + printUsage(); +} + +my $token = gateway::perform_login($master_server, $username, $password, $domain_name, $domain_type); + +my $jsonString = storage::get_all_replication_targets($master_server, $token, $stsid, $dvid); +print "$jsonString\n"; + +gateway::perform_logout($master_server, $token); diff --git a/snippets/perl/storage/get_replication_target_by_id_on_dv.pl b/snippets/perl/storage/get_replication_target_by_id_on_dv.pl new file mode 100644 index 0000000..3887b9d --- /dev/null +++ b/snippets/perl/storage/get_replication_target_by_id_on_dv.pl @@ -0,0 +1,40 @@ +#Load module netbackup.pm from current directory +use lib"../."; + +use gateway; +use storage::storage; +use Getopt::Long qw(GetOptions); +sub printUsage { + print "\nUsage : perl get_replication_target_by_id_on_dv.pl -nbmaster -username -password -stsid -dvid -payload [-domainname ] [-domaintype ]\n\n"; + die; +} + +my $master_server; +my $username; +my $password; +my $payload_file; +my $domainname; +my $domaintype; + +GetOptions( +'nbmaster=s' => \$master_server, +'username=s' => \$username, +'password=s' => \$password, +'stsid=s' => \$stsid, +'dvid=s' => \$dvid, +'reptargetid=s' => \$reptargetid, +'payload=s' => \$payload_file, +'domainname=s' => \$domain_name, +'domaintype=s' => \$domain_type, +) or printUsage(); + +if (!$master_server || !$username || !$password || !$stsid || !$dvid) { + printUsage(); +} + +my $token = gateway::perform_login($master_server, $username, $password, $domain_name, $domain_type); + +my $jsonString = storage::get_all_replication_targets($master_server, $token, $stsid, $dvid, $reptargetid); +print "$jsonString\n"; + +gateway::perform_logout($master_server, $token); diff --git a/snippets/perl/storage/post_add_replication_target_on_dv.pl b/snippets/perl/storage/post_add_replication_target_on_dv.pl new file mode 100644 index 0000000..10ebe4d --- /dev/null +++ b/snippets/perl/storage/post_add_replication_target_on_dv.pl @@ -0,0 +1,39 @@ +#Load module netbackup.pm from current directory +use lib"../."; + +use gateway; +use storage::storage; +use Getopt::Long qw(GetOptions); +sub printUsage { + print "\nUsage : perl post_add_replication_target_on_dv.pl -nbmaster -username -password -stsid -dvid -payload [-domainname ] [-domaintype ]\n\n"; + die; +} + +my $master_server; +my $username; +my $password; +my $payload_file; +my $domainname; +my $domaintype; + +GetOptions( +'nbmaster=s' => \$master_server, +'username=s' => \$username, +'password=s' => \$password, +'stsid=s' => \$stsid, +'dvid=s' => \$dvid, +'payload=s' => \$payload_file, +'domainname=s' => \$domain_name, +'domaintype=s' => \$domain_type, +) or printUsage(); + +if (!$master_server || !$username || !$password || !$stsid || !$dvid) { + printUsage(); +} + +my $token = gateway::perform_login($master_server, $username, $password, $domain_name, $domain_type); + +my $jsonString = storage::post_add_replication_target_on_dv($master_server, $token, $stsid, $dvid, $payload_file); +print "$jsonString\n"; + +gateway::perform_logout($master_server, $token); diff --git a/snippets/perl/storage/post_delete_replication_target_on_dv.pl b/snippets/perl/storage/post_delete_replication_target_on_dv.pl new file mode 100644 index 0000000..d8327a2 --- /dev/null +++ b/snippets/perl/storage/post_delete_replication_target_on_dv.pl @@ -0,0 +1,39 @@ +#Load module netbackup.pm from current directory +use lib"../."; + +use gateway; +use storage::storage; +use Getopt::Long qw(GetOptions); +sub printUsage { + print "\nUsage : perl post_delete_replication_target_on_dv.pl -nbmaster -username -password -stsid -dvid -payload [-domainname ] [-domaintype ]\n\n"; + die; +} + +my $master_server; +my $username; +my $password; +my $payload_file; +my $domainname; +my $domaintype; + +GetOptions( +'nbmaster=s' => \$master_server, +'username=s' => \$username, +'password=s' => \$password, +'stsid=s' => \$stsid, +'dvid=s' => \$dvid, +'payload=s' => \$payload_file, +'domainname=s' => \$domain_name, +'domaintype=s' => \$domain_type, +) or printUsage(); + +if (!$master_server || !$username || !$password || !$stsid || !$dvid) { + printUsage(); +} + +my $token = gateway::perform_login($master_server, $username, $password, $domain_name, $domain_type); + +my $jsonString = storage::post_delete_replication_target_on_dv($master_server, $token, $stsid, $dvid, $payload_file); +print "$jsonString\n"; + +gateway::perform_logout($master_server, $token); diff --git a/snippets/perl/storage/storage.pm b/snippets/perl/storage/storage.pm index 44b7fd7..cff13d2 100644 --- a/snippets/perl/storage/storage.pm +++ b/snippets/perl/storage/storage.pm @@ -464,5 +464,149 @@ sub get_storage_unit_by_name { print "ERROR :: GET Storage unit by Name Request Failed!\n"; } } + +# Add a replication target on a disk volume +sub post_add_replication_target_on_dv { + my $arguments_count = scalar(@_); + if ($arguments_count != 5) { + print "ERROR :: Incorrect number of arguments passed to post_add_replication_target_on_dv()\n"; + print "Usage : post_add_replication_target_on_dv( , , ) \n"; + return; + } + + my $master_server = $_[0]; + my $token = $_[1]; + my $stsid = $_[2]; + my $dvid = $_[3]; + my $filename = $_[4]; + + my @dvid_split = @split /:/, $dvid + my $dvid_hex = sprintf "0x%02x", hex $dvid_hex[0]; + my $url = "$PROTOCOL$master_server:$NB_PORT/netbackup/storage/storage-servers/".$stsid."/disk-volumes/".$dvid_hex."/replication-targets"; + open(my $fh, '<:encoding(UTF-8)', $filename) + or die "Could not open file '$filename' $!"; + + my $payload = ""; + while (my $row = <$fh>) { + chomp $row; + $payload .= $row; + } + print "payload: $payload\n"; + + my $json = common::send_http_request($url, "POST", $token, $payload, undef, $CONTENT_TYPE); + + if (defined $json) { + print "Successfully completed POST Storage Server Request.\n"; + + my $pretty = JSON->new->pretty->encode($json); + return $pretty; + } + else { + print "ERROR :: Add replication target Request Failed!\n"; + } +} + +# Delete a replication target on a disk volume +sub post_delete_replication_target_on_dv { + my $arguments_count = scalar(@_); + if ($arguments_count != 5) { + print "ERROR :: Incorrect number of arguments passed to post_delete_replication_target_on_dv()\n"; + print "Usage : post_delete_replication_target_on_dv( , , ) \n"; + return; + } + + my $master_server = $_[0]; + my $token = $_[1]; + my $stsid = $_[2]; + my $dvid = $_[3]; + my $filename = $_[4]; + + my @dvid_split = @split /:/, $dvid + my $dvid_hex = sprintf "0x%02x", hex $dvid_hex[0]; + my $url = "$PROTOCOL$master_server:$NB_PORT/netbackup/storage/storage-servers/".$stsid."/disk-volumes/".$dvid_hex."/replication-targets"; + open(my $fh, '<:encoding(UTF-8)', $filename) + or die "Could not open file '$filename' $!"; + + my $payload = ""; + while (my $row = <$fh>) { + chomp $row; + $payload .= $row; + } + print "payload: $payload\n"; + + my $json = common::send_http_request($url, "POST", $token, $payload, undef, $CONTENT_TYPE); + + if (defined $json) { + print "Successfully completed POST Storage Server Request.\n"; + + my $pretty = JSON->new->pretty->encode($json); + return $pretty; + } + else { + print "ERROR :: Delete replication target Request Failed!\n"; + } +} + +sub get_replication_targets_by_id { + my $arguments_count = scalar(@_); + if ($arguments_count != 5) { + print "ERROR :: Incorrect number of arguments passed to get_replication_targets_by_id()\n"; + print "Usage : get_replication_targets_by_id( , , ) \n"; + return; + } + + my $master_server = $_[0]; + my $token = $_[1]; + my $stsid = $_[2]; + my $dvid = $_[3]; + my $reptargetid = $_[4]; + + my @dvid_split = @split /:/, $dvid + my $dvid_hex = sprintf "0x%02x", hex $dvid_hex[0]; + my $url = "$PROTOCOL$master_server:$NB_PORT/netbackup/storage/storage-servers/".$stsid."/disk-volumes/".$dvid_hex."/replication-targetsi/".$reptargetid; + + my $json = common::send_http_request($url, "GET", $token, undef, undef, $CONTENT_TYPE); + + if (defined $json) { + print "Successfully completed GET replication target by id Request.\n"; + + my $pretty = JSON->new->pretty->encode($json); + return $pretty; + } + else { + print "ERROR :: GET replication target by id Request Failed!\n"; + } +} + +sub get_all_replication_targets { + my $arguments_count = scalar(@_); + if ($arguments_count != 4) { + print "ERROR :: Incorrect number of arguments passed to get_all_replication_targets()\n"; + print "Usage : post_add_replication_target_on_dv( , , ) \n"; + return; + } + + my $master_server = $_[0]; + my $token = $_[1]; + my $stsid = $_[2]; + my $dvid = $_[3]; + + my @dvid_split = @split /:/, $dvid + my $dvid_hex = sprintf "0x%02x", hex $dvid_hex[0]; + my $url = "$PROTOCOL$master_server:$NB_PORT/netbackup/storage/storage-servers/".$stsid."/disk-volumes/".$dvid_hex."/replication-targets"; + + my $json = common::send_http_request($url, "GET", $token, undef, undef, $CONTENT_TYPE); + + if (defined $json) { + print "Successfully completed GET all replication targets Request.\n"; + + my $pretty = JSON->new->pretty->encode($json); + return $pretty; + } + else { + print "ERROR :: GET all replication targets Request Failed!\n"; + } +} + 1; diff --git a/snippets/powershell/storage/Get-NB-replication-targets-to-disk-volume-by-id.ps1 b/snippets/powershell/storage/Get-NB-replication-targets-to-disk-volume-by-id.ps1 new file mode 100644 index 0000000..4308999 --- /dev/null +++ b/snippets/powershell/storage/Get-NB-replication-targets-to-disk-volume-by-id.ps1 @@ -0,0 +1,122 @@ +<# + +.SYNOPSIS +This sample script demonstrates the use of NetBackup REST API for fetching the replication targets on a disk volume + +.DESCRIPTION +This script will fetch scpecified disk pool. + +.EXAMPLE +./Get-NB-get-disk-pool-by-id.ps1 -nbmaster "nb-master.example.com" -username "administrator" -password "secret" -dpid "disk pool id" -reptargetid "replication targetid" +#> + +param ( + [string]$nbmaster = $(throw "Please specify the name of NetBackup master server using -nbmaster parameter."), + [string]$username = $(throw "Please specify the user name using -username parameter."), + [string]$password = $(throw "Please specify the password using -password parameter."), + [string]$stsid = $(throw "Please specify the storage server identifier using -stsid parameter.") + [string]$dvid = $(throw "Please specify the storage server using -dvid parameter.") + [string]$reptargetid = $(throw "Please specify the replication target id using -reptargetid parameter.") +) + +##################################################################### +# Initial Setup +# Note: This allows self-signed certificates and enables TLS v1.2 +##################################################################### + +function InitialSetup() +{ + + [Net.ServicePointManager]::SecurityProtocol = "Tls12" + + # Allow self-signed certificates + if ([System.Net.ServicePointManager]::CertificatePolicy -notlike 'TrustAllCertsPolicy') + { + Add-Type -TypeDefinition @" + using System.Net; + using System.Security.Cryptography.X509Certificates; + public class TrustAllCertsPolicy : ICertificatePolicy { + public bool CheckValidationResult( + ServicePoint srvPoint, X509Certificate certificate, + WebRequest request, int certificateProblem) { + return true; + } + } +"@ + [System.Net.ServicePointManager]::CertificatePolicy = New-Object -TypeName TrustAllCertsPolicy + [Net.ServicePointManager]::SecurityProtocol = "Tls12" + + # Force TLS v1.2 + try { + if ([Net.ServicePointManager]::SecurityProtocol -notcontains 'Tls12') { + [Net.ServicePointManager]::SecurityProtocol += [Net.SecurityProtocolType]::Tls12 + } + } + catch { + Write-Host $_.Exception.InnerException.Message + } + } +} + +InitialSetup + +##################################################################### +# Global Variables +##################################################################### + +$port = 1556 +$basepath = "https://" + $nbmaster + ":" + $port + "/netbackup" +$content_type1 = "application/vnd.netbackup+json;version=1.0" +$content_type2 = "application/vnd.netbackup+json;version=2.0" +$content_type3 = "application/vnd.netbackup+json;version=3.0" + +##################################################################### +# Login +##################################################################### + +$uri = $basepath + "/login" + +$body = @{ + userName=$username + password=$password +} + +$response = Invoke-WebRequest ` + -Uri $uri ` + -Method POST ` + -Body (ConvertTo-Json -InputObject $body) ` + -ContentType $content_type1 + +if ($response.StatusCode -ne 201) +{ + throw "Unable to connect to the Netbackup master server!" +} +Write-Host "Login successful.`n" +$content = (ConvertFrom-Json -InputObject $response) + +##################################################################### +# GET NetBackup Disk Pool +##################################################################### + +$headers = @{ + "Authorization" = $content.token +} + +$sts_uri = $basepath + "/storage/disk-pools/" + $dpid + + +$response_get = Invoke-WebRequest ` + -Uri $sts_uri ` + -Method GET ` + -ContentType $contentType ` + -Headers $headers + +if ($response_get.StatusCode -ne 200) +{ + throw "Unable to fetch disk pool." +} + +Write-Host "Replication targets fetched successfully.`n" +Write-Host $response_get + +$response_get = (ConvertFrom-Json -InputObject $response_get) diff --git a/snippets/powershell/storage/Get-NB-replication-targets-to-disk-volume.ps1 b/snippets/powershell/storage/Get-NB-replication-targets-to-disk-volume.ps1 new file mode 100644 index 0000000..52a1e1f --- /dev/null +++ b/snippets/powershell/storage/Get-NB-replication-targets-to-disk-volume.ps1 @@ -0,0 +1,121 @@ +<# + +.SYNOPSIS +This sample script demonstrates the use of NetBackup REST API for fetching storage servers. + +.DESCRIPTION +This script will fetch storage servers. + +.EXAMPLE +./Get-NB-get-storage-server.ps1 -nbmaster "nb-master.example.com" -username "administrator" -password "secret" -stsid "storage server id" -dvid "diskvolume id" +#> + +param ( + [string]$nbmaster = $(throw "Please specify the name of NetBackup master server using -nbmaster parameter."), + [string]$username = $(throw "Please specify the user name using -username parameter."), + [string]$password = $(throw "Please specify the password using -password parameter.") + [string]$stsid = $(throw "Please specify the storage server identifier using -stsid parameter.") + [string]$dvid = $(throw "Please specify the storage server using -dvid parameter.") +) + +##################################################################### +# Initial Setup +# Note: This allows self-signed certificates and enables TLS v1.2 +##################################################################### + +function InitialSetup() +{ + + [Net.ServicePointManager]::SecurityProtocol = "Tls12" + + # Allow self-signed certificates + if ([System.Net.ServicePointManager]::CertificatePolicy -notlike 'TrustAllCertsPolicy') + { + Add-Type -TypeDefinition @" + using System.Net; + using System.Security.Cryptography.X509Certificates; + public class TrustAllCertsPolicy : ICertificatePolicy { + public bool CheckValidationResult( + ServicePoint srvPoint, X509Certificate certificate, + WebRequest request, int certificateProblem) { + return true; + } + } +"@ + [System.Net.ServicePointManager]::CertificatePolicy = New-Object -TypeName TrustAllCertsPolicy + [Net.ServicePointManager]::SecurityProtocol = "Tls12" + + # Force TLS v1.2 + try { + if ([Net.ServicePointManager]::SecurityProtocol -notcontains 'Tls12') { + [Net.ServicePointManager]::SecurityProtocol += [Net.SecurityProtocolType]::Tls12 + } + } + catch { + Write-Host $_.Exception.InnerException.Message + } + } +} + +InitialSetup + +##################################################################### +# Global Variables +##################################################################### + +$port = 1556 +$basepath = "https://" + $nbmaster + ":" + $port + "/netbackup" +$content_type1 = "application/vnd.netbackup+json;version=1.0" +$content_type2 = "application/vnd.netbackup+json;version=2.0" +$content_type3 = "application/vnd.netbackup+json;version=3.0" + +##################################################################### +# Login +##################################################################### + +$uri = $basepath + "/login" + +$body = @{ + userName=$username + password=$password +} + +$response = Invoke-WebRequest ` + -Uri $uri ` + -Method POST ` + -Body (ConvertTo-Json -InputObject $body) ` + -ContentType $content_type1 + +if ($response.StatusCode -ne 201) +{ + throw "Unable to connect to the Netbackup master server!" +} +Write-Host "Login successful.`n" +$content = (ConvertFrom-Json -InputObject $response) + +##################################################################### +# GET NetBackup Storage servers +##################################################################### + +$headers = @{ + "Authorization" = $content.token +} + +$sts_uri = $basepath + "/storage/storage-servers" + stsid + "/disk-volumes/" + dvid + "/replication-targets" + + +$response_getAll = Invoke-WebRequest ` + -Uri $sts_uri ` + -Method GET ` + -ContentType $contentType ` + -Headers $headers + +if ($response_getAll.StatusCode -ne 200) +{ + throw "Unable to fetch storage servers." +} + +Write-Host "storage servers fetched successfully.`n" +Write-Host $response_getAll + +$response_getAll = (ConvertFrom-Json -InputObject $response_getAll) diff --git a/snippets/powershell/storage/Post-NB-add-replication-target-to-disk-volume.ps1 b/snippets/powershell/storage/Post-NB-add-replication-target-to-disk-volume.ps1 new file mode 100644 index 0000000..2881599 --- /dev/null +++ b/snippets/powershell/storage/Post-NB-add-replication-target-to-disk-volume.ps1 @@ -0,0 +1,145 @@ +<# + +.SYNOPSIS +This sample script demonstrates the use of NetBackup REST API for setting replication target at disk volume for msdp. + +.DESCRIPTION +This script will add replication target at disk volume level for msdp + +.EXAMPLE +./Post-NB-add-replication-target-to-disk-volume.ps1 -nbmaster "nb-master.example.com" -username "administrator" -password "secret" -stsid "storage server id" -dvid "diskvolume id" +#> + +param ( + [string]$nbmaster = $(throw "Please specify the name of NetBackup master server using -nbmaster parameter."), + [string]$username = $(throw "Please specify the user name using -username parameter."), + [string]$password = $(throw "Please specify the password using -password parameter.") + [string]$stsid = $(throw "Please specify the storage server identifier using -stsid parameter.") + [string]$dvid = $(throw "Please specify the diskvolume id using -dvid parameter.") +) + +##################################################################### +# Initial Setup +# Note: This allows self-signed certificates and enables TLS v1.2 +##################################################################### + +function InitialSetup() +{ + + [Net.ServicePointManager]::SecurityProtocol = "Tls12" + + # Allow self-signed certificates + if ([System.Net.ServicePointManager]::CertificatePolicy -notlike 'TrustAllCertsPolicy') + { + Add-Type -TypeDefinition @" + using System.Net; + using System.Security.Cryptography.X509Certificates; + public class TrustAllCertsPolicy : ICertificatePolicy { + public bool CheckValidationResult( + ServicePoint srvPoint, X509Certificate certificate, + WebRequest request, int certificateProblem) { + return true; + } + } +"@ + [System.Net.ServicePointManager]::CertificatePolicy = New-Object -TypeName TrustAllCertsPolicy + [Net.ServicePointManager]::SecurityProtocol = "Tls12" + + # Force TLS v1.2 + try { + if ([Net.ServicePointManager]::SecurityProtocol -notcontains 'Tls12') { + [Net.ServicePointManager]::SecurityProtocol += [Net.SecurityProtocolType]::Tls12 + } + }G + catch { + Write-Host $_.Exception.InnerException.Message + } + } +} + +InitialSetup + +##################################################################### +# Global Variables +##################################################################### + +$port = 1556 +$basepath = "https://" + $nbmaster + ":" + $port + "/netbackup" +$content_type1 = "application/vnd.netbackup+json;version=1.0" +$content_type2 = "application/vnd.netbackup+json;version=2.0" +$content_type3 = "application/vnd.netbackup+json;version=3.0" + +##################################################################### +# Login +##################################################################### + +$uri = $basepath + "/login" + +$body = @{ + userName=$username + password=$password +} + +$response = Invoke-WebRequest ` + -Uri $uri ` + -Method POST ` + -Body (ConvertTo-Json -InputObject $body) ` + -ContentType $content_type1 + +if ($response.StatusCode -ne 201) +{ + throw "Unable to connect to the Netbackup master server!" +} +Write-Host "Login successful.`n" +$content = (ConvertFrom-Json -InputObject $response) + +##################################################################### +# POST Add replication target on disk volume level with specified details. +##################################################################### + +$headers = @{ + "Authorization" = $content.token +} + +$sts_uri = $basepath + "/storage/storage-servers" + $stsid + "/disk-volumes/" + dvid + "/replication-targets" + +$json = '{ +{ + "data": { + "type": "volumeReplicationTarget", + "attributes": { + "operationType": "SET_REPLICATION", + "targetVolumeName": "DISK_VOLUME_NAME", + "targetStorageServerDetails": { + "masterServerName": "TARGET_MASTER_SERVER", + "mediaServerName": "TARGET_MEDIA_SERVER", + "storageServerName": "TARGET_STORAGE_SERVER_NAME", + "storageServerType": "TARGET_STORAGE_SERVER_TYPE", + "credentials": { + "userName": "TARGET_USERID", + "password": "TARGET_PASSWORD" + } + } + } + } +} +} +' + +$response_add_replication_target_on_dv = Invoke-WebRequest ` + -Uri $sts_uri ` + -Method POST ` + -Body ($json) ` + -ContentType $content_type3 ` + -Headers $headers + +if ($response_add_replication_target_on_dv.StatusCode -ne 204) +{ + throw "Unable to set replication target." +} + +Write-Host "Replication target on with the specified details on disk volume is added successfully.`n" +echo $response_add_replication_target_on_dv +Write-Host $response_add_replication_target_on_dv + +$response_add_replication_target_on_dv = (ConvertFrom-Json -InputObject $response_create_sts) diff --git a/snippets/powershell/storage/Post-NB-delete-replication-target-to-disk-volume.ps1 b/snippets/powershell/storage/Post-NB-delete-replication-target-to-disk-volume.ps1 new file mode 100644 index 0000000..08602a6 --- /dev/null +++ b/snippets/powershell/storage/Post-NB-delete-replication-target-to-disk-volume.ps1 @@ -0,0 +1,145 @@ +<# + +.SYNOPSIS +This sample script demonstrates the use of NetBackup REST API for deletion of replication target added at disk volume level for msdp + +.DESCRIPTION +This script will delete replication target added at disk volume level for msdp + +.EXAMPLE +./Post-NB-delete-replication-target-to-disk-volume.ps1 -nbmaster "nb-master.example.com" -username "administrator" -password "secret" -stsid "storage server id" -dvid "diskvolume id" +#> + +param ( + [string]$nbmaster = $(throw "Please specify the name of NetBackup master server using -nbmaster parameter."), + [string]$username = $(throw "Please specify the user name using -username parameter."), + [string]$password = $(throw "Please specify the password using -password parameter.") + [string]$stsid = $(throw "Please specify the storage server identifier using -stsid parameter.") + [string]$dvid = $(throw "Please specify the diskvolume id using -dvid parameter.") +) + +##################################################################### +# Initial Setup +# Note: This allows self-signed certificates and enables TLS v1.2 +##################################################################### + +function InitialSetup() +{ + + [Net.ServicePointManager]::SecurityProtocol = "Tls12" + + # Allow self-signed certificates + if ([System.Net.ServicePointManager]::CertificatePolicy -notlike 'TrustAllCertsPolicy') + { + Add-Type -TypeDefinition @" + using System.Net; + using System.Security.Cryptography.X509Certificates; + public class TrustAllCertsPolicy : ICertificatePolicy { + public bool CheckValidationResult( + ServicePoint srvPoint, X509Certificate certificate, + WebRequest request, int certificateProblem) { + return true; + } + } +"@ + [System.Net.ServicePointManager]::CertificatePolicy = New-Object -TypeName TrustAllCertsPolicy + [Net.ServicePointManager]::SecurityProtocol = "Tls12" + + # Force TLS v1.2 + try { + if ([Net.ServicePointManager]::SecurityProtocol -notcontains 'Tls12') { + [Net.ServicePointManager]::SecurityProtocol += [Net.SecurityProtocolType]::Tls12 + } + }G + catch { + Write-Host $_.Exception.InnerException.Message + } + } +} + +InitialSetup + +##################################################################### +# Global Variables +##################################################################### + +$port = 1556 +$basepath = "https://" + $nbmaster + ":" + $port + "/netbackup" +$content_type1 = "application/vnd.netbackup+json;version=1.0" +$content_type2 = "application/vnd.netbackup+json;version=2.0" +$content_type3 = "application/vnd.netbackup+json;version=3.0" + +##################################################################### +# Login +##################################################################### + +$uri = $basepath + "/login" + +$body = @{ + userName=$username + password=$password +} + +$response = Invoke-WebRequest ` + -Uri $uri ` + -Method POST ` + -Body (ConvertTo-Json -InputObject $body) ` + -ContentType $content_type1 + +if ($response.StatusCode -ne 201) +{ + throw "Unable to connect to the Netbackup master server!" +} +Write-Host "Login successful.`n" +$content = (ConvertFrom-Json -InputObject $response) + +##################################################################### +# POST Delete replication target on disk volume level with specified details. +##################################################################### + +$headers = @{ + "Authorization" = $content.token +} + +$sts_uri = $basepath + "/storage/storage-servers" + $stsid + "/disk-volumes/" + dvid + "/replication-targets" + +$json = '{ +{ + "data": { + "type": "volumeReplicationTarget", + "attributes": { + "operationType": "DELETE_REPLICATION", + "targetVolumeName": "DISK_VOLUME_NAME", + "targetStorageServerDetails": { + "masterServerName": "TARGET_MASTER_SERVER", + "mediaServerName": "TARGET_MEDIA_SERVER", + "storageServerName": "TARGET_STORAGE_SERVER_NAME", + "storageServerType": "TARGET_STORAGE_SERVER_TYPE", + "credentials": { + "userName": "TARGET_USERID", + "password": "TARGET_PASSWORD" + } + } + } + } +} +} +' + +$response_delete_replication_target_on_dv = Invoke-WebRequest ` + -Uri $sts_uri ` + -Method POST ` + -Body ($json) ` + -ContentType $content_type3 ` + -Headers $headers + +if ($response_delete_replication_target_on_dv.StatusCode -ne 204) +{ + throw "Unable to delete replication target." +} + +Write-Host "Replication target on with the specified details on disk volume is deleted successfully.`n" +echo $response_delete_replication_target_on_dv +Write-Host $response_delete_replication_target_on_dv + +$response_delete_replication_target_on_dv = (ConvertFrom-Json -InputObject $response_create_sts) diff --git a/snippets/powershell/storage/README.md b/snippets/powershell/storage/README.md index 4123fed..b6c6e56 100644 --- a/snippets/powershell/storage/README.md +++ b/snippets/powershell/storage/README.md @@ -37,3 +37,8 @@ Use the following commands to run the PowerShell samples. - `.\Delete-NB-delete-disk-pool.ps1 -nbmaster -username -password -dpid ` - `.\Delete-NB-delete-storage-server.ps1 -nbmaster -username -password -stsid ` - `.\Delete-NB-delete-storage-unit.ps1 -nbmaster -username -password -stu_name ` +- `.\Post-NB-add-replication-target-to-disk-volume.ps1 -nbmaster -username -password -stsid -dvid ` +- `.\Post-NB-delete-replication-target-to-disk-volume.ps1 -nbmaster -username -password -stsid -dvid ` +- `.\Get-NB-replication-targets-to-disk-volume.ps1 -nbmaster -username -password -stsid -dvid ` +- `.\Get-NB-replication-targets-to-disk-volume-by-id.ps1 -nbmaster -username -password -stsid -dvid -reptargetid ` + diff --git a/snippets/python/storage/README.md b/snippets/python/storage/README.md index 04eb6d2..5437051 100644 --- a/snippets/python/storage/README.md +++ b/snippets/python/storage/README.md @@ -31,4 +31,7 @@ Use the following commands to run the python samples. - `python -W ignore patch_disk_pool.py -nbmaster -username -password -payload -dpid [-domainname ]` - `python -W ignore create_storage_server.py -nbmaster -username -password -payload -stsid [-domainname ] [-domaintype ]` - `python -W ignore patch_storage_unit.py -nbmaster -username -password -payload -stu_name [-domainname ] [-domaintype ]` - +- `python -W ignore add_replication_target_on_diskvolume.py -nbmaster -username -password -payload -stsid -dvid [-domainname ] [-domaintype ]` +- `python -W ignore get_all_replication_targets_on_diskvolume.py -nbmaster -username -password -stsid -dvid [-domainname ] [-domaintype ]` +- `python -W ignore get_replication_target_by_id_on_diskvolume.py -nbmaster -username -password -stsid -dvid -reptargetid [-domainname ] [-domaintype ]` +- `python -W ignore delete_replication_target_on_diskvolume.py -nbmaster -username -password -payload -stsid -dvid [-domainname ] [-domaintype ]` diff --git a/snippets/python/storage/add_replication_target_on_diskvolume.py b/snippets/python/storage/add_replication_target_on_diskvolume.py new file mode 100644 index 0000000..be41cf3 --- /dev/null +++ b/snippets/python/storage/add_replication_target_on_diskvolume.py @@ -0,0 +1,85 @@ +import os +import sys +import storage +import json +import texttable as tt + +protocol = "https" +nbmaster = "" +username = "" +password = "" +domainname = "" +domaintype = "" + +port = 1556 + +def print_usage(): + print("Example:") + print("python -W ignore add_replication_target_on_diskvolume.py -nbmaster -username -password -payload -stsid -dvid [-domainname ] [-domaintype ]\n\n\n") + +def read_command_line_arguments(): + if len(sys.argv)%2 == 0: + print_usage() + exit() + + global nbmaster + global username + global password + global domainname + global domaintype + global payload + global stsid + global dvid + + for i in range(1, len(sys.argv), 2): + if sys.argv[i] == "-nbmaster": + nbmaster = sys.argv[i + 1] + elif sys.argv[i] == "-username": + username = sys.argv[i + 1] + elif sys.argv[i] == "-password": + password = sys.argv[i + 1] + elif sys.argv[i] == "-payload": + payload = sys.argv[i + 1] + if os.path.exists(payload): + print + os.path.basename(payload) + elif sys.argv[i] == "-stsid": + stsid = sys.argv[i + 1] + elif sys.argv[i] == "-dvid": + dvid = sys.argv[i + 1] + elif sys.argv[i] == "-domainname": + domainname = sys.argv[i + 1] + elif sys.argv[i] == "-domaintype": + domaintype = sys.argv[i + 1] + else: + print_usage() + exit() + + if nbmaster == "": + print("Please provide the value for 'nbmaster'") + exit() + elif username == "": + print("Please provide the value for 'username'") + exit() + elif password == "": + print("Please provide the value for 'password'") + elif payload == "": + print("Please provide the value for 'payload'") + exit() + elif stsid == "": + print("Please provide the value for 'stsid'") + exit() + elif dvid == "": + print("Please provide the value for 'dvid'") + exit() + +print_usage() + +read_command_line_arguments() + +base_url = protocol + "://" + nbmaster + ":" + str(port) + "/netbackup" + +jwt = storage.perform_login(username, password, base_url, domainname, domaintype) + +storage.add_replication_target_on_diskvolume(jwt, base_url, payload, stsid, dvid) + diff --git a/snippets/python/storage/delete_replication_target_on_diskvolume.py b/snippets/python/storage/delete_replication_target_on_diskvolume.py new file mode 100644 index 0000000..201263c --- /dev/null +++ b/snippets/python/storage/delete_replication_target_on_diskvolume.py @@ -0,0 +1,85 @@ +import os +import sys +import storage +import json +import texttable as tt + +protocol = "https" +nbmaster = "" +username = "" +password = "" +domainname = "" +domaintype = "" + +port = 1556 + +def print_usage(): + print("Example:") + print("python -W ignore delete_replication_target_on_diskvolume.py -nbmaster -username -password -payload -stsid -dvid [-domainname ] [-domaintype ]\n\n\n") + +def read_command_line_arguments(): + if len(sys.argv)%2 == 0: + print_usage() + exit() + + global nbmaster + global username + global password + global domainname + global domaintype + global payload + global stsid + global dvid + + for i in range(1, len(sys.argv), 2): + if sys.argv[i] == "-nbmaster": + nbmaster = sys.argv[i + 1] + elif sys.argv[i] == "-username": + username = sys.argv[i + 1] + elif sys.argv[i] == "-password": + password = sys.argv[i + 1] + elif sys.argv[i] == "-payload": + payload = sys.argv[i + 1] + if os.path.exists(payload): + print + os.path.basename(payload) + elif sys.argv[i] == "-stsid": + stsid = sys.argv[i + 1] + elif sys.argv[i] == "-dvid": + dvid = sys.argv[i + 1] + elif sys.argv[i] == "-domainname": + domainname = sys.argv[i + 1] + elif sys.argv[i] == "-domaintype": + domaintype = sys.argv[i + 1] + else: + print_usage() + exit() + + if nbmaster == "": + print("Please provide the value for 'nbmaster'") + exit() + elif username == "": + print("Please provide the value for 'username'") + exit() + elif password == "": + print("Please provide the value for 'password'") + elif payload == "": + print("Please provide the value for 'payload'") + exit() + elif stsid == "": + print("Please provide the value for 'stsid'") + exit() + elif dvid == "": + print("Please provide the value for 'dvid'") + exit() + +print_usage() + +read_command_line_arguments() + +base_url = protocol + "://" + nbmaster + ":" + str(port) + "/netbackup" + +jwt = storage.perform_login(username, password, base_url, domainname, domaintype) + +storage.delete_replication_target_on_diskvolume(jwt, base_url, payload, stsid, dvid) + diff --git a/snippets/python/storage/get_all_replication_targets_on_diskvolume.py b/snippets/python/storage/get_all_replication_targets_on_diskvolume.py new file mode 100644 index 0000000..d135c10 --- /dev/null +++ b/snippets/python/storage/get_all_replication_targets_on_diskvolume.py @@ -0,0 +1,79 @@ +import os +import sys +import storage +import json +import texttable as tt + +protocol = "https" +nbmaster = "" +username = "" +password = "" +domainname = "" +domaintype = "" + +port = 1556 + +def print_usage(): + print("Example:") + print("python -W ignore get_all_replication_targets_on_diskvolume.py -nbmaster -username -password -stsid -dvid [-domainname ] [-domaintype ]\n\n\n") + +def read_command_line_arguments(): + if len(sys.argv)%2 == 0: + print_usage() + exit() + + global nbmaster + global username + global password + global domainname + global domaintype + global stsid + global dvid + + + for i in range(1, len(sys.argv), 2): + if sys.argv[i] == "-nbmaster": + nbmaster = sys.argv[i + 1] + elif sys.argv[i] == "-username": + username = sys.argv[i + 1] + elif sys.argv[i] == "-password": + password = sys.argv[i + 1] + elif sys.argv[i] == "-stsid": + stsid = sys.argv[i + 1] + elif sys.argv[i] == "-dvid": + dvid = sys.argv[i + 1] + elif sys.argv[i] == "-domainname": + domainname = sys.argv[i + 1] + elif sys.argv[i] == "-domaintype": + domaintype = sys.argv[i + 1] + else: + print_usage() + exit() + + if nbmaster == "": + print("Please provide the value for 'nbmaster'") + exit() + elif username == "": + print("Please provide the value for 'username'") + exit() + elif password == "": + print("Please provide the value for 'password'") + exit() + elif stsid == "": + print("Please provide the value for 'stsid'") + exit() + elif dvid == "": + print("Please provide the value for 'dvid'") + exit() + +print_usage() + +read_command_line_arguments() + +base_url = protocol + "://" + nbmaster + ":" + str(port) + "/netbackup" + +jwt = storage.perform_login(username, password, base_url, domainname, domaintype) + +response = storage.get_all_replication_targets_on_diskvolume(jwt, base_url, stsid, dvid) + +print(response) diff --git a/snippets/python/storage/get_replication_target_by_id_on_diskvolume.py b/snippets/python/storage/get_replication_target_by_id_on_diskvolume.py new file mode 100644 index 0000000..d74751a --- /dev/null +++ b/snippets/python/storage/get_replication_target_by_id_on_diskvolume.py @@ -0,0 +1,85 @@ +import os +import sys +import storage +import json +import texttable as tt + +protocol = "https" +nbmaster = "" +username = "" +password = "" +domainname = "" +domaintype = "" + +port = 1556 + +def print_usage(): + print("Example:") + print("python -W ignore get_replication_target_by_id_on_diskvolume.py -nbmaster -username -password -stsid -dvid -reptargetid [-domainname ] [-domaintype ]\n\n\n") + +def read_command_line_arguments(): + if len(sys.argv)%2 == 0: + print_usage() + exit() + + global nbmaster + global username + global password + global domainname + global domaintype + global stsid + global dvid + global reptargetid + + + for i in range(1, len(sys.argv), 2): + if sys.argv[i] == "-nbmaster": + nbmaster = sys.argv[i + 1] + elif sys.argv[i] == "-username": + username = sys.argv[i + 1] + elif sys.argv[i] == "-password": + password = sys.argv[i + 1] + elif sys.argv[i] == "-stsid": + stsid = sys.argv[i + 1] + elif sys.argv[i] == "-dvid": + dvid = sys.argv[i + 1] + elif sys.argv[i] == "-reptargetid": + reptargetid = sys.argv[i + 1] + elif sys.argv[i] == "-domainname": + domainname = sys.argv[i + 1] + elif sys.argv[i] == "-domaintype": + domaintype = sys.argv[i + 1] + else: + print_usage() + exit() + + if nbmaster == "": + print("Please provide the value for 'nbmaster'") + exit() + elif username == "": + print("Please provide the value for 'username'") + exit() + elif password == "": + print("Please provide the value for 'password'") + exit() + elif stsid == "": + print("Please provide the value for 'stsid'") + exit() + elif dvid == "": + print("Please provide the value for 'dvid'") + exit() + elif reptargetid == "": + print("Please provide the value for 'reptargetid'") + exit() + +print_usage() + +read_command_line_arguments() + +base_url = protocol + "://" + nbmaster + ":" + str(port) + "/netbackup" + +jwt = storage.perform_login(username, password, base_url, domainname, domaintype) + +response = storage.get_replication_target_by_id_on_diskvolume(jwt, base_url, stsid, dvid, reptargetid) + +print(response) diff --git a/snippets/python/storage/storage.py b/snippets/python/storage/storage.py index d86dfa4..5fba99d 100644 --- a/snippets/python/storage/storage.py +++ b/snippets/python/storage/storage.py @@ -1,6 +1,6 @@ import requests -content_type = "application/vnd.netbackup+json; version=3.0" +content_type = "application/vnd.netbackup+json; version=4.0" def perform_login(username, password, base_url, domain_name, domain_type): @@ -281,4 +281,78 @@ def delete_disk_pools(jwt, base_url, dpid): if resp.status_code != 204: raise Exception('DELETE DP with specific ID failed with status code {} and {}'.format(resp.status_code, resp.json())) - print("\nThe DP is deleted with status code: {}\n".format(resp.status_code)) \ No newline at end of file + print("\nThe DP is deleted with status code: {}\n".format(resp.status_code)) + +def add_replication_target_on_diskvolume(jwt, base_url, file_name, stsid, dvid): + # add and delete replication target has same URI, just that the operationType parameter is DELETE_REPLICATION in case of add. + dvid = dvid.split(":",1)[0].encode('utf-8') + url = base_url + "/storage/storage-servers/" + stsid + "/disk-volumes/" + dvid.hex() + "/replication-targets" + + headers = {'Content-Type': content_type, 'Authorization': jwt} + + path = file_name + + req_body = open(path, 'r').read() + + print("performing POST on {}\n".format(url), req_body) + + resp = requests.post(url, headers=headers, data=req_body, verify=False) + + if resp.status_code != 204: + raise Exception('Add replication target on diskvolume API failed with status code {}'.format(resp.status_code)) + + print("\nThe replication target is added with status code: {}\n".format(resp.status_code)) + +def get_all_replication_targets_on_diskvolume(jwt, base_url, stsid, dvid): + dvid = dvid.split(":",1)[0].encode('utf-8') + url = base_url + "/storage/storage-servers/" + stsid + "/disk-volumes/" + dvid.hex() + "/replication-targets" + headers = {'Content-Type': content_type, 'Authorization': jwt} + query_params = { + "page[limit]": 100, #This changes the default page size to 100 + } + + print("performing GET on {}\n".format(url)) + + resp = requests.get(url, headers=headers, params=query_params, verify=False) + + if resp.status_code != 200: + raise Exception('Get all replication targets on a diskvolume API failed with status code {} and {}'.format(resp.status_code, resp.json())) + + return resp.json() + +def get_replication_target_by_id_on_diskvolume(jwt, base_url, stsid, dvid, reptargetid): + dvid = dvid.split(":",1)[0].encode('utf-8') + url = base_url + "/storage/storage-servers/" + stsid + "/disk-volumes/" + dvid.hex() + "/replication-targets/" + reptargetid + headers = {'Content-Type': content_type, 'Authorization': jwt} + query_params = { + } + + print("performing GET on {}\n".format(url)) + + resp = requests.get(url, headers=headers, params=query_params, verify=False) + + if resp.status_code != 200: + raise Exception('Get replication target by specific id on a diskvolume API failed with status code {} and {}'.format(resp.status_code, resp.json())) + + return resp.json() + +def delete_replication_target_on_diskvolume(jwt, base_url, file_name, stsid, dvid): + # add and delete replication target has same URI, just that the operationType parameter is DELETE_REPLICATION in case of add. + dvid = dvid.split(":",1)[0].encode('utf-8') + url = base_url + "/storage/storage-servers/" + stsid + "/disk-volumes/" + dvid.hex() + "/replication-targets" + + headers = {'Content-Type': content_type, 'Authorization': jwt} + + path = file_name + + req_body = open(path, 'r').read() + + print("performing POST on {}\n".format(url), req_body) + + resp = requests.post(url, headers=headers, data=req_body, verify=False) + + if resp.status_code != 204: + raise Exception('Delete replication target on diskvolume API failed with status code {}'.format(resp.status_code)) + + print("\nThe replication target is deleted with status code: {}\n".format(resp.status_code)) + diff --git a/snippets/sample-payloads/storage-samples/add_replication_target_on_diskvolume.json b/snippets/sample-payloads/storage-samples/add_replication_target_on_diskvolume.json new file mode 100644 index 0000000..a371740 --- /dev/null +++ b/snippets/sample-payloads/storage-samples/add_replication_target_on_diskvolume.json @@ -0,0 +1,19 @@ +{ + "data": { + "type": "volumeReplicationTarget", + "attributes": { + "operationType": "SET_REPLICATION", + "targetVolumeName": "DISK_VOLUME_NAME", + "targetStorageServerDetails": { + "masterServerName": "TARGET_MASTER_SERVER", + "mediaServerName": "TARGET_MEDIA_SERVER", + "storageServerName": "TARGET_STORAGE_SERVER_NAME", + "storageServerType": "TARGET_STORAGE_SERVER_TYPE", + "credentials": { + "userName": "TARGET_USERID", + "password": "TARGET_PASSWORD" + } + } + } + } +} diff --git a/snippets/sample-payloads/storage-samples/delete_replication_target_on_diskvolume.json b/snippets/sample-payloads/storage-samples/delete_replication_target_on_diskvolume.json new file mode 100644 index 0000000..f45e773 --- /dev/null +++ b/snippets/sample-payloads/storage-samples/delete_replication_target_on_diskvolume.json @@ -0,0 +1,19 @@ +{ + "data": { + "type": "volumeReplicationTarget", + "attributes": { + "operationType": "DELETE_REPLICATION", + "targetVolumeName": "DISK_VOLUME_NAME", + "targetStorageServerDetails": { + "masterServerName": "TARGET_MASTER_SERVER", + "mediaServerName": "TARGET_MEDIA_SERVER", + "storageServerName": "TARGET_STORAGE_SERVER_NAME", + "storageServerType": "TARGET_STORAGE_SERVER_TYPE", + "credentials": { + "userName": "TARGET_USERID", + "password": "TARGET_PASSWORD" + } + } + } + } +}