开发人员指南
为 Red Hat Ceph Storage 使用各种应用程序编程接口
摘要
第 1 章 Ceph 对象网关管理 API
作为开发者,您可以通过与 RESTful 应用编程接口(API)交互来管理 Ceph 对象网关。Ceph 对象网关在 RESTful API 中提供了 radosgw-admin
命令的功能。您可以管理用户、数据、配额和使用,并可与其他管理平台集成。
红帽建议在配置 Ceph 对象网关时使用命令行界面。
管理 API 提供以下功能:
1.1. 先决条件
- 一个正在运行的 Red Hat Ceph Storage 集群。
- RESTful 客户端。
1.2. 管理操作
管理应用程序编程接口(API)请求将在以可配置的"admin"资源入口点开头的 URI 上进行。管理 API 的授权重复了 S3 的授权机制。有些操作需要用户具有特殊的管理功能。响应实体类型(可以是 XML 或 JSON)可指定为请求中的"format"选项,如果未指定,则默认为 JSON。
示例
PUT /admin/user?caps&format=json HTTP/1.1 Host: FULLY_QUALIFIED_DOMAIN_NAME Content-Type: text/plain Authorization: AUTHORIZATION_TOKEN usage=read
1.3. 管理身份验证请求
Amazon 的 S3 服务使用访问密钥和请求标头的哈希和 secret 密钥来验证请求。它有提供经过身份验证的请求(特别是大型上传)的好处,而没有 SSL 开销。
S3 API 的大部分用例都涉及使用开源 S3 客户端,如 Amazon SDK 中用于 Java 或 Python Boto 的 AmazonS3Client
。这些库不支持 Ceph 对象网关管理员 API。您可以子类和扩展这些库来支持 Ceph Admin API。或者,您可以创建唯一的网关客户端。
创建 execute()
方法
本节中的 CephAdminAPI 示例类演示了如何创建 执行()
方法,获取请求参数,对请求进行身份验证,调用 Ceph Admin API 并接收响应。
CephAdminAPI
类示例不受支持或用于商业用途。它只用于演示目的。
调用 Ceph 对象网关
客户端代码 包含对 Ceph 对象网关的五个调用,以演示 CRUD 操作:
- 创建用户
- 获取用户
- 修改用户
- 创建子用户
- 删除用户
要使用此示例,请获取 httpcomponents-client-4.5.3
Apache HTTP 组件。您可以在此处下载该文件:http://hc.apache.org/downloads.cgi。然后解压缩 tar 文件,导航到其 lib
目录,并将内容复制到 JAVA_HOME
目录或自定义类路径的 /jre/lib/ext
目录中。
当您检查 CephAdminAPI 类示例时,请注意 execute()
采用 HTTP 方法、请求路径、可选的子资源、null
(如果未指定),以及参数映射。若要使用 subresources 执行,例如 subuser
、和 key
,您需要在 execute()
方法中指定子资源作为参数。
示例方法:
- 构建 URI。
- 构建 HTTP 标头字符串。
-
实例化 HTTP 请求,如
PUT
、POST
、GET
、DELETE
。 -
在 HTTP 标头字符串和请求标头中添加
Date
标头。 -
在 HTTP 请求标头中添加
Authorization
标头。 - 实例化 HTTP 客户端,并传递实例化的 HTTP 请求。
- 发出请求。
- 返回响应。
构建标头字符串
构建标头字符串是涉及 Amazon 的 S3 身份验证过程的过程的一部分。具体来说,示例方法如下:
-
添加请求类型,如
PUT
、POST
、GET
和DELETE
。 - 添加日期。
- 添加 requestPath。
请求类型应该是大写的,没有前导或尾随空格。如果您不修剪空格,身份验证将失败。日期需要 以 GMT 表示,否则身份验证将失败。
exemplary 方法没有任何其他标头。Amazon S3 身份验证流程按 x-amz
标头顺序排序。因此,如果您要添加 x-amz
标头,确保以字典顺序添加它们。
构建了标头字符串后,下一步是实例化 HTTP 请求并传递 URI。考试卷方法使用 PUT
来创建用户和子用户,GET
用于获取用户,POST
用于修改用户和 DELETE
以删除用户。
实例化了一个请求后,添加 Date
标头后跟 Authorization
标头。Amazon 的 S3 身份验证使用标准 Authorization
标头,且结构如下:
Authorization: AWS ACCESS_KEY:HASH_OF_HEADER_AND_SECRET
CephAdminAPI 示例类具有一个 base64Sha1Hmac()
方法,它采用 admin 用户的标头字符串和 secret 密钥,并将 SHA1 HMAC 作为 base-64 编码字符串返回。每个 execute()
调用都将调用同一行代码来构建 Authorization
标头:
httpRequest.addHeader("Authorization", "AWS " + this.getAccessKey() + ":" + base64Sha1Hmac(headerString.toString(), this.getSecretKey()));
以下 CephAdminAPI
示例类要求您将访问密钥、secret 密钥和端点传递给构造器。class 提供在运行时更改它们的访问器方法。
示例
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); } } }
后续 CephAdminAPIClient
示例演示如何实例化 CephAdminAPI
类,构建请求参数映射,并使用 execute()
方法创建、获取、更新和删除用户。
示例
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(); } } }
其它资源
- 如需了解更多详细信息,请参阅 Red Hat Ceph Storage Developer Guide 中的 S3 身份验证部分。
- 有关 Amazon S3 身份验证流程的更广泛的解释,请参阅 Amazon Simple Storage Service 文档中的 Signing and Authenticating REST Requests 部分。
1.4. 创建管理用户
要从 Ceph 对象网关节点运行 radosgw-admin
命令,请确保节点具有 admin 密钥。admin 密钥可以从任何 Ceph 监控节点复制。
先决条件
- Ceph 对象网关节点的根级别访问权限.
流程
创建对象网关用户:
语法
radosgw-admin user create --uid="USER_NAME" --display-name="DISPLAY_NAME"
示例
[user@client ~]$ radosgw-admin user create --uid="admin-api-user" --display-name="Admin API User"
radosgw-admin
命令行界面将返回用户。输出示例
{ "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": [] }
为您创建的用户分配管理功能:
语法
radosgw-admin caps add --uid="USER_NAME" --caps="users=*"
示例
[user@client ~]$ radosgw-admin caps add --uid=admin-api-user --caps="users=*"
radosgw-admin
命令行界面将返回用户。"caps":
将具有您分配给用户的能力:输出示例
{ "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": [] }
现在,您有有管理特权的用户。
1.5. 获取用户信息
获取用户信息。
功能
users=read
语法
GET /admin/user?format=json HTTP/1.1
Host: FULLY_QUALIFIED_DOMAIN_NAME
名称 | 描述 | Type | 示例 | 必需 |
---|---|---|---|---|
| 请求信息的用户。 | 字符串 |
| 是 |
名称 | 描述 | Type | 父 |
---|---|---|---|
| 用于用户数据信息的容器。 | Container | 不适用 |
| 用户 ID。 | 字符串 |
|
| 显示用户的名称。 | 字符串 |
|
| 如果用户已被挂起,则为 true。 | 布尔值 |
|
| 用户所有的 bucket 的最大数量。 | 整数 |
|
| 与此用户帐户关联的子用户。 | Container |
|
| 与这个用户帐户关联的 S3 密钥。 | Container |
|
| 与此用户帐户关联的 Swift 密钥。 | Container |
|
| 用户能力。 | Container |
|
如果成功,响应将包含用户信息。
特殊错误响应
无。
1.6. 创建用户
创建新用户。默认情况下,将自动创建 S3 密钥对并在响应中返回。如果只提供了 access-key
或 secret-key
中的一个,则会自动生成忽略的密钥。默认情况下,生成的密钥会添加到密钥环中,而不替换现有的密钥对。如果指定了 access-key
,并引用用户拥有的现有密钥,则会修改它。
功能
`users=write`
语法
PUT /admin/user?format=json HTTP/1.1
Host: FULLY_QUALIFIED_DOMAIN_NAME
名称 | 描述 | Type | 示例 | 必需 |
---|---|---|---|---|
| 要创建的用户 ID。 | 字符串 |
| 是 |
| 要创建的用户的显示名称。 | 字符串 |
| 是 |
| 与用户关联的电子邮件地址。 | 字符串 |
| 否 |
| 要生成的密钥类型,选项为:swift、s3(默认)。 | 字符串 |
| 否 |
| 指定访问密钥。 | 字符串 |
| 否 |
| 指定 secret 密钥。 | 字符串 |
| 否 |
| 用户能力。 | 字符串 |
| 否 |
| 生成新密钥对,并将 添加到现有的密钥环中。 | 布尔值 | True [True] | 否 |
| 指定用户可以拥有的最大存储桶数。 | 整数 | 500 [1000] | 否 |
| 指定是否应暂停用户。 | 布尔值 | false [False] | 否 |
名称 | 描述 | Type | 父 |
---|---|---|---|
| 用于用户数据信息的容器。 | Container | 不适用 |
| 用户 ID。 | 字符串 |
|
| 显示用户的名称。 | 字符串 |
|
| 如果用户已被挂起,则为 true。 | 布尔值 |
|
| 用户所有的 bucket 的最大数量。 | 整数 |
|
| 与此用户帐户关联的子用户。 | Container |
|
| 与这个用户帐户关联的 S3 密钥。 | Container |
|
| 与此用户帐户关联的 Swift 密钥。 | Container |
|
| 用户能力。 | Container |
|
如果成功,响应将包含用户信息。
名称 | 描述 | 代码 |
---|---|---|
| 尝试创建现有用户。 | 409 冲突 |
| 指定无效的访问密钥。 | 400 错误请求 |
| 指定了无效的密钥类型。 | 400 错误请求 |
| 指定了无效的 secret key。 | 400 错误请求 |
| 指定了无效的密钥类型。 | 400 错误请求 |
| 提供的访问密钥存在,但属于另一用户。 | 409 冲突 |
| 提供的电子邮件地址已存在。 | 409 冲突 |
| 尝试授予无效的 admin 功能。 | 400 错误请求 |
其它资源
- 有关创建子用户,请参阅 Red Hat Ceph Storage 开发人员指南。
1.7. 修改用户
修改现有用户。
功能
`users=write`
语法
POST /admin/user?format=json HTTP/1.1
Host: FULLY_QUALIFIED_DOMAIN_NAME
名称 | 描述 | Type | 示例 | 必需 |
---|---|---|---|---|
| 要修改的用户 ID。 | 字符串 |
| 是 |
| 要修改的用户的显示名称。 | 字符串 |
| 否 |
| 与用户关联的电子邮件地址。 | 字符串 |
| 否 |
| 生成新密钥对,并将 添加到现有的密钥环中。 | 布尔值 | True [False] | 否 |
| 指定访问密钥。 | 字符串 |
| 否 |
| 指定 secret 密钥。 | 字符串 |
| 否 |
| 要生成的密钥类型,选项为:swift、s3(默认)。 | 字符串 |
| 否 |
| 用户能力。 | 字符串 |
| 否 |
| 指定用户可以拥有的最大存储桶数。 | 整数 | 500 [1000] | 否 |
| 指定是否应暂停用户。 | 布尔值 | false [False] | 否 |
名称 | 描述 | Type | 父 |
---|---|---|---|
| 用于用户数据信息的容器。 | Container | 不适用 |
| 用户 ID。 | 字符串 |
|
| 显示用户的名称。 | 字符串 |
|
| 如果用户已被挂起,则为 true。 | 布尔值 |
|
| 用户所有的 bucket 的最大数量。 | 整数 |
|
| 与此用户帐户关联的子用户。 | Container |
|
| 与这个用户帐户关联的 S3 密钥。 | Container |
|
| 与此用户帐户关联的 Swift 密钥。 | Container |
|
| 用户能力。 | Container |
|
如果成功,响应将包含用户信息。
名称 | 描述 | 代码 |
---|---|---|
| 指定无效的访问密钥。 | 400 错误请求 |
| 指定了无效的密钥类型。 | 400 错误请求 |
| 指定了无效的 secret key。 | 400 错误请求 |
| 提供的访问密钥存在,但属于另一用户。 | 409 冲突 |
| 提供的电子邮件地址已存在。 | 409 冲突 |
| 尝试授予无效的 admin 功能。 | 400 错误请求 |
其它资源
- 如需修改子用户,请参阅 Red Hat Ceph Storage 开发人员指南。
1.8. 删除用户
移除现有用户。
功能
`users=write`
语法
DELETE /admin/user?format=json HTTP/1.1
Host: FULLY_QUALIFIED_DOMAIN_NAME
名称 | 描述 | Type | 示例 | 必需 |
---|---|---|---|---|
| 要删除的用户 ID。 | 字符串 |
| 是。 |
| 指定属于该用户的存储桶和对象时,也会被删除。 | 布尔值 | true | 否 |
响应实体
无。
特殊错误响应
无。
其它资源
- 有关删除子用户,请参阅 Red Hat Ceph Storage 开发者指南。
1.9. 创建子用户
创建一个新的子用户,主要用于使用 Swift API 的客户端。
有效请求需要 gen-subuser
或 subuser
。通常,对于子用户非常有用,必须通过指定 访问
来授予权限。与用户创建一样,如果没有 secret
指定 子用户
,则会自动生成 secret 密钥。
功能
`users=write`
语法
PUT /admin/user?subuser&format=json HTTP/1.1
Host FULLY_QUALIFIED_DOMAIN_NAME
名称 | 描述 | Type | 示例 | 必需 |
---|---|---|---|---|
| 要创建子用户的用户 ID。 | 字符串 |
| 是 |
| 指定要创建的子用户 ID。 | 字符串 |
|
是(或 |
| 指定要创建的子用户 ID。 | 字符串 |
|
是(或 |
| 指定 secret 密钥。 | 字符串 |
| 否 |
| 要生成的密钥类型,选项为:swift(默认)、s3。 | 字符串 |
| 否 |
|
为子用户设置访问权限,应为 | 字符串 |
| 否 |
| 生成 secret 密钥。 | 布尔值 | True [False] | 否 |
名称 | 描述 | Type | 父 |
---|---|---|---|
| 与用户帐户关联的子用户。 | Container | 不适用 |
| 子用户 ID。 | 字符串 |
|
| 对用户帐户的子用户访问。 | 字符串 |
|
如果成功,响应包含子用户信息。
名称 | 描述 | 代码 |
---|---|---|
| 存在指定的子用户。 | 409 冲突 |
| 指定了无效的密钥类型。 | 400 错误请求 |
| 指定了无效的 secret key。 | 400 错误请求 |
| 指定了无效的子用户访问。 | 400 错误请求 |
1.10. 修改子用户
修改现有子用户。
功能
`users=write`
语法
POST /admin/user?subuser&format=json HTTP/1.1
Host FULLY_QUALIFIED_DOMAIN_NAME
名称 | 描述 | Type | 示例 | 必需 |
---|---|---|---|---|
| 将修改子用户的用户 ID。 | 字符串 |
| 是 |
| 要修改的子用户 ID。 | 字符串 |
| 是 |
| 为 subuser 生成新 secret 密钥,并替换现有的密钥。 | 布尔值 | True [False] | 否 |
| 指定 secret 密钥。 | 字符串 |
| 否 |
| 要生成的密钥类型,选项为:swift(默认)、s3。 | 字符串 |
| 否 |
|
为子用户设置访问权限,应为 | 字符串 |
| 否 |
名称 | 描述 | Type | 父 |
---|---|---|---|
| 与用户帐户关联的子用户。 | Container | 不适用 |
| 子用户 ID。 | 字符串 |
|
| 对用户帐户的子用户访问。 | 字符串 |
|
如果成功,响应包含子用户信息。
名称 | 描述 | 代码 |
---|---|---|
| 指定了无效的密钥类型。 | 400 错误请求 |
| 指定了无效的 secret key。 | 400 错误请求 |
| 指定了无效的子用户访问。 | 400 错误请求 |
1.11. 删除子用户
移除现有的子用户。
功能
`users=write`
语法
DELETE /admin/user?subuser&format=json HTTP/1.1
Host FULLY_QUALIFIED_DOMAIN_NAME
名称 | 描述 | Type | 示例 | 必需 |
---|---|---|---|---|
| 要删除的子用户的用户 ID。 | 字符串 |
| 是 |
| 要删除的子用户 ID。 | 字符串 |
| 是 |
| 删除属于子用户的密钥。 | 布尔值 | True [True] | 否 |
响应实体
无。
特殊错误响应
无。
1.12. 为用户添加功能
向指定用户添加管理权限。
功能
`users=write`
语法
PUT /admin/user?caps&format=json HTTP/1.1
Host FULLY_QUALIFIED_DOMAIN_NAME
名称 | 描述 | Type | 示例 | 必需 |
---|---|---|---|---|
| 要添加的管理功能的用户 ID。 | 字符串 |
| 是 |
| 添加用户的管理功能。 | 字符串 |
| 是 |
名称 | 描述 | Type | 父 |
---|---|---|---|
| 用于用户数据信息的容器。 | Container | 不适用 |
| 用户 ID。 | 字符串 |
|
| 用户能力。 | Container |
|
如果成功,响应将包含用户的功能。
名称 | 描述 | 代码 |
---|---|---|
| 尝试授予无效的 admin 功能。 | 400 错误请求 |
1.13. 从用户中删除功能
从指定用户删除管理权限。
功能
`users=write`
语法
DELETE /admin/user?caps&format=json HTTP/1.1
Host FULLY_QUALIFIED_DOMAIN_NAME
名称 | 描述 | Type | 示例 | 必需 |
---|---|---|---|---|
| 从中删除管理功能的用户 ID。 | 字符串 |
| 是 |
| 从用户中删除的管理功能。 | 字符串 |
| 是 |
名称 | 描述 | Type | 父 |
---|---|---|---|
| 用于用户数据信息的容器。 | Container | 不适用 |
| 用户 ID。 | 字符串 |
|
| 用户能力。 | Container |
|
如果成功,响应将包含用户的功能。
名称 | 描述 | 代码 |
---|---|---|
| 尝试删除无效的管理员功能。 | 400 错误请求 |
| 用户没有指定的能力。 | 404 not Found |
1.14. 创建密钥
创建新密钥。如果指定了 subuser
,那么默认创建的密钥将是 swift 类型。如果只提供一个 access-key
或 secret-key
,则会自动生成提交的密钥,如果只指定了 secret-key
,则会自动生成 access-key
。默认情况下,生成的密钥会添加到密钥环中,而不替换现有的密钥对。如果指定了 access-key
,并引用用户拥有的现有密钥,则会修改它。响应是一个容器,它列出了与创建的密钥相同的所有类型。
在创建 swift 密钥时,指定 access-key
选项将无效。另外,每个用户或子用户只能保留一个 swift 密钥。
功能
`users=write`
语法
PUT /admin/user?key&format=json HTTP/1.1
Host FULLY_QUALIFIED_DOMAIN_NAME
名称 | 描述 | Type | 示例 | 必需 |
---|---|---|---|---|
| 用于接收新密钥的用户 ID。 | 字符串 |
| 是 |
| 用于接收新密钥的子用户 ID。 | 字符串 |
| 否 |
| 要生成的密钥类型,选项为:swift、s3(默认)。 | 字符串 |
| 否 |
| 指定 access key。 | 字符串 |
| 否 |
| 指定 secret 密钥。 | 字符串 |
| 否 |
| 生成新密钥对,并将 添加到现有的密钥环中。 | 布尔值 |
True [ | 否 |
名称 | 描述 | Type | 父 |
---|---|---|---|
| 与此用户帐户关联的类型密钥。 | Container | 不适用 |
| 与密钥关联的用户帐户。 | 字符串 |
|
| access key。 | 字符串 |
|
| secret 密钥 | 字符串 |
|
名称 | 描述 | 代码 |
---|---|---|
| 指定无效的访问密钥。 | 400 错误请求 |
| 指定了无效的密钥类型。 | 400 错误请求 |
| 指定了无效的 secret key。 | 400 错误请求 |
| 指定了无效的密钥类型。 | 400 错误请求 |
| 提供的访问密钥存在,但属于另一用户。 | 409 冲突 |
1.15. 删除密钥
删除现有密钥。
功能
`users=write`
语法
DELETE /admin/user?key&format=json HTTP/1.1
Host FULLY_QUALIFIED_DOMAIN_NAME
名称 | 描述 | Type | 示例 | 必需 |
---|---|---|---|---|
| 属于 S3 密钥对的 S3 访问密钥来移除。 | 字符串 |
| 是 |
| 从中删除该密钥的用户。 | 字符串 |
| 否 |
| 从中删除该密钥的子用户。 | 字符串 |
| 否 |
| 要移除的关键类型,选项为:swift、s3。 注意 移除 swift 密钥是必需的。 | 字符串 |
| 否 |
特殊错误响应
无。
响应实体
无。
1.16. bucket 通知
作为存储管理员,您可以使用这些 API 为存储桶通知机制提供配置和部署接口。API 主题是命名的对象,其中包含特定端点的定义。bucket 通知将主题与特定 bucket 关联。S3 bucket operations 部分提供有关 bucket 通知的更多详情。
在所有主题操作中,参数都是 URL 编码,并使用 application/x-www-form-urlencoded
内容类型在消息正文中发送。
需要重新创建与这个主题相关联的任何存储桶通知,以使主题更新生效。
1.16.1. 先决条件
- 在 Ceph 对象网关上创建 bucket 通知。
1.16.2. 创建主题
您可以在创建存储桶通知前创建主题。主题是 SNS 操作的一个简单通知服务(SNS)实体及所有主题操作(即 create
, delete
, list
和 get
)是 SNS 操作。主题需要具有创建存储桶通知时使用的端点参数。请求成功后,响应中包含稍后可用来在存储桶通知请求中引用此主题的 Amazon Resource Name(ARN)主题。
topic_arn
提供存储桶通知配置,并在创建主题后生成。
先决条件
- 一个正在运行的 Red Hat Ceph Storage 集群。
- 根级别访问权限.
- 安装 Ceph 对象网关.
- 用户 access key 和 secret key。
- 端点参数.
流程
创建带有请求格式的主题:
语法
POST Action=CreateTopic &Name=TOPIC_NAME [&Attributes.entry.1.key=amqp-exchange&Attributes.entry.1.value=EXCHANGE] [&Attributes.entry.2.key=amqp-ack-level&Attributes.entry.2.value=none|broker|routable] [&Attributes.entry.3.key=verify-ssl&Attributes.entry.3.value=true|false] [&Attributes.entry.4.key=kafka-ack-level&Attributes.entry.4.value=none|broker] [&Attributes.entry.5.key=use-ssl&Attributes.entry.5.value=true|false] [&Attributes.entry.6.key=ca-location&Attributes.entry.6.value=FILE_PATH] [&Attributes.entry.7.key=OpaqueData&Attributes.entry.7.value=OPAQUE_DATA] [&Attributes.entry.8.key=push-endpoint&Attributes.entry.8.value=ENDPOINT]
以下是请求参数:
-
端点
:发送通知的端点 URL。 -
OpaqueData
: 不透明数据在主题配置中设置,并添加到该主题触发的所有通知。 HTTP 端点:
-
URL
: http[s]://FQDN[: PORT ] -
port defaults to
: 分别为 HTTP[S] 使用 80/443。 -
verify-ssl
:指示服务器证书是否由客户端验证。默认情况下,它是true
。
-
AMQP0.9.1 端点:
-
URL
: amqp://[USER : PASSWORD @] FQDN [: PORT][/VHOST]. -
用户和密码分别默认为:
guest
和guest
。 - 用户和密码只能通过 HTTPS 提供。否则,主题创建请求将被拒绝。
-
端口默认为 :
5672。 -
vhost
默认为:"/" -
AMQP-exchange
:交换必须存在,并可基于主题路由消息。这是用于 AMQP0.9.1 的强制参数。指向同一端点的不同主题必须使用相同的交换。 AMQP-acklevel
: 不需要最终确认,因为消息可能会在代理中存入最终目的地。有三个确认方法:-
none
:当发送到代理,则消息被视为已发送
。 -
broker
:默认情况下,如果代理确认,则消息会被视为已发送
。 routable
:如果代理可路由到使用者,则消息被视为已发送
。注意特定参数的键和值不必驻留在同一行中,或者以任何特定顺序使用,但必须使用相同的索引。属性索引不需要是连续的,或从任何特定值开始。
注意topic-name
用于 AMQP 主题。
-
-
Kafka 端点:
-
URL
: kafka://[USER: PASSWORD @] FQDN[: PORT]. -
如果
use-ssl
默认设为false
。如果将use-ssl
设置为true
,则与代理的连接会使用安全的连接。 -
如果提供了
ca-location
,并且使用安全连接,则会使用指定的 CA 而不是默认的端口来验证代理。 - 用户和密码只能通过 HTTP[S] 提供。如果没有,则topic 创建请求将被拒绝。
-
只能通过
use-ssl
来提供用户和密码,如果不是,则与代理的连接会失败。 -
端口默认为
: 9092。 kafka-acklevel
: 不需要结束确认,因为信息可能会在代理中被传送到最终目的地前保留。存在两个确认方法:-
none
:当发送到代理,则消息被视为已发送
。 -
broker
:默认情况下,如果代理确认,则消息将被发送
。
-
-
-
以以下格式创建响应:
语法
<CreateTopicResponse xmlns="https://sns.amazonaws.com/doc/2010-03-31/"> <CreateTopicResult> <TopicArn></TopicArn> </CreateTopicResult> <ResponseMetadata> <RequestId></RequestId> </ResponseMetadata> </CreateTopicResponse>
注意响应中的 Amazon 资源名称(ARN)的格式将采用以下格式:arn:
aws:sns:ZONE_GROUP:TENANT:TOPIC
以下是一个 AMQP0.9.1 端点的示例:
语法
"client.create_topic(Name='my-topic' , Attributes={'push-endpoint': 'amqp://127.0.0.1:5672', 'amqp-exchange': 'ex1', 'amqp-ack-level': 'broker'})"
1.16.3. 获取主题信息
返回有关特定主题的信息。如果提供,这可包括端点信息。
先决条件
- 一个正在运行的 Red Hat Ceph Storage 集群。
- 根级别访问权限.
- 安装 Ceph 对象网关.
- 用户 access key 和 secret key。
- 端点参数.
流程
使用以下请求格式获取主题信息:
语法
POST Action=GetTopic &TopicArn=TOPIC_ARN
以下是响应格式的示例:
<GetTopicResponse> <GetTopicRersult> <Topic> <User> </User> <Name> </Name> <EndPoint> <EndpointAddress> </EndpointAddress> <EndpointArgs> </EndpointArgs> <EndpointTopic> </EndpointTopic> </EndPoint> <TopicArn> </TopicArn> <OpaqueData> </OpaqueData> </Topic> </GetTopicResult> <ResponseMetadata> <RequestId> </RequestId> </ResponseMetadata> </GetTopicResponse>
这些是标签及其定义:
-
User
:创建该主题的用户的名称。 -
Name
:主题的名称. -
EndpointAddress
:端点 URL。如果端点 URL 包含用户和密码信息,则必须通过 HTTPS 进行请求。如果没有,则主题的 get 请求将被拒绝。 -
EndPointArgs
:端点参数。 -
EndpointTopic
:将发送到端点的主题名称可以和上述主题名称不同。 -
TopicArn
: Topic ARN。
-
1.16.4. 列出主题
列出用户已定义的主题。
先决条件
- 一个正在运行的 Red Hat Ceph Storage 集群。
- 根级别访问权限.
- 安装 Ceph 对象网关.
- 用户 access key 和 secret key。
- 端点参数.
流程
使用以下请求格式列出主题信息:
POST Action=ListTopics
以下是响应格式的示例:
<ListTopicdResponse xmlns="https://sns.amazonaws.com/doc/2020-03-31/"> <ListTopicsRersult> <Topics> <member> <User> </User> <Name> </Name> <EndPoint> <EndpointAddress> </EndpointAddress> <EndpointArgs> </EndpointArgs> <EndpointTopic> </EndpointTopic> </EndPoint> <TopicArn> </TopicArn> <OpaqueData> </OpaqueData> </member> </Topics> </ListTopicsResult> <ResponseMetadata> <RequestId> </RequestId> </ResponseMetadata> </ListTopicsResponse>
注意如果端点 URL 包含用户和密码信息,在任何主题中,则必须通过 HTTPS 进行请求。如果没有,则主题列表请求将被拒绝。
1.16.5. 删除主题
删除被删除的主题结果,且无操作,而不是失败。
先决条件
- 一个正在运行的 Red Hat Ceph Storage 集群。
- 根级别访问权限.
- 安装 Ceph 对象网关.
- 用户 access key 和 secret key。
- 端点参数.
流程
使用以下请求格式删除主题:
语法
POST Action=DeleteTopic &TopicArn=TOPIC_ARN
以下是响应格式的示例:
<DeleteTopicResponse xmlns="https://sns.amazonaws.com/doc/2020-03-31/"> <ResponseMetadata> <RequestId> </RequestId> </ResponseMetadata> </DeleteTopicResponse>
1.16.6. 事件记录
事件包含 Ceph 对象网关操作的信息,并通过所选端点以有效负载形式发送,如 HTTP、HTTPS、Kafka 或 AMQ0.9.1。事件记录采用 JSON 格式。
示例
{"Records":[ { "eventVersion":"2.1", "eventSource":"ceph:s3", "awsRegion":"us-east-1", "eventTime":"2019-11-22T13:47:35.124724Z", "eventName":"s3:ObjectCreated:Put", "userIdentity":{ "principalId":"tester" }, "requestParameters":{ "sourceIPAddress":"" }, "responseElements":{ "x-amz-request-id":"503a4c37-85eb-47cd-8681-2817e80b4281.5330.903595", "x-amz-id-2":"14d2-zone1-zonegroup1" }, "s3":{ "s3SchemaVersion":"1.0", "configurationId":"mynotif1", "bucket":{ "name":"mybucket1", "ownerIdentity":{ "principalId":"tester" }, "arn":"arn:aws:s3:us-east-1::mybucket1", "id":"503a4c37-85eb-47cd-8681-2817e80b4281.5332.38" }, "object":{ "key":"myimage1.jpg", "size":"1024", "eTag":"37b51d194a7513e45b56f6524f2d51f2", "versionId":"", "sequencer": "F7E6D75DC742D108", "metadata":[], "tags":[] } }, "eventId":"", "opaqueData":"me@example.com" } ]}
以下是事件记录密钥及其定义:
-
awsRegion
: Zonegroup。 -
eventTime
: 指示触发事件的时间的时间戳。 -
eventName
:事件类型。 -
userIdentity.principalId
:触发该事件的用户的身份。 -
requestParameters.sourceIPAddress
:触发该事件的客户端的 IP 地址。不支持此字段。 -
responseElements.x-amz-request-id
:触发事件的请求 ID。 -
responseElements.x_amz_id_2
:触发事件的 Ceph 对象网关的身份。身份格式为 RGWID-ZONE-ZONEGROUP。 -
s3.configurationId
:创建事件的通知 ID。 -
s3.bucket.name
:存储桶的名称。 -
s3.bucket.ownerIdentity.principalId
:存储桶的所有者。 -
s3.bucket.arn
: bucket 的 Amazon Resource Name(ARN)。 -
s3.bucket.id
:存储桶的身份。 -
s3.object.key
:对象键。 -
s3.object.size
:对象的大小。 -
s3.object.eTag
:对象 etag。 -
s3.object.version
:版本控制存储桶中的对象版本。 -
s3.object.sequencer
:以十六进制格式为每个对象增大更改的标识符。 -
s3.object.metadata
:对象上设置的任何元数据,作为x-amz-meta
。 -
s3.object.tags
:对象上设置的任何标签。 -
s3.eventId
:事件的唯一标识。 -
s3.opaqueData
: Opaque 数据在主题配置中设置,并添加到该主题触发的所有通知中。
1.16.7. 支持的事件类型
支持以下事件类型:
-
s3:ObjectCreated:*
-
s3:ObjectCreated:Put
-
s3:ObjectCreated:Post
-
s3:ObjectCreated:Copy
-
s3:ObjectCreated:CompleteMultipartUpload
-
s3:ObjectRemoved:*
-
s3:ObjectRemoved:Delete
-
s3:ObjectRemoved:DeleteMarkerCreated
1.16.8. 其它资源
- 如需了解更多详细信息,请参阅 Red Hat Ceph Storage Object Gateway 配置和管理指南中的创建存储桶通知部分 。
1.17. 获取存储桶信息
获取有关现有 bucket 子集的信息。如果在没有 bucket
的情况下指定 uid
,则返回属于该用户的所有存储桶。如果只指定 存储桶
,则会检索该特定存储桶的信息。
功能
`buckets=read`
语法
GET /admin/bucket?format=json HTTP/1.1
Host FULLY_QUALIFIED_DOMAIN_NAME
名称 | 描述 | Type | 示例 | 必需 |
---|---|---|---|---|
| 用于返回信息的存储桶。 | 字符串 |
| 否 |
| 检索存储桶信息的用户。 | 字符串 |
| 否 |
| 返回存储桶统计信息。 | 布尔值 | True [False] | 否 |
名称 | 描述 | Type | 父 |
---|---|---|---|
| 每个存储桶信息。 | Container | 不适用 |
| 包含一个或多个 bucket 容器的列表。 | Container |
|
用于单一存储桶信息的容器。 | Container |
|
|
bucket 的名称。 | 字符串 |
|
|
bucket 存储在其中的池。 | 字符串 |
|
|
唯一的存储桶 ID。 | 字符串 |
|
|
内部存储桶标签。 | 字符串 |
|
|
bucket 所有者的用户 ID。 | 字符串 |
|
|
存储使用信息。 | Container |
|
|
如果请求成功,则返回包含所需存储桶信息的 bucket 容器。
名称 | 描述 | 代码 |
---|---|---|
| bucket 索引修复失败。 | 409 冲突 |
1.18. 检查存储桶索引
检查现有存储桶的索引。
要通过 check-objects
检查多部分对象核算,必须将修复
设置为 True。
功能
buckets=write
语法
GET /admin/bucket?index&format=json HTTP/1.1
Host FULLY_QUALIFIED_DOMAIN_NAME
名称 | 描述 | Type | 示例 | 必需 |
---|---|---|---|---|
| 用于返回信息的存储桶。 | 字符串 |
| 是 |
| 检查 multipart 对象核算。 | 布尔值 | True [False] | 否 |
| 另外,在检查时修复存储桶索引。 | 布尔值 | false [False] | 否 |
名称 | 描述 | Type |
---|---|---|
| bucket 索引的状态。 | 字符串 |
名称 | 描述 | 代码 |
---|---|---|
| bucket 索引修复失败。 | 409 冲突 |
1.19. 删除存储桶
删除现有的存储桶。
功能
`buckets=write`
语法
DELETE /admin/bucket?format=json HTTP/1.1
Host FULLY_QUALIFIED_DOMAIN_NAME
名称 | 描述 | Type | 示例 | 必需 |
---|---|---|---|---|
| 要删除的存储桶。 | 字符串 |
| 是 |
| 删除前移除 bucket 对象。 | 布尔值 | True [False] | 否 |
响应实体
无。
名称 | 描述 | 代码 |
---|---|---|
| 尝试删除非空存储桶。 | 409 冲突 |
| 无法删除对象。 | 409 冲突 |
1.20. 链接存储桶
将存储桶链接到指定用户,从任何先前用户取消链接存储桶。
功能
`buckets=write`
语法
PUT /admin/bucket?format=json HTTP/1.1
Host FULLY_QUALIFIED_DOMAIN_NAME
名称 | 描述 | Type | 示例 | 必需 |
---|---|---|---|---|
| 取消链接的存储桶。 | 字符串 |
| 是 |
| 将存储桶链接到的用户 ID。 | 字符串 |
| 是 |
名称 | 描述 | Type | 父 |
---|---|---|---|
| 用于单一存储桶信息的容器。 | Container | 不适用 |
| bucket 的名称。 | 字符串 |
|
| bucket 存储在其中的池。 | 字符串 |
|
| 唯一的存储桶 ID。 | 字符串 |
|
| 内部存储桶标签。 | 字符串 |
|
| bucket 所有者的用户 ID。 | 字符串 |
|
| 存储使用信息。 | Container |
|
| bucket 索引的状态。 | 字符串 |
|
名称 | 描述 | 代码 |
---|---|---|
| 无法从指定用户取消链接存储桶。 | 409 冲突 |
| 无法将存储桶链接到指定用户。 | 409 冲突 |
1.21. 取消链接存储桶
从指定用户取消链接存储桶。主要用于更改 bucket 所有权。
功能
`buckets=write`
语法
POST /admin/bucket?format=json HTTP/1.1
Host FULLY_QUALIFIED_DOMAIN_NAME
名称 | 描述 | Type | 示例 | 必需 |
---|---|---|---|---|
| 取消链接的存储桶。 | 字符串 |
| 是 |
| 从中取消链接存储桶的用户 ID。 | 字符串 |
| 是 |
响应实体
无。
名称 | 描述 | 代码 |
---|---|---|
| 无法从指定用户取消链接存储桶。 | 409 冲突 |
1.22. 获取存储桶或对象策略
对一个对象或 bucket 的读取策略。
功能
`buckets=read`
语法
GET /admin/bucket?policy&format=json HTTP/1.1
Host FULLY_QUALIFIED_DOMAIN_NAME
名称 | 描述 | Type | 示例 | 必需 |
---|---|---|---|---|
| 要从中读取策略的存储桶。 | 字符串 |
| 是 |
| 从中读取策略的对象。 | 字符串 |
| 否 |
名称 | 描述 | Type | 父 |
---|---|---|---|
| 访问控制策略。 | Container | 不适用 |
如果成功,返回对象或存储桶策略
名称 | 描述 | 代码 |
---|---|---|
| 没有为存储桶策略请求指定存储桶,或未为对象策略请求指定对象。 | 400 错误请求 |
1.23. 删除对象
删除现有对象。
不需要所有者才能终止。
功能
`buckets=write`
语法
DELETE /admin/bucket?object&format=json HTTP/1.1
Host FULLY_QUALIFIED_DOMAIN_NAME
名称 | 描述 | Type | 示例 | 必需 |
---|---|---|---|---|
| 包含要删除的对象的存储桶。 | 字符串 |
| 是 |
| 要移除的对象。 | 字符串 |
| 是 |
响应实体
无。
名称 | 描述 | 代码 |
---|---|---|
| 指定对象不存在。 | 404 not Found |
| 无法删除对象。 | 409 冲突 |
1.24. 配额
管理操作 API 允许您在用户和由用户拥有的 bucket 中设置配额。配额包括 bucket 中对象的最大数量,以及最大存储大小(以 MB 为单位)。
要查看配额,用户必须具有 users=read
能力。要设置,修改或禁用配额,用户必须具有 users=write
功能。
配额的有效参数包括:
-
Bucket:
bucket
选项允许您为用户拥有的 bucket 指定配额。 -
maximum Objects:
max-objects
设置允许您指定对象的最大数量。负值将禁用此设置。 -
Maximum Size: 您可以使用
max-size
选项为最大字节数指定配额。负值将禁用此设置。 -
Quota Scope:
quota-scope
选项设定配额的范围。选项为bucket
和user
。
1.25. 获取用户配额
要获得配额,用户必须具有带有 read
权限的 users
能力。
语法
GET /admin/user?quota&uid=UID"a-type=user
1.26. 设置用户配额
要获得配额,用户必须具有带有 write
权限的 users
能力。
语法
PUT /admin/user?quota&uid=UID"a-type=user
内容必须包括配额设置的 JSON 表示,如相应读取操作中编码。
1.27. 获取存储桶配额
要获取存储桶配额,用户必须
设置 读取权限
。
语法
GET /admin/user?quota&uid=UID"a-type=bucket
1.28. 设置存储桶配额
要获得配额,用户必须具有带有 write
权限的 users
能力。
语法
PUT /admin/user?quota&uid=UID"a-type=bucket
内容必须包括配额设置的 JSON 表示,如相应读取操作中编码。
1.29. 为独立存储桶设置配额
要设置配额,用户必须设置 具有写入权限
的 bucket
能力。
语法
PUT /admin/bucket?quota&uid=UID&bucket=BUCKET_NAME"a
内容必须包含配额设置的 JSON 表示。
1.30. 获取用法信息
请求带宽使用量信息。
功能
`usage=read`
语法
GET /admin/usage?format=json HTTP/1.1
Host: FULLY_QUALIFIED_DOMAIN_NAME
名称 | 描述 | Type | 必需 |
---|---|---|---|
| 请求信息的用户。 | 字符串. | 是 |
|
日期和(可选)指定所请求数据的开始时间。例如, | 字符串 | 否 |
|
日期和时间(可选)指定所请求数据的结束时间(非默认)。例如, | 字符串 | 否 |
| 指定是否应返回数据条目。 | 布尔值 | 否 |
| 指定是否应该返回数据摘要。 | 布尔值 | 否 |
名称 | 描述 | Type |
---|---|---|
| 用于用法信息的容器。 | Container |
| 用于用法条目信息的容器。 | Container |
| 用于用户数据信息的容器。 | Container |
| 拥有存储桶的用户的名称。 | 字符串 |
| bucket 名称。 | 字符串 |
| 指定数据的时间下限(在第一个相关小时开始)。 | 字符串 |
|
自 | 字符串 |
| 用于统计类别的容器。 | Container |
| 用于统计条目的容器。 | Container |
| 提供统计的请求类别的名称。 | 字符串 |
| Ceph 对象网关发送的字节数。 | 整数 |
| Ceph 对象网关收到的字节数。 | 整数 |
| 操作数量。 | 整数 |
| 成功操作数量。 | 整数 |
| 用于统计(stats)摘要的容器。 | Container |
| 容器用于统计摘要聚合的总数。 | Container |
如果成功,响应包含请求的信息。
1.31. 删除使用信息
删除使用信息。如果未指定日期,可删除所有使用信息。
功能
`usage=write`
语法
DELETE /admin/usage?format=json HTTP/1.1
Host: FULLY_QUALIFIED_DOMAIN_NAME
名称 | 描述 | Type | 示例 | 必需 |
---|---|---|---|---|
| 请求信息的用户。 | 字符串 |
| 否 |
| 日期和(可选)指定所请求数据的开始时间。 | 字符串 |
| 否 |
| 日期和时间(可选)指定所请求数据的结束时间(不包括)。 | 字符串 |
| 否 |
|
未指定 | 布尔值 | True [False] | 否 |
1.32. 标准错误响应
下表详细介绍了标准错误响应及其描述。
名称 | 描述 | 代码 |
---|---|---|
| 拒绝访问。 | 403 Forbidden |
| 内部服务器错误. | 500 内部服务器错误 |
| 用户不存在。 | 404 not Found |
| bucket 不存在。 | 404 not Found |
| 没有这样的 access key。 | 404 not Found |
第 2 章 Ceph 对象网关和 S3 API
作为开发者,您可以使用与 Amazon S3 数据访问模型兼容的 RESTful 应用编程接口(API)。您可以通过 Ceph 对象网关管理 Red Hat Ceph Storage 集群中存储的 bucket 和对象。
2.1. 先决条件
- 一个正在运行的 Red Hat Ceph Storage 集群。
- RESTful 客户端。
2.2. S3 限制
应谨慎使用以下限制。您的硬件选择会有影响,因此您应该始终与您的红帽客户团队讨论这些要求。
-
Maximum object size when using Amazon S3: 单个 Amazon S3 对象的大小范围可以为从 0B 到最多 5TB。单个
PUT
中可以上传的最大对象为 5GB。对于大于 100MB 的对象,您应该考虑使用多部分上传功能。 - 使用 Amazon S3 时的最大 元数据大小对可应用到对象的用户元数据的总大小没有定义限制,但单个 HTTP 请求限制为 16,000 字节。
- Red Hat Ceph Storage 集群的数据开销量为存储 S3 对象和元数据: 这里的估计为 200-300 字节,以及对象名称的长度。版本化的对象会消耗与版本数量成比例的额外空间。另外,在多部分上传和其他事务更新过程中会产生临时开销,但这些开销会在垃圾回收期间恢复。
其它资源
- 如需了解 不支持的标头字段 的详细信息,请参阅 Red Hat Ceph Storage Developer Guide。
2.3. 使用 S3 API 访问 Ceph 对象网关
作为开发者,您必须配置对 Ceph 对象网关和安全令牌服务(STS)的访问权限,然后才能开始使用 Amazon S3 API。
2.3.1. 先决条件
- 一个正在运行的 Red Hat Ceph Storage 集群。
- 正在运行的 Ceph 对象网关.
- RESTful 客户端。
2.3.2. S3 身份验证
对 Ceph 对象网关的请求可以是经过身份验证的用户或未经身份验证的请求。Ceph 对象网关假定匿名用户发送了未经身份验证的请求。Ceph 对象网关支持 ACL。
对于大多数用例,客户端使用现有开源库,如 Amazon SDK 的 AmazonS3Client
用于 Java 和 Python Boto。使用开源库,只需传递访问密钥和密钥,库会为您构建请求标头和身份验证签名。但是,您可以创建请求并签署它们。
在向 Ceph 对象网关服务器发送前,在请求中包括访问密钥和基于 64 编码的消息身份验证代码(HMAC)的要求。Ceph 对象网关使用兼容 S3 的身份验证方法。
示例
HTTP/1.1 PUT /buckets/bucket/object.mpeg Host: cname.domain.com Date: Mon, 2 Jan 2012 00:01:01 +0000 Content-Encoding: mpeg Content-Length: 9999999 Authorization: AWS ACCESS_KEY:HASH_OF_HEADER_AND_SECRET
在上例中,将 ACCESS_KEY
替换为 access key ID 的值,后跟一个冒号(:
)。将 HASH_OF_HEADER_AND_SECRET
替换为一个规范标头字符串的哈希值,以及与访问密钥 ID 对应的 secret。
生成标头字符串和 secret 的哈希值
生成标头字符串和 secret 的哈希值:
- 获取标头字符串的值。
- 将请求标头字符串规范化为规范形式。
- 使用 SHA-1 哈希算法生成 HMAC。
-
将
hmac
结果编码为 base-64。
规范化标头
将标头规范化为规范形式:
-
获取
所有内容
标头。 -
删除除
content-type
和content-md5
外的所有content-
标头。 -
确保
content-
标头名称是小写。 -
以字典顺序对
content-
标题排序。 -
确保带有
Date
标头,并确保指定的日期使用 GMT 而不是偏移量。 -
获取以
x-amz-
开头的所有标题。 -
确保
x-amz-
标头都是小写。 -
适当地对
x-amz-
headers 进行排序。 - 将同一字段名称的多个实例合并到一个字段中,并使用逗号分隔字段值。
- 使用单个空格替换标题值中的空格和换行符。
- 在冒号前后删除空格。
- 在每个标头后面添加一个新行。
- 将标头合并回请求标头。
将 HASH_OF_HEADER_AND_SECRET
替换为 base-64 编码的 HMAC 字符串。
其它资源
- 如需了解更多详细信息,请参阅 Amazon Simple Storage Service 文档中的签名和授权 REST Requests 部分。
2.3.3. S3 服务器端加密
Ceph 对象网关支持为 S3 应用编程接口(API)对上载对象进行服务器端加密。服务器端加密意味着 S3 客户端以未加密的形式通过 HTTP 发送数据,而 Ceph 对象网关以加密的形式将数据存储在 Red Hat Ceph Storage 集群中。
红帽不支持静态大型对象(SLO)或动态大对象(DLO)的 S3 对象加密。
若要使用加密,客户端请求需要通过 SSL 连接发送请求。除非 Ceph 对象网关使用 SSL,否则红帽不支持从客户端进行 S3 加密。但是,为测试目的,管理员可以在运行时将 rgw_crypt_require_ssl
配置设置设置为
来禁用 SSL,再重新启动网关实例,或者在 Ansible 配置文件中将其设置为 false
false
。
在生产环境中,可能无法通过 SSL 发送加密的请求。在这种情况下,使用 HTTP 和服务器端加密发送请求。
有关如何使用服务器端加密配置 HTTP 的详情,请参考下面的附加资源部分。
管理加密密钥有两个选项:
客户提供的键
在使用客户提供的密钥时,S3 客户端会传递加密密钥以及每个请求来读取或写入加密数据。客户负责管理这些密钥。客户必须记住用于加密每个对象的 Ceph 对象网关的关键是什么。
Ceph 对象网关根据 Amazon SSE-C 规范在 S3 API 中实施客户提供的关键行为。
由于客户处理密钥管理,并且 S3 客户端将密钥传递到 Ceph 对象网关,因此 Ceph 对象网关不需要特殊配置来支持这种加密模式。
密钥管理服务
在使用密钥管理服务时,安全密钥管理服务存储密钥,Ceph 对象网关则按需检索密钥,为数据加密或解密请求提供服务。
Ceph 对象网关根据 Amazon SSE-KMS 规范在 S3 API 中实施关键管理服务行为。
目前,唯一测试的关键管理实施是 HashiCorp Vault 和 OpenStack Barbican。但是,OpenStack Barbican 是一个技术预览,不支持在生产环境中使用。
2.3.4. S3 访问控制列表
Ceph 对象网关支持 S3 兼容访问控制列表(ACL)功能。ACL 是访问权限列表,可指定用户可以对存储桶或对象执行的操作。在应用到存储桶而不是应用到对象时,每个授权都有不同的意义:
权限 | Bucket | Object |
---|---|---|
| Grantee 可以列出存储桶中的对象。 | Grantee 可以读取对象。 |
| Grantee 可以编写或删除存储桶中的对象。 | 不适用 |
| Grantee 可以读取存储桶 ACL。 | Grantee 可以读取对象 ACL。 |
| Grantee 可以编写存储桶 ACL。 | Grantee 可以写入对象 ACL。 |
| Grantee 具有存储桶中对象的完整权限。 | Grantee 可以读取和写入对象 ACL。 |
2.3.5. 使用 S3 准备对 Ceph 对象网关的访问
在尝试访问网关服务器前,您必须在 Ceph 对象网关节点上遵循一些前提条件。
不要修改 Ceph 配置文件以使用端口 80
,让 Civetweb
使用默认的 Ansible 配置端口 8080。
先决条件
- 安装 Ceph 对象网关软件.
- Ceph 对象网关节点的根级别访问权限.
流程
以
root
用户身份,打开防火墙上的端口8080
:[root@rgw ~]# firewall-cmd --zone=public --add-port=8080/tcp --permanent [root@rgw ~]# firewall-cmd --reload
如对象网关配置和管理指南中所述,为网关使用的 DNS 服务器添加通配符。
您还可以为本地 DNS 缓存设置网关节点。要做到这一点,请执行以下步骤:
以
root
用户身份,安装和设置dnsmasq
:[root@rgw ~]# yum install dnsmasq [root@rgw ~]# echo "address=/.FQDN_OF_GATEWAY_NODE/IP_OF_GATEWAY_NODE" | tee --append /etc/dnsmasq.conf [root@rgw ~]# systemctl start dnsmasq [root@rgw ~]# systemctl enable dnsmasq
将
IP_OF_GATEWAY_NODE
和FQDN_OF_GATEWAY_NODE
替换为网关节点的 IP 地址和 FQDN。作为
root
用户,停止 NetworkManager:[root@rgw ~]# systemctl stop NetworkManager [root@rgw ~]# systemctl disable NetworkManager
以
root
用户身份,将网关服务器的 IP 设置为名称服务器:[root@rgw ~]# echo "DNS1=IP_OF_GATEWAY_NODE" | tee --append /etc/sysconfig/network-scripts/ifcfg-eth0 [root@rgw ~]# echo "IP_OF_GATEWAY_NODE FQDN_OF_GATEWAY_NODE" | tee --append /etc/hosts [root@rgw ~]# systemctl restart network [root@rgw ~]# systemctl enable network [root@rgw ~]# systemctl restart dnsmasq
将
IP_OF_GATEWAY_NODE
和FQDN_OF_GATEWAY_NODE
替换为网关节点的 IP 地址和 FQDN。验证子域请求:
[user@rgw ~]$ ping mybucket.FQDN_OF_GATEWAY_NODE
将
FQDN_OF_GATEWAY_NODE
替换为网关节点的 FQDN。警告为本地 DNS 缓存设置网关服务器仅用于测试目的。执行此操作后您将无法访问外部网络。强烈建议您为 Red Hat Ceph Storage 集群和网关节点使用正确的 DNS 服务器。
-
如对象网关配置和管理指南 中所述,为
S3
访问创建radosgw
用户,并复制生成的access_key
和secret_key
。您需要这些密钥进行S3
访问和随后的 bucket 管理任务。
2.3.6. 使用 Ruby AWS S3 访问 Ceph 对象网关
您可以使用 Ruby 编程语言以及 aws-s3
gem 用于 S3
访问。在用于通过 Ruby AWS::S3
访问 Ceph 对象网关服务器的节点上执行下方所述的步骤。
先决条件
- Ceph 对象网关用户级访问权限.
- 访问 Ceph 对象网关的 root 级别访问节点。
- 互联网访问。
流程
安装
ruby
软件包:[root@dev ~]# yum install ruby
注意以上命令将安装
ruby
,它是rubygems
和ruby-libs
等基本依赖项。如果某种方式命令没有安装所有依赖项,请单独安装它们。安装
aws-s3
Ruby 软件包:[root@dev ~]# gem install aws-s3
创建项目目录:
[user@dev ~]$ mkdir ruby_aws_s3 [user@dev ~]$ cd ruby_aws_s3
创建连接文件:
[user@dev ~]$ vim conn.rb
将以下内容粘贴到
conn.rb
文件中:语法
#!/usr/bin/env ruby require 'aws/s3' require 'resolv-replace' AWS::S3::Base.establish_connection!( :server => 'FQDN_OF_GATEWAY_NODE', :port => '8080', :access_key_id => 'MY_ACCESS_KEY', :secret_access_key => 'MY_SECRET_KEY' )
将
FQDN_OF_GATEWAY_NODE
替换为 Ceph 对象网关节点的 FQDN。将MY_ACCESS_KEY
和MY_SECRET_KEY
替换为您在为 S3 创建radosgw
用户进行S3
访问时生成的access_key
和secret_key
,如 Red Hat Ceph Storage Object Gateway Configuration and Administration Guide 中所述。示例
#!/usr/bin/env ruby require 'aws/s3' require 'resolv-replace' AWS::S3::Base.establish_connection!( :server => 'testclient.englab.pnq.redhat.com', :port => '8080', :access_key_id => '98J4R9P22P5CDL65HKP8', :secret_access_key => '6C+jcaP0dp0+FZfrRNgyGA9EzRy25pURldwje049' )
保存文件并退出编辑器。
使文件可执行:
[user@dev ~]$ chmod +x conn.rb
运行该文件:
[user@dev ~]$ ./conn.rb | echo $?
如果您在文件中正确提供了值,命令的输出将是
0
。创建存储桶的新文件:
[user@dev ~]$ vim create_bucket.rb
将以下内容粘贴到文件中:
#!/usr/bin/env ruby load 'conn.rb' AWS::S3::Bucket.create('my-new-bucket1')
保存文件并退出编辑器。
使文件可执行:
[user@dev ~]$ chmod +x create_bucket.rb
运行该文件:
[user@dev ~]$ ./create_bucket.rb
如果命令的输出为
true
,这表示 bucketmy-new-bucket1
已创建成功。创建用于列出所拥有的存储桶的新文件:
[user@dev ~]$ vim list_owned_buckets.rb
将以下内容粘贴到文件中:
#!/usr/bin/env ruby load 'conn.rb' AWS::S3::Service.buckets.each do |bucket| puts "{bucket.name}\t{bucket.creation_date}" end
保存文件并退出编辑器。
使文件可执行:
[user@dev ~]$ chmod +x list_owned_buckets.rb
运行该文件:
[user@dev ~]$ ./list_owned_buckets.rb
输出应类似如下:
my-new-bucket1 2020-01-21 10:33:19 UTC
创建用于创建对象的新文件:
[user@dev ~]$ vim create_object.rb
将以下内容粘贴到文件中:
#!/usr/bin/env ruby load 'conn.rb' AWS::S3::S3Object.store( 'hello.txt', 'Hello World!', 'my-new-bucket1', :content_type => 'text/plain' )
保存文件并退出编辑器。
使文件可执行:
[user@dev ~]$ chmod +x create_object.rb
运行该文件:
[user@dev ~]$ ./create_object.rb
这将创建一个含有字符串
Hello World!
的文件hello.txt
。创建用于列出存储桶内容的新文件:
[user@dev ~]$ vim list_bucket_content.rb
将以下内容粘贴到文件中:
#!/usr/bin/env ruby load 'conn.rb' new_bucket = AWS::S3::Bucket.find('my-new-bucket1') new_bucket.each do |object| puts "{object.key}\t{object.about['content-length']}\t{object.about['last-modified']}" end
保存文件并退出编辑器。
使文件成为可执行文件。
[user@dev ~]$ chmod +x list_bucket_content.rb
运行该文件:
[user@dev ~]$ ./list_bucket_content.rb
输出将类似如下:
hello.txt 12 Fri, 22 Jan 2020 15:54:52 GMT
创建用于删除空存储桶的新文件:
[user@dev ~]$ vim del_empty_bucket.rb
将以下内容粘贴到文件中:
#!/usr/bin/env ruby load 'conn.rb' AWS::S3::Bucket.delete('my-new-bucket1')
保存文件并退出编辑器。
使文件可执行:
[user@dev ~]$ chmod +x del_empty_bucket.rb
运行该文件:
[user@dev ~]$ ./del_empty_bucket.rb | echo $?
如果删除了存储桶,命令会返回
0
作为输出。注意编辑
create_bucket.rb
文件,以创建空存储桶,例如:my-new-bucket4、
my-new-bucket5
。接下来,在尝试删除空存储桶前相应地编辑上述del_empty_bucket.rb
文件。创建用于删除非空存储桶的新文件:
[user@dev ~]$ vim del_non_empty_bucket.rb
将以下内容粘贴到文件中:
#!/usr/bin/env ruby load 'conn.rb' AWS::S3::Bucket.delete('my-new-bucket1', :force => true)
保存文件并退出编辑器。
使文件可执行:
[user@dev ~]$ chmod +x del_non_empty_bucket.rb
运行该文件:
[user@dev ~]$ ./del_non_empty_bucket.rb | echo $?
如果删除了存储桶,命令会返回
0
作为输出。创建用于删除对象的新文件:
[user@dev ~]$ vim delete_object.rb
将以下内容粘贴到文件中:
#!/usr/bin/env ruby load 'conn.rb' AWS::S3::S3Object.delete('hello.txt', 'my-new-bucket1')
保存文件并退出编辑器。
使文件可执行:
[user@dev ~]$ chmod +x delete_object.rb
运行该文件:
[user@dev ~]$ ./delete_object.rb
这将删除对象
hello.txt
。
2.3.7. 使用 Ruby AWS SDK 访问 Ceph 对象网关
您可以使用 Ruby 编程语言以及 aws-sdk
gem 用于 S3
访问。在用于通过 Ruby AWS::SDK
访问 Ceph 对象网关服务器的节点上执行下方所述的步骤。
先决条件
- Ceph 对象网关用户级访问权限.
- 访问 Ceph 对象网关的 root 级别访问节点。
- 互联网访问。
流程
安装
ruby
软件包:[root@dev ~]# yum install ruby
注意以上命令将安装
ruby
,它是rubygems
和ruby-libs
等基本依赖项。如果某种方式命令没有安装所有依赖项,请单独安装它们。安装
aws-sdk
Ruby 软件包:[root@dev ~]# gem install aws-sdk
创建项目目录:
[user@dev ~]$ mkdir ruby_aws_sdk [user@dev ~]$ cd ruby_aws_sdk
创建连接文件:
[user@ruby_aws_sdk]$ vim conn.rb
将以下内容粘贴到
conn.rb
文件中:语法
#!/usr/bin/env ruby require 'aws-sdk' require 'resolv-replace' Aws.config.update( endpoint: 'http://FQDN_OF_GATEWAY_NODE:8080', access_key_id: 'MY_ACCESS_KEY', secret_access_key: 'MY_SECRET_KEY', force_path_style: true, region: 'us-east-1' )
将
FQDN_OF_GATEWAY_NODE
替换为 Ceph 对象网关节点的 FQDN。将MY_ACCESS_KEY
和MY_SECRET_KEY
替换为您在为 S3 创建radosgw
用户进行S3
访问时生成的access_key
和secret_key
,如 Red Hat Ceph Storage Object Gateway Configuration and Administration Guide 中所述。示例
#!/usr/bin/env ruby require 'aws-sdk' require 'resolv-replace' Aws.config.update( endpoint: 'http://testclient.englab.pnq.redhat.com:8080', access_key_id: '98J4R9P22P5CDL65HKP8', secret_access_key: '6C+jcaP0dp0+FZfrRNgyGA9EzRy25pURldwje049', force_path_style: true, region: 'us-east-1' )
保存文件并退出编辑器。
使文件可执行:
[user@ruby_aws_sdk]$ chmod +x conn.rb
运行该文件:
[user@ruby_aws_sdk]$ ./conn.rb | echo $?
如果您在文件中正确提供了值,命令的输出将是
0
。创建存储桶的新文件:
[user@ruby_aws_sdk]$ vim create_bucket.rb
将以下内容粘贴到文件中:
语法
#!/usr/bin/env ruby load 'conn.rb' s3_client = Aws::S3::Client.new s3_client.create_bucket(bucket: 'my-new-bucket2')
保存文件并退出编辑器。
使文件可执行:
[user@ruby_aws_sdk]$ chmod +x create_bucket.rb
运行该文件:
[user@ruby_aws_sdk]$ ./create_bucket.rb
如果命令的输出为
true
,这表示 bucketmy-new-bucket2
已创建成功。创建用于列出所拥有的存储桶的新文件:
[user@ruby_aws_sdk]$ vim list_owned_buckets.rb
将以下内容粘贴到文件中:
#!/usr/bin/env ruby load 'conn.rb' s3_client = Aws::S3::Client.new s3_client.list_buckets.buckets.each do |bucket| puts "{bucket.name}\t{bucket.creation_date}" end
保存文件并退出编辑器。
使文件可执行:
[user@ruby_aws_sdk]$ chmod +x list_owned_buckets.rb
运行该文件:
[user@ruby_aws_sdk]$ ./list_owned_buckets.rb
输出应类似如下:
my-new-bucket2 2022-04-21 10:33:19 UTC
创建用于创建对象的新文件:
[user@ruby_aws_sdk]$ vim create_object.rb
将以下内容粘贴到文件中:
#!/usr/bin/env ruby load 'conn.rb' s3_client = Aws::S3::Client.new s3_client.put_object( key: 'hello.txt', body: 'Hello World!', bucket: 'my-new-bucket2', content_type: 'text/plain' )
保存文件并退出编辑器。
使文件可执行:
[user@ruby_aws_sdk]$ chmod +x create_object.rb
运行该文件:
[user@ruby_aws_sdk]$ ./create_object.rb
这将创建一个含有字符串
Hello World!
的文件hello.txt
。创建用于列出存储桶内容的新文件:
[user@ruby_aws_sdk]$ vim list_bucket_content.rb
将以下内容粘贴到文件中:
#!/usr/bin/env ruby load 'conn.rb' s3_client = Aws::S3::Client.new s3_client.list_objects(bucket: 'my-new-bucket2').contents.each do |object| puts "{object.key}\t{object.size}" end
保存文件并退出编辑器。
使文件成为可执行文件。
[user@ruby_aws_sdk]$ chmod +x list_bucket_content.rb
运行该文件:
[user@ruby_aws_sdk]$ ./list_bucket_content.rb
输出将类似如下:
hello.txt 12 Fri, 22 Apr 2022 15:54:52 GMT
创建用于删除空存储桶的新文件:
[user@ruby_aws_sdk]$ vim del_empty_bucket.rb
将以下内容粘贴到文件中:
#!/usr/bin/env ruby load 'conn.rb' s3_client = Aws::S3::Client.new s3_client.delete_bucket(bucket: 'my-new-bucket2')
保存文件并退出编辑器。
使文件可执行:
[user@ruby_aws_sdk]$ chmod +x del_empty_bucket.rb
运行该文件:
[user@ruby_aws_sdk]$ ./del_empty_bucket.rb | echo $?
如果删除了存储桶,命令会返回
0
作为输出。注意编辑
create_bucket.rb
文件以创建空存储桶,例如:my-new-bucket6
、my-new-bucket7
。接下来,在尝试删除空存储桶前相应地编辑上述del_empty_bucket.rb
文件。创建用于删除非空存储桶的新文件:
[user@ruby_aws_sdk]$ vim del_non_empty_bucket.rb
将以下内容粘贴到文件中:
#!/usr/bin/env ruby load 'conn.rb' s3_client = Aws::S3::Client.new Aws::S3::Bucket.new('my-new-bucket2', client: s3_client).clear! s3_client.delete_bucket(bucket: 'my-new-bucket2')
保存文件并退出编辑器。
使文件可执行:
[user@ruby_aws_sdk]$ chmod +x del_non_empty_bucket.rb
运行该文件:
[user@ruby_aws_sdk]$ ./del_non_empty_bucket.rb | echo $?
如果删除了存储桶,命令会返回
0
作为输出。创建用于删除对象的新文件:
[user@ruby_aws_sdk]$ vim delete_object.rb
将以下内容粘贴到文件中:
#!/usr/bin/env ruby load 'conn.rb' s3_client = Aws::S3::Client.new s3_client.delete_object(key: 'hello.txt', bucket: 'my-new-bucket2')
保存文件并退出编辑器。
使文件可执行:
[user@ruby_aws_sdk]$ chmod +x delete_object.rb
运行该文件:
[user@ruby_aws_sdk]$ ./delete_object.rb
这将删除对象
hello.txt
。
2.3.8. 使用 PHP 访问 Ceph 对象网关
您可以使用 PHP 脚本进行 S3 访问。此流程提供一些示例 PHP 脚本来执行各种任务,如删除存储桶或对象。
以下给出的示例针对 php v5.4.16
和 aws-sdk v2.8.24
测试。不要使用最新版本的 aws-sdk
for php
,因为它需要没有包括在 RHEL 7
默认仓库中的 php >= 5.5+
.php 5.5
。如果要使用 php 5.5
,则必须启用 epel
和其他第三方存储库。另外,php 5.5
和最新版本的 aws-sdk
的配置选项也不同。
先决条件
- 根级访问开发工作站。
- 互联网访问。
流程
安装
php
软件包:[root@dev ~]# yum install php
-
下载适用于 PHP 的
aws-sdk
的 zip 存档并解压缩。 创建项目目录:
[user@dev ~]$ mkdir php_s3 [user@dev ~]$ cd php_s3
将提取的
aws
目录复制到项目目录中。例如:[user@php_s3]$ cp -r ~/Downloads/aws/ ~/php_s3/
创建连接文件:
[user@php_s3]$ vim conn.php
将以下内容粘贴到
conn.php
文件中:语法
<?php define('AWS_KEY', 'MY_ACCESS_KEY'); define('AWS_SECRET_KEY', 'MY_SECRET_KEY'); define('HOST', 'FQDN_OF_GATEWAY_NODE'); define('PORT', '8080'); // require the AWS SDK for php library require '/PATH_TO_AWS/aws-autoloader.php'; use Aws\S3\S3Client; // Establish connection with host using S3 Client client = S3Client::factory(array( 'base_url' => HOST, 'port' => PORT, 'key' => AWS_KEY, 'secret' => AWS_SECRET_KEY )); ?>
将
FQDN_OF_GATEWAY_NODE
替换为网关节点的 FQDN。按照 Red Hat Ceph Storage Object Gateway Configuration 和 Administration Guide 所述,将MY_ACCESS_KEY
和MY_SECRET_KEY
替换为创建S3
访问时生成的access_key
和secret_key
。使用您复制到
php
项目目录的提取的aws
目录替换PATH_TO_AWS
。保存文件并退出编辑器。
运行该文件:
[user@php_s3]$ php -f conn.php | echo $?
如果您在文件中正确提供了值,命令的输出将是
0
。创建存储桶的新文件:
[user@php_s3]$ vim create_bucket.php
将以下内容粘贴到新文件中:
语法
<?php include 'conn.php'; client->createBucket(array('Bucket' => 'my-new-bucket3')); ?>
保存文件并退出编辑器。
运行该文件:
[user@php_s3]$ php -f create_bucket.php
创建用于列出所拥有的存储桶的新文件:
[user@php_s3]$ vim list_owned_buckets.php
将以下内容粘贴到文件中:
语法
<?php include 'conn.php'; blist = client->listBuckets(); echo "Buckets belonging to " . blist['Owner']['ID'] . ":\n"; foreach (blist['Buckets'] as b) { echo "{b['Name']}\t{b['CreationDate']}\n"; } ?>
保存文件并退出编辑器。
运行该文件:
[user@php_s3]$ php -f list_owned_buckets.php
输出应类似于如下:
my-new-bucket3 2022-04-21 10:33:19 UTC
首先创建名为
hello.txt
的源文件,以创建对象:[user@php_s3]$ echo "Hello World!" > hello.txt
创建新 php 文件:
[user@php_s3]$ vim create_object.php
将以下内容粘贴到文件中:
语法
<?php include 'conn.php'; key = 'hello.txt'; source_file = './hello.txt'; acl = 'private'; bucket = 'my-new-bucket3'; client->upload(bucket, key, fopen(source_file, 'r'), acl); ?>
保存文件并退出编辑器。
运行该文件:
[user@php_s3]$ php -f create_object.php
这将在 bucket
my-new-bucket3
中创建对象hello.txt
。创建用于列出存储桶内容的新文件:
[user@php_s3]$ vim list_bucket_content.php
将以下内容粘贴到文件中:
语法
<?php include 'conn.php'; o_iter = client->getIterator('ListObjects', array( 'Bucket' => 'my-new-bucket3' )); foreach (o_iter as o) { echo "{o['Key']}\t{o['Size']}\t{o['LastModified']}\n"; } ?>
保存文件并退出编辑器。
运行该文件:
[user@php_s3]$ php -f list_bucket_content.php
输出类似如下:
hello.txt 12 Fri, 22 Apr 2022 15:54:52 GMT
创建用于删除空存储桶的新文件:
[user@php_s3]$ vim del_empty_bucket.php
将以下内容粘贴到文件中:
语法
<?php include 'conn.php'; client->deleteBucket(array('Bucket' => 'my-new-bucket3')); ?>
保存文件并退出编辑器。
运行该文件:
[user@php_s3]$ php -f del_empty_bucket.php | echo $?
如果删除了存储桶,命令会返回
0
作为输出。注意编辑
create_bucket.php
文件以创建空存储桶,例如:my-new-bucket4、
my-new-bucket5
。接下来,在尝试删除空存储桶前相应地编辑上述del_empty_bucket.php
文件。重要PHP 2 和
aws-sdk
的新版本不支持删除非空存储桶。创建用于删除对象的新文件:
[user@php_s3]$ vim delete_object.php
将以下内容粘贴到文件中:
语法
<?php include 'conn.php'; client->deleteObject(array( 'Bucket' => 'my-new-bucket3', 'Key' => 'hello.txt', )); ?>
保存文件并退出编辑器。
运行该文件:
[user@php_s3]$ php -f delete_object.php
这将删除对象
hello.txt
。
2.3.9. 使用 AWS CLI 访问 Ceph 对象网关
您可以使用 AWS CLI 进行 S3 访问。此流程提供安装 AWS CLI 和一些示例命令来执行各种任务的步骤,如从 MFA-Delete 启用了存储桶中删除对象。
先决条件
- Ceph 对象网关用户级访问权限.
- 根级访问开发工作站。
-
使用
radosgw-admin mfa create
创建多因素身份验证(MFA) TOTP 令牌
流程
安装
awscli
软件包:[user@dev]$ pip3 install --user awscli
配置
awscli
以使用 AWS CLI 访问 Ceph 对象存储:语法
aws configure --profile=MY_PROFILE_NAME AWS Access Key ID [None]: MY_ACCESS_KEY AWS Secret Access Key [None]: MY_SECRET_KEY Default region name [None]: Default output format [None]:
将
MY_PROFILE_NAME
替换为您要用来识别此配置集的名称。按照 Red Hat Ceph Storage Object Gateway Configuration 和 Administration Guide 所述,将MY_ACCESS_KEY
和MY_SECRET_KEY
替换为创建S3
访问时生成的access_key
和secret_key
。示例
[user@dev]$ aws configure --profile=ceph AWS Access Key ID [None]: 12345 AWS Secret Access Key [None]: 67890 Default region name [None]: Default output format [None]:
创建一个别名以指向 Ceph 对象网关节点的 FQDN:
语法
alias aws="aws --endpoint-url=http://FQDN_OF_GATEWAY_NODE:8080"
将
FQDN_OF_GATEWAY_NODE
替换为 Ceph 对象网关节点的 FQDN。示例
[user@dev]$ alias aws="aws --endpoint-url=http://testclient.englab.pnq.redhat.com:8080"
创建新存储桶:
语法
aws --profile=MY_PROFILE_NAME s3api create-bucket --bucket BUCKET_NAME
将
MY_PROFILE_NAME
替换为您创建使用此配置集的名称。将BUCKET_NAME
替换为新存储桶的名称。示例
[user@dev]$ aws --profile=ceph s3api create-bucket --bucket mybucket
列出拥有的存储桶:
语法
aws --profile=MY_PROFILE_NAME s3api list-buckets
将
MY_PROFILE_NAME
替换为您创建使用此配置集的名称。示例
[user@dev]$ aws --profile=ceph s3api list-buckets { "Buckets": [ { "Name": "mybucket", "CreationDate": "2021-08-31T16:46:15.257Z" } ], "Owner": { "DisplayName": "User", "ID": "user" } }
为 MFA-Delete 配置存储桶:
语法
aws --profile=MY_PROFILE_NAME s3api put-bucket-versioning --bucket BUCKET_NAME --versioning-configuration '{"Status":"Enabled","MFADelete":"Enabled"}' --mfa 'TOTP_SERIAL TOTP_PIN'
-
将
MY_PROFILE_NAME
替换为您创建使用此配置集的名称。 -
将
BUCKET_NAME
替换为新存储桶的名称。 -
将
TOTP_SERIAL
替换为 TOTP 令牌的 ID,并将TOTP_PIN
替换为 MFA 身份验证设备上的当前 pin。 -
TOTP_SERIAL
是为 S3 创建 radosgw 用户时指定的字符串。 - 有关创建 MFA TOTP 令牌的详情,请参阅 Red Hat Ceph Storage Object Gateway Configuration 和 Administration Guide 中创建新的多因素身份验证 TOTP 令牌 部分。
有关使用 oathtool 创建 MFA seed for multi-factor authentication 部分,请参阅 Red Hat Ceph Storage Developer Guide 中的 oathtool 部分。
示例
[user@dev]$ aws --profile=ceph s3api put-bucket-versioning --bucket mybucket --versioning-configuration '{"Status":"Enabled","MFADelete":"Enabled"}' --mfa 'MFAtest 232009'
-
将
查看存储桶版本状态的 MFA-Delete 状态:
语法
aws --profile=MY_PROFILE_NAME s3api get-bucket-versioning --bucket BUCKET_NAME
将
MY_PROFILE_NAME
替换为您创建使用此配置集的名称。将BUCKET_NAME
替换为新存储桶的名称。示例
[user@dev]$ aws --profile=ceph s3api get-bucket-versioning --bucket mybucket { "Status": "Enabled", "MFADelete": "Enabled" }
在启用了 MFA-Delete 的存储桶中添加对象:
语法
aws --profile=MY_PROFILE_NAME s3api put-object --bucket BUCKET_NAME --key OBJECT_KEY --body LOCAL_FILE
-
将
MY_PROFILE_NAME
替换为您创建使用此配置集的名称。 -
将
BUCKET_NAME
替换为新存储桶的名称。 -
将
OBJECT_KEY
替换为将唯一标识存储桶中对象的名称。 将
LOCAL_FILE
替换为要上传的本地文件的名称。示例
[user@dev]$ aws --profile=ceph s3api put-object --bucket mybucket --key example --body testfile { "ETag": "\"5679b828547a4b44cfb24a23fd9bb9d5\"", "VersionId": "3VyyYPTEuIofdvMPWbr1znlOu7lJE3r" }
-
将
列出特定对象的对象版本:
语法
aws --profile=MY_PROFILE_NAME s3api list-object-versions --bucket BUCKET_NAME --key OBJEC_KEY]
-
将
MY_PROFILE_NAME
替换为您创建使用此配置集的名称。 -
将
BUCKET_NAME
替换为新存储桶的名称。 将
OBJECT_KEY
替换为在存储桶中唯一标识对象的名称。示例
[user@dev]$ aws --profile=ceph s3api list-object-versions --bucket mybucket --key example { "IsTruncated": false, "KeyMarker": "example", "VersionIdMarker": "", "Versions": [ { "ETag": "\"5679b828547a4b44cfb24a23fd9bb9d5\"", "Size": 196, "StorageClass": "STANDARD", "Key": "example", "VersionId": "3VyyYPTEuIofdvMPWbr1znlOu7lJE3r", "IsLatest": true, "LastModified": "2021-08-31T17:48:45.484Z", "Owner": { "DisplayName": "User", "ID": "user" } } ], "Name": "mybucket", "Prefix": "", "MaxKeys": 1000, "EncodingType": "url" }
-
将
在启用了 MFA-Delete 的存储桶中删除对象:
语法
aws --profile=MY_PROFILE_NAME s3api delete-object --bucket BUCKET_NAME --key OBJECT_KEY --version-id VERSION_ID --mfa 'TOTP_SERIAL TOTP_PIN'
-
将
MY_PROFILE_NAME
替换为您创建使用此配置集的名称。 -
将
BUCKET_NAME
替换为包含要删除的对象的存储桶的名称。 -
将
OBJECT_KEY
替换为唯一标识 bucket 中对象的名称。 -
将
VERSION_ID
替换为您要删除的对象的特定版本的 VersionID。 将
TOTP_SERIAL
替换为代表 TOTP 令牌的 ID 和TOTP_PIN
的字符串,在您的 MFA 身份验证设备上显示当前的 pin。示例
[user@dev]$ aws --profile=ceph s3api delete-object --bucket mybucket --key example --version-id 3VyyYPTEuIofdvMPWbr1znlOu7lJE3r --mfa 'MFAtest 420797' { "VersionId": "3VyyYPTEuIofdvMPWbr1znlOu7lJE3r" }
如果没有包含 MFA 令牌,则请求会失败并显示以下错误。
示例
[user@dev]$ aws --profile=ceph s3api delete-object --bucket mybucket --key example --version-id 3VyyYPTEuIofdvMPWbr1znlOu7lJE3r An error occurred (AccessDenied) when calling the DeleteObject operation: Unknown
-
将
列出对象版本以验证是否已从 MFA-Delete 启用存储桶中删除:
语法
aws --profile=MY_PROFILE_NAME s3api list-object-versions --bucket BUCKET_NAME --key OBJECT_KEY
-
将
MY_PROFILE_NAME
替换为您创建使用此配置集的名称。 -
将
BUCKET_NAME
替换为存储桶的名称。 将
OBJECT_KEY
替换为唯一标识 bucket 中对象的名称。示例
[user@dev]$ aws --profile=ceph s3api list-object-versions --bucket mybucket --key example { "IsTruncated": false, "KeyMarker": "example", "VersionIdMarker": "", "Name": "mybucket", "Prefix": "", "MaxKeys": 1000, "EncodingType": "url" }
-
将
2.3.10. 使用 oathtool 命令为多因素身份验证创建 seed
要设置多因素身份验证(MFA),您必须创建一个 secret,供基于时间的一次性密码(TOTP)生成器和后端 MFA 系统使用。您可以使用 oathtool
生成十六进制的 seed 以及可选的 qrencode
来创建 QR 代码,将令牌导入到您的 MFA 设备。
先决条件
- Linux 系统。
- 访问命令行 shell.
-
root
或sudo
访问 Linux 系统。
流程
安装
oathtool
软件包:[root@dev]# dnf install oathtool
安装
qrencode
软件包:[root@dev]# dnf install qrencode
从
urandom
Linux 设备文件中生成 30 个字符,并将其存储在 shell 变量SEED
中:示例
[user@dev]$ SEED=$(head -10 /dev/urandom | sha512sum | cut -b 1-30)
通过在
SEED
变量中运行 echo 来打印 seed:示例
[user@dev]$ echo $SEED BA6GLJBJIKC3D7W7YFYXXAQ7
将
SEED
馈送到 oathtool 命令中:语法
oathtool -v -d6 $SEED
示例
[user@dev]$ oathtool -v -d6 $SEED Hex secret: 083c65a4294285b1fedfc1717b821f Base32 secret: BA6GLJBJIKC3D7W7YFYXXAQ7 Digits: 6 Window size: 0 Start counter: 0x0 (0) 823182
注意base32 secret 需要在您的 MFA 设备的 authenticator 应用程序中添加令牌。您可以使用 QR 代码将令牌导入到验证器应用程序,或使用 base32 机密手动添加它。
可选:创建一个 QR 代码镜像文件,将令牌添加到验证器中:
语法
qrencode -o /tmp/user.png 'otpauth://totp/TOTP_SERIAL?secret=_BASE32_SECRET'
将
TOTP_SERIAL
替换为代表(TOTP)令牌 ID 的字符串,并将BASE32_SECRET
替换为 oathtool 生成的 Base32 secret。示例
[user@dev]$ qrencode -o /tmp/user.png 'otpauth://totp/MFAtest?secret=BA6GLJBJIKC3D7W7YFYXXAQ7'
- 扫描生成的 QR 代码镜像文件,将令牌添加到 MFA 设备的验证器应用程序中。
-
使用
radowgw-admin
命令为用户创建多因素身份验证 TOTP 令牌。
2.3.11. 安全令牌服务
Amazon Web Services 的安全令牌服务(STS)返回一组临时安全凭证来验证用户。Ceph 对象网关实施 STS 应用程序编程接口(API)的子集,为身份和访问管理(IAM)提供临时凭证。使用这些临时凭证,通过在 Ceph 对象网关中使用 STS 引擎来验证 S3 调用。您可以使用 IAM 策略限制临时凭证,该策略是传递给 STS API 的参数。
其它资源
- Amazon Web Services Secure Token Service 欢迎页面。
- 有关 STS Lite 和 Keystone 的详细信息,请参阅 Red Hat Ceph Storage 开发者指南中的" 配置并使用 STS Lite" 一节。
- 有关 STS Lite 和 Keystone 的限制,请参阅 Red Hat Ceph Storage Developer Guide 的使用 STS Lite 和 Keystone 的限制。
2.3.11.1. 安全令牌服务应用程序编程接口
Ceph 对象网关实施下列安全令牌服务(STS)应用程序编程接口(API):
AssumeRole
此 API 返回一组临时凭证,用于跨帐户访问。这些临时凭证都允许,附加了 AssumeRole API 的 Role 和策略的权限策略。RoleArn
和 RoleSessionName
请求参数是必需的,但其他请求参数是可选的。
RoleArn
- 描述
- 假定为 Amazon 资源名(ARN)的角色,长度为 20 到 2048 个字符。
- Type
- 字符串
- 必需
- 是
RoleSessionName
- 描述
-
识别要假定的角色会话名称。当不同的主体或不同的原因假设角色时,角色会话名称可以唯一标识一个会话。此参数的值的长度为 2 到 64 个字符。允许
=
、、、、、@
和-
字符,但不允许有空格。 - Type
- 字符串
- 必需
- 是
policy
- 描述
- 以 JSON 格式的身份和访问管理策略(IAM),用于在内联会话中使用。此参数的值的长度为 1 到 2048 个字符。
- Type
- 字符串
- 必需
- 否
DurationSeconds
- 描述
-
会话持续时间(以秒为单位),最小值为
900
秒,最大值为43200
秒。默认值为3600
秒。 - Type
- 整数
- 必需
- 否
ExternalId
- 描述
- 假设另一个帐户的角色时,请提供一个唯一的外部标识符(如果可用)。这个参数的值的长度为 2 到 1224 个字符。
- Type
- 字符串
- 必需
- 否
SerialNumber
- 描述
- 用户从关联的多因素身份验证(MFA)设备识别号。参数的值可以是硬件设备或虚拟设备的序列号,长度为 9 到 256 个字符。
- Type
- 字符串
- 必需
- 否
TokenCode
- 描述
- 如果信任策略需要 MFA,则从多因素身份验证(MFA)设备生成的值。如果需要 MFA 设备,如果此参数的值为空或过期,则 AssumeRole 调用会返回 "access denied" 错误消息。这个参数的值的固定长度为 6 个字符。
- Type
- 字符串
- 必需
- 否
AssumeRoleWithWebIdentity
此 API 为应用进行身份验证的用户返回一组临时凭据,如 OpenID Connect 或 OAuth 2.0 身份提供程序。RoleArn
和 RoleSessionName
请求参数是必需的,但其他请求参数是可选的。
RoleArn
- 描述
- 假定为 Amazon 资源名(ARN)的角色,长度为 20 到 2048 个字符。
- Type
- 字符串
- 必需
- 是
RoleSessionName
- 描述
-
识别要假定的角色会话名称。当不同的主体或不同的原因假设角色时,角色会话名称可以唯一标识一个会话。此参数的值的长度为 2 到 64 个字符。允许
=
、、、、、@
和-
字符,但不允许有空格。 - Type
- 字符串
- 必需
- 是
policy
- 描述
- 以 JSON 格式的身份和访问管理策略(IAM),用于在内联会话中使用。此参数的值的长度为 1 到 2048 个字符。
- Type
- 字符串
- 必需
- 否
DurationSeconds
- 描述
-
会话持续时间(以秒为单位),最小值为
900
秒,最大值为43200
秒。默认值为3600
秒。 - Type
- 整数
- 必需
- 否
ProviderId
- 描述
- 身份提供程序中域名的完全限定主机组件。此参数的值仅对 OAuth 2.0 访问令牌有效,长度为 4 到 2048 个字符。
- Type
- 字符串
- 必需
- 否
WebIdentityToken
- 描述
- 从身份提供程序提供的 OpenID Connect 身份令牌或 OAuth 2.0 访问令牌。此参数的值的长度为 4 到 2048 个字符。
- Type
- 字符串
- 必需
- 否
其它资源
- 如需了解更多详细信息,请参阅 Red Hat Ceph Storage 开发者指南中的使用 安全令牌服务 API 部分的示例。
- Amazon Web Services Security Token Service,AssumeRole 操作。
- Amazon Web Services Security Token Service,AssumeRoleWithWebIdentity 操作。
2.3.11.2. 配置安全令牌服务
配置安全令牌服务(STS),以用于使用 Ceph Ansible 的 Ceph 对象网关。
S3 和 STS API 共同存在于同一命名空间中,两者都可从 Ceph 对象网关中的同一端点访问。
先决条件
- Ceph Ansible 管理节点。
- 一个正在运行的 Red Hat Ceph Storage 集群。
- 正在运行的 Ceph 对象网关.
流程
打开以编辑
group_vars/rgws.yml
文件。添加以下行:
rgw_sts_key = STS_KEY rgw_s3_auth_use_sts = true
替换:
-
STS_KEY
带有用于加密会话令牌的密钥。
-
-
保存对
group_vars/rgws.yml
文件的更改。 再次运行适当的 Ceph Ansible playbook:
裸机部署:
[user@admin ceph-ansible]$ ansible-playbook site.yml --limit rgws
容器部署:
[user@admin ceph-ansible]$ ansible-playbook site-docker.yml --limit rgws
其它资源
- 有关 STS API 的详情,请参阅 Red Hat Ceph Storage 开发者指南中的安全令牌服务应用程序接口 部分。
2.3.11.3. 为 OpenID Connect 供应商创建用户
要在 Ceph 对象网关和 OpenID Connect 供应商间建立信任,请创建一个用户实体和角色信任策略。
先决条件
- Ceph 对象网关节点的用户级访问权限。
流程
创建新 Ceph 用户:
语法
radosgw-admin --uid USER_NAME --display-name "DISPLAY_NAME" --access_key USER_NAME --secret SECRET user create
示例
[user@rgw ~]$ radosgw-admin --uid TESTER --display-name "TestUser" --access_key TESTER --secret test123 user create
配置 Ceph 用户功能:
语法
radosgw-admin caps add --uid="USER_NAME" --caps="oidc-provider=*"
示例
[user@rgw ~]$ radosgw-admin caps add --uid="TESTER" --caps="oidc-provider=*"
使用 Secure Token Service(STS)API 在角色信任策略中添加条件:
语法
"{\"Version\":\"2020-01-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Federated\":[\"arn:aws:iam:::oidc-provider/IDP_URL\"]},\"Action\":[\"sts:AssumeRoleWithWebIdentity\"],\"Condition\":{\"StringEquals\":{\"IDP_URL:app_id\":\"AUD_FIELD\"\}\}\}\]\}"
重要上述语法示例中的
app_id
必须与传入令牌的AUD_FIELD
字段匹配。
其它资源
- 有关 Amazon 网站上的 OpenID Connect 身份提供商文章,请参阅 Obtaining Root CA Thumbprint。
- 有关 STS API 的详情,请参阅 Red Hat Ceph Storage 开发者指南中的安全令牌服务应用程序接口 部分。
- 如需了解更多详细信息,请参阅 Red Hat Ceph Storage 开发者指南中的使用 安全令牌服务 API 部分的示例。
2.3.11.4. 获取 OpenID Connect 供应商的 thumbprint
要获得 OpenID Connect 供应商(IDP)配置文档。
先决条件
-
安装
openssl
和curl
软件包。
流程
从 IDP 的 URL 获取配置文档:
语法
curl -k -v \ -X GET \ -H "Content-Type: application/x-www-form-urlencoded" \ "IDP_URL:8000/CONTEXT/realms/REALM/.well-known/openid-configuration" \ | jq .
示例
[user@client ~]$ curl -k -v \ -X GET \ -H "Content-Type: application/x-www-form-urlencoded" \ "http://www.example.com:8000/auth/realms/quickstart/.well-known/openid-configuration" \ | jq .
获取 IDP 证书:
语法
curl -k -v \ -X GET \ -H "Content-Type: application/x-www-form-urlencoded" \ "IDP_URL/CONTEXT/realms/REALM/protocol/openid-connect/certs" \ | jq .
示例
[user@client ~]$ curl -k -v \ -X GET \ -H "Content-Type: application/x-www-form-urlencoded" \ "http://www.example.com/auth/realms/quickstart/protocol/openid-connect/certs" \ | jq .
-
复制上一命令中的"x5c"响应的结果,并将它粘贴到
certificate.crt
文件中。在末尾末尾包括--BEGIN CERTIFICATE--
-- 获取证书指纹:
语法
openssl x509 -in CERT_FILE -fingerprint -noout
示例
[user@client ~]$ openssl x509 -in certificate.crt -fingerprint -noout SHA1 Fingerprint=F7:D7:B3:51:5D:D0:D3:19:DD:21:9A:43:A9:EA:72:7A:D6:06:52:87
- 从 SHA1 指纹中删除所有冒号,并将其用作在 IAM 请求中创建 IDP 实体的输入。
其它资源
- 有关 Amazon 网站上的 OpenID Connect 身份提供商文章,请参阅 Obtaining Root CA Thumbprint。
- 有关 STS API 的详情,请参阅 Red Hat Ceph Storage 开发者指南中的安全令牌服务应用程序接口 部分。
- 如需了解更多详细信息,请参阅 Red Hat Ceph Storage 开发者指南中的使用 安全令牌服务 API 部分的示例。
2.3.11.5. 在 Keystone 中配置和使用 STS Lite(技术预览)
同一命名空间中的 Amazon 安全令牌服务(STS)和 S3 API 共存。STS 选项可以和 Keystone 选项一起配置。
S3 和 STS API 都可以使用 Ceph 对象网关中的同一端点来访问。
先决条件
- Red Hat Ceph Storage 3.2 或更高版本。
- 正在运行的 Ceph 对象网关.
- 安装 Boto Python 模块,版本 3 或更高版本。
流程
使用以下选项打开并编辑
group_vars/rgws.yml
文件:rgw_sts_key = STS_KEY rgw_s3_auth_use_sts = true
替换:
-
STS_KEY
带有用于加密会话令牌的密钥。
-
再次运行适当的 Ceph Ansible playbook:
裸机部署:
[user@admin ceph-ansible]$ ansible-playbook site.yml --limit rgws
容器部署:
[user@admin ceph-ansible]$ ansible-playbook site-docker.yml --limit rgws
生成 EC2 凭证:
示例
[user@osp ~]$ openstack ec2 credentials create +------------+--------------------------------------------------------+ | Field | Value | +------------+--------------------------------------------------------+ | access | b924dfc87d454d15896691182fdeb0ef | | links | {u'self': u'http://192.168.0.15/identity/v3/users/ | | | 40a7140e424f493d8165abc652dc731c/credentials/ | | | OS-EC2/b924dfc87d454d15896691182fdeb0ef'} | | project_id | c703801dccaf4a0aaa39bec8c481e25a | | secret | 6a2142613c504c42a94ba2b82147dc28 | | trust_id | None | | user_id | 40a7140e424f493d8165abc652dc731c | +------------+--------------------------------------------------------+
使用生成的凭证,通过 GetSessionToken API 来备份一组临时安全凭证。
示例
import boto3 access_key = b924dfc87d454d15896691182fdeb0ef secret_key = 6a2142613c504c42a94ba2b82147dc28 client = boto3.client('sts', aws_access_key_id=access_key, aws_secret_access_key=secret_key, endpoint_url=https://www.example.com/rgw, region_name='', ) response = client.get_session_token( DurationSeconds=43200 )
获取临时凭证可用于发出 S3 调用:
示例
s3client = boto3.client('s3', aws_access_key_id = response['Credentials']['AccessKeyId'], aws_secret_access_key = response['Credentials']['SecretAccessKey'], aws_session_token = response['Credentials']['SessionToken'], endpoint_url=https://www.example.com/s3, region_name='') bucket = s3client.create_bucket(Bucket='my-new-shiny-bucket') response = s3client.list_buckets() for bucket in response["Buckets"]: print "{name}\t{created}".format( name = bucket['Name'], created = bucket['CreationDate'], )
创建新的 S3Access 角色并配置策略。
使用管理 CAPS 为用户分配:
语法
radosgw-admin caps add --uid="USER" --caps="roles=*"
示例
[user@client]$ radosgw-admin caps add --uid="gwadmin" --caps="roles=*"
创建 S3Access 角色:
语法
radosgw-admin role create --role-name=ROLE_NAME --path=PATH --assume-role-policy-doc=TRUST_POLICY_DOC
示例
[user@client]$ radosgw-admin role create --role-name=S3Access --path=/application_abc/component_xyz/ --assume-role-policy-doc=\{\"Version\":\"2012-10-17\",\"Statement\":\[\{\"Effect\":\"Allow\",\"Principal\":\{\"AWS\":\[\"arn:aws:iam:::user/TESTER\"\]\},\"Action\":\[\"sts:AssumeRole\"\]\}\]\}
将权限策略附加到 S3Access 角色:
语法
radosgw-admin role-policy put --role-name=ROLE_NAME --policy-name=POLICY_NAME --policy-doc=PERMISSION_POLICY_DOC
示例
[user@client]$ radosgw-admin role-policy put --role-name=S3Access --policy-name=Policy --policy-doc=\{\"Version\":\"2012-10-17\",\"Statement\":\[\{\"Effect\":\"Allow\",\"Action\":\[\"s3:*\"\],\"Resource\":\"arn:aws:s3:::example_bucket\"\}\]\}
-
现在,另一个用户可以假定
gwadmin
用户的角色。例如,gwuser
用户可以假定gwadmin
用户权限。 记录假定用户的
access_key
和secret_key
值。示例
[user@client]$ radosgw-admin user info --uid=gwuser | grep -A1 access_key
使用 AssumeRole API 调用,提供来自假定用户的
access_key
和secret_key
值:示例
import boto3 access_key = 11BS02LGFB6AL6H1ADMW secret_key = vzCEkuryfn060dfee4fgQPqFrncKEIkh3ZcdOANY client = boto3.client('sts', aws_access_key_id=access_key, aws_secret_access_key=secret_key, endpoint_url=https://www.example.com/rgw, region_name='', ) response = client.assume_role( RoleArn='arn:aws:iam:::role/application_abc/component_xyz/S3Access', RoleSessionName='Bob', DurationSeconds=3600 )
重要AssumeRole API 需要 S3Access 角色。
其它资源
- 有关安装 Boto Python 模块的更多信息,请参阅 Red Hat Ceph Storage Object Gateway 指南中的 Test S3 Access 部分。
- 如需更多信息,请参阅 Red Hat Ceph Storage Object Gateway 指南中的 创建用户 部分。
2.3.11.6. 围绕将 STS Lite 与 Keystone 搭配使用的限制(技术预览)
Keystone 的一个限制是它不支持 STS 请求。请求中不包含另一个限制的有效负载哈希。要解决这两个限制,必须修改 Boto 身份验证代码。
先决条件
- 正在运行的 Red Hat Ceph Storage 集群,版本 3.2 或更高版本。
- 正在运行的 Ceph 对象网关.
- 安装 Boto Python 模块,版本 3 或更高版本。
流程
打开并编辑 Boto 的
auth.py
文件。将以下四行添加到代码块中:
class SigV4Auth(BaseSigner): """ Sign a request with Signature V4. """ REQUIRES_REGION = True def __init__(self, credentials, service_name, region_name): self.credentials = credentials # We initialize these value here so the unit tests can have # valid values. But these will get overriden in ``add_auth`` # later for real requests. self._region_name = region_name if service_name == 'sts': 1 self._service_name = 's3' 2 else: 3 self._service_name = service_name 4
将以下两行添加到代码块中:
def _modify_request_before_signing(self, request): if 'Authorization' in request.headers: del request.headers['Authorization'] self._set_necessary_date_headers(request) if self.credentials.token: if 'X-Amz-Security-Token' in request.headers: del request.headers['X-Amz-Security-Token'] request.headers['X-Amz-Security-Token'] = self.credentials.token if not request.context.get('payload_signing_enabled', True): if 'X-Amz-Content-SHA256' in request.headers: del request.headers['X-Amz-Content-SHA256'] request.headers['X-Amz-Content-SHA256'] = UNSIGNED_PAYLOAD 1 else: 2 request.headers['X-Amz-Content-SHA256'] = self.payload(request)
其它资源
- 有关安装 Boto Python 模块的更多信息,请参阅 Red Hat Ceph Storage Object Gateway 指南中的 Test S3 Access 部分。
2.3.12. STS 中基于属性访问控制(ABAC)的会话标签
会话标签是键值对,可在生成用户时传递。它们作为 aws:PrincipalTag
在会话中传递,或者由安全令牌服务(STS)返回的临时凭证。这些主体标签由会话标签组成,这些标签作为 web 令牌的一部分以及附加到所假定角色的标签组成。
目前,会话标签仅支持作为传递给 AssumeRoleWithWebIdentity
的 web 令牌的一部分。
标签必须始终在以下命名空间中指定: https://aws.amazon.com/tags
。
如果联合用户传递的 web 令牌包含会话标签,则信任策略必须具有 sts:TagSession
权限。否则,AssumeRoleWithWebIdentity
操作会失败。
带有 sts:TagSession
的信任策略示例:
{ "Version":"2012-10-17", "Statement":[ { "Effect":"Allow", "Action":["sts:AssumeRoleWithWebIdentity","sts:TagSession"], "Principal":{"Federated":["arn:aws:iam:::oidc-provider/localhost:8080/auth/realms/quickstart"]}, "Condition":{"StringEquals":{"localhost:8080/auth/realms/quickstart:sub":"test"}} }] }
Properties
以下是会话标签的属性:
会话标签可以是多值。
注意Amazon Web Service (AWS)不支持多值的会话标签。
- Keycloak 可以设置为最多 50 个会话标签的 OpenID Connect 身份提供程序(IDP)。
- 允许键的最大大小为 128 个字符。
- 允许的值是 256 个字符的最大值。
-
标签或值不能以
aws:
开头。
其它资源
- 有关 安全令牌服务 的更多信息,请参阅 Red Hat Ceph Storage 开发者指南中的 安全令牌服务部分。
2.3.12.1. 标签键
以下是可在角色信任策略或角色权限策略中使用的标签键。
aws:RequestTag
- 描述
将请求中传递的键值对与角色信任策略中的键值对进行比较。
如果
AssumeRoleWithWebIdentity
,会话标签可以在角色信任策略中用作aws:RequestTag
。这些会话标签由 web 令牌中的 Keycloak 传递。因此,联合用户可以假定角色。
aws:PrincipalTag
- 描述
将附加到主体的键值对与策略中的键值对进行比较。
如果
AssumeRoleWithWebIdentity
,当一个用户通过身份验证后,会话标签会在临时凭证中显示为主体标签。这些会话标签由 web 令牌中的 Keycloak 传递。在角色权限策略中,它们可以用作aws:PrincipalTag
。
iam:ResourceTag
- 描述
将附加到资源的键值对与策略中的键值对进行比较。
如果
AssumeRoleWithWebIdentity
,附加到该角色的标签与信任策略中的标签进行比较,以便用户假定角色。注意Ceph 对象网关现在支持 RESTful API 在角色上进行标记、列出标签和取消标记操作。
aws:TagKeys
- 描述
将请求中的标签与策略中的标签进行比较。
对于
AssumeRoleWithWebIdentity
,标签用于检查角色信任策略或权限策略中的标签键,然后再允许用户假定角色。
s3:ResourceTag
- 描述
将 S3 资源中存在的标签与角色权限策略中的标签进行比较,即 bucket 或对象。
它可用于在 Ceph 对象网关中授权 S3 操作。但是,AWS 中不允许这样做。
它是用于引用附加到对象或 bucket 的标签的关键。可以使用可用于相同功能的 RESTful API,将标签附加到对象或 bucket。
2.3.12.2. S3 资源标签
下表显示了支持哪些 S3 资源标签类型来授权特定操作。
- 标签类型:对象类型
- 操作
-
GetObject
,GetObjectTags
,DeleteObjectTags
,DeleteObject
,PutACLs
,InitMultipart
, AbortMultipart, 'ListMultipart
,GetAttrs
,PutObjectRetention
,GetObjectRetention
,PutObjectLegalHold
,GetObjectLegalHold
- 标签类型:Bucket 标签
- 操作
-
PutObjectTags
,GetBucketTags
,PutBucketTags
,DeleteBucketTags
,GetBucketReplication
,DeleteBucketReplication
,GetBucketVersioning
,SetBucketVersioning
,GetBucketWebsite
,SetBucketWebsite
,DeleteBucketWebsite
,StatBucket
,ListBucket
,GetBucketLogging
,GetBucketLocation
,DeleteBucket
,GetLC
,PutLC
,DeleteLC
,GetCORS
,PutCORS
, GetRequestPayment ,GetRequestPayment
,SetRequestPayment
.PutBucketPolicy
,GetBucketPolicy
,DeleteBucketPolicy
,PutBucketObjectLock
,GetBucketObjectLock
,GetBucketPolicyStatus
,PutBucketPublicAccessBlock
,GetBucketPublicAccessBlock
,DeleteBucketPublicAccessBlock
- 标签类型:存储桶 ACL 的 Bucket 标签,对象 ACL 的对象标签
- 操作
-
GetACLs
,PutACLs
- 标签类型:源对象的对象标签,目的地存储桶的 Bucket 标签
- 操作
-
PutObject
,CopyObject
2.4. S3 存储桶操作
作为开发者,您可以通过 Ceph 对象网关通过 Amazon S3 应用编程接口(API)执行存储桶操作。
下表列出了存储桶的 Amazon S3 功能操作,以及功能的支持状态。
功能 | Status | 备注 |
---|---|---|
支持 | ||
支持 | 不同的一组可实施 ACL。 | |
部分支持 |
支持 | |
部分支持 |
支持 | |
支持 | ||
支持 | ||
支持 | ||
支持 | ||
支持 | ||
支持 | ||
支持 | 不同的可处理 ACL 集 | |
支持 | 不同的可处理 ACL 集 | |
支持 | ||
支持 | ||
支持 | ||
支持 | ||
支持 | ||
支持 | ||
部分支持 | ||
支持 | ||
支持 | ||
支持 |
2.4.1. 先决条件
- 一个正在运行的 Red Hat Ceph Storage 集群。
- RESTful 客户端。
2.4.2. S3 创建存储桶通知
在 bucket 级别上创建 bucket 通知。通知配置具有 Red Hat Ceph Storage 对象网关 S3 事件,即 ObjectCreated
和 ObjectRemoved
。这些需要发布,以及发送 bucket 通知的目的地。bucket 通知是 S3 操作。
要为 s3:objectCreate
和 s3:objectRemove
事件创建存储桶通知,可使用 PUT:
示例
client.put_bucket_notification_configuration( Bucket=bucket_name, NotificationConfiguration={ 'TopicConfigurations': [ { 'Id': notification_name, 'TopicArn': topic_arn, 'Events': ['s3:ObjectCreated:*', 's3:ObjectRemoved:*'] }]})
红帽支持 ObjectCreate
事件,如 put
, post
, multipartUpload
, 和 copy
。红帽还支持 ObjectRemove
事件,如 object_delete
和 s3_multi_object_delete
。
请求实体
NotificationConfiguration
- 描述
-
TopicConfiguration
实体列表。 - Type
- Container
- 必需
- 是
TopicConfiguration
- 描述
-
事件主题的
Id
,Topic
和list
。 - Type
- Container
- 必需
- 是
id
- 描述
- 通知的名称。
- Type
- 字符串
- 必需
- 是
Topic
- 描述
Topic Amazon Resource Name(ARN)
注意必须事先创建主题。
- Type
- 字符串
- 必需
- 是
事件
- 描述
- 支持的事件列表。可以使用多个事件实体。如果省略,则处理所有事件。
- Type
- 字符串
- 必需
- 否
Filter
- 描述
-
S3Key
、S3Metadata
和S3Tags
实体。 - Type
- Container
- 必需
- 否
S3Key
- 描述
-
FilterRule
实体列表,用于根据对象密钥进行过滤。最多 3 个实体可能位于列表中,例如Name
可以是为prefix
,suffix
或regex
。列表中的所有过滤规则必须与过滤器匹配。 - Type
- Container
- 必需
- 否
S3Metadata
- 描述
-
FilterRule
实体列表,用于根据对象元数据进行过滤。列表中的所有过滤规则必须与对象中定义的元数据匹配。但是,如果对象具有过滤器中没有列出的其他元数据条目,则对象仍然匹配。 - Type
- Container
- 必需
- 否
S3Tags
- 描述
-
FilterRule
实体列表,用于根据对象标签进行过滤。列表中的所有过滤规则必须与对象中定义的标签匹配。但是,如果对象没有列在过滤器中,则对象仍然匹配。 - Type
- Container
- 必需
- 否
S3Key.FilterRule
- 描述
-
Name
和Value
实体。Name 为:prefix
,suffix
或regex
.值
会保存键前缀、键后缀或正则表达式,用于相应地匹配的密钥。 - Type
- Container
- 必需
- 是
S3Metadata.FilterRule
- 描述
-
Name
和Value
实体。name 是x-amz-meta-xxx
等 metadata 属性的名称。该值是此属性的预期值。 - Type
- Container
- 必需
- 是
S3Tags.FilterRule
- 描述
-
Name
和Value
实体。name 是 tag 键,值为 tag 值。 - Type
- Container
- 必需
- 是
HTTP 响应
400
- 状态代码
-
MalformedXML
- 描述
- XML 并未充分创建。
400
- 状态代码
-
InvalidArgument
- 描述
- 缺少 Id 或 missing 或 invalid topic ARN 或 invalid event。
404
- 状态代码
-
NoSuchBucket
- 描述
- bucket 不存在。
404
- 状态代码
-
NoSuchKey
- 描述
- 主题不存在。
id="s3-get-bucket-notifications_dev"]
2.4.3. S3 获取存储桶通知
获取特定的通知,或列出存储桶中配置的所有通知。
语法
Get /BUCKET?notification=NOTIFICATION_ID HTTP/1.1 Host: cname.domain.com Date: date Authorization: AWS ACCESS_KEY:HASH_OF_HEADER_AND_SECRET
示例
Get /testbucket?notification=testnotificationID HTTP/1.1 Host: cname.domain.com Date: date Authorization: AWS ACCESS_KEY:HASH_OF_HEADER_AND_SECRET
响应示例
<NotificationConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <TopicConfiguration> <Id></Id> <Topic></Topic> <Event></Event> <Filter> <S3Key> <FilterRule> <Name></Name> <Value></Value> </FilterRule> </S3Key> <S3Metadata> <FilterRule> <Name></Name> <Value></Value> </FilterRule> </S3Metadata> <S3Tags> <FilterRule> <Name></Name> <Value></Value> </FilterRule> </S3Tags> </Filter> </TopicConfiguration> </NotificationConfiguration>
notification
子资源返回存储桶通知配置或空 notification Configuration
元素。调用者必须是存储桶所有者。
请求实体
notification-id
- 描述
- 通知的名称。如果未提供 ID,则会列出所有通知。
- Type
- 字符串
NotificationConfiguration
- 描述
-
TopicConfiguration
实体列表。 - Type
- Container
- 必需
- 是
TopicConfiguration
- 描述
-
事件主题的
Id
,Topic
和list
。 - Type
- Container
- 必需
- 是
id
- 描述
- 通知的名称。
- Type
- 字符串
- 必需
- 是
Topic
- 描述
Topic Amazon Resource Name(ARN)
注意必须事先创建主题。
- Type
- 字符串
- 必需
- 是
事件
- 描述
- 处理的事件。可能存在多个事件实体。
- Type
- 字符串
- 必需
- 是
Filter
- 描述
- 指定配置的过滤器。
- Type
- Container
- 必需
- 否
HTTP 响应
404
- 状态代码
-
NoSuchBucket
- 描述
- bucket 不存在。
404
- 状态代码
-
NoSuchKey
- 描述
- 如果提供了通知,则不会存在。
2.4.4. S3 删除存储桶通知
从存储桶中删除特定或所有通知。
通知删除是对 S3 通知 API 的扩展。当存储桶被删除时,存储桶上所有定义的通知都会被删除。删除一个未知的示例 double delete
的通知不会被视为错误。
要删除特定或所有通知,请使用 DELETE:
语法
DELETE /BUCKET?notification=NOTIFICATION_ID HTTP/1.1
示例
DELETE /testbucket?notification=testnotificationID HTTP/1.1
请求实体
notification-id
- 描述
- 通知的名称。如果没有提供通知 ID,则存储桶上的所有通知都会被删除。
- Type
- 字符串
HTTP 响应
404
- 状态代码
-
NoSuchBucket
- 描述
- bucket 不存在。
2.4.5. 访问存储桶主机名
访问存储桶时有两种不同的模式。第一种方法和首选的方法将 bucket 标识为 URI 中的顶级目录。
示例
GET /mybucket HTTP/1.1 Host: cname.domain.com
第二种方法通过虚拟 bucket 主机名标识 bucket。
示例
GET / HTTP/1.1 Host: mybucket.cname.domain.com
红帽首选第一种方法,因为第二种方法需要昂贵的域认证和 DNS 通配符。
2.4.6. S3 列表存储桶
GET /
返回由发出请求的用户创建的 bucket 列表。GET /
仅返回由经过身份验证的用户创建的存储桶。您不能发出匿名请求。
语法
GET / HTTP/1.1 Host: cname.domain.com Authorization: AWS ACCESS_KEY:HASH_OF_HEADER_AND_SECRET
名称 | Type | 描述 |
---|---|---|
| Container | 用于存储桶列表的容器。 |
| Container | 用于存储桶信息的容器。 |
| 字符串 | bucket 名称. |
| Date | 创建存储桶时的 UTC 时间。 |
| Container | 用于结果的容器。 |
| Container |
bucket 所有者的 |
| 字符串 | bucket 所有者的 ID。 |
| 字符串 | bucket 所有者的显示名称。 |
2.4.7. S3 返回存储桶对象列表
返回存储桶对象列表。
语法
GET /BUCKET?max-keys=25 HTTP/1.1
Host: cname.domain.com
名称 | Type | 描述 |
---|---|---|
| 字符串 | 仅返回包含指定前缀的对象。 |
| 字符串 | 前缀与其他对象名称之间的分隔符。 |
| 字符串 | 返回的对象列表的开头索引。 |
| 整数 | 要返回的最大密钥数。默认值为 1000。 |
HTTP 状态 | 状态代码 | 描述 |
---|---|---|
| 确定 | 检索的存储桶 |
GET /BUCKET
返回存储桶的容器,并带有以下字段:
名称 | Type | 描述 |
---|---|---|
| 实体 | 容器,用于对象列表。 |
| 字符串 | 其内容要返回的存储桶的名称。 |
| 字符串 | 对象密钥的前缀。 |
| 字符串 | 返回的对象列表的开头索引。 |
| 整数 | 返回的最大键数。 |
| 字符串 |
如果设置,具有相同前缀的对象将显示在 |
| 布尔值 |
如果为 |
| Container | 如果多个对象包含相同的前缀,它们将显示在此列表中。 |
ListBucketResult
包含对象,其中每个对象都在一个 Contents
容器中。
名称 | Type | 描述 |
---|---|---|
| Object | 对象的容器。 |
| 字符串 | 对象的密钥。 |
| Date | 对象的最后修改日期/时间。 |
| 字符串 | 对象的 MD-5 哈希。(标签) |
| 整数 | 对象的大小。 |
| 字符串 |
应始终返回 |
2.4.8. S3 创建新存储桶
创建新存储桶。要创建存储桶,必须有用户 ID 和有效的 AWS 访问密钥 ID 才能验证请求。您不能以匿名用户身份创建存储桶。
约束
通常,存储桶名称应该遵循域名约束。
- bucket 名称必须是唯一的。
- bucket 名称必须以小写字母开头和结尾。
- bucket 名称可以包含短划线(-)。
语法
PUT /BUCKET HTTP/1.1 Host: cname.domain.com x-amz-acl: public-read-write Authorization: AWS ACCESS_KEY:HASH_OF_HEADER_AND_SECRET
名称 | 描述 | 有效值 | 必需 |
---|---|---|---|
| 不可禁用的 ACL. |
| 否 |
HTTP 响应
如果存储桶名称是唯一的,在约束和未使用范围内,操作会成功。如果具有相同名称的存储桶已经存在,并且该用户是 bucket 所有者,则操作将成功。如果存储桶名称已经在使用中,则操作将失败。
HTTP 状态 | 状态代码 | 描述 |
---|---|---|
| BucketAlreadyExists | bucket 已存在于不同用户的所有权下。 |
2.4.9. S3 删除存储桶
删除存储桶。您可以在成功删除存储桶后重复使用存储桶名称。
语法
DELETE /BUCKET HTTP/1.1 Host: cname.domain.com Authorization: AWS ACCESS_KEY:HASH_OF_HEADER_AND_SECRET
HTTP 状态 | 状态代码 | 描述 |
---|---|---|
| 无内容 | 已删除存储桶。 |
2.4.10. S3 存储桶生命周期
您可以使用存储桶生命周期配置来管理对象,以便在其生命周期内有效存储它们。Ceph 对象网关中的 S3 API 支持 AWS 存储桶生命周期操作的子集:
-
expiration
:这定义了存储桶内对象的寿命。取对象应实时或过期日期的天数,该日期指向 Ceph 对象网关将删除该对象。如果存储桶没有启用版本控制,Ceph 对象网关将永久删除对象。如果 bucket 启用版本控制,Ceph 对象网关为当前版本创建删除标记,然后删除当前版本。 -
NoncurrentVersionExpiration
:这定义了存储桶中非当前对象版本的寿命。要使用此功能,存储桶必须启用版本控制。它取非当前对象应处于活动状态的天数,此时 Ceph 对象网关将删除非当前对象。 -
AbortIncompleteMultipartUpload
:这定义了未完成的多部分上传在中止前的天数。
生命周期配置包含使用 <Rule>
元素的一个或多个规则。
示例
<LifecycleConfiguration> <Rule> <Prefix/> <Status>Enabled</Status> <Expiration> <Days>10</Days> </Expiration> </Rule> </LifecycleConfiguration>
生命周期规则可根据您在生命周期规则中指定的 < Filter>
; 元素,应用到存储桶中的所有对象子集。您可以使用以下方法指定过滤器:
- 密钥前缀
- 对象标签
- 密钥前缀和一个或多个对象标签
密钥前缀
您可以根据密钥名称前缀,将生命周期规则应用到对象的子集。例如,指定 <keypre/>
将应用到以 keypre/
开头的对象:
<LifecycleConfiguration> <Rule> <Status>Enabled</Status> <Filter> <Prefix>keypre/</Prefix> </Filter> </Rule> </LifecycleConfiguration>
您还可以将不同的生命周期规则应用到具有不同密钥前缀的对象:
<LifecycleConfiguration> <Rule> <Status>Enabled</Status> <Filter> <Prefix>keypre/</Prefix> </Filter> </Rule> <Rule> <Status>Enabled</Status> <Filter> <Prefix>mypre/</Prefix> </Filter> </Rule> </LifecycleConfiguration>
对象标签
您可以使用 <Key>
和 <Value>
元素将生命周期规则应用到带有特定标签的对象:
<LifecycleConfiguration> <Rule> <Status>Enabled</Status> <Filter> <Tag> <Key>key</Key> <Value>value</Value> </Tag> </Filter> </Rule> </LifecycleConfiguration>
前缀和一个或多个标签
在生命周期规则中,您可以根据密钥前缀和一个或多个标签指定过滤器。它们必须嵌套在 < And>
元素中。过滤器只能有一个前缀,以及零个或多个标签:
<LifecycleConfiguration> <Rule> <Status>Enabled</Status> <Filter> <And> <Prefix>key-prefix</Prefix> <Tag> <Key>key1</Key> <Value>value1</Value> </Tag> <Tag> <Key>key2</Key> <Value>value2</Value> </Tag> ... </And> </Filter> </Rule> </LifecycleConfiguration>
2.4.11. S3 GET 存储桶生命周期
要获取存储桶生命周期,请使用 GET
并指定目标存储桶。
语法
GET /BUCKET?lifecycle HTTP/1.1 Host: cname.domain.com Authorization: AWS ACCESS_KEY:HASH_OF_HEADER_AND_SECRET
请求 Headers
如需更多信息,请参阅 Common Request Headers。
响应
响应中包含存储桶生命周期及其元素。
2.4.12. S3 创建或替换存储桶生命周期
要创建或替换存储桶生命周期,请使用 PUT
,并指定目标存储桶和生命周期配置。Ceph 对象网关仅支持 S3 生命周期功能的子集。
语法
PUT /BUCKET?lifecycle HTTP/1.1 Host: cname.domain.com Authorization: AWS ACCESS_KEY:HASH_OF_HEADER_AND_SECRET <LifecycleConfiguration> <Rule> <Expiration> <Days>10</Days> </Expiration> </Rule> ... <Rule> </Rule> </LifecycleConfiguration>
名称 | 描述 | 有效值 | 必需 |
---|---|---|---|
content-md5 | 消息的 base64 编码 MD-5 哈希。 | 字符串无默认值或限制。 | 否 |
其它资源
- 有关常见 Amazon S3 请求标头 的详细信息,请参阅 Red Hat Ceph Storage Developer Guide。
- 如需了解有关 Amazon S3 存储桶生命周期 的详细信息,请参阅 Red Hat Ceph Storage 开发人员指南。
2.4.13. S3 删除存储桶生命周期
要删除存储桶生命周期,请使用 DELETE
并指定目标存储桶。
语法
DELETE /BUCKET?lifecycle HTTP/1.1 Host: cname.domain.com Authorization: AWS ACCESS_KEY:HASH_OF_HEADER_AND_SECRET
请求 Headers
请求不包含任何特殊元素。
响应
响应返回常见的响应状态。
2.4.14. S3 get bucket 位置
检索 bucket 的 zone group。用户需要是存储桶所有者才能调用它。通过在 PUT 请求期间提供 LocationConstraint
,可以将 bucket 限制到 zone group。
将 location
子资源添加到存储桶资源,如下所示。
语法
GET /BUCKET?location HTTP/1.1 Host: cname.domain.com Authorization: AWS ACCESS_KEY:HASH_OF_HEADER_AND_SECRET
名称 | Type | 描述 |
---|---|---|
| 字符串 | bucket 所在的 zone group, default zone group 的空字符串 |
2.4.15. S3 获取存储桶版本
检索 bucket 的版本控制状态。用户需要是存储桶所有者才能调用它。
将 versioning
子资源添加到存储桶资源,如下所示。
语法
GET /BUCKET?versioning HTTP/1.1 Host: cname.domain.com Authorization: AWS ACCESS_KEY:HASH_OF_HEADER_AND_SECRET
2.4.16. S3 放置存储桶版本
此子资源设置现有存储桶的 versioning 状态。用户需要是存储桶所有者来设置版本控制状态。如果存储桶上没有设置 versioning 状态,则没有版本状态。执行 GET 版本请求不会返回 versioning 状态值。
设置存储桶版本状态:
enabled
:为存储桶中的对象启用版本控制。添加到存储桶的所有对象都会获得一个唯一的版本 ID。暂停
:禁用存储桶中对象的版本控制。添加到存储桶的所有对象都会接收版本 ID null。
语法
PUT /BUCKET?versioning HTTP/1.1
名称 | Type | 描述 |
---|---|---|
| container | 用于请求的容器。 |
| 字符串 | 设置存储桶的版本控制状态。有效值: Suspended/Enabled |
2.4.17. S3 获取存储桶访问控制列表
检索 bucket 访问控制列表。用户需要是存储桶所有者,或被授予存储桶的 READ_ACP
权限。
将 acl
子资源添加到存储桶请求,如下所示。
语法
GET /BUCKET?acl HTTP/1.1 Host: cname.domain.com Authorization: AWS ACCESS_KEY:HASH_OF_HEADER_AND_SECRET
名称 | Type | 描述 |
---|---|---|
| Container | 用于响应的容器。 |
| Container | ACL 信息的容器。 |
| Container |
bucket 所有者的 |
| 字符串 | bucket 所有者的 ID。 |
| 字符串 | bucket 所有者的显示名称。 |
| Container |
适用于 |
| Container |
允许权限的用户的 |
| 字符串 |
提供给 |
2.4.18. S3 放置存储桶访问控制列表
设置到现有存储桶的访问控制。用户需要是存储桶所有者,或被授予存储桶的 WRITE_ACP
权限。
将 acl
子资源添加到存储桶请求,如下所示。
语法
PUT /BUCKET?acl HTTP/1.1
名称 | Type | 描述 |
---|---|---|
| Container | 用于请求的容器。 |
| Container | ACL 信息的容器。 |
| Container |
bucket 所有者的 |
| 字符串 | bucket 所有者的 ID。 |
| 字符串 | bucket 所有者的显示名称。 |
| Container |
适用于 |
| Container |
允许权限的用户的 |
| 字符串 |
提供给 |
2.4.19. S3 get bucket cors
检索为存储桶设置的 cors 配置信息。用户需要是存储桶所有者,或被授予存储桶的 READ_ACP
权限。
将 cors
子资源添加到存储桶请求,如下所示。
语法
GET /BUCKET?cors HTTP/1.1 Host: cname.domain.com Authorization: AWS ACCESS_KEY:HASH_OF_HEADER_AND_SECRET
2.4.20. S3 put bucket cors
为存储桶设置 cors 配置。用户需要是存储桶所有者,或被授予存储桶的 READ_ACP
权限。
将 cors
子资源添加到存储桶请求,如下所示。
语法
PUT /BUCKET?cors HTTP/1.1 Host: cname.domain.com Authorization: AWS ACCESS_KEY:HASH_OF_HEADER_AND_SECRET
2.4.21. S3 删除存储桶 cors
删除为存储桶设置的 cors 配置信息。用户需要是存储桶所有者,或被授予存储桶的 READ_ACP
权限。
将 cors
子资源添加到存储桶请求,如下所示。
语法
DELETE /BUCKET?cors HTTP/1.1 Host: cname.domain.com Authorization: AWS ACCESS_KEY:HASH_OF_HEADER_AND_SECRET
2.4.22. S3 列表存储桶对象版本
返回存储桶中所有对象版本的元数据列表。需要指向存储桶的 READ 访问权限。
将 version
子资源添加到存储桶请求,如下所示。
语法
GET /BUCKET?versions HTTP/1.1 Host: cname.domain.com Authorization: AWS ACCESS_KEY:HASH_OF_HEADER_AND_SECRET
您可以为 GET /BUCKET?version
指定参数,但不需要它们。
名称 | Type | 描述 |
---|---|---|
| 字符串 | 返回的 in-progress 上传,其密钥包含指定前缀。 |
| 字符串 | 前缀与其他对象名称之间的分隔符。 |
| 字符串 | 上传列表的开头标记。 |
| 整数 | 上传的最大 in-progres 数。默认值为 1000。 |
| 字符串 | 指定用于开始列表的对象版本。 |
名称 | Type | 描述 |
---|---|---|
| 字符串 |
通过密钥标记请求参数指定的 |
| 字符串 |
如果 |
| 字符串 |
如果 |
| 布尔值 |
如果为 |
| 整数 | 上传部分的大小。 |
| 字符串 | 所有者的显示名称。 |
| 字符串 | 所有者的 ID。 |
| Container |
用于拥有对象的用户的 |
| 字符串 |
用于存储生成的对象的方法。 |
| Container | 版本信息的容器。 |
| 字符串 | 对象的版本 ID。 |
| 字符串 | 已截断响应中密钥的最后一个版本。 |
2.4.23. S3 头存储桶
在存储桶上调用 HEAD,以确定它是否存在以及调用者是否有访问权限。如果存储桶存在并且调用者具有权限,则返回 200 OK
;如果存储桶不存在,则返回 404 Not Found
。如果存储桶存在,但调用者没有访问权限,则返回 403 Forbidden
。
语法
HEAD /BUCKET HTTP/1.1 Host: cname.domain.com Date: date Authorization: AWS ACCESS_KEY:HASH_OF_HEADER_AND_SECRET
2.4.24. S3 列表多部分上传
GET /?uploads
返回当前 in-progress 多部分上传列表,即应用启动多部分上传,但服务尚未完成所有上传。
语法
GET /BUCKET?uploads HTTP/1.1
您可以为 GET /BUCKET?uploads
指定参数,但参数都不是必需的。
名称 | Type | 描述 |
---|---|---|
| 字符串 | 返回的 in-progress 上传,其密钥包含指定前缀。 |
| 字符串 | 前缀与其他对象名称之间的分隔符。 |
| 字符串 | 上传列表的开头标记。 |
| 整数 | 上传的最大 in-progres 数。默认值为 1000。 |
| 整数 | 多部分上传的最大数量。范围为 1 到1000。默认值为 1000。 |
| 字符串 |
如果没有指定 |
名称 | Type | 描述 |
---|---|---|
| Container | 用于结果的容器。 |
| 字符串 |
|
| 字符串 | 将接收存储桶内容的存储桶。 |
| 字符串 |
通过密钥标记请求参数指定的 |
| 字符串 |
|
| 字符串 |
如果 |
| 字符串 |
如果 |
| 整数 |
|
| 字符串 |
如果设置,具有相同前缀的对象将显示在 |
| 布尔值 |
如果为 |
| Container |
|
| 字符串 | 在多部分上传完成后,对象的键。 |
| 字符串 |
标识多部分上传的 |
| Container |
包含开始上传的用户的 |
| 字符串 | 启动器的显示名称。 |
| 字符串 | 启动器的 ID。 |
| Container |
拥有上传对象的用户的 |
| 字符串 |
用于存储生成的对象的方法。 |
| Date | 用户开始上传的日期和时间。 |
| Container | 如果多个对象包含相同的前缀,它们将显示在此列表中。 |
| 字符串 |
在前缀后面使用前缀的子字符串,如 |
2.4.25. S3 存储桶策略
Ceph 对象网关支持应用到 bucket 的 Amazon S3 策略语言的子集。
创建和删除
Ceph 对象网关通过标准 S3 操作来管理 S3 Bucket 策略,而不使用 radosgw-admin
CLI 工具。
管理员可以使用 s3cmd
命令来设置或删除策略。
示例
$ cat > examplepol { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": {"AWS": ["arn:aws:iam::usfolks:user/fred"]}, "Action": "s3:PutObjectAcl", "Resource": [ "arn:aws:s3:::happybucket/*" ] }] } $ s3cmd setpolicy examplepol s3://happybucket $ s3cmd delpolicy s3://happybucket
限制
Ceph 对象网关仅支持以下 S3 操作:
-
s3:AbortMultipartUpload
-
s3:CreateBucket
-
s3:DeleteBucketPolicy
-
s3:DeleteBucket
-
s3:DeleteBucketWebsite
-
s3:DeleteObject
-
s3:DeleteObjectVersion
-
s3:GetBucketAcl
-
s3:GetBucketCORS
-
s3:GetBucketLocation
-
s3:GetBucketPolicy
-
s3:GetBucketRequestPayment
-
s3:GetBucketVersioning
-
s3:GetBucketWebsite
-
s3:GetLifecycleConfiguration
-
s3:GetObjectAcl
-
s3:GetObject
-
s3:GetObjectTorrent
-
s3:GetObjectVersionAcl
-
s3:GetObjectVersion
-
s3:GetObjectVersionTorrent
-
s3:ListAllMyBuckets
-
s3:ListBucketMultiPartUploads
-
s3:ListBucket
-
s3:ListBucketVersions
-
s3:ListMultipartUploadParts
-
s3:PutBucketAcl
-
s3:PutBucketCORS
-
s3:PutBucketPolicy
-
s3:PutBucketRequestPayment
-
s3:PutBucketVersioning
-
s3:PutBucketWebsite
-
s3:PutLifecycleConfiguration
-
s3:PutObjectAcl
-
s3:PutObject
-
s3:PutObjectVersionAcl
Ceph 对象网关不支持在用户、组或角色上设置策略。
Ceph 对象网关使用 RGW 的"租户"标识符来代替 Amazon twelve-bit 帐户 ID。希望使用 Amazon Web Service(AWS)S3 和 Ceph 对象网关 S3 之间的策略,必须在创建用户时将 Amazon 帐户 ID 用作租户 ID。
使用 AWS S3 时,所有租户共享一个命名空间。与之相反,Ceph 对象网关为每个租户提供自己的 bucket 命名空间。目前,Ceph 对象网关客户端试图访问属于另一个租户 MUST 地址的 bucket,作为 S3 请求中的 tenant:bucket
。
在 AWS 中,存储桶策略可以授予其他帐户的访问权限,然后该帐户所有者可以向具有用户权限的单独用户授予访问权限。由于 Ceph 对象网关尚不支持用户、角色和组权限,因此帐户所有者需要直接向个别用户授予访问权限。
授予 bucket 的完整帐户访问权限,授予该帐户中所有用户的访问权限。
bucket 策略 不支持 字符串插值。
Ceph 对象网关支持以下条件键:
-
aws:CurrentTime
-
aws:EpochTime
-
aws:PrincipalType
-
aws:Referer
-
aws:SecureTransport
-
aws:SourceIp
-
aws:UserAgent
-
aws:username
Ceph 对象网关仅支持以下条件键进行 ListBucket
操作:
-
s3:prefix
-
s3:delimiter
-
s3:max-keys
对 Swift 的影响
Ceph 对象网关提供在 Swift API 下设置 bucket 策略的功能。但是,使用 S3 API 管理 Swift 以及 S3 操作设置的存储桶策略。
Ceph 对象网关将 Swift 凭据与策略中指定的主体匹配。
2.4.26. S3 获取存储桶上的请求支付配置
使用 requestPayment
子资源返回存储桶的请求支付配置。用户需要是存储桶所有者,或被授予存储桶的 READ_ACP
权限。
将 requestPayment
子资源添加到存储桶请求,如下所示。
语法
GET /BUCKET?requestPayment HTTP/1.1 Host: cname.domain.com Authorization: AWS ACCESS_KEY:HASH_OF_HEADER_AND_SECRET
2.4.27. S3 在存储桶上设置请求支付配置
使用 requestPayment
子资源来设置存储桶的请求支付配置。默认情况下,存储桶所有者需要从存储桶下载。此配置参数可让 bucket 所有者指定请求者将被请求及从存储桶下载的数据。
将 requestPayment
子资源添加到存储桶请求,如下所示。
语法
PUT /BUCKET?requestPayment HTTP/1.1
Host: cname.domain.com
名称 | Type | 描述 |
---|---|---|
| Enum | 指定下载和请求费用的支付费用。 |
| Container |
用于 |
2.4.28. 多租户存储桶操作
当客户端应用访问 bucket 时,它始终与特定用户的凭据一同运行。在 Red Hat Ceph Storage 集群中,每个用户都属于一个租户。因此,如果没有明确指定租户,每个 bucket 操作在其上下文中都有一个隐式租户。因此,多租户与之前的版本完全向后兼容,只要引用的存储桶和引用用户所属的租户。
已根据所使用的协议和身份验证系统,使用扩展来指定明确的租户会有所不同。
在以下示例中,冒号分隔租户和 bucket。因此,一个示例 URL 是:
https://rgw.domain.com/tenant:bucket
相反,一个简单的 Python 示例将租户和存储桶方法本身分开:
示例
from boto.s3.connection import S3Connection, OrdinaryCallingFormat c = S3Connection( aws_access_key_id="TESTER", aws_secret_access_key="test123", host="rgw.domain.com", calling_format = OrdinaryCallingFormat() ) bucket = c.get_bucket("tenant:bucket")
无法利用多租户使用 S3-style 子域,因为主机名不能包含冒号或任何已在存储桶名称中无效的其他分隔符。使用句点会创建模糊的语法。因此,bucket-in-URL-path
格式必须与多租户一起使用。
其它资源
- 详情请查看 Multi Tenancy。
2.4.29. 其它资源
- 有关配置存储桶网站的详细信息,请参阅 Red Hat Ceph Storage Object Gateway 配置和管理指南。
2.5. S3 对象操作
作为开发者,您可以通过 Ceph 对象网关通过 Amazon S3 应用编程接口(API)执行对象操作。
下表列出了对象的 Amazon S3 功能操作,以及功能的支持状态。
获取对象 | 支持 | |
---|---|---|
支持 | ||
支持 | ||
支持 | ||
支持 | ||
支持 | ||
支持 | ||
支持 | ||
支持 | ||
支持 | ||
支持 | ||
支持 | ||
支持 | ||
支持 | ||
支持 | ||
支持 | ||
Multi-Tenancy | 支持 |
2.5.1. 先决条件
- 一个正在运行的 Red Hat Ceph Storage 集群。
- RESTful 客户端。
2.5.2. S3 从存储桶获取对象
从存储桶检索对象:
语法
GET /BUCKET/OBJECT HTTP/1.1
添加 versionId
子资源以检索对象的特定版本:
语法
GET /BUCKET/OBJECT?versionId=VERSION_ID HTTP/1.1
名称 | 描述 | 有效值 | 必需 |
---|---|---|---|
range | 要检索的对象范围。 | 范围: bytes=beginbyte-endbyte | 否 |
if-modified-since | 仅当自时间戳起修改时才会获得。 | Timestamp | 否 |
if-unmodified-since | 只有自时间戳起没有修改时才会获得。 | Timestamp | 否 |
if-match | 仅在对象 ETag 匹配 ETag 时才会获得。 | 实体标签 | 否 |
if-none-match | 仅在对象 ETag 匹配 ETag 时才会获得。 | 实体标签 | 否 |
名称 | 描述 |
---|---|
Content-Range | 只有在请求中指定范围标头字段时,才会返回数据范围 |
x-amz-version-id | 返回版本 ID 或 null。 |
2.5.3. S3 获取对象信息
返回有关对象的信息。此请求将返回与 Get Object 请求相同的标头信息,但将仅包含元数据,而不包括对象数据有效负载。
检索对象的当前版本:
语法
HEAD /BUCKET/OBJECT HTTP/1.1
添加 versionId
子资源以检索特定版本的信息:
语法
HEAD /BUCKET/OBJECT?versionId=VERSION_ID HTTP/1.1
名称 | 描述 | 有效值 | 必需 |
---|---|---|---|
range | 要检索的对象范围。 | 范围: bytes=beginbyte-endbyte | 否 |
if-modified-since | 仅当自时间戳起修改时才会获得。 | Timestamp | 否 |
if-unmodified-since | 只有自时间戳起没有修改时才会获得。 | Timestamp | 否 |
if-match | 仅在对象 ETag 匹配 ETag 时才会获得。 | 实体标签 | 否 |
if-none-match | 仅在对象 ETag 匹配 ETag 时才会获得。 | 实体标签 | 否 |
名称 | 描述 |
---|---|
x-amz-version-id | 返回版本 ID 或 null。 |
2.5.4. S3 将对象添加到存储桶
添加对象到存储桶。您必须在存储桶上具有写入权限才能执行此操作。
语法
PUT /BUCKET/OBJECT HTTP/1.1
名称 | 描述 | 有效值 | 必需 |
---|---|---|---|
content-md5 | 消息的 base64 编码 MD-5 哈希。 | 字符串无默认值或限制。 | 否 |
content-type | 标准 MIME 类型。 |
任何 MIME 类型。默认: | 否 |
x-amz-meta-<…> | 用户元数据。与对象存储。 | 字符串最多 8kb。无默认值。 | 否 |
x-amz-acl | 不可行的 ACL. |
| 否 |
名称 | 描述 |
---|---|
x-amz-version-id | 返回版本 ID 或 null。 |
2.5.5. S3 删除对象
删除对象。要求在包含存储桶上设置 WRITE 权限。
删除对象。如果对象版本控制为 on,它会创建一个标记。
语法
DELETE /BUCKET/OBJECT HTTP/1.1
要在对对象进行版本控制时删除对象,您必须指定 versionId
子资源以及要删除的对象的版本。
DELETE /BUCKET/OBJECT?versionId=VERSION_ID HTTP/1.1
2.5.6. S3 删除多个对象
此 API 调用从存储桶中删除多个对象。
语法
POST /BUCKET/OBJECT?delete HTTP/1.1
2.5.7. S3 获取对象的访问控制列表(ACL)
返回对象的当前版本的 ACL:
语法
GET /BUCKET/OBJECT?acl HTTP/1.1
添加 versionId
子资源以检索特定版本的 ACL:
语法
GET /BUCKET/OBJECT?versionId=VERSION_ID&acl HTTP/1.1
名称 | 描述 |
---|---|
x-amz-version-id | 返回版本 ID 或 null。 |
名称 | Type | 描述 |
---|---|---|
| Container | 用于响应的容器。 |
| Container | ACL 信息的容器。 |
| Container |
对象所有者 |
| 字符串 | 对象所有者的 ID。 |
| 字符串 | 对象所有者的显示名称。 |
| Container |
适用于 |
| Container |
允许权限的用户的 |
| 字符串 |
授予 |
2.5.8. S3 设置对象的访问控制列表(ACL)
为对象的当前版本设置对象 ACL。
语法
PUT /BUCKET/OBJECT?acl
名称 | Type | 描述 |
---|---|---|
| Container | 用于响应的容器。 |
| Container | ACL 信息的容器。 |
| Container |
对象所有者 |
| 字符串 | 对象所有者的 ID。 |
| 字符串 | 对象所有者的显示名称。 |
| Container |
适用于 |
| Container |
允许权限的用户的 |
| 字符串 |
授予 |
2.5.9. S3 复制一个对象
要复制对象,请使用 PUT
并指定目标存储桶和对象名称。
语法
PUT /DEST_BUCKET/DEST_OBJECT HTTP/1.1 x-amz-copy-source: SOURCE_BUCKET/SOURCE_OBJECT
名称 | 描述 | 有效值 | 必需 |
---|---|---|---|
x-amz-copy-source | 源 bucket 名称 + 对象名称。 | BUCKET/OBJECT | 是 |
x-amz-acl | 不可行的 ACL. |
| 否 |
x-amz-copy-if-modified-since | 仅在自时间戳起修改时才会复制。 | Timestamp | 否 |
x-amz-copy-if-unmodified-since | 仅在自时间戳起未修改后复制。 | Timestamp | 否 |
x-amz-copy-if-match | 只有在对象 ETag 匹配 ETag 时复制。 | 实体标签 | 否 |
x-amz-copy-if-none-match | 仅在对象 ETag 不匹配时才复制。 | 实体标签 | 否 |
名称 | Type | 描述 |
---|---|---|
CopyObjectResult | Container | 用于响应元素的容器。 |
LastModified | Date | 源对象的最后修改日期。 |
Etag | 字符串 | 新对象的 ETag。 |
其它资源
- <additional resource 1>
- <additional resource 2>
2.5.10. S3 使用 HTML 表单向存储桶添加对象
使用 HTML 表单将对象添加到存储桶。您必须在存储桶上具有写入权限才能执行此操作。
语法
POST /BUCKET/OBJECT HTTP/1.1
2.5.11. S3 确定请求选项
用于确定实际请求是否可以通过特定原始卷、HTTP 方法和标头发送的 preflight 请求。
语法
OPTIONS /OBJECT HTTP/1.1
2.5.12. S3 启动多部分上传
启动多部分上传过程。返回 UploadId
,您可以在添加额外部分、列出部分和完成或带出多部分上传时指定。
语法
POST /BUCKET/OBJECT?uploads
名称 | 描述 | 有效值 | 必需 |
---|---|---|---|
| 消息的 base64 编码 MD-5 哈希。 | 字符串无默认值或限制。 | 否 |
| 标准 MIME 类型。 |
任何 MIME 类型。默认: | 否 |
| 用户元数据。与对象存储。 | 字符串最多 8kb。无默认值。 | 否 |
| 不可行的 ACL. |
| 否 |
名称 | Type | 描述 |
---|---|---|
| Container | 用于结果的容器。 |
| 字符串 | 将接收对象内容的存储桶。 |
| 字符串 |
由密钥请求参数指定的 |
| 字符串 |
由 |
2.5.13. S3 在多部分上传中添加部分
添加部分到多部分上传。
指定 uploadId
子资源以及上传 ID,将部分添加到多部分上传:
语法
PUT /BUCKET/OBJECT?partNumber=&uploadId=UPLOAD_ID HTTP/1.1
可能会返回以下 HTTP 响应:
HTTP 状态 | 状态代码 | 描述 |
---|---|---|
| NoSuchUpload | 指定 upload-id 与此对象上任何启动上传都不匹配 |
2.5.14. S3 列出多部分上传
指定 uploadId
子资源以及上传 ID 来列出多部分上传:
语法
GET /BUCKET/OBJECT?uploadId=UPLOAD_ID HTTP/1.1
名称 | Type | 描述 |
---|---|---|
| Container | 用于结果的容器。 |
| 字符串 | 将接收对象内容的存储桶。 |
| 字符串 |
由密钥请求参数指定的 |
| 字符串 |
由 |
| Container |
包含开始上传的用户的 |
| 字符串 | 启动器的 ID。 |
| 字符串 | 启动器的显示名称。 |
| Container |
拥有上传对象的用户的 |
| 字符串 |
用于存储生成的对象的方法。 |
| 字符串 |
如果 |
| 字符串 |
如果 |
| 整数 |
根据 |
| 布尔值 |
如果为 |
| Container |
用于 |
| 整数 | 部分的标识号。 |
| 字符串 | 部分的实体标签。 |
| 整数 | 上传部分的大小。 |
2.5.15. S3 汇编上传的部分
装配已上传的部分并创建新的对象,从而完成多部分上传。
指定 uploadId
子资源以及上传 ID 以完成多部分上传:
语法
POST /BUCKET/OBJECT?uploadId=UPLOAD_ID HTTP/1.1
名称 | Type | 描述 | 必需 |
---|---|---|---|
| Container | 由一个或多个部分组成的容器。 | 是 |
| Container |
适用于 | 是 |
| 整数 | 部分的标识符。 | 是 |
| 字符串 | 部分的实体标签。 | 是 |
名称 | Type | 描述 |
---|---|---|
| Container | 用于响应的容器。 |
| URI | 新对象的资源标识符(path)。 |
| 字符串 | 包含新对象的存储桶的名称。 |
| 字符串 | 对象的密钥。 |
| 字符串 | 新对象的实体标签。 |
2.5.16. S3 复制多部分上传
通过从现有对象复制数据作为数据源来上传部分。
指定 uploadId
子资源以及上传 ID,以执行多部分上传副本:
语法
PUT /BUCKET/OBJECT?partNumber=PartNumber&uploadId=UPLOAD_ID HTTP/1.1 Host: cname.domain.com Authorization: AWS ACCESS_KEY:HASH_OF_HEADER_AND_SECRET
名称 | 描述 | 有效值 | 必需 |
---|---|---|---|
| 源存储桶名称和对象名称。 | BUCKET/OBJECT | 是 |
| 从源对象复制的字节数。 |
范围: | 否 |
名称 | Type | 描述 |
---|---|---|
| Container | 用于所有响应元素的容器。 |
| 字符串 | 返回新部分的 ETag。 |
| 字符串 | 返回部分上次修改的日期。 |
.Additional Resources
- 有关此功能的更多信息,请参阅 Amazon S3 网站。
2.5.17. S3 中止多部分上传
中止多部分上传。
指定 uploadId
子资源以及上传 ID 以中止多部分上传:
语法
DELETE /BUCKET/OBJECT?uploadId=UPLOAD_ID HTTP/1.1
2.5.18. S3 Hadoop 互操作性
对于需要 Hadoop 分布式文件系统(HDFS)访问的数据分析应用,可以使用用于 Hadoop 的 Apache S3A 连接器来访问 Ceph 对象网关。S3A 连接器是一个开源工具,它能够将 S3 兼容对象存储呈现为 HDFS 文件系统,具有 HDFS 文件系统对应用程序进行读写语义,同时数据存储在 Ceph 对象网关中。
Ceph 对象网关与 Hadoop 2.7.3 附带的 S3A 连接器完全兼容。
2.5.19. 其它资源
- 如需了解有关多租户的详细信息,请参阅 Red Hat Ceph Storage Object Gateway 配置和管理指南。
2.6. 其它资源
第 3 章 Ceph 对象网关和 Swift API
作为开发者,您可以使用与 Swift API 数据访问模型兼容的 RESTful 应用编程接口(API)。您可以通过 Ceph 对象网关管理 Red Hat Ceph Storage 集群中存储的 bucket 和对象。
下表描述了当前 Swift 功能功能的支持状态:
功能 | Status | 备注 |
---|---|---|
支持 | ||
获取帐户元数据 | 支持 | 没有自定义元数据 |
支持 | 支持 Swift ACL 的子集 | |
支持 | ||
支持 | ||
支持 | ||
支持 | ||
获取容器元数据 | 支持 | |
支持 | ||
删除容器元数据 | 支持 | |
支持 | ||
支持 | ||
创建大对象 | 支持 | |
支持 | ||
支持 | ||
支持 | ||
支持 | ||
支持 | ||
CORS | 不支持 | |
过期对象 | 支持 | |
对象版本控制 | 不支持 | |
静态网站 | 不支持 |
3.1. 先决条件
- 一个正在运行的 Red Hat Ceph Storage 集群。
- RESTful 客户端。
3.2. Swift API 限制
应谨慎使用以下限制。您的硬件选择会有影响,因此您应该始终与您的红帽客户团队讨论这些要求。
- 使用 Swift API 时的最大对象大小: 5GB
- 使用 Swift API 时的最大元数据大小: 对可应用到对象的用户元数据的总大小没有定义限制,但单个 HTTP 请求限制为 16,000 字节。
3.3. 创建 Swift 用户
要测试 Swift 接口,请创建一个 Swift 子用户。创建 Swift 用户分为两个步骤:第一步是创建用户。第二步是创建机密密钥。
在多站点部署中,始终在 master zone group 的 master zone 中的主机上创建用户。
先决条件
- 安装 Ceph 对象网关.
- Ceph 对象网关节点的根级别访问权限.
流程
创建 Swift 用户:
语法
radosgw-admin subuser create --uid=NAME --subuser=NAME:swift --access=full
使用 Swift 用户名替换
NAME
,例如:示例
[root@rgw]# radosgw-admin subuser create --uid=testuser --subuser=testuser:swift --access=full { "user_id": "testuser", "display_name": "First User", "email": "", "suspended": 0, "max_buckets": 1000, "auid": 0, "subusers": [ { "id": "testuser:swift", "permissions": "full-control" } ], "keys": [ { "user": "testuser", "access_key": "O8JDE41XMI74O185EHKD", "secret_key": "i4Au2yxG5wtr1JK01mI8kjJPM93HNAoVWOSTdJd6" } ], "swift_keys": [ { "user": "testuser:swift", "secret_key": "13TLtdEW7bCqgttQgPzxFxziu0AgabtOc6vM8DLA" } ], "caps": [], "op_mask": "read, write, delete", "default_placement": "", "placement_tags": [], "bucket_quota": { "enabled": false, "check_on_raw": false, "max_size": -1, "max_size_kb": 0, "max_objects": -1 }, "user_quota": { "enabled": false, "check_on_raw": false, "max_size": -1, "max_size_kb": 0, "max_objects": -1 }, "temp_url_keys": [], "type": "rgw" }
创建 secret 密钥:
语法
radosgw-admin key create --subuser=NAME:swift --key-type=swift --gen-secret
使用 Swift 用户名替换
NAME
,例如:示例
[root@rgw]# radosgw-admin key create --subuser=testuser:swift --key-type=swift --gen-secret { "user_id": "testuser", "display_name": "First User", "email": "", "suspended": 0, "max_buckets": 1000, "auid": 0, "subusers": [ { "id": "testuser:swift", "permissions": "full-control" } ], "keys": [ { "user": "testuser", "access_key": "O8JDE41XMI74O185EHKD", "secret_key": "i4Au2yxG5wtr1JK01mI8kjJPM93HNAoVWOSTdJd6" } ], "swift_keys": [ { "user": "testuser:swift", "secret_key": "a4ioT4jEP653CDcdU8p4OuhruwABBRZmyNUbnSSt" } ], "caps": [], "op_mask": "read, write, delete", "default_placement": "", "placement_tags": [], "bucket_quota": { "enabled": false, "check_on_raw": false, "max_size": -1, "max_size_kb": 0, "max_objects": -1 }, "user_quota": { "enabled": false, "check_on_raw": false, "max_size": -1, "max_size_kb": 0, "max_objects": -1 }, "temp_url_keys": [], "type": "rgw" }
3.4. Swift 验证用户
要对用户进行身份验证,请在标题中创建一个包含 X-Auth-User
和 X-Auth-Key
的请求。
语法
GET /auth HTTP/1.1 Host: swift.example.com X-Auth-User: johndoe X-Auth-Key: R7UUOLFDI2ZI9PRCQ53K
响应示例
HTTP/1.1 204 No Content Date: Mon, 16 Jul 2012 11:05:33 GMT Server: swift X-Storage-Url: https://swift.example.com X-Storage-Token: UOlCCC8TahFKlWuv9DB09TWHF0nDjpPElha0kAa Content-Length: 0 Content-Type: text/plain; charset=UTF-8
您可以通过在身份验证过程中使用 X-Storage-Url
值执行 GET
请求来检索有关 Ceph Swift 兼容服务的数据。
其它资源
- 如需 Swift 请求标头,请参阅 Red Hat Ceph Storage Developer Guide。
- 如需 Swift 响应标头,请参阅 Red Hat Ceph Storage Developer Guide。
3.5. Swift 容器操作
作为开发者,您可以通过 Ceph 对象网关通过 Swift 应用编程接口(API)执行容器操作。您可以列出、创建、更新和删除容器。您还可以添加或更新容器的元数据。
3.5.1. 先决条件
- 一个正在运行的 Red Hat Ceph Storage 集群。
- RESTful 客户端。
3.5.2. Swift 容器操作
容器是用于存储数据对象的机制。帐户可以有许多容器,但容器名称必须是唯一的。此 API 允许客户端创建容器,设置访问控制和元数据,检索容器的内容,以及删除容器。由于此 API 对特定用户帐户中的信息发出与请求相关的请求,因此此 API 中的所有请求都必须进行身份验证,除非容器访问控制被有意公开访问,即允许匿名请求。
Amazon S3 API 使用术语"bucket"来描述数据容器。当您听说到 Swift API 中的"bucket"时,术语"bucket"可能会与术语"容器"等同。
对象存储的一个方面是它不支持分层路径或目录。相反,它支持由一个或多个容器组成的一个级别,每个容器可能具有对象。RADOS 网关的 Swift API 支持 'pseudo-hierarchical 容器' 的概念,这是一种使用对象命名来模拟容器或目录层次结构,而无需实际在存储系统中实施。您可以使用伪层次结构名称来命名对象,例如 photos/buildings/empire-state.jpg,但容器名称不能包含正斜杠(/
)字符。
将大型对象上传到版本的 Swift 容器时,在 python-swiftclient
程序中使用 --leave-segments
选项。不要使用 --leave-segments
覆盖清单文件。因此,现有对象会被覆盖,这会导致数据丢失。
3.5.3. Swift 更新容器的访问控制列表(ACL)
当用户创建容器时,用户默认对容器具有读写权限。要允许其他用户读取容器的内容或写入容器,您必须特别启用该用户。您也可以在 X-Container-Read
或 X-Container-Write
设置中指定 *
,这样可以有效地让所有用户从或写入容器。设置 *
使容器变为公共容器。这是它允许匿名用户从容器读取或写入到容器。
语法
POST /AP_VERSION/ACCOUNT/TENANT:CONTAINER HTTP/1.1 Host: FULLY_QUALIFIED_DOMAIN_NAME X-Auth-Token: AUTH_TOKEN X-Container-Read: * X-Container-Write: UID1, UID2, UID3
名称 | 描述 | Type | 必需 |
---|---|---|---|
| 具有容器读取权限的用户 ID。 | 用户 ID 的以逗号分隔的字符串值。 | 否 |
| 具有容器写入权限的用户 ID。 | 用户 ID 的以逗号分隔的字符串值。 | 否 |
3.5.4. Swift 列出容器
指定 API 版本并且帐户返回特定用户帐户的容器列表的 GET
请求。由于请求返回特定用户的容器,因此请求需要身份验证令牌。无法匿名发出请求。
语法
GET /API_VERSION/ACCOUNT HTTP/1.1 Host: FULLY_QUALIFIED_DOMAIN_NAME X-Auth-Token: AUTH_TOKEN
名称 | 描述 | Type | 必需 | 有效值 |
---|---|---|---|---|
| 将结果数量限制为指定的值。 | 整数 | 否 | 不适用 |
| 定义结果的格式。 | 字符串 | 否 |
|
| 返回大于标记值的结果列表。 | 字符串 | 否 | 不适用 |
响应包含容器列表,或使用 HTTP 204 响应代码返回
名称 | 描述 | Type |
---|---|---|
| 帐户信息列表。 | Container |
| 容器列表。 | Container |
| 容器的名称。 | 字符串 |
| 容器的大小。 | 整数 |
3.5.5. Swift 列出容器的对象
要列出容器内的对象,请使用 API 版本、帐户和容器名称来创建一个 GET
请求。您可以指定查询参数来过滤完整列表,或用参数返回存储在容器中的前 10,000 项名称的列表。
语法
GET /AP_VERSION/TENANT:CONTAINER HTTP/1.1 Host: FULLY_QUALIFIED_DOMAIN_NAME X-Auth-Token: AUTH_TOKEN
名称 | 描述 | Type | 有效值 | 必需 |
---|---|---|---|---|
| 定义结果的格式。 | 字符串 |
| 否 |
| 将结果设置为以指定前缀开头的对象。 | 字符串 | 不适用 | 否 |
| 返回大于标记值的结果列表。 | 字符串 | 不适用 | 否 |
| 将结果数量限制为指定的值。 | 整数 | 0 - 10,000 | 否 |
| 前缀与其他对象名称之间的分隔符。 | 字符串 | 不适用 | 否 |
| 对象的伪层次结构路径。 | 字符串 | 不适用 | 否 |
名称 | 描述 | Type |
---|---|---|
| 容器。 | Container |
| 容器内的对象。 | Container |
| 容器中对象的名称。 | 字符串 |
| 对象内容的散列代码。 | 字符串 |
| 最后一次修改对象内容的时间。 | Date |
| 对象中的内容类型。 | 字符串 |
3.5.6. Swift 创建容器
若要创建新容器,请为 PUT
请求提供 API 版本、帐户和新容器的名称。容器名称必须是唯一的,不得包含正斜杠(/)字符,且应小于 256 字节。您可以在请求中包含访问控制标头和元数据标头。您还可以包含指定一组 PG 的密钥的存储策略。例如,执行 radosgw-admin zone get
以查看 placement_pools
下的可用键的列表。存储策略允许您为容器指定一组特殊的池,如基于 SSD 的存储。操作是幂等的。如果您请求创建已存在的容器,它会返回 HTTP 202 返回代码,但不会创建另一个容器。
语法
PUT /AP_VERSION/ACCOUNT/TENANT:CONTAINER HTTP/1.1 Host: FULLY_QUALIFIED_DOMAIN_NAME X-Auth-Token: AUTH_TOKEN X-Container-Read: COMMA_SEPARATED_UIDS X-Container-Write: COMMA_SEPARATED_UIDS X-Container-Meta-KEY:VALUE X-Storage-Policy: PLACEMENT_POOLS_KEY
名称 | 描述 | Type | 必需 |
---|---|---|---|
| 具有容器读取权限的用户 ID。 | 用户 ID 的以逗号分隔的字符串值。 | 否 |
| 具有容器写入权限的用户 ID。 | 用户 ID 的以逗号分隔的字符串值。 | 否 |
| 用户定义的 meta 数据键,它采用任意字符串值。 | 字符串 | 否 |
|
在 Ceph 对象网关的 | 字符串 | 否 |
如果容器已存在具有相同名称的容器,并且用户是容器所有者,则操作将成功。否则,操作将失败。
名称 | 描述 | 状态代码 |
---|---|---|
| 容器已存在于其他用户的所有权下。 |
|
3.5.7. Swift 删除容器
要删除容器,请使用 API 版本、帐户和容器名称进行 DELETE
请求。容器必须为空。如果您想检查容器是否为空,请对容器执行 HEAD
请求。成功移除容器后,您将能够重复利用容器名称。
语法
DELETE /AP_VERSION/ACCOUNT/TENANT:CONTAINER HTTP/1.1 Host: FULLY_QUALIFIED_DOMAIN_NAME X-Auth-Token: AUTH_TOKEN
名称 | 描述 | 状态代码 |
---|---|---|
| 容器已被删除。 |
|
3.5.8. Swift 添加或更新容器元数据
要向容器添加元数据,请使用 API 版本、帐户和容器名称发出 POST
请求。容器必须具有写入权限才能添加或更新元数据。
语法
POST /AP_VERSION/ACCOUNT/TENANT:CONTAINER HTTP/1.1 Host: FULLY_QUALIFIED_DOMAIN_NAME X-Auth-Token: AUTH_TOKEN X-Container-Meta-Color: red X-Container-Meta-Taste: salty
名称 | 描述 | Type | 必需 |
---|---|---|---|
| 用户定义的 meta 数据键,它采用任意字符串值。 | 字符串 | 否 |
3.6. Swift 对象操作
作为开发者,您可以通过 Ceph 对象网关通过 Swift 应用编程接口(API)执行对象操作。您可以列出、创建、更新和删除对象。您还可以添加或更新对象的元数据。
3.6.1. 先决条件
- 一个正在运行的 Red Hat Ceph Storage 集群。
- RESTful 客户端。
3.6.2. Swift 对象操作
对象是用于存储数据和元数据的容器。容器可能有许多对象,但对象名称必须是唯一的。此 API 允许客户端创建对象,设置访问控制和元数据,检索对象的数据和元数据,以及删除对象。由于此 API 发出与特定用户帐户中信息相关的请求,因此此 API 中的所有请求都必须经过身份验证。除非容器或对象的访问控制被有意公开访问,否则这是允许匿名请求。
3.6.3. Swift 获取对象
要检索对象,请使用 API 版本、帐户、容器和对象名称发出 GET
请求。必须具有容器的读取权限,以检索对象。
语法
GET /AP_VERSION/ACCOUNT/TENANT:CONTAINER/OBJECT HTTP/1.1 Host: FULLY_QUALIFIED_DOMAIN_NAME X-Auth-Token: AUTH_TOKEN
名称 | 描述 | Type | 必需 |
---|---|---|---|
| 要检索对象内容的子集,您可以指定一个字节范围。 | Date | 否 |
|
只有因为源对象的 | Date | 否 |
|
仅在不修改源对象 | Date | 否 |
| 只有在请求中的 ETag 与源对象的 ETag 匹配时才复制。 | etag。 | 否 |
| 只有在请求中的 ETag 不与源对象的 ETag 匹配时才复制。 | etag。 | 否 |
名称 | 描述 |
---|---|
| 对象内容子集的范围。仅在请求中指定范围标头字段时返回。 |
3.6.4. Swift 创建或更新对象
若要创建新对象,请为 PUT
请求提供 API 版本、帐户、容器名称和新对象的名称。您必须具有容器的写入权限才能创建或更新对象。对象名称在容器内必须是唯一的。PUT
请求不是幂等的,因此如果您不使用唯一名称,则请求将更新对象。但是,您可以在对象名称中使用伪层次结构语法,如果它位于不同的伪层次结构目录中,将其与同一名称的另一个对象区分开来。您可以在请求中包含访问控制标头和元数据标头。
语法
PUT /AP_VERSION/ACCOUNT/TENANT:CONTAINER HTTP/1.1 Host: FULLY_QUALIFIED_DOMAIN_NAME X-Auth-Token: AUTH_TOKEN
名称 | 描述 | Type | 必需 | 有效值 |
---|---|---|---|---|
| 对象内容的 MD5 哈希。建议: | 字符串 | 否 | 不适用 |
| 对象包含的内容类型。 | 字符串 | 否 | 不适用 |
| 指明对象是更大聚合对象的一部分。 | 字符串 | 否 |
|
3.6.5. Swift 删除对象
要删除对象,请使用 API 版本、帐户、容器和对象名称发出 DELETE
请求。您必须具有容器的写入权限,才能删除其中的对象。成功删除对象后,您将能够重复利用对象名称。
语法
DELETE /API_VERSION/ACCOUNT/TENANT:CONTAINER/OBJECT HTTP/1.1 Host: FULLY_QUALIFIED_DOMAIN_NAME X-Auth-Token: AUTH_TOKEN
3.6.6. Swift 复制对象
通过复制对象,您可以制作对象的服务器端副本,因此您不必下载对象并将其上传到其他容器下。要将一个对象的内容复制到另一个对象,您可以使用 API 版本、帐户和容器名称发出 PUT
请求或 COPY
请求。
对于 PUT
请求,请使用请求中的目标容器和对象名称,以及请求标头中的源容器和对象。
对于 Copy
request,请使用请求中的源容器和对象,以及请求标头中的目标容器和对象。您必须具有容器的写入权限才能复制对象。目标对象名称在容器内必须是唯一的。请求不是幂等的,因此如果您不使用唯一名称,则请求将更新目标对象。如果目标名称位于不同的伪层次结构目录中,您可以使用伪层次结构语法,将目的地对象与同一名称的源对象区分开。您可以在请求中包含访问控制标头和元数据标头。
语法
PUT /AP_VERSION/ACCOUNT/TENANT:CONTAINER HTTP/1.1 X-Copy-From: TENANT:SOURCE_CONTAINER/SOURCE_OBJECT Host: FULLY_QUALIFIED_DOMAIN_NAME X-Auth-Token: AUTH_TOKEN
或者:
语法
COPY /AP_VERSION/ACCOUNT/TENANT:SOURCE_CONTAINER/SOURCE_OBJECT HTTP/1.1 Destination: TENANT:DEST_CONTAINER/DEST_OBJECT
名称 | 描述 | Type | 必需 |
---|---|---|---|
|
与 | 字符串 |
是,如果使用 |
|
与 | 字符串 |
是,如果使用 |
|
只有因为源对象的 | Date | 否 |
|
仅在不修改源对象 | Date | 否 |
| 只有在请求中的 ETag 与源对象的 ETag 匹配时才复制。 | etag。 | 否 |
| 只有在请求中的 ETag 不与源对象的 ETag 匹配时才复制。 | etag。 | 否 |
3.6.7. Swift 获取对象元数据
要检索对象的元数据,请利用 API 版本、帐户、容器和对象名称发出 HEAD
请求。您必须具有容器的读取权限,以便从容器内的对象检索元数据。此请求返回与对象本身的请求相同的标头信息,但不会返回对象的数据。
语法
HEAD /AP_VERSION/ACCOUNT/TENANT:CONTAINER/OBJECT HTTP/1.1 Host: FULLY_QUALIFIED_DOMAIN_NAME X-Auth-Token: AUTH_TOKEN
3.6.8. Swift 添加或更新对象元数据
要向对象添加元数据,请使用 API 版本、帐户、容器和对象名称发出 POST
请求。父容器必须具有写入权限才能添加或更新元数据。
语法
POST /AP_VERSION/ACCOUNT/TENANT:CONTAINER/OBJECT HTTP/1.1 Host: FULLY_QUALIFIED_DOMAIN_NAME X-Auth-Token: AUTH_TOKEN
名称 | 描述 | Type | 必需 |
---|---|---|---|
| 用户定义的 meta 数据键,它采用任意字符串值。 | 字符串 | 否 |
3.7. Swift 临时 URL 操作
要允许临时访问,temp url 功能由 radosgw
的 swift 端点支持。例如,GET 请求到对象,无需共享凭据。
对于此功能,首先应设置 X-Account-Meta-Temp-URL-Key
和 optionally X-Account-Meta-Temp-URL-URL-Key-2
的值。Temp URL 功能依赖于针对这些 secret 密钥的 HMAC-SHA1 签名。
3.7.1. Swift 获取临时 URL 对象
临时 URL 使用加密 HMAC-SHA1 签名,其中包含以下元素:
- Request 方法的值,实例"GET"
- 自 epoch(即 Unix 时间)以来的过期时间(单位为秒)
- 从 "v1" 开始的请求路径
以上项目在它们之间附加了换行符,并使用 SHA-1 哈希算法(之前发布的 Temp URL 键)生成 HMAC。
要演示上述的 python 脚本的示例如下:
示例
import hmac from hashlib import sha1 from time import time method = 'GET' host = 'https://objectstore.example.com' 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) hmac_body = hmac.new(key, hmac_body, sha1).hexdigest() 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
输出示例
https://objectstore.example.com/v1/your-bucket/your-object?temp_url_sig=ff4657876227fc6025f04fcf1e82818266d022c6&temp_url_expires=1423200992
3.7.2. Swift POST 临时 URL 密钥
使用所需密钥向 swift 帐户发出 POST
请求,将为帐户提供临时 URL 访问的帐户的 secret 临时 URL 密钥。支持两个密钥,并且会针对密钥检查签名(如果存在),因此这些密钥可以被轮转,而不会无效的临时 URL。
语法
POST /API_VERSION/ACCOUNT HTTP/1.1 Host: FULLY_QUALIFIED_DOMAIN_NAME X-Auth-Token: AUTH_TOKEN
名称 | 描述 | Type | 必需 |
---|---|---|---|
| 使用任意字符串值的用户定义的键。 | 字符串 | 是 |
| 使用任意字符串值的用户定义的键。 | 字符串 | 否 |
3.8. Swift 多租户容器操作
当客户端应用访问容器时,它始终使用特定用户的凭证运行。在 Red Hat Ceph Storage 集群中,每个用户都属于一个租户。因此,如果没有明确指定租户,则每个容器操作在其上下文中都有一个隐式租户。因此,多租户与之前的版本完全向后兼容,只要引用容器并且引用用户所属的租户。
已根据所使用的协议和身份验证系统,使用扩展来指定明确的租户会有所不同。
冒号分隔租户和容器,因此一个示例 URL 为:
示例
https://rgw.domain.com/tenant:container
相反,在 create_container()
方法中,只需要在容器方法本身中分离租户和容器:
示例
create_container("tenant:container")
3.9. 其它资源
- 如需了解有关多租户的详细信息,请参阅 Red Hat Ceph Storage Object Gateway 配置和管理指南。
- 请参阅附录 D,以了解 Swift 请求标头。
- 请参阅附录 E for Swift 响应标头。
附录 A. S3 通用请求标头
下表列出了有效的通用请求标头及其描述。
请求标头 | 描述 |
---|---|
| 请求正文的长度。 |
| 请求时间和日期(以 UTC 为单位)。 |
| 主机服务器的名称。 |
| 身份验证令牌。 |
附录 B. S3 通用响应状态代码
下表列出了有效的通用 HTTP 响应状态及其相应的代码。
HTTP 状态 | 响应代码 |
---|---|
| 继续 |
| 成功 |
| 已创建 |
| 已接受 |
| NoContent |
| 部分内容 |
| NotModified |
| InvalidArgument |
| InvalidDigest |
| BadDigest |
| InvalidBucketName |
| InvalidObjectName |
| UnresolvableGrantByEmailAddress |
| InvalidPart |
| InvalidPartOrder |
| RequestTimeout |
| EntityTooLarge |
| AccessDenied |
| UserSuspended |
| RequestTimeTooSkewed |
| NoSuchKey |
| NoSuchBucket |
| NoSuchUpload |
| MethodNotAllowed |
| RequestTimeout |
| BucketAlreadyExists |
| BucketNotEmpty |
| MissingContentLength |
| PreconditionFailed |
| InvalidRange |
| UnprocessableEntity |
| InternalError |
附录 C. S3 不支持的标头字段
名称 | Type |
---|---|
x-amz-security-token | Request(请求) |
Server | 响应 |
x-amz-delete-marker | 响应 |
x-amz-id-2 | 响应 |
x-amz-request-id | 响应 |
x-amz-version-id | 响应 |
附录 D. Swift 请求标头(Registry)
名称 | 描述 | Type | 必需 |
---|---|---|---|
| 进行身份验证的主要 Ceph 对象网关用户名。 | 字符串 | 是 |
| 与 Ceph 对象网关用户名关联的密钥。 | 字符串 | 是 |
附录 E. Swift 响应标头
服务器的响应应包含 X-Auth-Token
值。响应可能还包含 X-Storage-Url
,它提供 API_VERSION/ACCOUNT
前缀,该前缀是在 API 文档中其他请求中指定的。
名称 | 描述 | Type |
---|---|---|
|
请求中指定的 | 字符串 |
|
用户的 URL 和 | 字符串 |
附录 F. 使用安全令牌服务 API 的示例
这些示例使用 Python 的 boto3
模块与 Ceph 对象网关安全令牌服务(STS)的接口。在这些示例中,TESTER2
假设一个由 TESTER1
创建的角色,因为根据附加到该角色的权限策略访问由 TESTER1
拥有的 S3 资源。
AssumeRole 示例创建一个角色,为角色分配一个策略,然后假定一个角色获取临时凭证,并使用这些临时凭证访问 S3 资源。
AssumeRoleWithWebIdentity 示例使用带有 Keycloak 的外部应用程序(OpenID Connect 身份提供程序)验证用户,它假定一个角色获取临时凭证,并根据角色的权限策略访问 S3 资源。
AssumeRole 示例
import boto3 iam_client = boto3.client('iam', aws_access_key_id=ACCESS_KEY_OF_TESTER1, aws_secret_access_key=SECRET_KEY_OF_TESTER1, endpoint_url=<IAM URL>, region_name='' ) policy_document = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"arn:aws:iam:::user/TESTER1\"]},\"Action\":[\"sts:AssumeRole\"]}]}" role_response = iam_client.create_role( AssumeRolePolicyDocument=policy_document, Path='/', RoleName='S3Access', ) role_policy = "{\"Version\":\"2012-10-17\",\"Statement\":{\"Effect\":\"Allow\",\"Action\":\"s3:*\",\"Resource\":\"arn:aws:s3:::*\"}}" response = iam_client.put_role_policy( RoleName='S3Access', PolicyName='Policy1', PolicyDocument=role_policy ) sts_client = boto3.client('sts', aws_access_key_id=ACCESS_KEY_OF_TESTER2, aws_secret_access_key=SECRET_KEY_OF_TESTER2, endpoint_url=<STS URL>, region_name='', ) response = sts_client.assume_role( RoleArn=role_response['Role']['Arn'], RoleSessionName='Bob', DurationSeconds=3600 ) s3client = boto3.client('s3', aws_access_key_id = response['Credentials']['AccessKeyId'], aws_secret_access_key = response['Credentials']['SecretAccessKey'], aws_session_token = response['Credentials']['SessionToken'], endpoint_url=<S3 URL>, region_name='',) bucket_name = 'my-bucket' s3bucket = s3client.create_bucket(Bucket=bucket_name) resp = s3client.list_buckets()
AssumeRoleWithWebIdentity 示例
import boto3 iam_client = boto3.client('iam', aws_access_key_id=ACCESS_KEY_OF_TESTER1, aws_secret_access_key=SECRET_KEY_OF_TESTER1, endpoint_url=<IAM URL>, region_name='' ) policy_document = "{\"Version\":\"2012-10-17\",\"Statement\":\[\{\"Effect\":\"Allow\",\"Principal\":\{\"Federated\":\[\"arn:aws:iam:::oidc-provider/localhost:8080/auth/realms/demo\"\]\},\"Action\":\[\"sts:AssumeRoleWithWebIdentity\"\],\"Condition\":\{\"StringEquals\":\{\"localhost:8080/auth/realms/demo:app_id\":\"customer-portal\"\}\}\}\]\}" role_response = iam_client.create_role( AssumeRolePolicyDocument=policy_document, Path='/', RoleName='S3Access', ) role_policy = "{\"Version\":\"2012-10-17\",\"Statement\":{\"Effect\":\"Allow\",\"Action\":\"s3:*\",\"Resource\":\"arn:aws:s3:::*\"}}" response = iam_client.put_role_policy( RoleName='S3Access', PolicyName='Policy1', PolicyDocument=role_policy ) sts_client = boto3.client('sts', aws_access_key_id=ACCESS_KEY_OF_TESTER2, aws_secret_access_key=SECRET_KEY_OF_TESTER2, endpoint_url=<STS URL>, region_name='', ) response = client.assume_role_with_web_identity( RoleArn=role_response['Role']['Arn'], RoleSessionName='Bob', DurationSeconds=3600, WebIdentityToken=<Web Token> ) s3client = boto3.client('s3', aws_access_key_id = response['Credentials']['AccessKeyId'], aws_secret_access_key = response['Credentials']['SecretAccessKey'], aws_session_token = response['Credentials']['SessionToken'], endpoint_url=<S3 URL>, region_name='',) bucket_name = 'my-bucket' s3bucket = s3client.create_bucket(Bucket=bucket_name) resp = s3client.list_buckets()
其它资源
-
有关使用 Python 的
boto
模块的更多详细信息,请参阅 Red Hat Ceph Storage Object Gateway and Administration Guide 中的 Test S3 Access 部分。
附录 G. 在 STS 中使用会话标签进行基于属性的访问控制示例
以下列表包含在 STS 中使用带有属性的访问控制(ABAC)的会话标签示例。
web 令牌中 Keycloak 传递的会话标签示例
{ "jti": "947960a3-7e91-4027-99f6-da719b0d4059", "exp": 1627438044, "nbf": 0, "iat": 1627402044, "iss": "http://localhost:8080/auth/realms/quickstart", "aud": "app-profile-jsp", "sub": "test", "typ": "ID", "azp": "app-profile-jsp", "auth_time": 0, "session_state": "3a46e3e7-d198-4a64-8b51-69682bcfc670", "preferred_username": "test", "email_verified": false, "acr": "1", "https://aws.amazon.com/tags": [ { "principal_tags": { "Department": [ "Engineering", "Marketing" ] } } ], "client_id": "app-profile-jsp", "username": "test", "active": true }
aws:RequestTag
示例
{ "Version":"2012-10-17", "Statement":[ { "Effect":"Allow", "Action":["sts:AssumeRoleWithWebIdentity","sts:TagSession"], "Principal":{"Federated":["arn:aws:iam:::oidc-provider/localhost:8080/auth/realms/quickstart"]}, "Condition":{"StringEquals":{"aws:RequestTag/Department":"Engineering"}} }] }
aws:PrincipalTag
示例
{ "Version":"2012-10-17", "Statement":[ { "Effect":"Allow", "Action":["s3:*"], "Resource":["arn:aws:s3::t1tenant:my-test-bucket","arn:aws:s3::t1tenant:my-test-bucket/*],"+ "Condition":{"StringEquals":{"aws:PrincipalTag/Department":"Engineering"}} }] }
aws:ResourceTag
示例
{
"Version":"2012-10-17",
"Statement":[
{
"Effect":"Allow",
"Action":["sts:AssumeRoleWithWebIdentity","sts:TagSession"],
"Principal":{"Federated":["arn:aws:iam:::oidc-provider/localhost:8080/auth/realms/quickstart"]},
"Condition":{"StringEquals":{"iam:ResourceTag/Department":"Engineering"}}1
}]
}
aws:TagKeys
示例
{
"Version":"2012-10-17",
"Statement":[
{
"Effect":"Allow",
"Action":["sts:AssumeRoleWithWebIdentity","sts:TagSession"],
"Principal":{"Federated":["arn:aws:iam:::oidc-provider/localhost:8080/auth/realms/quickstart"]},
"Condition":{"ForAllValues:StringEquals":{"aws:TagKeys":["Marketing,Engineering"]}}1
}]
}
- 1
ForAllValues:StringEquals
测试请求中的每个标签键是策略里标签键的子集。因此,条件限制请求中传递的标签键。
s3:ResourceTag
示例
{
"Version":"2012-10-17",
"Statement":[
{
"Effect":"Allow",
"Action":["s3:PutBucketTagging"],
"Resource":["arn:aws:s3::t1tenant:my-test-bucket\","arn:aws:s3::t1tenant:my-test-bucket/*"]
},
{
"Effect":"Allow",
"Action":["s3:*"],
"Resource":["*"],
"Condition":{"StringEquals":{"s3:ResourceTag/Department":\"Engineering"}}1
}
}
- 1
- 要进行上述操作,您需要将 'Department=Engineering' 标签附加到要应用此策略的存储桶或对象。
带有 iam:ResourceTag
的 aws:RequestTag
示例
{
"Version":"2012-10-17",
"Statement":[
{
"Effect":"Allow",
"Action":["sts:AssumeRoleWithWebIdentity","sts:TagSession"],
"Principal":{"Federated":["arn:aws:iam:::oidc-provider/localhost:8080/auth/realms/quickstart"]},
"Condition":{"StringEquals":{"aws:RequestTag/Department":"${iam:ResourceTag/Department}"}}1
}]
}
- 1
- 这是通过匹配传入请求中的标签和附加到该角色的标签来假定角色。
aws:RequestTag
是 JSON Web Token (JWT)中的传入标签,iam:ResourceTag
是附加到所假定角色的标签。
带有 s3:ResourceTag
的 aws:PrincipalTag
示例
{
"Version":"2012-10-17",
"Statement":[
{
"Effect":"Allow",
"Action":["s3:PutBucketTagging"],
"Resource":["arn:aws:s3::t1tenant:my-test-bucket\","arn:aws:s3::t1tenant:my-test-bucket/*"]
},
{
"Effect":"Allow",
"Action":["s3:*"],
"Resource":["*"],
"Condition":{"StringEquals":{"s3:ResourceTag/Department":"${aws:PrincipalTag/Department}"}}1
}
}
- 1
- 这是通过使用 S3 资源标签匹配主体标签来评估角色权限策略。
AWS:PrincipalTag
是与临时凭证一同传递的标签,s3:ResourceTag
是附加到 S3 资源的标签,即对象或存储桶。
附录 H. 演示会话标签使用的代码示例
以下是标记角色、存储桶或对象的示例代码,并在角色信任和角色权限策略中使用标签键。
该示例假定标签 Department=Engineering
由 Keycloak 在 JSON Web Token (JWT)访问令牌中传递。
# -*- coding: utf-8 -*- import boto3 import json from nose.tools import eq_ as eq access_key = 'TESTER' secret_key = 'test123' endpoint = 'http://s3.us-east.localhost:8000' s3client = boto3.client('s3', aws_access_key_id = access_key, aws_secret_access_key = secret_key, endpoint_url = endpoint, region_name='',) s3res = boto3.resource('s3', aws_access_key_id = access_key, aws_secret_access_key = secret_key, endpoint_url = endpoint, region_name='',) iam_client = boto3.client('iam', aws_access_key_id=access_key, aws_secret_access_key=secret_key, endpoint_url=endpoint, region_name='' ) bucket_name = 'test-bucket' s3bucket = s3client.create_bucket(Bucket=bucket_name) bucket_tagging = s3res.BucketTagging(bucket_name) Set_Tag = bucket_tagging.put(Tagging={'TagSet':[{'Key':'Department', 'Value': 'Engineering'}]}) try: response = iam_client.create_open_id_connect_provider( Url='http://localhost:8080/auth/realms/quickstart', ClientIDList=[ 'app-profile-jsp', 'app-jee-jsp' ], ThumbprintList=[ 'F7D7B3515DD0D319DD219A43A9EA727AD6065287' ] ) except ClientError as e: print ("Provider already exists") policy_document = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Federated\":[\"arn:aws:iam:::oidc-provider/localhost:8080/auth/realms/quickstart\"]},\"Action\":[\"sts:AssumeRoleWithWebIdentity\",\"sts:TagSession\"],\"Condition\":{\"StringEquals\":{\"aws:RequestTag/Department\":\"${iam:ResourceTag/Department}\"}}}]}" role_response = "" print ("\n Getting Role \n") try: role_response = iam_client.get_role( RoleName='S3Access' ) print (role_response) except ClientError as e: if e.response['Code'] == 'NoSuchEntity': print ("\n Creating Role \n") tags_list = [ {'Key':'Department','Value':'Engineering'}, ] role_response = iam_client.create_role( AssumeRolePolicyDocument=policy_document, Path='/', RoleName='S3Access', Tags=tags_list, ) print (role_response) else: print("Unexpected error: %s" % e) role_policy = "{\"Version\":\"2012-10-17\",\"Statement\":{\"Effect\":\"Allow\",\"Action\":\"s3:*\",\"Resource\":\"arn:aws:s3:::*\",\"Condition\":{\"StringEquals\":{\"s3:ResourceTag/Department\":[\"${aws:PrincipalTag/Department}\"]}}}}" response = iam_client.put_role_policy( RoleName='S3Access', PolicyName='Policy1', PolicyDocument=role_policy ) sts_client = boto3.client('sts', aws_access_key_id='abc', aws_secret_access_key='def', endpoint_url = endpoint, region_name = '', ) print ("\n Assuming Role with Web Identity\n") response = sts_client.assume_role_with_web_identity( RoleArn=role_response['Role']['Arn'], RoleSessionName='Bob', DurationSeconds=900, WebIdentityToken='<web-token>') s3client2 = boto3.client('s3', aws_access_key_id = response['Credentials']['AccessKeyId'], aws_secret_access_key = response['Credentials']['SecretAccessKey'], aws_session_token = response['Credentials']['SessionToken'], endpoint_url='http://s3.us-east.localhost:8000', region_name='',) bucket_body = 'this is a test file' tags = 'Department=Engineering' key = "test-1.txt" s3_put_obj = s3client2.put_object(Body=bucket_body, Bucket=bucket_name, Key=key, Tagging=tags) eq(s3_put_obj['ResponseMetadata']['HTTPStatusCode'],200) s3_get_obj = s3client2.get_object(Bucket=bucket_name, Key=key) eq(s3_get_obj['ResponseMetadata']['HTTPStatusCode'],200)