Storage Virtualize RESTful API

The Storage Virtualize Representational State Transfer (REST) model application programming interface (API) consists of command targets that are used to create, read, update, and delete system resources. These command targets allow command parameters to pass through unedited to the Storage Virtualize command-line interface, which handles parsing parameter specifications for validity and error reporting. Use Hypertext Transfer Protocol Secure (HTTPS) to successfully communicate with the RESTful API server.

The RESTful API server does not consider transport security (such as SSL), but instead assumes that requests are initiated from a local, secured server. The HTTPS protocol provides privacy through data encryption. The RESTful API provides security by requiring command authentication by using tokens. The token timeout is a user configurable option and the default value is 60 minutes. However, the token timeout value can be viewed and changed by using lssecurity or chsecurity commands.

Uniform Resource Locators (URLs) target different node objects on the system. The HTTPS POST method acts on command targets that are specified in the URL. To make changes or view information about different objects on the system, you must create and send a request to the system. You are required to provide certain elements for the RESTful API server to receive and transform the request into a command, as described in the next section.

Making an HTTPS request

To interact with the system by using the RESTful API, make an HTTPS command request with a valid configuration node URL destination. Open TCP port 7443 and include the keyword rest. For IBM Storage Virtualize for Public Cloud on Amazon Web Services (AWS), you must manually open TCP port 7443 in the AWS security group before you use the RESTful API. The following URL formats are used for all requests:
https://system_ip:7443/rest/v1/target/ID
Where:
  • system_ip is the IP address to which you are sending requests.
  • The port number is always 7443 for the Storage Virtualize RESTful API.
  • rest is a keyword.
  • v1 is version 1 of API.
  • target is the target object of commands, which includes any object IDs, names, and parameters.
  • ID is the object ID.
https://system_ip:7443/rest/v1/command
Where:
  • system_ip is the system IP address, which is the address that is taken by the configuration node of the system.
  • The port number is always 7443 for the Storage Virtualize RESTful API.
  • rest is a keyword.
  • v1 is the version 1 of the API.
  • command is the target command object (such as auth or lseventlog with any parameters).
    The command specification follows this format:
    command_name,method="POST",headers={'parameter_name': 'parameter_value',
    'parameter_name': 'parameter_value',...}
Why we use POST exclusively: All of the Storage Virtualize RESTful API command targets are named after Storage Virtualize commands, with names that already reflect Create, Read, Update, and Delete actions. MK commands make (create) resources, LS commands list (read) resources, CH commands change (update) resources, and RM commands remove (delete) resources. Using HTTP methods on such commands is redundant.

All commands, including LS commands, accept at least one named parameter because the Storage Virtualize RESTful API is POST method only. It implements a convention of appending positional parameters to the URI, and packing named parameters into the request body as JavaScript Object Notation (JSON) strings.

Why we do not use GET: Most HTTP servers reject GET requests with body data. To support GET, means appending named parameters to the URI as a query string. A query string does not support arbitrary data. A valid URI cannot contain white space and other reserved characters that might be present in the data. Therefore, you must URL-encode named parameter data before you append it to the URI. In addition to that inconvenience, the key-value structure of named parameter data must be conveyed in some way. The query string would likely be a URL-encoded JSON object. Supporting the GET method means that parameter data represented in your programming language of choice must pass through two separate encoders before the data is sent as part of an HTTP request.

The more elegant method for the command targets was to adopt POST exclusively.

As mentioned, in addition to the URL and the name of the command target, other information is required in the request line and in the body of the HTTP request that regards the action to take on the specified object. In the request line, include the POST HTTP method. Include any required parameters (such as RAID level or IP address) in the body of the request. For more information, refer to https://<system-ip>:7443/rest/explorer/ for OpenApi explorer guide.

Provide any required parameters as valid JSON in the HTTP body, such as shown in the following example:
{'X-Auth-Username': 'superuser'}

The request is routed to port 7443 on the specified destination (which must be the configuration node of the system), where the request is received by the RESTful API server. The server runs the command, collects any resulting output, then creates an HTTP response like the following example:

Response header
 content-length: 273 
 content-type: application/json;  charset=UTF-8 
 date: Mon,21 Jun 2021 10:47:18 GMT 
 server: nginx 
 strict-transport-security:  max-age=31536000; includeSubDomains
Response body
{
  "key": "value"
}

API limits

To handle the incoming requests from client, the web server is configured with some rate limits so that API does not fail. The API returns 429 HTTP error code to the client if that limit is reached. The following table lists the rate limits that are configured on the web server.

Table 1.
Rate Limit Type Requests
Max active connections per cluster RESTful API 4
Max requests/sec to auth endpoint RESTful API 3
Max requests/sec to command endpoints RESTful API 10
Number of simultaneous CLIs in progress System 1

