diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:54:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:54:28 +0000 |
commit | e6918187568dbd01842d8d1d2c808ce16a894239 (patch) | |
tree | 64f88b554b444a49f656b6c656111a145cbbaa28 /doc/radosgw/swift | |
parent | Initial commit. (diff) | |
download | ceph-b26c4052f3542036551aa9dec9caa4226e456195.tar.xz ceph-b26c4052f3542036551aa9dec9caa4226e456195.zip |
Adding upstream version 18.2.2.upstream/18.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'doc/radosgw/swift')
-rw-r--r-- | doc/radosgw/swift/auth.rst | 82 | ||||
-rw-r--r-- | doc/radosgw/swift/containerops.rst | 341 | ||||
-rw-r--r-- | doc/radosgw/swift/java.rst | 175 | ||||
-rw-r--r-- | doc/radosgw/swift/objectops.rst | 271 | ||||
-rw-r--r-- | doc/radosgw/swift/python.rst | 114 | ||||
-rw-r--r-- | doc/radosgw/swift/ruby.rst | 119 | ||||
-rw-r--r-- | doc/radosgw/swift/serviceops.rst | 76 | ||||
-rw-r--r-- | doc/radosgw/swift/tempurl.rst | 102 | ||||
-rw-r--r-- | doc/radosgw/swift/tutorial.rst | 62 |
9 files changed, 1342 insertions, 0 deletions
diff --git a/doc/radosgw/swift/auth.rst b/doc/radosgw/swift/auth.rst new file mode 100644 index 000000000..12d6b23ff --- /dev/null +++ b/doc/radosgw/swift/auth.rst @@ -0,0 +1,82 @@ +================ + Authentication +================ + +Swift API requests that require authentication must contain an +``X-Storage-Token`` authentication token in the request header. +The token may be retrieved from RADOS Gateway, or from another authenticator. +To obtain a token from RADOS Gateway, you must create a user. For example:: + + sudo radosgw-admin user create --subuser="{username}:{subusername}" --uid="{username}" + --display-name="{Display Name}" --key-type=swift --secret="{password}" --access=full + +For details on RADOS Gateway administration, see `radosgw-admin`_. + +.. _radosgw-admin: ../../../man/8/radosgw-admin/ + +.. note:: + For those used to the Swift API this is implementing the Swift auth v1.0 API, as such + `{username}` above is generally equivalent to a Swift `account` and `{subusername}` + is a user under that account. + +Auth Get +-------- + +To authenticate a user, make a request containing an ``X-Auth-User`` and a +``X-Auth-Key`` in the header. + +Syntax +~~~~~~ + +:: + + GET /auth HTTP/1.1 + Host: swift.radosgwhost.com + X-Auth-User: johndoe + X-Auth-Key: R7UUOLFDI2ZI9PRCQ53K + +Request Headers +~~~~~~~~~~~~~~~ + +``X-Auth-User`` + +:Description: The key RADOS GW username to authenticate. +:Type: String +:Required: Yes + +``X-Auth-Key`` + +:Description: The key associated to a RADOS GW username. +:Type: String +:Required: Yes + + +Response Headers +~~~~~~~~~~~~~~~~ + +The response from the server should include an ``X-Auth-Token`` value. The +response may also contain a ``X-Storage-Url`` that provides the +``{api version}/{account}`` prefix that is specified in other requests +throughout the API documentation. + + +``X-Storage-Token`` + +:Description: The authorization token for the ``X-Auth-User`` specified in the request. +:Type: String + + +``X-Storage-Url`` + +:Description: The URL and ``{api version}/{account}`` path for the user. +:Type: String + +A typical response looks like this:: + + HTTP/1.1 204 No Content + Date: Mon, 16 Jul 2012 11:05:33 GMT + Server: swift + X-Storage-Url: https://swift.radosgwhost.com/v1/ACCT-12345 + X-Auth-Token: UOlCCC8TahFKlWuv9DB09TWHF0nDjpPElha0kAa + Content-Length: 0 + Content-Type: text/plain; charset=UTF-8 diff --git a/doc/radosgw/swift/containerops.rst b/doc/radosgw/swift/containerops.rst new file mode 100644 index 000000000..434b90ef5 --- /dev/null +++ b/doc/radosgw/swift/containerops.rst @@ -0,0 +1,341 @@ +====================== + Container Operations +====================== + +A container is a mechanism for storing data objects. An account may +have many containers, but container names must be unique. This API enables a +client to create a container, set access controls and metadata, +retrieve a container's contents, and delete a container. Since this API +makes requests related to information in a particular user's account, all +requests in this API must be authenticated unless a container's access control +is deliberately made publicly accessible (i.e., allows anonymous requests). + +.. note:: The Amazon S3 API uses the term 'bucket' to describe a data container. + When you hear someone refer to a 'bucket' within the Swift API, the term + 'bucket' may be construed as the equivalent of the term 'container.' + +One facet of object storage is that it does not support hierarchical paths +or directories. Instead, it supports one level consisting of one or more +containers, where each container may have objects. The RADOS Gateway's +Swift-compatible API supports the notion of 'pseudo-hierarchical containers,' +which is a means of using object naming to emulate a container (or directory) +hierarchy without actually implementing one in the storage system. You may +name objects with pseudo-hierarchical names +(e.g., photos/buildings/empire-state.jpg), but container names cannot +contain a forward slash (``/``) character. + + +Create a Container +================== + +To create a new container, make a ``PUT`` request with the API version, account, +and the name of the new container. The container name must be unique, must not +contain a forward-slash (/) character, and should be less than 256 bytes. You +may include access control headers and metadata headers in the request. The +operation is idempotent; that is, if you make a request to create a container +that already exists, it will return with a HTTP 202 return code, but will not +create another container. + + +Syntax +~~~~~~ + +:: + + PUT /{api version}/{account}/{container} HTTP/1.1 + Host: {fqdn} + X-Auth-Token: {auth-token} + X-Container-Read: {comma-separated-uids} + X-Container-Write: {comma-separated-uids} + X-Container-Meta-{key}: {value} + + +Headers +~~~~~~~ + +``X-Container-Read`` + +:Description: The user IDs with read permissions for the container. +:Type: Comma-separated string values of user IDs. +:Required: No + +``X-Container-Write`` + +:Description: The user IDs with write permissions for the container. +:Type: Comma-separated string values of user IDs. +:Required: No + +``X-Container-Meta-{key}`` + +:Description: A user-defined meta data key that takes an arbitrary string value. +:Type: String +:Required: No + + +HTTP Response +~~~~~~~~~~~~~ + +If a container with the same name already exists, and the user is the +container owner then the operation will succeed. Otherwise the operation +will fail. + +``409`` + +:Description: The container already exists under a different user's ownership. +:Status Code: ``BucketAlreadyExists`` + + + + +List a Container's Objects +========================== + +To list the objects within a container, make a ``GET`` request with the +API version, account, and the name of the container. You can specify query +parameters to filter the full list, or leave out the parameters to return a list +of the first 10,000 object names stored in the container. + + +Syntax +~~~~~~ + +:: + + GET /{api version}/{container} HTTP/1.1 + Host: {fqdn} + X-Auth-Token: {auth-token} + + +Parameters +~~~~~~~~~~ + +``format`` + +:Description: Defines the format of the result. +:Type: String +:Valid Values: ``json`` | ``xml`` +:Required: No + +``prefix`` + +:Description: Limits the result set to objects beginning with the specified prefix. +:Type: String +:Required: No + +``marker`` + +:Description: Returns a list of results greater than the marker value. +:Type: String +:Required: No + +``limit`` + +:Description: Limits the number of results to the specified value. +:Type: Integer +:Valid Range: 0 - 10,000 +:Required: No + +``delimiter`` + +:Description: The delimiter between the prefix and the rest of the object name. +:Type: String +:Required: No + +``path`` + +:Description: The pseudo-hierarchical path of the objects. +:Type: String +:Required: No + +``allow_unordered`` + +:Description: Allows the results to be returned unordered to reduce computation overhead. Cannot be used with ``delimiter``. +:Type: Boolean +:Required: No +:Non-Standard Extension: Yes + + +Response Entities +~~~~~~~~~~~~~~~~~ + +``container`` + +:Description: The container. +:Type: Container + +``object`` + +:Description: An object within the container. +:Type: Container + +``name`` + +:Description: The name of an object within the container. +:Type: String + +``hash`` + +:Description: A hash code of the object's contents. +:Type: String + +``last_modified`` + +:Description: The last time the object's contents were modified. +:Type: Date + +``content_type`` + +:Description: The type of content within the object. +:Type: String + + + +Update a Container's ACLs +========================= + +When a user creates a container, the user has read and write access to the +container by default. To allow other users to read a container's contents or +write to a container, you must specifically enable the user. +You may also specify ``*`` in the ``X-Container-Read`` or ``X-Container-Write`` +settings, which effectively enables all users to either read from or write +to the container. Setting ``*`` makes the container public. That is it +enables anonymous users to either read from or write to the container. + +.. note:: If you are planning to expose public read ACL functionality + for the Swift API, it is strongly recommended to include the + Swift account name in the endpoint definition, so as to most + closely emulate the behavior of native OpenStack Swift. To + do so, set the ``ceph.conf`` configuration option ``rgw + swift account in url = true``, and update your Keystone + endpoint to the URL suffix ``/v1/AUTH_%(tenant_id)s`` + (instead of just ``/v1``). + + +Syntax +~~~~~~ + +:: + + POST /{api version}/{account}/{container} HTTP/1.1 + Host: {fqdn} + X-Auth-Token: {auth-token} + X-Container-Read: * + X-Container-Write: {uid1}, {uid2}, {uid3} + +Request Headers +~~~~~~~~~~~~~~~ + +``X-Container-Read`` + +:Description: The user IDs with read permissions for the container. +:Type: Comma-separated string values of user IDs. +:Required: No + +``X-Container-Write`` + +:Description: The user IDs with write permissions for the container. +:Type: Comma-separated string values of user IDs. +:Required: No + + +Add/Update Container Metadata +============================= + +To add metadata to a container, make a ``POST`` request with the API version, +account, and container name. You must have write permissions on the +container to add or update metadata. + +Syntax +~~~~~~ + +:: + + POST /{api version}/{account}/{container} HTTP/1.1 + Host: {fqdn} + X-Auth-Token: {auth-token} + X-Container-Meta-Color: red + X-Container-Meta-Taste: salty + +Request Headers +~~~~~~~~~~~~~~~ + +``X-Container-Meta-{key}`` + +:Description: A user-defined meta data key that takes an arbitrary string value. +:Type: String +:Required: No + + +Enable Object Versioning for a Container +======================================== + +To enable object versioning a container, make a ``POST`` request with +the API version, account, and container name. You must have write +permissions on the container to add or update metadata. + +.. note:: Object versioning support is not enabled in radosgw by + default; you must set ``rgw swift versioning enabled = + true`` in ``ceph.conf`` to enable this feature. + +Syntax +~~~~~~ + +:: + + POST /{api version}/{account}/{container} HTTP/1.1 + Host: {fqdn} + X-Auth-Token: {auth-token} + X-Versions-Location: {archive-container} + +Request Headers +~~~~~~~~~~~~~~~ + +``X-Versions-Location`` + +:Description: The name of a container (the "archive container") that + will be used to store versions of the objects in the + container that the ``POST`` request is made on (the + "current container"). The archive container need not + exist at the time it is being referenced, but once + ``X-Versions-Location`` is set on the current container, + and object versioning is thus enabled, the archive + container must exist before any further objects are + updated or deleted in the current container. + + .. note:: ``X-Versions-Location`` is the only + versioning-related header that radosgw + interprets. ``X-History-Location``, supported + by native OpenStack Swift, is currently not + supported by radosgw. +:Type: String +:Required: No (if this header is passed with an empty value, object + versioning on the current container is disabled, but the + archive container continues to exist.) + + +Delete a Container +================== + +To delete a container, make a ``DELETE`` request with the API version, account, +and the name of the container. The container must be empty. If you'd like to check +if the container is empty, execute a ``HEAD`` request against the container. Once +you have successfully removed the container, you will be able to reuse the container name. + +Syntax +~~~~~~ + +:: + + DELETE /{api version}/{account}/{container} HTTP/1.1 + Host: {fqdn} + X-Auth-Token: {auth-token} + + +HTTP Response +~~~~~~~~~~~~~ + +``204`` + +:Description: The container was removed. +:Status Code: ``NoContent`` + diff --git a/doc/radosgw/swift/java.rst b/doc/radosgw/swift/java.rst new file mode 100644 index 000000000..8977a3b16 --- /dev/null +++ b/doc/radosgw/swift/java.rst @@ -0,0 +1,175 @@ +.. _java_swift: + +===================== + Java Swift Examples +===================== + +Setup +===== + +The following examples may require some or all of the following Java +classes to be imported: + +.. code-block:: java + + import org.javaswift.joss.client.factory.AccountConfig; + import org.javaswift.joss.client.factory.AccountFactory; + import org.javaswift.joss.client.factory.AuthenticationMethod; + import org.javaswift.joss.model.Account; + import org.javaswift.joss.model.Container; + import org.javaswift.joss.model.StoredObject; + import java.io.File; + import java.io.IOException; + import java.util.*; + + +Create a Connection +=================== + +This creates a connection so that you can interact with the server: + +.. code-block:: java + + String username = "USERNAME"; + String password = "PASSWORD"; + String authUrl = "https://radosgw.endpoint/auth/1.0"; + + AccountConfig config = new AccountConfig(); + config.setUsername(username); + config.setPassword(password); + config.setAuthUrl(authUrl); + config.setAuthenticationMethod(AuthenticationMethod.BASIC); + Account account = new AccountFactory(config).createAccount(); + + +Create a Container +================== + +This creates a new container called ``my-new-container``: + +.. code-block:: java + + Container container = account.getContainer("my-new-container"); + container.create(); + + +Create an Object +================ + +This creates an object ``foo.txt`` from the file named ``foo.txt`` in +the container ``my-new-container``: + +.. code-block:: java + + Container container = account.getContainer("my-new-container"); + StoredObject object = container.getObject("foo.txt"); + object.uploadObject(new File("foo.txt")); + + +Add/Update Object Metadata +========================== + +This adds the metadata key-value pair ``key``:``value`` to the object named +``foo.txt`` in the container ``my-new-container``: + +.. code-block:: java + + Container container = account.getContainer("my-new-container"); + StoredObject object = container.getObject("foo.txt"); + Map<String, Object> metadata = new TreeMap<String, Object>(); + metadata.put("key", "value"); + object.setMetadata(metadata); + + +List Owned Containers +===================== + +This gets a list of Containers that you own. +This also prints out the container name. + +.. code-block:: java + + Collection<Container> containers = account.list(); + for (Container currentContainer : containers) { + System.out.println(currentContainer.getName()); + } + +The output will look something like this:: + + mahbuckat1 + mahbuckat2 + mahbuckat3 + + +List a Container's Content +========================== + +This gets a list of objects in the container ``my-new-container``; and, it also +prints out each object's name, the file size, and last modified date: + +.. code-block:: java + + Container container = account.getContainer("my-new-container"); + Collection<StoredObject> objects = container.list(); + for (StoredObject currentObject : objects) { + System.out.println(currentObject.getName()); + } + +The output will look something like this:: + + myphoto1.jpg + myphoto2.jpg + + +Retrieve an Object's Metadata +============================= + +This retrieves metadata and gets the MIME type for an object named ``foo.txt`` +in a container named ``my-new-container``: + +.. code-block:: java + + Container container = account.getContainer("my-new-container"); + StoredObject object = container.getObject("foo.txt"); + Map<String, Object> returnedMetadata = object.getMetadata(); + for (String name : returnedMetadata.keySet()) { + System.out.println("META / "+name+": "+returnedMetadata.get(name)); + } + + +Retrieve an Object +================== + +This downloads the object ``foo.txt`` in the container ``my-new-container`` +and saves it in ``./outfile.txt``: + +.. code-block:: java + + Container container = account.getContainer("my-new-container"); + StoredObject object = container.getObject("foo.txt"); + object.downloadObject(new File("outfile.txt")); + + +Delete an Object +================ + +This deletes the object ``goodbye.txt`` in the container "my-new-container": + +.. code-block:: java + + Container container = account.getContainer("my-new-container"); + StoredObject object = container.getObject("foo.txt"); + object.delete(); + + +Delete a Container +================== + +This deletes a container named "my-new-container": + +.. code-block:: java + + Container container = account.getContainer("my-new-container"); + container.delete(); + +.. note:: The container must be empty! Otherwise it won't work! diff --git a/doc/radosgw/swift/objectops.rst b/doc/radosgw/swift/objectops.rst new file mode 100644 index 000000000..fc8d21967 --- /dev/null +++ b/doc/radosgw/swift/objectops.rst @@ -0,0 +1,271 @@ +=================== + Object Operations +=================== + +An object is a container for storing data and metadata. A container may +have many objects, but the object names must be unique. This API enables a +client to create an object, set access controls and metadata, retrieve an +object's data and metadata, and delete an object. Since this API makes requests +related to information in a particular user's account, all requests in this API +must be authenticated unless the container or object's access control is +deliberately made publicly accessible (i.e., allows anonymous requests). + + +Create/Update an Object +======================= + +To create a new object, make a ``PUT`` request with the API version, account, +container name and the name of the new object. You must have write permission +on the container to create or update an object. The object name must be +unique within the container. The ``PUT`` request is not idempotent, so if you +do not use a unique name, the request will update the object. However, you may +use pseudo-hierarchical syntax in your object name to distinguish it from +another object of the same name if it is under a different pseudo-hierarchical +directory. You may include access control headers and metadata headers in the +request. + + +Syntax +~~~~~~ + +:: + + PUT /{api version}/{account}/{container}/{object} HTTP/1.1 + Host: {fqdn} + X-Auth-Token: {auth-token} + + +Request Headers +~~~~~~~~~~~~~~~ + +``ETag`` + +:Description: An MD5 hash of the object's contents. Recommended. +:Type: String +:Required: No + + +``Content-Type`` + +:Description: The type of content the object contains. +:Type: String +:Required: No + + +``Transfer-Encoding`` + +:Description: Indicates whether the object is part of a larger aggregate object. +:Type: String +:Valid Values: ``chunked`` +:Required: No + + +Copy an Object +============== + +Copying an object allows you to make a server-side copy of an object, so that +you don't have to download it and upload it under another container/name. +To copy the contents of one object to another object, you may make either a +``PUT`` request or a ``COPY`` request with the API version, account, and the +container name. For a ``PUT`` request, use the destination container and object +name in the request, and the source container and object in the request header. +For a ``Copy`` request, use the source container and object in the request, and +the destination container and object in the request header. You must have write +permission on the container to copy an object. The destination object name must be +unique within the container. The request is not idempotent, so if you do not use +a unique name, the request will update the destination object. However, you may +use pseudo-hierarchical syntax in your object name to distinguish the destination +object from the source object of the same name if it is under a different +pseudo-hierarchical directory. You may include access control headers and metadata +headers in the request. + +Syntax +~~~~~~ + +:: + + PUT /{api version}/{account}/{dest-container}/{dest-object} HTTP/1.1 + X-Copy-From: {source-container}/{source-object} + Host: {fqdn} + X-Auth-Token: {auth-token} + + +or alternatively: + +:: + + COPY /{api version}/{account}/{source-container}/{source-object} HTTP/1.1 + Destination: {dest-container}/{dest-object} + +Request Headers +~~~~~~~~~~~~~~~ + +``X-Copy-From`` + +:Description: Used with a ``PUT`` request to define the source container/object path. +:Type: String +:Required: Yes, if using ``PUT`` + + +``Destination`` + +:Description: Used with a ``COPY`` request to define the destination container/object path. +:Type: String +:Required: Yes, if using ``COPY`` + + +``If-Modified-Since`` + +:Description: Only copies if modified since the date/time of the source object's ``last_modified`` attribute. +:Type: Date +:Required: No + + +``If-Unmodified-Since`` + +:Description: Only copies if not modified since the date/time of the source object's ``last_modified`` attribute. +:Type: Date +:Required: No + +``Copy-If-Match`` + +:Description: Copies only if the ETag in the request matches the source object's ETag. +:Type: ETag. +:Required: No + + +``Copy-If-None-Match`` + +:Description: Copies only if the ETag in the request does not match the source object's ETag. +:Type: ETag. +:Required: No + + +Delete an Object +================ + +To delete an object, make a ``DELETE`` request with the API version, account, +container and object name. You must have write permissions on the container to delete +an object within it. Once you have successfully deleted the object, you will be able to +reuse the object name. + +Syntax +~~~~~~ + +:: + + DELETE /{api version}/{account}/{container}/{object} HTTP/1.1 + Host: {fqdn} + X-Auth-Token: {auth-token} + + +Get an Object +============= + +To retrieve an object, make a ``GET`` request with the API version, account, +container and object name. You must have read permissions on the container to +retrieve an object within it. + +Syntax +~~~~~~ + +:: + + GET /{api version}/{account}/{container}/{object} HTTP/1.1 + Host: {fqdn} + X-Auth-Token: {auth-token} + + + +Request Headers +~~~~~~~~~~~~~~~ + +``range`` + +:Description: To retrieve a subset of an object's contents, you may specify a byte range. +:Type: Date +:Required: No + + +``If-Modified-Since`` + +:Description: Only copies if modified since the date/time of the source object's ``last_modified`` attribute. +:Type: Date +:Required: No + + +``If-Unmodified-Since`` + +:Description: Only copies if not modified since the date/time of the source object's ``last_modified`` attribute. +:Type: Date +:Required: No + +``Copy-If-Match`` + +:Description: Copies only if the ETag in the request matches the source object's ETag. +:Type: ETag. +:Required: No + + +``Copy-If-None-Match`` + +:Description: Copies only if the ETag in the request does not match the source object's ETag. +:Type: ETag. +:Required: No + + + +Response Headers +~~~~~~~~~~~~~~~~ + +``Content-Range`` + +:Description: The range of the subset of object contents. Returned only if the range header field was specified in the request + + +Get Object Metadata +=================== + +To retrieve an object's metadata, make a ``HEAD`` request with the API version, +account, container and object name. You must have read permissions on the +container to retrieve metadata from an object within the container. This request +returns the same header information as the request for the object itself, but +it does not return the object's data. + +Syntax +~~~~~~ + +:: + + HEAD /{api version}/{account}/{container}/{object} HTTP/1.1 + Host: {fqdn} + X-Auth-Token: {auth-token} + + + +Add/Update Object Metadata +========================== + +To add metadata to an object, make a ``POST`` request with the API version, +account, container and object name. You must have write permissions on the +parent container to add or update metadata. + + +Syntax +~~~~~~ + +:: + + POST /{api version}/{account}/{container}/{object} HTTP/1.1 + Host: {fqdn} + X-Auth-Token: {auth-token} + +Request Headers +~~~~~~~~~~~~~~~ + +``X-Object-Meta-{key}`` + +:Description: A user-defined meta data key that takes an arbitrary string value. +:Type: String +:Required: No + diff --git a/doc/radosgw/swift/python.rst b/doc/radosgw/swift/python.rst new file mode 100644 index 000000000..0b1f8d0da --- /dev/null +++ b/doc/radosgw/swift/python.rst @@ -0,0 +1,114 @@ +.. _python_swift: + +===================== +Python Swift Examples +===================== + +Create a Connection +=================== + +This creates a connection so that you can interact with the server: + +.. code-block:: python + + import swiftclient + user = 'account_name:username' + key = 'your_api_key' + + conn = swiftclient.Connection( + user=user, + key=key, + authurl='https://objects.dreamhost.com/auth', + ) + + +Create a Container +================== + +This creates a new container called ``my-new-container``: + +.. code-block:: python + + container_name = 'my-new-container' + conn.put_container(container_name) + + +Create an Object +================ + +This creates a file ``hello.txt`` from the file named ``my_hello.txt``: + +.. code-block:: python + + with open('hello.txt', 'r') as hello_file: + conn.put_object(container_name, 'hello.txt', + contents= hello_file.read(), + content_type='text/plain') + + +List Owned Containers +===================== + +This gets a list of containers that you own, and prints out the container name: + +.. code-block:: python + + for container in conn.get_account()[1]: + print(container['name']) + +The output will look something like this:: + + mahbuckat1 + mahbuckat2 + mahbuckat3 + +List a Container's Content +========================== + +This gets a list of objects in the container, and prints out each +object's name, the file size, and last modified date: + +.. code-block:: python + + for data in conn.get_container(container_name)[1]: + print('{0}\t{1}\t{2}'.format(data['name'], data['bytes'], data['last_modified'])) + +The output will look something like this:: + + myphoto1.jpg 251262 2011-08-08T21:35:48.000Z + myphoto2.jpg 262518 2011-08-08T21:38:01.000Z + + +Retrieve an Object +================== + +This downloads the object ``hello.txt`` and saves it in +``./my_hello.txt``: + +.. code-block:: python + + obj_tuple = conn.get_object(container_name, 'hello.txt') + with open('my_hello.txt', 'w') as my_hello: + my_hello.write(obj_tuple[1]) + + +Delete an Object +================ + +This deletes the object ``hello.txt``: + +.. code-block:: python + + conn.delete_object(container_name, 'hello.txt') + +Delete a Container +================== + +.. note:: + + The container must be empty! Otherwise the request won't work! + +.. code-block:: python + + conn.delete_container(container_name) + diff --git a/doc/radosgw/swift/ruby.rst b/doc/radosgw/swift/ruby.rst new file mode 100644 index 000000000..a20b66d88 --- /dev/null +++ b/doc/radosgw/swift/ruby.rst @@ -0,0 +1,119 @@ +.. _ruby_swift: + +===================== + Ruby Swift Examples +===================== + +Create a Connection +=================== + +This creates a connection so that you can interact with the server: + +.. code-block:: ruby + + require 'cloudfiles' + username = 'account_name:user_name' + api_key = 'your_secret_key' + + conn = CloudFiles::Connection.new( + :username => username, + :api_key => api_key, + :auth_url => 'http://objects.dreamhost.com/auth' + ) + + +Create a Container +================== + +This creates a new container called ``my-new-container`` + +.. code-block:: ruby + + container = conn.create_container('my-new-container') + + +Create an Object +================ + +This creates a file ``hello.txt`` from the file named ``my_hello.txt`` + +.. code-block:: ruby + + obj = container.create_object('hello.txt') + obj.load_from_filename('./my_hello.txt') + obj.content_type = 'text/plain' + + + +List Owned Containers +===================== + +This gets a list of Containers that you own, and also prints out +the container name: + +.. code-block:: ruby + + conn.containers.each do |container| + puts container + end + +The output will look something like this:: + + mahbuckat1 + mahbuckat2 + mahbuckat3 + + +List a Container's Contents +=========================== + +This gets a list of objects in the container, and prints out each +object's name, the file size, and last modified date: + +.. code-block:: ruby + + require 'date' # not necessary in the next version + + container.objects_detail.each do |name, data| + puts "#{name}\t#{data[:bytes]}\t#{data[:last_modified]}" + end + +The output will look something like this:: + + myphoto1.jpg 251262 2011-08-08T21:35:48.000Z + myphoto2.jpg 262518 2011-08-08T21:38:01.000Z + + + +Retrieve an Object +================== + +This downloads the object ``hello.txt`` and saves it in +``./my_hello.txt``: + +.. code-block:: ruby + + obj = container.object('hello.txt') + obj.save_to_filename('./my_hello.txt') + + +Delete an Object +================ + +This deletes the object ``goodbye.txt``: + +.. code-block:: ruby + + container.delete_object('goodbye.txt') + + +Delete a Container +================== + +.. note:: + + The container must be empty! Otherwise the request won't work! + +.. code-block:: ruby + + container.delete_container('my-new-container') diff --git a/doc/radosgw/swift/serviceops.rst b/doc/radosgw/swift/serviceops.rst new file mode 100644 index 000000000..a00f3d807 --- /dev/null +++ b/doc/radosgw/swift/serviceops.rst @@ -0,0 +1,76 @@ +==================== + Service Operations +==================== + +To retrieve data about our Swift-compatible service, you may execute ``GET`` +requests using the ``X-Storage-Url`` value retrieved during authentication. + +List Containers +=============== + +A ``GET`` request that specifies the API version and the account will return +a list of containers for a particular user account. Since the request returns +a particular user's containers, the request requires an authentication token. +The request cannot be made anonymously. + +Syntax +~~~~~~ + +:: + + GET /{api version}/{account} HTTP/1.1 + Host: {fqdn} + X-Auth-Token: {auth-token} + + + +Request Parameters +~~~~~~~~~~~~~~~~~~ + +``limit`` + +:Description: Limits the number of results to the specified value. +:Type: Integer +:Required: No + +``format`` + +:Description: Defines the format of the result. +:Type: String +:Valid Values: ``json`` | ``xml`` +:Required: No + + +``marker`` + +:Description: Returns a list of results greater than the marker value. +:Type: String +:Required: No + + + +Response Entities +~~~~~~~~~~~~~~~~~ + +The response contains a list of containers, or returns with an HTTP +204 response code + +``account`` + +:Description: A list for account information. +:Type: Container + +``container`` + +:Description: The list of containers. +:Type: Container + +``name`` + +:Description: The name of a container. +:Type: String + +``bytes`` + +:Description: The size of the container. +:Type: Integer
\ No newline at end of file diff --git a/doc/radosgw/swift/tempurl.rst b/doc/radosgw/swift/tempurl.rst new file mode 100644 index 000000000..41dbb0ccb --- /dev/null +++ b/doc/radosgw/swift/tempurl.rst @@ -0,0 +1,102 @@ +==================== + Temp URL Operations +==================== + +To allow temporary access (for eg for `GET` requests) to objects +without the need to share credentials, temp url functionality is +supported by swift endpoint of radosgw. For this functionality, +initially the value of `X-Account-Meta-Temp-URL-Key` and optionally +`X-Account-Meta-Temp-URL-Key-2` should be set. The Temp URL +functionality relies on a HMAC-SHA1 signature against these secret +keys. + +.. note:: If you are planning to expose Temp URL functionality for the + Swift API, it is strongly recommended to include the Swift + account name in the endpoint definition, so as to most + closely emulate the behavior of native OpenStack Swift. To + do so, set the ``ceph.conf`` configuration option ``rgw + swift account in url = true``, and update your Keystone + endpoint to the URL suffix ``/v1/AUTH_%(tenant_id)s`` + (instead of just ``/v1``). + + +POST Temp-URL Keys +================== + +A ``POST`` request to the Swift account with the required key will set +the secret temp URL key for the account, against which temporary URL +access can be provided to accounts. Up to two keys are supported, and +signatures are checked against both the keys, if present, so that keys +can be rotated without invalidating the temporary URLs. + +.. note:: Native OpenStack Swift also supports the option to set + temporary URL keys at the container level, issuing a + ``POST`` or ``PUT`` request against a container that sets + ``X-Container-Meta-Temp-URL-Key`` or + ``X-Container-Meta-Temp-URL-Key-2``. This functionality is + not supported in radosgw; temporary URL keys can only be set + and used at the account level. + +Syntax +~~~~~~ + +:: + + POST /{api version}/{account} HTTP/1.1 + Host: {fqdn} + X-Auth-Token: {auth-token} + +Request Headers +~~~~~~~~~~~~~~~ + +``X-Account-Meta-Temp-URL-Key`` + +:Description: A user-defined key that takes an arbitrary string value. +:Type: String +:Required: Yes + +``X-Account-Meta-Temp-URL-Key-2`` + +:Description: A user-defined key that takes an arbitrary string value. +:Type: String +:Required: No + + +GET Temp-URL Objects +==================== + +Temporary URL uses a cryptographic HMAC-SHA1 signature, which includes +the following elements: + +#. The value of the Request method, "GET" for instance +#. The expiry time, in format of seconds since the epoch, ie Unix time +#. The request path starting from "v1" onwards + +The above items are normalized with newlines appended between them, +and a HMAC is generated using the SHA-1 hashing algorithm against one +of the Temp URL Keys posted earlier. + +A sample python script to demonstrate the above is given below: + + +.. code-block:: python + + import hmac + from hashlib import sha1 + from time import time + + method = 'GET' + host = 'https://objectstore.example.com/swift' + duration_in_seconds = 300 # Duration for which the url is valid + expires = int(time() + duration_in_seconds) + path = '/v1/your-bucket/your-object' + key = 'secret' + hmac_body = '%s\n%s\n%s' % (method, expires, path) + sig = hmac.new(key, hmac_body, sha1).hexdigest() + rest_uri = "{host}{path}?temp_url_sig={sig}&temp_url_expires={expires}".format( + host=host, path=path, sig=sig, expires=expires) + print(rest_uri) + + # Example Output + # https://objectstore.example.com/swift/v1/your-bucket/your-object?temp_url_sig=ff4657876227fc6025f04fcf1e82818266d022c6&temp_url_expires=1423200992 + diff --git a/doc/radosgw/swift/tutorial.rst b/doc/radosgw/swift/tutorial.rst new file mode 100644 index 000000000..5d2889b19 --- /dev/null +++ b/doc/radosgw/swift/tutorial.rst @@ -0,0 +1,62 @@ +========== + Tutorial +========== + +The Swift-compatible API tutorials follow a simple container-based object +lifecycle. The first step requires you to setup a connection between your +client and the RADOS Gateway server. Then, you may follow a natural +container and object lifecycle, including adding and retrieving object +metadata. See example code for the following languages: + +- `Java`_ +- `Python`_ +- `Ruby`_ + + +.. ditaa:: + + +----------------------------+ +-----------------------------+ + | | | | + | Create a Connection |------->| Create a Container | + | | | | + +----------------------------+ +-----------------------------+ + | + +--------------------------------------+ + | + v + +----------------------------+ +-----------------------------+ + | | | | + | Create an Object |------->| Add/Update Object Metadata | + | | | | + +----------------------------+ +-----------------------------+ + | + +--------------------------------------+ + | + v + +----------------------------+ +-----------------------------+ + | | | | + | List Owned Containers |------->| List a Container's Contents | + | | | | + +----------------------------+ +-----------------------------+ + | + +--------------------------------------+ + | + v + +----------------------------+ +-----------------------------+ + | | | | + | Get an Object's Metadata |------->| Retrieve an Object | + | | | | + +----------------------------+ +-----------------------------+ + | + +--------------------------------------+ + | + v + +----------------------------+ +-----------------------------+ + | | | | + | Delete an Object |------->| Delete a Container | + | | | | + +----------------------------+ +-----------------------------+ + +.. _Java: ../java +.. _Python: ../python +.. _Ruby: ../ruby |