dropdown menu

POWERVC - API CURL


POWERVC API

API (Application Programming Interface) is an interface or in other words a sort of "software" (combinations of protocols, subroutines...) which receives requests and sends responses to remote servers  and applications. For example a weather application on a mobile phone sends a request regarding the temperature, and the API on the remote server receives this request and sends back a response with the current temperature. APIs are very helpful for developers, as programs can use those automatically and also through the internet as HTTP requests. Some examples for these HTTP calls could be GET, PUT, POST, or DELETE.

PowerVC is built on OpenStack, which is an open-source cloud computing platform. Openstack provides an API, that can be used for writing softwares that manages the cloud. (create servers, stop/start servers, create images etc.) To accomplish these tasks, the software needs to communicate with the OpenStack API. PowerVC in the background also uses these Openstack APIs. If we want to build a new solution on top of PowerVC, we have these options:
- Supported OpenStack APIs - APIs provided by OpenStack and can be used with PowerVC without any modifications.
- Extended OpenStack APIs - APIs provided by OpenStack, but their functions are extended by PowerVC.
- PowerVC APIs - These APIs do not exist in OpenStack and are exclusive to PowerVC.


APIs are available in two formats:
(Preferred by IBM)       https://<ip-hostname>:<service-port>/...
(this one also works)    https://<ip-hostname>/powervc/openstack/<service>/...

https ://<POWERVC>:8774/v2/<TENANTID>/servers
https ://<POWERV>/powervc/openstack/compute/v2/<TENANTID>/servers



All PowerVC ports:
https://www.ibm.com/support/knowledgecenter/en/SSXK2N_1.3.2/com.ibm.powervc.standard.help.doc/powervc_planning_security_firewall_hmc.html

Regarding version numbers /opt/ibm/powervc/powervcrc file can give some idea:
export OS_IDENTITY_API_VERSION=3
export OS_COMPUTE_API_VERSION=2.46
export OS_NETWORK_API_VERSION=2.0
export OS_IMAGE_API_VERSION=2
export OS_VOLUME_API_VERSION=2

--------------------------------------------------------

API CALLS WITH CURL
(for scripting)

One possibility to use API calls is by using the program "curl" from a remote AIX/LINUX machine. curl can send the needed HTTP request to the PowerVC server and if we follow some syntax, we can achieve our task in one line (comparing to python where we need to use small scripts.)

To get any info from PowerVC through API calls (like CPU/RAM settings or stop/start LPAR), we need to go through several steps. First we need to authenticate ourselves on the PowerVC server with a user and password to get a token, and we can use this token for later calls to achieve what we want. (By default a token is valid for 6 hours.)

As writing an API call can get long and complex, in below examples I will use variables (with CAPITAL letters), to make these API calls easier to read.

for example:
POWERVC='<FQDN name of powervc server>'
(it may needed to do export: export POWERVC='<server name>')

During the below examples, I used API calls on an AIX where python with json.tool was installed.
(On linux the greps/awk/sed may not work, so remove those parts from the command and re-write them.)

SHOW DETAILS OF AN LPAR (VM) THROUGH API:

the steps in short:
1. put user and password in json format (either a variable or a file can be used)
2. get a token from PowerVC
3. get tenant id
4. get the VM id (which is the id of the VM in the openstack)
5. show all details of the specified VM


1.  AUTH_JSON

First we need to authenticate with a user and password, and this needs to be done in JSON format. We have 2 possibilities:
 - create a variable (AUTH_JSON) with the needed details (I prefer this one)
- or create a file (auth.json) with the needed details

Variable:
AUTH_JSON='{"auth":{"scope":{"project":{"domain":{"name":"Default"},"name":"ibm-default"}},"identity":{"password":{"user":{"domain":{"name":"Default"},"password":"abcd1234","name":"root"}},"methods":["password"]}}}'

(In the above and below example I used to "root" user with password  "abcd1234", and the project I used is the "ibm-default". The project "ibm-default" exist by default in PowerVC.)

