Print Email PDF

Explore the API with qq raw

Explore the REST API of Qumulo Core, and learn about its URLs, using a command-line utility with easy login.

This approach is most useful if you are trying to learn about the URL structure and responses of the Qumulo Core REST API in preparation of writing your own scripts against the API.

  • If you are writing scripts in Python, use the Python bindings included in the Qumulo API pip package.
    • Python bindings are version-specific; make sure to install the version of the bindings that match your cluster's version using the following command:
      pip install qumulo-api==<version> (i.e., pip install qumulo-api==2.14.5)
  • If you are not writing scripts but want to administer Qumulo Core from the command line, you probably want to use the qq CLI.

A REST-style API is organized as a set of URLs, each of which responds to one or more HTTP verbs such as GET, PUT, POST, PATCH and DELETE. The qq raw command, included with the Qumulo Core CLI tools, allows you to make requests using those verbs to Qumulo URLs and simplifies the authentication that would otherwise be required to issue requests using tools such as "curl." As a convenience, it also allows using URL references that are relative to the local cluster without always specifying a full URL, include a host name, the http: prefix, and so on.

Let’s discover some URLs in the Qumulo REST API URL space. You can use the raw subcommand to issue HTTP requests against various URLs, substituting a Qumulo node's hostname for <hostname>:

To start, try the following command:

qq --host <hostname> raw GET /v1/version
{
"revision_id": "Qumulo Core 2.14.5",
"build_id": "160765.1.18",
"flavor": "release",
"build_date": "2020-01-17T20:41:03Z"
}

Note that we’ve given qq raw an HTTP verb (GET) and a URL that is relative to the specified node. There is no need to supply the prefix, https://hostname, which you would need using other tools.

NOTE: Relative URLs like the one above can be found in the Interactive API Overview page in the UI by clicking API & Tools.

The /v1/version API did not require authentication. Let’s try a URL that does.

qq --hostname <hostname> raw

qumulo.lib.request.RequestError:

Error 401: unknown: Need to log in first to establish credentials.

To log in, we can use the login feature of qq (you will be prompted for a password:

qq --hostname <hostname> login -u admin

qq --hostname <hostname> raw GET /v1/files/quotas/
{"quotas": [
{"id": "2","limit": "52000000000000"}
],
"paging": {"next": "",}
}

Note that the latter request succeeded because the previous qq login command had stored the credentials in a local credential cache.

We can also use HTTP verbs other than GET. When using POST, PUT, or PATCH, the command will wait for input on stdin, which will be included in the request body. For example, we can create a snapshot as follows:

echo '{ "name": "bananagrams", "expiration": "2020-01-02T00:00:00Z" }' | qq --host <hostname> raw POST /v1/snapshots/
{
"created_by_policy": false,
"directory_name": "1814932_bananagrams",
"expiration": "2020-01-02T00:00:00Z",
"id": 1814932,
"name": "bananagrams",
"source_path": "/",
"timestamp": "2020-01-01T18:27:07.279498115Z"
}

To use qq raw effectively, you need to know what URLs to try and what request bodies they expect. Look at the APIs & Tools page in the UI for items that look like this:

Screen_Shot_2018-06-01_at_12.05.33_PM.png

The last line item, /v1/snapshots/:id:, shows the shape of a URL that you can use. The entry on the API & Tools Page will also display elements that are required (or optional) in the JSON request body, if any.

You can also send binary data using qq raw for commands that expect it like PUT /v1/files/:ref:/data. Make sure to specify that you want chunked transfer encoding by using --chunked and that the content type specified is application/octet-stream.

For example, in Linux you can create and copy the contents of a local file to Qumulo like this:

echo '{ "name": "foo", "action": "CREATE_FILE" }' | qq --host <hostname> raw POST /v1/files/%2F/entries/
{"path": "/foo", "name": "foo", "num_links": 1, "type": "FS_FILE_TYPE_FILE", "major_minor_numbers": {"major": 0, "minor": 0}, "symlink_target_type": "FS_FILE_TYPE_UNKNOWN", "file_number": "3", "id": "3", "mode": "0644", "owner": "500", "owner_details": {"id_type": "LOCAL_USER", "id_value": "admin"}, "group": "513", "group_details": {"id_type": "LOCAL_GROUP", "id_value": "Users"}, "blocks": "1", "datablocks": "0", "metablocks": "1", "size": "0", "modification_time": "2020-01-02T22:55:35.524009099Z", "change_time": "2020-01-02T22:55:35.524009099Z", "creation_time": "2020-01-02T22:55:35.524009099Z", "child_count": 0, "extended_attributes": {"read_only": false, "hidden": false, "system": false, "archive": true, "temporary": false, "compressed": false, "not_content_indexed": false, "sparse_file": false}, "directory_entry_hash_policy": null}
qq --host <hostname> --chunked raw --content-type application/octet-stream PUT /v1/files/%2Ffoo/data < ~/foo
{"path": "/foo", "name": "foo", "num_links": 1, "type": "FS_FILE_TYPE_FILE", "major_minor_numbers": {"major": 0, "minor": 0}, "symlink_target_type": "FS_FILE_TYPE_UNKNOWN", "file_number": "3", "id": "3", "mode": "0644", "owner": "500", "owner_details": {"id_type": "LOCAL_USER", "id_value": "admin"}, "group": "513", "group_details": {"id_type": "LOCAL_GROUP", "id_value": "Users"}, "blocks": "1", "datablocks": "1", "metablocks": "1", "size": "100", "modification_time": "2020-01-02T22:55:35.524009099Z", "change_time": "2020-01-02T22:55:35.524009099Z", "creation_time": "2020-01-02T22:55:35.524009099Z", "child_count": 0, "extended_attributes": {"read_only": false, "hidden": false, "system": false, "archive": true, "temporary": false, "compressed": false, "not_content_indexed": false, "sparse_file": false}, "directory_entry_hash_policy": null}
Was this article helpful?
0 out of 0 found this helpful

Comments

0 comments

Please sign in to leave a comment.

Have more questions?
Open a Case
Share it, if you like it.