Red Hat Training

A Red Hat training course is available for Red Hat Ceph Storage

Chapter 5. Object Gateway Admin API

The Ceph Object Gateway exposes features of the radosgw-admin CLI in a RESTful API too. We recommend using the CLI interface when setting up your Ceph Object Gateway. When you want to manage users, data, quotas and usage, the Ceph Object Gateway’s Admin API provides a RESTful interface that you can integrate with your management platform(s). Typical Admin API features include:

  • Create/Get/Modify/Delete User/Subuser
  • User Capabilities Management
  • Create/Delete Key
  • Get/Trim Usage
  • Bucket Operations

    • Get Bucket Info
    • Check Bucket Index
    • Remove Bucket
    • Link/Unlink Bucket
  • Object Operations
  • Quotas

5.1. Creating an Admin User

To use the Ceph Object Gateway Admin API, you must first:

  1. Create an object gateway user.

    radosgw-admin user create --uid="{user-name}" --display-name="{Display Name}"

    For example:

    radosgw-admin user create --uid="admin-api-user" --display-name="Admin API User"

    The radosgw-admin CLI will return the user. It will look something like this:

    {
        "user_id": "admin-api-user",
        "display_name": "Admin API User",
        "email": "",
        "suspended": 0,
        "max_buckets": 1000,
        "auid": 0,
        "subusers": [],
        "keys": [
            {
                "user": "admin-api-user",
                "access_key": "NRWGT19TWMYOB1YDBV1Y",
                "secret_key": "gr1VEGIV7rxcP3xvXDFCo4UDwwl2YoNrmtRlIAty"
            }
        ],
        "swift_keys": [],
        "caps": [],
        "op_mask": "read, write, delete",
        "default_placement": "",
        "placement_tags": [],
        "bucket_quota": {
            "enabled": false,
            "max_size_kb": -1,
            "max_objects": -1
        },
        "user_quota": {
            "enabled": false,
            "max_size_kb": -1,
            "max_objects": -1
        },
        "temp_url_keys": []
    }
  2. Assign administrative capabilities to the user you create.

    radosgw-admin caps add --uid="{user-name}" --caps="users=*"

    For example:

    radosgw-admin caps add --uid=admin-api-user --caps="users=*"

    The radosgw-admin CLI will return the user. The "caps": will have the capabilities you assigned to the user:

    {
        "user_id": "admin-api-user",
        "display_name": "Admin API User",
        "email": "",
        "suspended": 0,
        "max_buckets": 1000,
        "auid": 0,
        "subusers": [],
        "keys": [
            {
                "user": "admin-api-user",
                "access_key": "NRWGT19TWMYOB1YDBV1Y",
                "secret_key": "gr1VEGIV7rxcP3xvXDFCo4UDwwl2YoNrmtRlIAty"
            }
        ],
        "swift_keys": [],
        "caps": [
            {
                "type": "users",
                "perm": "*"
            }
        ],
        "op_mask": "read, write, delete",
        "default_placement": "",
        "placement_tags": [],
        "bucket_quota": {
            "enabled": false,
            "max_size_kb": -1,
            "max_objects": -1
        },
        "user_quota": {
            "enabled": false,
            "max_size_kb": -1,
            "max_objects": -1
        },
        "temp_url_keys": []
    }

    Now you have a user with administrative privileges.

5.2. Authenticating Requests

Amazon’s S3 service uses the access key and a hash of the request header and the secret key to authenticate the request, which has the benefit of providing an authenticated request (especially large uploads) without SSL overhead.

Most use cases for the S3 API involve using open source S3 clients such as the AmazonS3Client in the Amazon SDK for Java or Python Boto. These libraries do not support the Ceph Object Gateway Admin API. You can subclass and extend these libraries to support the Ceph Admin API. Alternatively, you may create your own Gateway client.

The CephAdminAPI example class in this section illustrates how to create an execute() method that can take request parameters, authenticate the request, call the Ceph Admin API and receive a response. The CephAdminAPI class example is not supported or intended for commercial use. It is for illustrative purposes only. The client code contains five calls to the Ceph Object Gateway to demonstrate CRUD operations:

  • Create a User
  • Get a User
  • Modify a User
  • Create a Subuser
  • Delete a User

To use this example, you will have to get the Apache HTTP Components, unzip the tar file, navigate to its lib directory and copy the contents to the /jre/lib/ext directory of your JAVA_HOME directory (or a classpath of your choosing).

As you examine the CephAdminAPI class example, notice that the execute() method takes an HTTP method, a request path, an optional subresource (null if not specified) and a map of parameters. To execute with subresources (e.g., subuser, key, etc.), you will need to specify the subresource as an argument in the execute() method.

The example method:

  1. Builds a URI.
  2. Builds an HTTP header string.
  3. Instantiates an HTTP request (e.g., PUT, POST, GET, DELETE).
  4. Adds the Date header to the HTTP header string and the request header.
  5. Adds the Authorization header to the HTTP request header.
  6. Instantiates an HTTP client and passes it the instantiated HTTP request.
  7. Makes a request.
  8. Returns a response.