------------------------------------------------------------------
or if we want we can use an auth.json file :
# cat auth.json
{
        "auth": {
                "scope": {
                        "project": {
                                "domain": {
                                        "name": "Default"
                                },
                                "name": "ibm-default"
                        }
                },
                "identity": {
                        "password": {
                                "user": {
                                        "domain": {
                                                "name": "Default"
                                        },
                                        "password": "abcd1234",
                                        "name": "root"
                                }
                        },
                        "methods": [
                                "password"
                        ]
                }
        }
}
------------------------------------------------------------------

2.  GET TOKEN_ID:

We need to request a token, and we will use this token id for later API calls.
($POWERVC AND $AUTH_JSON have been already set earlier.)

TOKEN_ID=`curl -1 -k -s -i -X POST https://$POWERVC:5000/v3/auth/tokens -H "Accept: application/json" -H "Content-Type: application/json" -d $AUTH_JSON | grep X-Subject-Token | cut -d ' ' -f2 | cat -v | sed 's/\^M//'`

the curl options used above:
-1: Use TLSv1.0 or greater
-k : “insecure” mode. Allow insecure server connections when using SSL.
-s: silent mode. Does not show progress bar
-i : show the http headers of the answer. Useful for debugging, but we need this her as the token id will be in the header
-X <GET/PUT/POST> : API requests
-H: http headers added to the request
      Accept: specifies the expected response content format
      Content-Type: specifies the request content format

Token can be found in the header in the line X-Subject-Token (that is why we need -i and we do grep and cut), and ….
…unfortunately curl puts a "^M" character at the end of the output (which echo did not show) so we needed to show this character first with "cat -v" and after remove it with sed.

------------------------------------------------------------------
….. if auth.json file was used:
curl -1 -k -i -X POST https://$POWERVC:5000/v3/auth/tokens -H "Accept: application/json" -H "Content-Type: application/json" -d @auth.json | grep X-Subject-Token | cut -d ' ' -f2
------------------------------------------------------------------


3.  GET TENANT ID:
(get the id of the IBM Default project)

Tenant and Project are the same thing (Openstack is using the term "Tenant" and PowerVC the term "Project".)

TENANT_ID=`curl -1 -k -s -X GET https://$POWERVC:5000/v3/projects -H "X-Auth-Token:$TOKEN_ID" | python -m json.tool | grep -p{ "IBM Default Tenant"| grep -w id | awk -F'"' '{print $4}'`

