Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python Scripts for Using Netbackup Access Hosts APIs #45

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions recipes/python/config/README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
### NetBackup Hosts Configuration Management API Code Samples
### NetBackup Config API Code Samples

This directory contains Python scripts demonstrating the use of NetBackup Hosts Configuration Management APIs to update exclude list on a NetBackup host.
This directory contains Python scripts demonstrating :
1. The use of NetBackup Hosts Configuration Management APIs to update exclude list on a NetBackup host.
2. The use of NetBackup Access Hosts API to view, add and delete an access-host on a NetBackup master.

#### Disclaimer

These samples are provided only for reference and not meant for production use.

#### Executing the script

Pre-requisites:
####Pre-requisites:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: Missing space between '#' and 'Pre-requisites'

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, prerequisites shouldn't be hyphenated. It's just an ordinary word.

- NetBackup 8.2 or higher
- Python 3.5 or higher
- Python modules: `requests`.

####Usage

#####NetBackup Hosts Configuration Management API
Comment on lines +16 to +18
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: Missing space between '#' and the heading

Use the following command to run the script. The command should be run from the parent directory of this 'config' directory.

`python -W ignore -m config.hosts_exclude_list -hostName <hostName> -nbmaster <masterServer> -username <username> -password <password> [-domainName <domainName>] [-domainType <domainType>]`

`Note: hostName is the name of the NetBackup host to set the exclude configuration. The exclude list is specified in the config/exclude_list file.`

#####NetBackup Access Hosts API
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: Missing space between '#' and the heading

Use the following command to run the script. The command should be run from the parent directory of this 'config' directory.

`python -W ignore -m config.access_hosts_api_usecases -hostName <hostName> -nbmaster <masterServer> -username <username> -password <password> [-domainName <domainName>] [-domainType <domainType>]`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What warnings need to be ignored in this script? Why not fix the warnings?


`Note: hostName is the name of the VMware Access host to add/delete using the Access Host APIs.`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why specifically mention VMware Access Host?


24 changes: 24 additions & 0 deletions recipes/python/config/access_hosts_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import requests

vmware_access_hosts_url = "/config/vmware/access-hosts/"
content_type_header = "application/vnd.netbackup+json;version=3.0"
accept_header = "application/vnd.netbackup+json;version=3.0"

def get_access_hosts(base_url, jwt, filter):
headers = {'Accept': accept_header, 'Authorization': jwt}
long_url = base_url + vmware_access_hosts_url + filter
response = requests.get(long_url, headers=headers, verify=False)
return response

def add_access_host(base_url, jwt, hostName):
headers = {'Content-Type': content_type_header, 'Authorization': jwt}
long_url = base_url + vmware_access_hosts_url
data = {'data':{'type':'accessHostRequest', 'id':'vmware', 'attributes':{'hostname':hostName, 'validate': 'false'}}}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the validate field really supposed to have the string value "false" and not the Boolean value False?

response = requests.post(long_url, headers=headers, json=data, verify=False)
return response

def delete_access_host(base_url, jwt, hostName):
headers = {'Content-Type': content_type_header, 'Authorization': jwt}
long_url = base_url + vmware_access_hosts_url + hostName
response = requests.delete(long_url, headers=headers, verify=False)
return response
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please include newlines at the ends of the text files.

165 changes: 165 additions & 0 deletions recipes/python/config/access_hosts_api_usecases.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import sys
import login.login_api as login_api
import config.access_hosts_api as access_hosts_api

nbmaster = ""
username = ""
password = ""
domainName = ""
domainType = ""
hostName = ""

EXCLUDE_CONFIG_NAME = "Exclude"

def print_disclaimer():
print("\n-------------------------------------------------------------------------------------------------")
print("-- This script requires Python3.5 or higher. --")
print("-- The system where this script is run should have Python 3.5 or higher version installed. --")
print("-------------------------------------------------------------------------------------------------")
print("The script requires 'requests' library to make the API calls.")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's pointless to mention this at run time. If you have the module, then the command will run and you don't need to be reminded that you need a module you already have. If you don't have the module, then the script won't even run, so this line of code wouldn't run anyway.

print("You can install the library using the command: pip install requests")
print("-------------------------------------------------------------------------------------------------")

def print_usage():
print("\nCommand-line usage (should be run from the parent directory of the 'config' directory):")
print("\tpython -W ignore -m config.access_hosts_api_usecases -hostName <hostName> -nbmaster <masterServer> -username <username> -password <password> [-domainName <domainName>] [-domainType <domainType>]")
print("Note: hostName is the name of the VMware Access host to add/delete using the Access Host APIs.\n")
print("-------------------------------------------------------------------------------------------------")

def read_command_line_arguments():
if len(sys.argv)%2 == 0:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use argparse for processing command-line arguments.