Building the header string is the portion of the process that involves Amazon’s S3 authentication procedure. Specifically, the example method does the following:

  1. Adds a request type (e.g., PUT, POST, GET, DELETE)
  2. Adds the date.
  3. Adds the requestPath.

The request type should be upper case with no leading or trailing white space. If you do not trim white space, authentication will fail. The date MUST be expressed in GMT, or authentication will fail.

The exemplary method does not have any other headers. The Amazon S3 authentication procedure sorts x-amz headers lexicographically. So if you are adding x-amz headers, be sure to add them lexicographically. See S3 Authentication in this guide for additional details. For a more extensive explanation of the Amazon S3 authentication procedure, consult the Signing and Authenticating REST Requests section of Amazon Simple Storage Service documentation.

Once you have built your header string, the next step is to instantiate an HTTP request and pass it the URI. The examplary method uses PUT for creating a user and subuser, GET for getting a user, POST for modifying a user and DELETE for deleting a user.

Once you instantiate a request, add the Date header followed by the Authorization header. Amazon’s S3 authentication uses the standard Authorization header, and has the following structure:

Authorization: AWS {access-key}:{hash-of-header-and-secret}

The CephAdminAPI example class has a base64Sha1Hmac() method, which takes the header string and the secret key for the admin user, and returns a SHA1 HMAC as a base-64 encoded string. Each execute() call will invoke the same line of code to build the Authorization header:

httpRequest.addHeader("Authorization", "AWS " + this.getAccessKey() + ":" + base64Sha1Hmac(headerString.toString(), this.getSecretKey()));

The following CephAdminAPI example class requires you to pass the access key, secret key and an endpoint to the constructor. The class provides accessor methods to change them at runtime.

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.time.ZoneId;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.Header;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.http.client.utils.URIBuilder;

import java.util.Base64;
import java.util.Base64.Encoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.Mac;

import java.util.Map;
import java.util.Iterator;
import java.util.Set;
import java.util.Map.Entry;

public class CephAdminAPI {

	/*
	 * Each call must specify an access key, secret key, endpoint and format.
	 */
	String accessKey;
	String secretKey;
	String endpoint;
	String scheme = "http"; //http only.
	int port = 80;

	/*
	 * A constructor that takes an access key, secret key, endpoint and format.
	 */
	public CephAdminAPI(String accessKey, String secretKey, String endpoint){
		this.accessKey = accessKey;
		this.secretKey = secretKey;
		this.endpoint = endpoint;
	}

	/*
	 * Accessor methods for access key, secret key, endpoint and format.
	 */
	public String getEndpoint(){
		return this.endpoint;
	}

	public void setEndpoint(String endpoint){
		this.endpoint = endpoint;
	}

	public String getAccessKey(){
		return this.accessKey;
	}

	public void setAccessKey(String accessKey){
		this.accessKey = accessKey;
	}

	public String getSecretKey(){
		return this.secretKey;
	}

	public void setSecretKey(String secretKey){
		this.secretKey = secretKey;
	}

