This use case demonstrates the steps required to create and map a volume to an SDC. The user is prompted for the following:
Each step of the process is divided into its own function.
To keep the code examples concise, input validation is not included. For example, when creating an NVMe host, the script does not check to ensure the host nqn is valid.
After successfully authenticating with PowerFlex Manager, the next step is to get the internal identifier for the storage pool to be used. This function uses the authentication token returned by the authentication function, the user-entered storage pool name, and the user-entered protection domain name.
The response from this API call will contain the id of the storage pool returned by the function. The storage pool id is required when creating the volume.
import requests
import getpass
#Import our PFxM Authentication function
from pfauth import authenticate
import json
import urllib3
def getSPId(pfxm, accessToken, spname, pdname):
#Get Storage Pool id from Storage Pool name
url = f'https://{pfxm}/api/types/StoragePool/instances/action/queryIdByKey'
payload = json.dumps({
"protectionDomainName": f"{pdname}",
"name": f"{spname}"
})
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': f'Bearer {accessToken}'
}
response = requests.post(url, headers=headers, data=payload, verify=False)
spid = response.text
spid = spid.replace('"','')
print(f'The id for storage pool {spname} is {spid}')
return spid
The SDC id can be retrieved using the IP address of the SDC. The SDC IP address is used as input to the function. The function returns the SDC id. The SDC id is required when we map the volume to the SDC.
def getSdcId(pfxm, accessToken, sdcip):
#Get SDC id from SDC IP address
url = f'https://{pfxm}/api/types/Sdc/instances/action/queryIdByKey'
payload = json.dumps({
"ip": f"{sdcip}",
})
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': f'Bearer {accessToken}'
}
response = requests.post(url, headers=headers, data=payload, verify=False)
sdcid = response.text
sdcid = sdcid.replace('"','')
print(f'The id for SDC {sdcip} is {sdcid}')
return sdcid
The input to the addVolume function includes user input and the spid variable returned from the getSPId function. In this example, some parameters are hard coded in the function. For example, the compression method is set to “None.” This function returns the id of the volume that has been created. The volume id is passed to the map volume function.
In this example, we are creating a volume from a medium granularity storage pool, which does not support compression. Therefore, we will set the compressionMethod parameter to None. If we were provisioning a volume from a fine granularity storage pool, which does support compression, we would need to know if compression was enabled on the pool.
def addVolume(pfxm, accessToken, volsize, volname, spid, provtype):
#Create volume API call using user entered information
url = f'https://{pfxm}/api/types/Volume/instances'
payload = json.dumps({
"volumeSizeInKb": f"{volsize}",
"storagePoolId": f"{spid}",
"name": f"{volname}",
"volumeType": f"{provtype}",
"compressionMethod": "None"
})
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': f'Bearer {accessToken}'
}
response = requests.post(url, headers = headers, data = payload, verify = False)
json_object = json.loads(response.text)
volid = str(json_object["id"])
print(f"The id for volume {volname} is {volid}")
return volid
The last function maps the volume using the volume id returned by the addVolume function and the SDC id returned by the getSdcId function.
def mapVolume(pfxm, accessToken, volid, sdcid):
#Map volume to SDC API call.
url = f'https://{pfxm}/api/instances/Volume::{volid}/action/addMappedSdc'
payload = json.dumps({
'sdcId': f'{sdcid}'
})
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': f'Bearer {accessToken}'
}
response = requests.post(url, headers=headers, data=payload, verify=False)
return response
The main section contains the input variables and the calls to each function.
#Prompt user for PowerFlex Manager username and password.
username = input('Enter PowerFlex Manager username:')
password = getpass.getpass('Enter password:')
#Pass variables to the authenticate() function.
accessToken = authenticate(username, password)
#Variables
#PFxM host
pfxm = 'pfmp.powerflex.lab'
#Parameters required to create volume and map to SDC.
pdname = 'PD-1'
spname = 'SP-SSD-1'
volname = 'apivol01'
volsize = '83886080'
provtype = 'ThinProvisioned'
sdcip = '172.102.15.56'
#Call functions
#Pass username and password. Function returns encoded token to be used in other functions.
accessToken = authenticate(username, password)
#Pass storage pool name and protection domain name. Function returns storage pool id
spid = getSPId(spname, pdname)
#Pass size and name of volume, storage pool id, volume type. Function returns id of new volume
volid = addVolume(volsize, volname, spid, provtype)
#Pass ip address of target SDC. Function returns the SDC id
sdcid = getSdcId(sdcip)
#Pass volume id and SDC id to map volume function. Return success code.
mapcode = mapVolume(volid, sdcid)
print(f'Volume {volname} successfully created and mapped to SDC {sdcip}')