print("\nInvalid command!")
print_usage()
exit()

global nbmaster
global username
global password
global domainName
global domainType
global hostName
global workload

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] == "-domainName":
domainName = sys.argv[i + 1]
elif sys.argv[i] == "-domainType":
domainType = sys.argv[i + 1]
elif sys.argv[i] == "-hostName":
hostName = sys.argv[i + 1]
else:
print("\nInvalid command!")
print_usage()
exit()

if nbmaster == "":
print("Please provide the value for 'nbmaster'\n")
exit()
elif username == "":
print("Please provide the value for 'username'\n")
exit()
elif password == "":
print("Please provide the value for 'password'\n")
exit()
elif hostName == "":
print("Using default hostName to 'test_vmwareAccessHost123'\n")
hostName = "test_vmwareAccessHost123"

def parse_access_host_response(response):
global nbmaster
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

global is only necessary when assigning to a variable from a different code block. This function only uses nbmaster.

resp_size = len(response.json()["data"])
if resp_size==0:
print("No Matching Entries Found on {}".format(nbmaster))
else:
print("{} Matching Entries Found on {} : ".format(resp_size, nbmaster))
i = 0;
for host in response.json()["data"]:
i = i+1
Comment on lines +81 to +83
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no need to keep track of i separately. That's what enumerate is for.

Suggested change
i = 0;
for host in response.json()["data"]:
i = i+1
for i, host in enumerate(response.json()["data"], 1):

print ("\t{}. hostName = {}, hostType = {}".format(i, host["id"], host["attributes"]["hostType"]))

def use_case_1(base_url, jwt):
global nbmaster
print("\n-------------------Use Case 1 Start -------------------")
print(" *** Description : Get All VMware Access Hosts on {} ***".format(nbmaster))
print("-------------------------------------------------------")
print("\nCalling GET Access-Hosts API ... ")
response = access_hosts_api.get_access_hosts(base_url, jwt, "")
print("\nParsing GET API response ... ")
parse_access_host_response(response)
print("-------------------Use Case 1 End ---------------------")

def use_case_2(base_url, jwt):
global nbmaster
global hostName
print("\n\n-------------------Use Case 2 Start -------------------")
print(" *** Description : Add VMware Dummy Access Host='{}' on {} ***".format(hostName, nbmaster))
print("-------------------------------------------------------")
print("\nCalling POST Access-Hosts API ... ")
response = access_hosts_api.add_access_host(base_url, jwt, hostName)
if response.status_code != 204:
print("\nAdd Access Host failed with status code {} and {}".format(response.status_code, response.json()))
raise SystemExit("\n\n")
else:
print("Add VMware Access Host successful.")

print("\nCalling GET Access-Hosts API ... ")
response = access_hosts_api.get_access_hosts(base_url, jwt, "")
print("Parsing GET API response ... ")
parse_access_host_response(response)
print("-------------------Use Case 2 End ---------------------")

def use_case_3(base_url, jwt):
global nbmaster
print("\n\n-------------------Use Case 3 Start -------------------")
print(" *** Description : Get All VMware Access Hosts of type 'CLIENT' on {} ***".format(nbmaster))
print("-------------------------------------------------------")
print("\nCalling GET Access-Hosts API with filter: hostType eq 'CLIENT'... ")
response = access_hosts_api.get_access_hosts(base_url, jwt, "?filter=hostType eq 'CLIENT'")
print("Parsing GET API response ... ")
parse_access_host_response(response)
print("-------------------Use Case 3 End ---------------------")


def use_case_4(base_url, jwt):
global nbmaster
global hostName
print("\n\n-------------------Use Case 4 Start -------------------")
print(" *** Description : Delete VMware Dummy Access Host = '{}' on {} ***".format(hostName, nbmaster))
print("-------------------------------------------------------")
print("\nCalling DELETE Access-Hosts API ... ")
response = access_hosts_api.delete_access_host(base_url, jwt, hostName)

if response.status_code != 204:
print("\nDelete Access Host failed with status code {} and {}".format(response.status_code, response.json()))
raise SystemExit("\n\n")
else:
print("Delete VMware Access Host successful.")

print("\nCalling GET Access-Hosts API ... ")
response = access_hosts_api.get_access_hosts(base_url, jwt, "")
print("Parsing GET API response ... ")
parse_access_host_response(response)
print("-------------------Use Case 4 End ---------------------")

print_disclaimer()
print_usage()
read_command_line_arguments()

base_url = "https://" + nbmaster + "/netbackup"

print("\nExecuting the script...")

jwt = login_api.perform_login(base_url, username, password, domainName, domainType)

use_case_1(base_url, jwt)
use_case_2(base_url, jwt)
use_case_3(base_url, jwt)
use_case_4(base_url, jwt)

print("\nScript completed successfully!\n")