Authentication overview

Aside from data encryption, the HTTPS server requires authentication of a valid username and password for each API session. Use two authentication header fields to specify your credentials: X-Auth-Username and X-Auth-Password.

The /auth endpoint uses the POST method for authentication request. The /auth endpoint returns JWT(JSON Web Token) authentication token that authenticates every command that a user runs. The JWT token has the token expiry encoded into it.

Initial authentication requires that you POST the authentication target (/auth) with the username and password. The RESTful API server returns a JWT token. The system supports configuring a session between 10 minutes to 2 hours. However, the default single session lasts a maximum of 1 hour. If the maximum allotted time is reached, an error code 403 occurs that indicate the loss of authorization. Also, the token expiry is configurable and can be set between 10 - 120minutes. Use the /auth command target to authorize again with the username and password.

For example, the following command passes the authentication command to target node IP 192.168.10.109 at port 7443:
https://192.168.10.109:7443/rest/v1/auth, method="POST", 
   headers={'X-Auth-Username': 'superuser', 'X-Auth-Password': 'passw0rd'}
The HTTP request that was sent to the API server looks like:

:authority: 192.168.10.109:7443
:method: POST
:path: /rest/v1/auth
:scheme: https
accept: application/json
content-length: 0
x-auth-password: passw0rd
x-auth-username: superuser
Where:
  • The host is directing the HTTP request to the port (7443) and IP address (192.168.10.109) on the system .
  • POST is the only HTTPS method that the Storage Virtualize RESTful API supports
  • rest is a keyword.
  • v1 is the version 1 of the API.
  • /auth is the authentication request command.
  • The accept specifies the content type (application/json).
  • The content length specifies the message size.
  • The x-auth-password and x-auth-username field is used to authenticate and retrieve token.
The successful auth command returns a token similar to the following example:
{"token":
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE2MTg4NDc4ODAsImV4cCI6MTYxODg1
MTQ4MCwianRpIjoiYTMzY2VlYmRkZGM3YmFhOTUwMmZmNGQ5ZmEwMzBhZTIiLCJzdiI6eyJ1c2VyI
joic3VwZXJ1c2VyIn19.1SXD8DoUYY-BO_cjGL9XZSnjTyBSRfp25YSWbr0Y9k5UaQrmz8xtp2XU
TR5l0PZKhqii4eU2AYf7gaTd3kfxWw}

The returned token string can be decoded by using any JWT decode library freely available on the web. The following is the example of the decoded JWT token string:

HEADER:ALGORITHM & TOKEN TYPE
{
  "typ": "JWT",
  "alg": "HS512"
}
PAYLOAD:DATA
{
  "iat": 1618847880,
  "exp": 1618851480,
  "jti": "a33ceebdddc7baa9502ff4d9fa030ae2",
  "sv": {
    "user": "superuser"
  }

}

API authentication management

To authenticate, use the user ID and the authentication (auth) target.

Use the authentication command target (auth) to authenticate by using the POST method. In this process, you provide a username and password through the X-Auth-Username and X-Auth­Password header fields. The beginning of the session is the only instance where you must enter the username and password. Upon successfully entering the username and password, an authentication JWT token is displayed, which has an expiry encoded into it. The token is a base64 encoded string that you include in future commands by using the X-Auth-Token header. The X-Auth-Token header in combination with the JWT authentication token replaces the username and password for each action. The JWT token authorizing hours are user configurable. The token remains authorized only for the configured time even if the token is unused. The default authorized time for the JWT token is one hour. After the configured time is reached, an error code of 403 occurs that indicates the loss of authorization. Use the /auth command target to reauthenticate with the username and password.

The system supports configuring a session between 10 minutes to 2 hours. However, the default single session lasts a maximum of 1 hour. If the maximum allotted time is reached, an error code 403 occurs that indicate the loss of authorization.

REST response

The following example shows the REST response for lsuser command:

[
    {
        "id": "0",
        "name": "superuser",
        "password": "yes",
        "ssh_key": "no",
        "remote": "no",
        "usergrp_id": "0",
        "usergrp_name": "SecurityAdmin",
        "owner_id": "",
        "owner_name": "",
        "locked": "no",
        "password_change_required": "no"
    }
]
The following example shows lsuser command that uses the SSH protocol :
lsuser

The resulting output:


id name password ssh_key remote usergrp_id usergrp_name owner_id owner_name locked password_change_required
0 superuser yes   no      no     0          SecurityAdmin                    no        no

Command target parameters

Refer to https://<system_ip>:7443/rest/explorer/ for OpenApi explorer for command targets parameters.