Bucket管理
Bucket既是BOS上的命名空间,也是计费、权限控制、日志记录等高级功能的管理实体。
-
Bucket名称在所有区域中具有全局唯一性,且不能修改。
说明: 百度智能云目前开放了多区域支持,请参考区域选择说明。
目前支持“华北-北京”、“华南-广州”和“华东-苏州”三个区域。北京区域:
http://bj.bcebos.com
,广州区域:http://gz.bcebos.com
,苏州区域:http://su.bcebos.com
。 - 存储在BOS上的每个Object都必须包含在一个Bucket中。
- 一个用户最多可创建100个Bucket,但每个Bucket中存放的Object的数量和大小总和没有限制,用户不需要考虑数据的可扩展性。
Bucket权限管理
目前BOS支持两种方式设置ACL. 具体可参考权限控制
第一种是使用Canned Acl,在put_object_acl的时候,通过头域的"x-bce-acl", "x-bce-grant-read", 或者 "x-bce-grant-permission"来设置对象的访问权限,当前可设置的权限包括private和public-read,三种类型的header不可以同时在一个请求中出现.
第二种方式是以自定义Acl样式, 具体可通过上传其json字符串, 设置access_control_list结构体, 或者直接上传ACL文件. 具体可参考权限控制概述
设置Bucket的访问权限
设置Canned ACL
如下代码将Bucket的权限设置为了private.
PutBucketAclRequest putBucketAclRequest(bucketName);
PutBucketAclResponse putBucketAclResponse;
putBucketAclRequest.set_canned_acl("private");
int ret = client.put_bucket_acl(putBucketAclRequest, &putBucketAclResponse);
if (ret) {
LOGF(WARN, "client err: %d", ret);
}
if (putBucketAclResponse.is_fail()) {
LOGF(WARN,"put_bucket_acl: [status_code = %d], [message = %s], [requestid = %s]",
putBucketAclResponse.status_code(),
putBucketAclResponse.error().message().c_str(),
putBucketAclResponse.error().request_id().c_str());
}
CannedACL包含三个值: private
、 public-read
、 public-read-write
,它们分别对应相关权限。
具体内容可以参考BOS API文档 使用CannedAcl方式的权限控制。
设置自定义ACL
用户可参考如下代码设置Bucket的自定义访问权限,支持三种不同参数:
PutBucketAclRequest putBucketAclRequest(bucketName);
PutBucketAclResponse putBucketAclResponse;
// 1. 通过上传acl json串
std::string jsonAcl =
"{\"accessControlList\":[{\"grantee\":[{\"id\":\"*\"}],\"permission\":[\"READ\"]},{"
"\"grantee\":[{\"id\":\"cb5f8xxxxxxxxxx82bbc\"}],\"permission\":["
"\"FULL_CONTROL\"]}]}";
std::string cannedAcl="public-read";
putBucketAclRequest.set_json_acl(jsonAcl);
// 2. 上传acl文件
std::string aclFilePath = "/tmp/acl.json"
int setRet = putBucketAclRequest.set_acl_file(aclFilePath);
if (ret) {
LOGF(WARN, "client set_acl_file: %d", ret);
}
// 3. 通过设置access_control_list数据
std::vector<Grant> grants;
Grant grant;
grantee.id = "77fxxxxxxxxxxx5fa406";
grant.grantee.push_back(grantee);
grant.permission.push_back("READ");
grants.push_back(grant);
putBucketAclRequest.set_access_control_list(grants);
int ret = client.put_bucket_acl(putObjectAclRequest, &putBucketAclRequest);
if (ret) {
LOGF(WARN, "client err: %d", ret);
}
if (putBucketAclRequest.is_fail()) {
LOGF(WARN,"put_bucket_acl: [status_code = %d], [message = %s], [requestid = %s]",
putBucketAclRequest.status_code(),
putBucketAclRequest.error().message().c_str(),
putBucketAclRequest.error().request_id().c_str());
}
查看Bucket的权限
如下代码可以查看Bucket的权限:
GetBucketAclRequest getBucketAclRequest("bucketName");
GetBucketAclResponse getBucketAclResponse;
int ret = client.get_bucket_acl(getBucketAclRequest, &getBucketAclResponse);
if (ret) {
LOGF(WARN, "client err: %d", ret);
}
if (getBucketAclResponse.is_fail()) {
LOGF(WARN,"get_bucket_acl: [status_code = %d], [message = %s], [requestid = %s]",
getBucketAclResponse.status_code(),
getBucketAclResponse.error().message().c_str(),
getBucketAclResponse.error().request_id().c_str());
}
//获取ownerid
std::string owner_id = getBucketAclResponse.owner().id;
//获取acl结构数据
std::vector<Grant> aclData = getBucketAclResponse.access_control_list();
std::string jsonStr = getBucketAclResponse.json_access_control_list();
get_bucket_acl
方法返回的response中可供调用的参数有:
参数 | 类型 | 说明 |
---|---|---|
owner | Owner(string) | Bucket owner id |
access_control_list | vector<Grant> | 保存acl的容器 |
Grant所有字段含义, 具体可参考权限控制概述
注意:
- 若您使用STS进行访问控制,C++ SDK仅支持传入STS, 不支持获取。
查看Bucket所属的区域
Bucket Location即Bucket Region,百度智能云支持的各region详细信息可参见区域选择说明。
如下代码可以获取该Bucket的Location信息:
Client client (ak, sk, config);
ListBucketsRequest listBucketsRequest;
ListBucketsResponse listBucketsResponse;
int ret = client.list_buckets(listBucketsRequest, &listBucketsResponse)
std::vector<BucketSummary> bucketSummaryList = listBucketsResponse.buckets();
if (listBucketsResponse.is_fail()) {
printf("error-message:%s\n", listBucketsResponse.error().message().c_str());
return ;
}
for(const BucketSummary& bs : bucketSummaryList){
std::cout << "name: " << bs.name <<
" location: " << bs.location << std::endl;
}
GetBucketLocationRequest getBucketLocationRequest("bucketName");
GetBucketLocationResponse getBucketLocationResponse;
ret = client.get_bucket_location(getBucketLocationRequest,
&getBucketLocationResponse);
if (getBucketLocationResponse.is_fail()) {
printf("error-message:%s\n", response.error().message().c_str());
return;
}
std::cout << "location: " << getBucketLocationResponse.location() << std::endl;
新建Bucket
如下代码可以新建一个Bucket:
int createBucket (Client& client, const std::string& bucketName) {
// 新建一个Bucket
PutBucketRequest request(bucketName);
PutBucketResponse response;
int ret = client.put_bucket(request, &response);
if (ret !=0) {
return ret;
}
if (response.is_fail()) {
printf("error-message:%s\n", response.error().message().c_str());
}
return ret;
}
int main() {
std::sting ak = "ak";
std::string sk = "sk";
Client client(ak, sk);
int ret = createBucket(client, "bucketName");
std::string ret_info = stringfy_ret_code(ret);
std::cout << ret_info << std::endl;
}
注意: 由于Bucket的名称在所有区域中是唯一的,所以需要保证bucketName不与其他所有区域上的Bucket名称相同。
Bucket的命名有以下规范:
- 只能包括小写字母,数字,短横线(-)。
- 必须以小写字母或者数字开头。
- 长度必须在3-63字节之间。
通过上述代码创建的bucket,权限是私有读写,存储类型是标准类型(Standard)。
列举Bucket
如下代码可以列出用户所有的Bucket:
int listBuckets (Client& client) {
// 获取用户的Bucket列表
ListBucketsRequest listBucketsRequest;
ListBucketsResponse listBucketsResponse;
int ret = client.list_buckets(listBucketsRequest, &listBucketsResponse);
std::vector<BucketSummary> bucketSummaryList = listBucketsResponse.buckets();
if (listBucketsResponse.is_fail()) {
printf("error-message:%s\n", listBucketsResponse.error().message().c_str());
return ret;
}
// 遍历Bucket
for(const BucketSummary& bs : bucketSummaryList){
std::cout << "bucketName: " << bs.name << std::endl;
}
return ret;
}
删除Bucket
如下代码可以删除一个Bucket:
int deleteBucket (Client& client, const std::string& bucketName) {
// 删除Bucket
DeleteBucketRequest request(bucketName);
DeleteBucketResponse response;
int ret = client.delete_bucket(request, &response);
if (response.is_fail()) {
printf("error-message:%s\n", listBucketsResponse.error().message().c_str());
}
return ret;
}
注意:
- 在删除前需要保证此Bucket下的所有Object和未完成的三步上传Part已经被删除,否则会删除失败。
- 在删除前确认该Bucket没有开通跨区域复制,不是跨区域复制规则中的源Bucket或目标Bucket,否则不能删除。
判断Bucket是否存在
若用户需要判断某个Bucket是否存在,则如下代码可以做到:
//0 表示check成功,bucket存在
//-1不存在
//other其他错误,具体error-message给出
int checkBucketExist (Client& client, const std::string& bucketName) {
bool exist = false;
// 获取Bucket的存在信息
HeadBucketRequest request(bucketName);
HeadBucketResponse response;
int ret = client.head_bucket(request, &response);
if (response.is_fail() && response.status_code() != 404){
printf("error-message:%s\n", response.error().message().c_str());
return ret;
} else if (response.status_code() == 404){
return -1;
}
//200 ok
return 0;
}
注意: 如果Bucket不为空(即Bucket中有Object存在),则Bucket无法被删除,必须清空Bucket后才能成功删除。