	/*
	 * Takes an HTTP Method, a resource and a map of arguments and
	 * returns a CloseableHTTPResponse.
	 */
	public CloseableHttpResponse execute(String HTTPMethod, String resource,
                                        String subresource, Map arguments) {

		String httpMethod = HTTPMethod;
		String requestPath = resource;
		StringBuffer request = new StringBuffer();
		StringBuffer headerString = new StringBuffer();
		HttpRequestBase httpRequest;
		CloseableHttpClient httpclient;
		URI uri;
		CloseableHttpResponse httpResponse = null;

		try {

			uri = new URIBuilder()
				.setScheme(this.scheme)
				.setHost(this.getEndpoint())
				.setPath(requestPath)
				.setPort(this.port)
				.build();


			if (subresource != null){
				uri = new URIBuilder(uri)
					.setCustomQuery(subresource)
					.build();
			}


			for (Iterator iter = arguments.entrySet().iterator();
			iter.hasNext();) {
				Entry entry = (Entry)iter.next();
				uri = new URIBuilder(uri)
					.setParameter(entry.getKey().toString(),
                                 entry.getValue().toString())
					.build();

			}

			request.append(uri);

			headerString.append(HTTPMethod.toUpperCase().trim() + "\n\n\n");

			OffsetDateTime dateTime = OffsetDateTime.now(ZoneId.of("GMT"));
			DateTimeFormatter formatter = DateTimeFormatter.RFC_1123_DATE_TIME;
			String date = dateTime.format(formatter);

			headerString.append(date + "\n");
			headerString.append(requestPath);

			if (HTTPMethod.equalsIgnoreCase("PUT")){
				httpRequest = new HttpPut(uri);
			} else if (HTTPMethod.equalsIgnoreCase("POST")){
				httpRequest = new HttpPost(uri);
			} else if (HTTPMethod.equalsIgnoreCase("GET")){
				httpRequest = new HttpGet(uri);
			} else if (HTTPMethod.equalsIgnoreCase("DELETE")){
				httpRequest = new HttpDelete(uri);
			} else {
				System.err.println("The HTTP Method must be PUT,
				POST, GET or DELETE.");
				throw new IOException();
			}

			httpRequest.addHeader("Date", date);
			httpRequest.addHeader("Authorization", "AWS " + this.getAccessKey()
			+ ":" + base64Sha1Hmac(headerString.toString(),
			this.getSecretKey()));

			httpclient = HttpClients.createDefault();
			httpResponse = httpclient.execute(httpRequest);

		} 	catch  (URISyntaxException e){
			System.err.println("The URI is not formatted properly.");
			e.printStackTrace();
		}  catch (IOException e){
			System.err.println("There was an error making the request.");
			e.printStackTrace();
		}
			return httpResponse;
	}

	/*
	 * Takes a uri and a secret key and returns a base64-encoded
	 * SHA-1 HMAC.
	 */
	public String base64Sha1Hmac(String uri, String secretKey) {
		try {

			byte[] keyBytes = secretKey.getBytes("UTF-8");
			SecretKeySpec signingKey = new SecretKeySpec(keyBytes, "HmacSHA1");

			Mac mac = Mac.getInstance("HmacSHA1");
			mac.init(signingKey);

			byte[] rawHmac = mac.doFinal(uri.getBytes("UTF-8"));

			Encoder base64 = Base64.getEncoder();
			return base64.encodeToString(rawHmac);

		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

}

The subsequent CephAdminAPIClient example illustrates how to instantiate the CephAdminAPI class, build a map of request parameters, and use the execute() method to create, get, update and delete a user.

import java.io.IOException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.HttpEntity;
import org.apache.http.util.EntityUtils;
import java.util.*;


public class CephAdminAPIClient {

	public static void main (String[] args){

		CephAdminAPI adminApi = new CephAdminAPI ("FFC6ZQ6EMIF64194158N",
		                            "Xac39eCAhlTGcCAUreuwe1ZuH5oVQFa51lbEMVoT",
		                            "ceph-client");

		/*
		 * Create a user
		 */
		Map requestArgs = new HashMap();
		requestArgs.put("access", "usage=read, write; users=read, write");
		requestArgs.put("display-name", "New User");
		requestArgs.put("email", "new-user@email.com");
		requestArgs.put("format", "json");
		requestArgs.put("uid", "new-user");

		CloseableHttpResponse response =
			adminApi.execute("PUT", "/admin/user", null, requestArgs);

		System.out.println(response.getStatusLine());
		HttpEntity entity = response.getEntity();

		try {
			System.out.println("\nResponse Content is: "
				+ EntityUtils.toString(entity, "UTF-8") + "\n");
			response.close();
		} catch (IOException e){
			System.err.println ("Encountered an I/O exception.");
			e.printStackTrace();
		}

		/*
		 * Get a user
		 */
		requestArgs = new HashMap();
		requestArgs.put("format", "json");
		requestArgs.put("uid", "new-user");

		response = adminApi.execute("GET", "/admin/user", null, requestArgs);

		System.out.println(response.getStatusLine());
		entity = response.getEntity();

		try {
			System.out.println("\nResponse Content is: "
				+ EntityUtils.toString(entity, "UTF-8") + "\n");
			response.close();
		} catch (IOException e){
			System.err.println ("Encountered an I/O exception.");
			e.printStackTrace();
		}

		/*
		 * Modify a user
		 */
		requestArgs = new HashMap();
		requestArgs.put("display-name", "John Doe");
		requestArgs.put("email", "johndoe@email.com");
		requestArgs.put("format", "json");
		requestArgs.put("uid", "new-user");
		requestArgs.put("max-buckets", "100");

		response = adminApi.execute("POST", "/admin/user", null, requestArgs);

		System.out.println(response.getStatusLine());
		entity = response.getEntity();

		try {
			System.out.println("\nResponse Content is: "
				+ EntityUtils.toString(entity, "UTF-8") + "\n");
			response.close();
		} catch (IOException e){
			System.err.println ("Encountered an I/O exception.");
			e.printStackTrace();
		}


		/*
		 * Create a subuser
		 */
		requestArgs = new HashMap();
		requestArgs.put("format", "json");
		requestArgs.put("uid", "new-user");
		requestArgs.put("subuser", "foobar");

		response = adminApi.execute("PUT", "/admin/user", "subuser", requestArgs);
		System.out.println(response.getStatusLine());
		entity = response.getEntity();

		try {
			System.out.println("\nResponse Content is: "
				+ EntityUtils.toString(entity, "UTF-8") + "\n");
			response.close();
		} catch (IOException e){
			System.err.println ("Encountered an I/O exception.");
			e.printStackTrace();
		}


		/*
		 * Delete a user
		 */
		requestArgs = new HashMap();
		requestArgs.put("format", "json");
		requestArgs.put("uid", "new-user");

		response = adminApi.execute("DELETE", "/admin/user", null, requestArgs);
		System.out.println(response.getStatusLine());
		entity = response.getEntity();

		try {
			System.out.println("\nResponse Content is: "
				+ EntityUtils.toString(entity, "UTF-8") + "\n");
			response.close();
		} catch (IOException e){
			System.err.println ("Encountered an I/O exception.");
			e.printStackTrace();
		}
	}
}

5.3. Admin Operations API

An admin API request will be done on a URI that starts with the configurable 'admin' resource entry point. Authorization for the admin API duplicates the S3 authorization mechanism. Some operations require that the user holds special administrative capabilities. The response entity type (XML or JSON) may be specified as the 'format' option in the request and defaults to JSON if not specified.

5.3.1. Get Usage

Request bandwidth usage information.

caps
usage=read

5.3.1.1. Syntax

GET /admin/usage?format=json HTTP/1.1
Host: {fqdn}

5.3.1.2. Request Parameters

NameDescriptionTypeRequired

uid

The user for which the information is requested.

String.

Yes

start

Date and (optional) time that specifies the start time of the requested data. E.g., 2012-09-25 16:00:00

String

No

end

Date and (optional) time that specifies the end time of the requested data (non-inclusive). E.g., 2012-09-25 16:00:00

String

No

show-entries

Specifies whether data entries should be returned.

Boolean

No

show-summary

Specifies whether data summary should be returned.

Boolean

No

5.3.1.3. Response Entities

If successful, the response contains the requested information.

NameDescriptionType

usage

A container for the usage information.

Container

entries

A container for the usage entries information.

Container

user

A container for the user data information.

Container

owner

The name of the user that owns the buckets.

String

bucket

The bucket name.

String

time

Time lower bound for which data is being specified (rounded to the beginning of the first relevant hour).

String

epoch

The time specified in seconds since 1/1/1970.

String

categories

A container for stats categories.

Container

entry

A container for stats entry.

Container

category

Name of request category for which the stats are provided.

String

bytes_sent

Number of bytes sent by the Ceph Object Gateway.

Integer

bytes_received

Number of bytes received by the Ceph Object Gateway.

Integer

ops

Number of operations.

Integer

successful_ops

Number of successful operations.

Integer

summary

A container for stats summary.

Container

total

A container for stats summary aggregated total.

Container

5.3.2. Trim Usage

Remove usage information. With no dates specified, removes all usage information.

caps
usage=write

5.3.2.1. Syntax

DELETE /admin/usage?format=json HTTP/1.1
Host: {fqdn}

5.3.2.2. Request Parameters

NameDescriptionTypeExampleRequired

uid

The user for which the information is requested.

String

foo_user

No

start

Date and (optional) time that specifies the start time of the requested data.

String

2012-09-25 16:00:00

No

end

Date and (optional) time that specifies the end time of the requested data (none inclusive).

String

2012-09-25 16:00:00

No

remove-all

Required when uid is not specified, in order to acknowledge multi-user data removal.

Boolean

True [False]

No

5.3.3. Get User Information

Get user information.

caps
users=read

5.3.3.1. Syntax

GET /admin/user?format=json HTTP/1.1
Host: {fqdn}

5.3.3.2. Request Parameters

NameDescriptionTypeExampleRequired

uid

The user for which the information is requested.

String

foo_user

Yes

5.3.3.3. Response Entities

If successful, the response contains the user information.

NameDescriptionTypeParent

user

A container for the user data information.

Container

N/A

user_id

The user ID.

String

user

display_name

Display name for the user.

String

user

suspended

True if the user is suspended.

Boolean

user

max_buckets

The maximum number of buckets to be owned by the user.

Integer

user

subusers

Subusers associated with this user account.

Container

user

keys

S3 keys associated with this user account.

Container

user

swift_keys

Swift keys associated with this user account.

Container

user

caps

User capabilities.

Container

user

5.3.3.4. Special Error Responses

None.

5.3.4. Creating a User

Create a new user. By Default, a S3 key pair will be created automatically and returned in the response. If only one of access-key or secret-key is provided, the omitted key will be automatically generated. By default, a generated key is added to the keyring without replacing an existing key pair. If access-key is specified and refers to an existing key owned by the user then it will be modified.

caps
users=write

5.3.4.1. Syntax

PUT /admin/user?format=json HTTP/1.1
Host: {fqdn}

5.3.4.2. Request Parameters

NameDescriptionTypeExampleRequired

uid

The user ID to be created.

String

foo_user

Yes

display-name

The display name of the user to be created.

String

foo user

Yes

email

The email address associated with the user.

String

foo@bar.com

No

key-type

Key type to be generated, options are: swift, s3 (default).

String

s3 [s3]

No

access-key

Specify access key.

String

ABCD0EF12GHIJ2K34LMN

No

secret-key

Specify secret key.

String

0AbCDEFg1h2i34JklM5nop6QrSTUV+WxyzaBC7D8

No

user-caps

User capabilities.

String

usage=read, write; users=read

No

generate-key

Generate a new key pair and add to the existing keyring.

Boolean

True [True]

No

max-buckets

Specify the maximum number of buckets the user can own.

Integer

500 [1000]

No

suspended

Specify whether the user should be suspended.

Boolean

False [False]

No

5.3.4.3. Response Entities

If successful, the response contains the user information.

NameDescriptionTypeParent

user

A container for the user data information.

Container

N/A

user_id

The user ID.

String

user

display_name

Display name for the user.

String

user

suspended

True if the user is suspended.

Boolean

user

max_buckets

The maximum number of buckets to be owned by the user.

Integer

user

subusers

Subusers associated with this user account.

Container

user

keys

S3 keys associated with this user account.

Container

user

swift_keys

Swift keys associated with this user account.

Container

user

caps

User capabilities.

Container

user

5.3.4.4. Special Error Responses

NameDescriptionCode

UserExists

Attempt to create existing user.

409 Conflict

InvalidAccessKey

Invalid access key specified.

400 Bad Request

InvalidKeyType

Invalid key type specified.

400 Bad Request

InvalidSecretKey

Invalid secret key specified.

400 Bad Request

InvalidKeyType

Invalid key type specified.

400 Bad Request

KeyExists

Provided access key exists and belongs to another user.

409 Conflict

EmailExists

Provided email address exists.

409 Conflict

InvalidCap

Attempt to grant invalid admin capability.

400 Bad Request

5.3.5. Modifying a User

Modify a user.

caps
users=write

5.3.5.1. Syntax

POST /admin/user?format=json HTTP/1.1
Host: {fqdn}

5.3.5.2. Request Parameters

NameDescriptionTypeExampleRequired

uid

The user ID to be modified.

String

foo_user

Yes

display-name

The display name of the user to be modified.

String

foo user

No

email

The email address to be associated with the user.

String

foo@bar.com

No

generate-key

Generate a new key pair and add to the existing keyring.

Boolean

True [False]

No

access-key

Specify access key.

String

ABCD0EF12GHIJ2K34LMN

No

secret-key

Specify secret key.

String

0AbCDEFg1h2i34JklM5nop6QrSTUV+WxyzaBC7D8

No

key-type

Key type to be generated, options are: swift, s3 (default).

String

s3

No

user-caps

User capabilities.

String

usage=read, write; users=read

No

max-buckets

Specify the maximum number of buckets the user can own.

Integer

500 [1000]

No

suspended

Specify whether the user should be suspended.

Boolean

False [False]

No

5.3.5.3. Response Entities

If successful, the response contains the user information.

NameDescriptionTypeParent

user

A container for the user data information.

Container

N/A

user_id

The user ID.

String

user

display_name

Display name for the user.

String

user

suspended

True if the user is suspended.

Boolean

user

max_buckets

The maximum number of buckets to be owned by the user.

Integer

user

subusers

Subusers associated with this user account.

Container

user

keys

S3 keys associated with this user account.

Container

user

swift_keys

Swift keys associated with this user account.

Container

user

caps

User capabilities.

Container

user

5.3.5.4. Special Error Responses

NameDescriptionCode

InvalidAccessKey

Invalid access key specified.

400 Bad Request

InvalidKeyType

Invalid key type specified.

400 Bad Request

InvalidSecretKey

Invalid secret key specified.

400 Bad Request

KeyExists

Provided access key exists and belongs to another user.

409 Conflict

EmailExists

Provided email address exists.

409 Conflict

InvalidCap

Attempt to grant invalid admin capability.

400 Bad Request

5.3.6. Removing a User

Remove an existing user.

caps
users=write

5.3.6.1. Syntax

DELETE /admin/user?format=json HTTP/1.1
Host: {fqdn}

5.3.6.2. Request Parameters

NameDescriptionTypeExampleRequired

uid

The user ID to be removed.

String

foo_user

Yes.

purge-data

When specified the buckets and objects belonging to the user will also be removed.

Boolean

True

No

5.3.6.3. Response Entities

None

5.3.6.4. Special Error Responses

None.

5.3.7. Creating a Subuser

Create a new subuser (primarily useful for clients using the Swift API). Note that either gen-subuser or subuser is required for a valid request. Note that in general for a subuser to be useful, it must be granted permissions by specifying access. As with user creation if subuser is specified without secret, then a secret key will be automatically generated.

caps
users=write

5.3.7.1. Syntax

PUT /admin/user?subuser&format=json HTTP/1.1
Host {fqdn}

5.3.7.2. Request Parameters

NameDescriptionTypeExampleRequired

uid

The user ID under which a subuser is to be created.

String

foo_user

Yes

subuser

Specify the subuser ID to be created.

String

sub_foo

Yes (or gen-subuser)

gen-subuser

Specify the subuser ID to be created.

String

sub_foo

Yes (or subuser)

secret-key

Specify secret key.

String

0AbCDEFg1h2i34JklM5nop6QrSTUVWxyzaBC7D8

No

key-type

Key type to be generated, options are: swift (default), s3.

String

swift [swift]

No

access

Set access permissions for sub-user, should be one of read, write, readwrite, full.

String

read

No

generate-secret

Generate the secret key.

Boolean

True [False]

No

5.3.7.3. Response Entities

If successful, the response contains the subuser information.

NameDescriptionTypeParent

subusers

Subusers associated with the user account.

Container

N/A

id

Subuser ID.

String

subusers

permissions

Subuser access to user account.

String

subusers

5.3.7.4. Special Error Responses

NameDescriptionCode

SubuserExists

Specified subuser exists.

409 Conflict

InvalidKeyType

Invalid key type specified.

400 Bad Request

InvalidSecretKey

Invalid secret key specified.

400 Bad Request

InvalidAccess

Invalid subuser access specified.

400 Bad Request

5.3.8. Modifying a Subuser

Modify an existing subuser

caps
users=write

5.3.8.1. Syntax

POST /admin/user?subuser&format=json HTTP/1.1
Host {fqdn}

5.3.8.2. Request Parameters

NameDescriptionTypeExampleRequired

uid

The user ID under which the subuser is to be modified.

String

foo_user

Yes

subuser

The subuser ID to be modified.

String

sub_foo

Yes

generate-secret

Generate a new secret key for the subuser, replacing the existing key.

Boolean

True [False]

No

secret

Specify secret key.

String

0AbCDEFg1h2i34JklM5nop6QrSTUV+WxyzaBC7D8

No

key-type

Key type to be generated, options are: swift (default), s3.

String

swift [swift]

No

access

Set access permissions for sub-user, should be one of read, write, readwrite, full.

String

read

No

5.3.8.3. Response Entities

If successful, the response contains the subuser information.

NameDescriptionTypeParent

subusers

Subusers associated with the user account.

Container

N/A

id

Subuser ID.

String

subusers

permissions

Subuser access to user account.

String

subusers

5.3.8.4. Special Error Responses

NameDescriptionCode

InvalidKeyType

Invalid key type specified.

400 Bad Request

InvalidSecretKey

Invalid secret key specified.

400 Bad Request

InvalidAccess

Invalid subuser access specified.

400 Bad Request

5.3.9. Removing a Subuser

Remove an existing subuser

caps
users=write

5.3.9.1. Syntax

DELETE /admin/user?subuser&format=json HTTP/1.1
Host {fqdn}

5.3.9.2. Request Parameters

NameDescriptionTypeExampleRequired

uid

The user ID under which the subuser is to be removed.

String

foo_user

Yes

subuser

The subuser ID to be removed.

String

sub_foo

Yes

purge-keys

Remove keys belonging to the subuser.

Boolean

True [True]

No

5.3.9.3. Response Entities

None.

5.3.9.4. Special Error Responses

None.

5.3.10. Creating a Key

Create a new key. If a subuser is specified then by default created keys will be swift type. If only one of access-key or secret-key is provided the committed key will be automatically generated, that is if only secret-key is specified then access-key will be automatically generated. By default, a generated key is added to the keyring without replacing an existing key pair. If access-key is specified and refers to an existing key owned by the user then it will be modified. The response is a container listing all keys of the same type as the key created. Note that when creating a swift key, specifying the option access-key will have no effect. Additionally, only one swift key may be held by each user or subuser.

caps
users=write

5.3.10.1. Syntax

PUT /admin/user?key&format=json HTTP/1.1
Host {fqdn}

5.3.10.2. Request Parameters

NameDescriptionTypeExampleRequired

uid

The user ID to receive the new key.

String

foo_user

Yes

subuser

The subuser ID to receive the new key.

String

sub_foo

No

key-type

Key type to be generated, options are: swift, s3 (default).

String

s3 [s3]

No

access-key

Specify the access key.

String

AB01C2D3EF45G6H7IJ8K

No

secret-key

Specify the secret key.

String

0ab/CdeFGhij1klmnopqRSTUv1WxyZabcDEFgHij

No

generate-key

Generate a new key pair and add to the existing keyring.

Boolean

True [True]

No

5.3.10.3. Response Entities

NameDescriptionTypeParent

keys

Keys of type created associated with this user account.

Container

N/A

user

The user account associated with the key.

String

keys

access-key

The access key.

String

keys

secret-key

The secret key

String

keys

5.3.10.4. Special Error Responses

NameDescriptionCode

InvalidAccessKey

Invalid access key specified.

400 Bad Request

InvalidKeyType

Invalid key type specified.

400 Bad Request

InvalidSecretKey

Invalid secret key specified.

400 Bad Request

InvalidKeyType

Invalid key type specified.

400 Bad Request

KeyExists

Provided access key exists and belongs to another user.

409 Conflict

5.3.11. Removing a Key

Remove an existing key.

caps
users=write

5.3.11.1. Syntax

DELETE /admin/user?key&format=json HTTP/1.1
Host {fqdn}

5.3.11.2. Request Parameters

NameDescriptionTypeExampleRequired

access-key

The S3 access key belonging to the S3 key pair to remove.

String

AB01C2D3EF45G6H7IJ8K

Yes

uid

The user to remove the key from.

String

foo_user

No

subuser

The subuser to remove the key from.

String

sub_foo

No

key-type

Key type to be removed, options are: swift, s3. NOTE: Required to remove swift key.

String

swift

No

5.3.11.3. Special Error Responses

None.

5.3.11.4. Response Entities

None.

5.3.12. Getting Bucket Information

Get information about a subset of the existing buckets. If uid is specified without bucket then all buckets beloning to the user will be returned. If bucket alone is specified, information for that particular bucket will be retrieved.

caps
buckets=read

5.3.12.1. Syntax

GET /admin/bucket?format=json HTTP/1.1
Host {fqdn}

5.3.12.2. Request Parameters

NameDescriptionTypeExampleRequired

bucket

The bucket to return info on.

String

foo_bucket

No

uid

The user to retrieve bucket information for.

String

foo_user

No

stats

Return bucket statistics.

Boolean

True [False]

No

5.3.12.3. Response Entities

If successful the request returns a buckets container containing the desired bucket information.

NameDescriptionTypeParent

stats

Per bucket information.

Container

N/A

buckets

Contains a list of one or more bucket containers.

Container

bucket

Container for single bucket information.

Container

buckets

name

The name of the bucket.

String

bucket

pool

The pool the bucket is stored in.

String

bucket

id

The unique bucket ID.

String

bucket

marker

Internal bucket tag.

String

bucket

owner

The user ID of the bucket owner.

String

bucket

usage

Storage usage information.

Container

bucket

index

5.3.12.4. Special Error Responses

NameDescriptionCode

IndexRepairFailed

Bucket index repair failed.

409 Conflict

5.3.13. Checking a Bucket Index

Check the index of an existing bucket. NOTE: to check multipart object accounting with check-objects, fix must be set to True.

caps
buckets=write

5.3.13.1. Syntax

GET /admin/bucket?index&format=json HTTP/1.1
Host {fqdn}

5.3.13.2. Request Parameters

NameDescriptionTypeExampleRequired

bucket

The bucket to return info on.

String

foo_bucket

Yes

check-objects

Check multipart object accounting.

Boolean

True [False]

No

fix

Also fix the bucket index when checking.

Boolean

False [False]

No

5.3.13.3. Response Entities

NameDescriptionType

index

Status of bucket index.

String

5.3.13.4. Special Error Responses

NameDescriptionCode

IndexRepairFailed

Bucket index repair failed.

409 Conflict

5.3.14. Removing a Bucket

Delete an existing bucket.

caps
buckets=write

5.3.14.1. Syntax

DELETE /admin/bucket?format=json HTTP/1.1
Host {fqdn}

5.3.14.2. Request Parameters

NameDescriptionTypeExampleRequired

bucket

The bucket to remove.

String

foo_bucket

Yes

purge-objects

Remove a buckets objects before deletion.

Boolean

True [False]

No

5.3.14.3. Response Entities

None.

5.3.14.4. Special Error Responses

NameDescriptionCode

BucketNotEmpty

Attempted to delete non-empty bucket.

409 Conflict

ObjectRemovalFailed

Unable to remove objects.

409 Conflict

5.3.15. Unlinking a Bucket

caps
buckets=write

5.3.15.1. Syntax

POST /admin/bucket?format=json HTTP/1.1
Host {fqdn}

5.3.15.2. Request Parameters

NameDescriptionTypeExampleRequired

bucket

The bucket to unlink.

String

foo_bucket

Yes

uid

The user ID to unlink the bucket from.

String

foo_user

Yes

5.3.15.3. Response Entities

None.

5.3.15.4. Special Error Responses

NameDescriptionCode

BucketUnlinkFailed

Unable to unlink bucket from specified user.

409 Conflict

5.3.16. Linking a Bucket

caps
buckets=write

5.3.16.1. Syntax

PUT /admin/bucket?format=json HTTP/1.1
Host {fqdn}

5.3.16.2. Request Parameters

NameDescriptionTypeExampleRequired

bucket

The bucket to unlink.

String

foo_bucket

Yes

uid

The user ID to link the bucket to.

String

foo_user

Yes

5.3.16.3. Response Entities

NameDescriptionTypeParent

bucket

Container for single bucket information.

Container

N/A

name

The name of the bucket.

String

bucket

pool

The pool the bucket is stored in.

String

bucket

id

The unique bucket ID.

String

bucket

marker

Internal bucket tag.

String

bucket

owner

The user ID of the bucket owner.

String

bucket

usage

Storage usage information.

Container

bucket

index

Status of bucket index.

String

bucket

5.3.16.4. Special Error Responses

NameDescriptionCode

BucketUnlinkFailed

Unable to unlink bucket from specified user.

409 Conflict

BucketLinkFailed

Unable to link bucket to specified user.

409 Conflict

5.3.17. Removing an Object

Remove an existing object. NOTE: Does not require owner to be non-suspended.

caps
buckets=write

5.3.17.1. Syntax

DELETE /admin/bucket?object&format=json HTTP/1.1
Host {fqdn}

5.3.17.2. Request Parameters

NameDescriptionTypeExampleRequired

bucket

The bucket containing the object to be removed.

String

foo_bucket

Yes

object

The object to remove.

String

foo.txt

Yes

5.3.17.3. Response Entities

None.

5.3.17.4. Special Error Responses

NameDescriptionCode

NoSuchObject

Specified object does not exist.

404 Not Found

ObjectRemovalFailed

Unable to remove objects.

409 Conflict

5.3.18. Getting Bucket or Object Policy

Read the policy of an object or bucket.

caps
buckets=read

5.3.18.1. Syntax

GET /admin/bucket?policy&format=json HTTP/1.1
Host {fqdn}

5.3.18.2. Request Parameters

NameDescriptionTypeExampleRequired

bucket

The bucket to read the policy from.

String

foo_bucket

Yes

object

The object to read the policy from.

String

foo.txt

No

5.3.18.3. Response Entities

If successful, returns the object or bucket policy

|policy | Access control policy.|Container

5.3.18.4. Special Error Responses

NameDescriptionCode

IncompleteBody

Either bucket was not specified for a bucket policy request or bucket and object were not specified for an object policy request.

400 Bad Request

5.3.19. Adding a Capability to an Existing User

Add an administrative capability to a specified user.

caps
users=write

5.3.19.1. Syntax

PUT /admin/user?caps&format=json HTTP/1.1
Host {fqdn}

5.3.19.2. Request Parameters

NameDescriptionTypeExampleRequired

uid

The user ID to add an administrative capability to.

String

foo_user

Yes

user-caps

The administrative capability to add to the user.

String

usage=read, write

Yes

5.3.19.3. Response Entities

If successful, the response contains the user’s capabilities.

NameDescriptionTypeParent

user

A container for the user data information.

Container

N/A

user_id

The user ID.

String

user

caps

User capabilities.

Container

user

5.3.19.4. Special Error Responses

NameDescriptionCode

InvalidCap

Attempt to grant invalid admin capability.

400 Bad Request

5.3.19.5. Example Request

PUT /admin/user?caps&format=json HTTP/1.1
Host: {fqdn}
Content-Type: text/plain
Authorization: {your-authorization-token}

usage=read

5.3.20. Removing a Capability from an Existing User

Remove an administrative capability from a specified user.

caps
users=write

5.3.20.1. Syntax

DELETE /admin/user?caps&format=json HTTP/1.1
Host {fqdn}

5.3.20.2. Request Parameters

NameDescriptionTypeExampleRequired

uid

The user ID to remove an administrative capability from.

String

foo_user

Yes

user-caps

The administrative capabilities to remove from the user.

String

usage=read, write

Yes

5.3.20.3. Response Entities

If successful, the response contains the user’s capabilities.

NameDescriptionTypeParent

user

A container for the user data information.

Container

N/A

user_id

The user ID.

String

user

caps

User capabilities.

Container

user

5.3.20.4. Special Error Responses

NameDescriptionCode

InvalidCap

Attempt to remove an invalid admin capability.

400 Bad Request

NoSuchCap

User does not possess specified capability.

404 Not Found

5.3.20.5. Special Error Responses

None.

5.3.21. Quotas

The Admin Operations API enables you to set quotas on users and on bucket owned by users. See Quota Management for additional details. Quotas include the maximum number of objects in a bucket and the maximum storage size in megabytes.

To view quotas, the user must have a users=read capability. To set, modify or disable a quota, the user must have users=write capability. See the Administration (CLI) for details.

Valid parameters for quotas include:

  • Bucket: The bucket option allows you to specify a quota for buckets owned by a user.
  • Maximum Objects: The max-objects setting allows you to specify the maximum number of objects. A negative value disables this setting.
  • Maximum Size: The max-size option allows you to specify a quota for the maximum number of bytes. A negative value disables this setting.
  • Quota Scope: The quota-scope option sets the scope for the quota. The options are bucket and user.

5.3.21.1. Getting User Quota

To get a quota, the user must have users capability set with read permission.

GET /admin/user?quota&uid=<uid>&quota-type=user

5.3.21.2. Setting User Quota

To set a quota, the user must have users capability set with write permission.

PUT /admin/user?quota&uid=<uid>&quota-type=user

The content must include a JSON representation of the quota settings as encoded in the corresponding read operation.

5.3.21.3. Getting Bucket Quota

To get a quota, the user must have users capability set with read permission.

GET /admin/user?quota&uid=<uid>&quota-type=bucket

5.3.21.4. Setting Bucket Quota

To set a quota, the user must have users capability set with write permission.

PUT /admin/user?quota&uid=<uid>&quota-type=bucket

The content must include a JSON representation of the quota settings as encoded in the corresponding read operation.

5.3.22. Standard Error Responses

NameDescriptionCode

AccessDenied

Access denied.

403 Forbidden

InternalError

Internal server error.

500 Internal Server Error

NoSuchUser

User does not exist.

404 Not Found

NoSuchBucket

Bucket does not exist.

404 Not Found

NoSuchKey

No such access key.

404 Not Found