(originally I used this: curl -1 -k -i -X GET https://$POWERVC:5000/v3/projects -H "X-Auth-Token:$TOKEN_ID")

some comments regarding curl:
-i was not used here, as we don’t need the header (otherwise json.tool could not parse output)
python -m json.tool : that is a tool which comes with python, which formats output to look pretty  (in more lines). (Without this tenant id is there, but in a 1 long line, and hard to grep for that)


4. GET VM_ID

First I put the LPAR name (VM_NAME) in a variable, what we can use in grep, to search for the ID of the needed VM:
VM_NAME=`lsattr -El inet0 -a hostname | awk '{print $2}'`

VM_ID=`curl -1 -k -s -X GET https://$POWERVC:8774/v2/$TENANT_ID/servers -H "Content-Type: application/json" -H "X-Auth-Token:$TOKEN_ID" | python -m json.tool | egrep 'name|id' | sed -n "N;/$VM_NAME/p;"|head -1 |awk -F '"' '{print $4}'`


5. GET VM DETAILS:
Showing all the details of a specific VM ($VM_ID is used), like CPU/RAM settings…..

curl -1 -k -s -X GET https://$POWERVC:8774/v2/$TENANT_ID/servers/$VM_ID -H "Content-Type: application/json" -H "X-Auth-Token:$TOKEN_ID" | python -m json.tool


--------------------------------------------------------


CREATE A VM THROUGH API

1. assign variables to PowerVC server and also the the name of the new VM
2. auth_json
3. token id (which will authorize us to do build/stop/start/delete things).
4. get the id of the tenant
5. Network id (VLAN) of the new server
6. image id which will be used to create VM
7. flavor id which is needed to create VM (it is the compute template which contains CPU and RAM settings for the new VM)
8. adding all these variables to an API_BUILD variable (to have a simpler syntax)
9. with a POST request create a VM


1. VARIABLES:
POWERVC='<fqdn of powervc>'
VM_NEW='<new vm name>'


2. AUTH_JSON
AUTH_JSON='{"auth":{"scope":{"project":{"domain":{"name":"Default"},"name":"deploy"}},"identity":{"password":{"user":{"domain":{"name":"Default"},"password":"abcd1234","name":"api_user"}},"methods":["password"]}}}'


 3. TOKEN ID
TOKEN_ID=`curl -1 -k -s -i -X POST https://$POWERVC:5000/v3/auth/tokens -H "Accept: application/json" -H "Content-Type: application/json" -d $AUTH_JSON | grep X-Subject-Token | cut -d ' ' -f2 | cat -v | sed 's/\^M//'`


4. TENANT ID
TENANT_ID=`curl -1 -k -s -X GET https://$POWERVC:5000/v3/projects -H "X-Auth-Token:$TOKEN_ID" | python -m json.tool | grep -p{ "IBM Default Tenant"| grep -w id | awk -F'"' '{print $4}'`


5. NET_ID (we grep for "prod_vlan", this vlan we created earlier in PowerVC for prod. VMs)
NET_ID=`curl -1 -k -s -X GET https://$POWERVC:9696/v2.0/networks -H "Content-Type: application/json" -H "X-Auth-Token: $TOKEN_ID" | python -m json.tool | grep -p{ "prod_vlan" | grep -w id | awk -F'"' '{print $4}'`


6. IMAGE_ID (we grep for AIX-71, this image was created earlier in PowerVC)
IMAGE_ID=`curl -1 -k -s -X GET https://$POWERVC:9292/v2/images -H "Content-Type: application/json" -H "X-Auth-Token:$TOKEN_ID" |  python -m json.tool | grep -p{  "AIX-71" | grep -w id | awk -F'"' '{print $4}'`


7. FLAVOR_ID (this is the name of the Compute Template we created in PowerVC, here we grep for Prod_VM)
FLAVOR_ID=`curl -1 -k -s -X GET https://$POWERVC:8774/v2/flavors -H "Content-Type: application/json" -H "X-Auth-Token:$TOKEN_ID" | python -m json.tool | egrep 'name|id' | sed -n "N;/Prod_VM/p;"|head -1 |awk -F '"' '{print $4}'`


8. API_BUILD (assigning all the above variables in a correct API syntax to this variable, to have a simpler syntax)
API_BUILD="{\"server\":{\"flavorRef\":\"$FLAVOR_ID\",\"name\":\"$VM_NEW\",\"imageRef\":\"$IMAGE_ID\",\"networks\":[{\"uuid\":\"$NET_ID\"}]}}"


9. Creating a VM: (this is the step where the VM will be created in PowerVC, with all the above parameters)
curl -1 -k -i -X POST https://$POWERVC:8774/v2/$TENANT_ID/servers -H "Content-Type: application/json" -H "X-Auth-Token: $TOKEN_ID" -d $API_BUILD

--------------------------------------------------------

Activation Input through API

If we want to use below Activation Input script in our API call, then the used small script should be encoded to BASE64 format, then we need to add it to a variable, which can be used in the API call:

This Activation Input can be edited in the Image Deployment window:




1. Convert that script to BASE64 format
https://www.base64encode.org/

2. Add it to a variable (it is called BASE_64)
BASE_64='IyEvdXNyL2Jpbi9zaAoKIyBTdXBwb3J0ZWQgTmV0d29yazogdW5peCwgbGFiCmV4cG9ydCBuZXR3b3JrPSd1bml4JwojIFN1cHBvcnRlZCBQdXBwZXQ6ICIiLCBkdCwgcngsIHBjaQpleHBvcnQgcHVwcGV0PSJwY2kiCgpzdGFydHNyYyAtcyBkaGNwY2QKc2xlZXAgNjA='

3. createa new API_BUILD variable (as in the above step 8)
API_BUILD="{\"server\":{\"flavorRef\":\"$FLAVOR_ID\",\"name\":\"$AIX_NAME\",\"imageRef\":\"$IMAGE_ID\",\"networks\":[{\"uuid\":\"$NET_ID\"}],\"user_data\":\"$BASE_64\"}}"

4. create the VM with POST request (the command is the same as in the above step 9)


--------------------------------------------------------

OTHER COMMANDS

LISTING (GET) COMMANDS:

GET VMs:
curl -k -H "X-Auth-Token:$TOKEN_ID" -X GET https://$POWERVC:8774/v2/$TENANT_ID/servers | python -mjson.tool

GET IMAGES:
curl -1 -k -s -X GET https://$POWERVC:9292/v2/images -H "Content-Type: application/json" -H "X-Auth-Token:$TOKEN_ID" |  python -m json.tool

GET NETWORKS:
curl -1 -k -s -X GET https://$POWERVC:9696/v2.0/networks -H "Content-Type: application/json" -H "X-Auth-Token: $TOKEN_ID" | python -m json.tool

GET FLAVORS (Compute Template):
curl -1 -k -s -X GET https://$POWERVC:8774/v2/flavors -H "Content-Type: application/json" -H "X-Auth-Token:$TOKEN_ID"

GET HMCS:
curl -1 -k -s -X GET https://$POWERVC:8774/v2/$TENANT_ID/ibm-hmcs -H "X-Auth-Token:$TOKEN_ID" | python -m json.tool
curl -1 -k -s -X GET https://$POWERVC:8774/v2/$TENANT_ID/ibm-hmcs/detail -H "X-Auth-Token:$TOKEN_ID" | python -m json.tool

GET MAN. SYS. (AND POWERVC):
curl -1 -k -s -X GET https://$POWERVC:8774/v2.1/$TENANT_ID/os-hosts -H "X-Auth-Token:$TOKEN_ID" | python -m json.tool


START/STOP VM:

curl -k -H "Content-Type: application/json" -H "X-Auth-Token:$TOKEN_ID" -X POST -d '{"os-start": null}' https://pvc/powervc/openstack/compute/v2/$TENANT_ID/servers/$VM_ID/action
curl -k -H "Content-Type: application/json" -H "X-Auth-Token:$TOKEN_ID" -X POST -d '{"os-stop": null}' https://pvc/powervc/openstack/compute/v2/$TENANT_ID/servers/$VM_ID/action


UPDATE (PUT) VM DETAILS:

CHANGING VM NAME (to new_aix_1234) in POWERVC:
API_NEW='{"server":{"name":"new_aix_1234"}}'

CHANGING VM NAME + ADDING IP ADDRESS TO A FIELD in POWERVC:
API_NEW='{"server":{"accessIPv4":"111.112.113.114","name":"new_aix_1234"}}'

curl -1 -k -s -X PUT https://$POWERVC:8774/v2/$TENANT_ID/servers/$VM_ID -H "Content-Type: application/json" -H "X-Auth-Token:$TOKEN_ID" -d $API_NEW | python -m json.tool


DELETE COMMANDS:

DELETE VM:
curl -1 -k -i -X DELETE https://$POWERVC:8774/v2/$TENANT_ID/servers/$VM_ID -H "Content-Type: application/json" -H "X-Auth-Token:$TOKEN_ID"



--------------------------------------------------------

Get a token from Openstack

There is an example at Openstack site how to get a token (I did not tested, looks tenant id already should be known)
https://docs.openstack.org/zaqar/pike/user/authentication_tokens.html


curl -X POST https://localhost:5000/v2.0/tokens -d '{"auth":{"passwordCredentials":{"username": "joecool", "password":"coolword"}, "tenantId":"5"}}' -H 'Content-type: application/json'

--------------------------------------------------------




1 comment:

API call said...

API calls are the backbone of modern software development, enabling applications to communicate with external services and retrieve data or trigger specific actions. They facilitate seamless integration, allowing developers to leverage the functionality and resources of APIs, unlocking a world of possibilities and enhancing the capabilities of their own applications.