Skip to content

Commit fbd0be5

Browse files
committed
更新至3.22.2版本
1 parent c3447b8 commit fbd0be5

13 files changed

+602
-38
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
Version 3.22.2
2+
3+
New Features:
4+
5+
1. Added interfaces related to virtual buckets
6+
2. Compatibility changes have been made for the use of the Python3 HTTPS parameter
7+
8+
-------------------------------------------------------------------------------------------------
9+
110
Version 3.21.8
211

312
New Features:

README_CN.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
Version 3.21.8
1+
Version 3.22.2
2+
新特性:
3+
1. 增加虚拟桶相关接口
4+
2. 针对Python3 HTTPS参数的使用做了兼容修改
5+
6+
-------------------------------------------------------------------------------------------------
7+
Version 3.21.8
28

39
新特性:
410

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
c1be9812a702d1301be1bbeb07da91fd18d8dd89895169c5a229b18b59d08f9d *huaweicloud-obs-sdk-python_.tar.gz
135 KB
Binary file not shown.

src/obs/__init__.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from obs.model import Redirect, RoutingRule, Tag, TagInfo, Transition, NoncurrentVersionTransition, Rule, Versions
2424
from obs.model import Object, WebsiteConfiguration, Logging, CompleteMultipartUploadRequest, DeleteObjectsRequest
2525
from obs.model import ListMultipartUploadsRequest, GetObjectRequest, UploadFileHeader, Payer
26-
from obs.model import ExtensionHeader, FetchStatus
26+
from obs.model import ExtensionHeader, FetchStatus, BucketAliasModel, ListBucketAliasModel
2727
from obs.workflow import WorkflowClient
2828
from obs.crypto_client import CryptoObsClient
2929
from obs.obs_cipher_suite import CTRCipherGenerator
@@ -91,5 +91,7 @@
9191
'WorkflowClient',
9292
'CryptoObsClient',
9393
'CTRCipherGenerator',
94-
'CtrRSACipherGenerator'
94+
'CtrRSACipherGenerator',
95+
'BucketAliasModel',
96+
'ListBucketAliasModel'
9597
]

src/obs/client.py

Lines changed: 294 additions & 11 deletions
Large diffs are not rendered by default.

src/obs/const.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
CONTENT_ENCODING_HEADER = 'Content-Encoding'
2727
CONTENT_LANGUAGE_HEADER = 'Content-Language'
2828
EXPIRES_HEADER = 'Expires'
29-
3029
DATE_HEADER = 'Date'
3130

3231
CONTENT_LIST = [CONTENT_TYPE_HEADER.lower(), CONTENT_MD5_HEADER.lower(), DATE_HEADER.lower()]
@@ -54,6 +53,14 @@
5453
ETAG_HEADER = 'ETag'
5554
LAST_MODIFIED_HEADER = 'Last-Modified'
5655

56+
LOCATION_CLUSTERGROUP_ID = 'location-clustergroup-id'
57+
X_AUTH_TOKEN_HEADER = 'X-Auth-Token'
58+
KEY_CLUSTER_GROUP_ID = 'cgId'
59+
VIRTUAL_BUCKET_NEED_AZ_COUNT = 2
60+
VIRTUAL_BUCKET_CREATEBUCKET_STAGED = 1
61+
VIRTUAL_BUCKET_CREATEALIAS_STAGED = 2
62+
VIRTUAL_BUCKET_BINDALIAS_STAGED = 3
63+
5764
VERSION_ID_PARAM = 'versionId'
5865
RESPONSE_CACHE_CONTROL_PARAM = 'response-cache-control'
5966
RESPONSE_CONTENT_DISPOSITION_PARAM = 'response-content-disposition'
@@ -62,6 +69,8 @@
6269
RESPONSE_CONTENT_TYPE_PARAM = 'response-content-type'
6370
RESPONSE_EXPIRES_PARAM = 'response-expires'
6471
X_IMAGE_PROCESS_PARAM = 'x-image-process'
72+
OBSALIAS_PARAM = 'obsalias'
73+
OBSBUCKETALIAS_PARAM = 'obsbucketalias'
6574

6675
HTTP_METHOD_PUT = 'PUT'
6776
HTTP_METHOD_POST = 'POST'
@@ -87,7 +96,7 @@
8796
DEFAULT_TASK_NUM = 8
8897
DEFAULT_TASK_QUEUE_SIZE = 20000
8998

90-
OBS_SDK_VERSION = '3.21.8'
99+
OBS_SDK_VERSION = '3.21.12'
91100

92101
V2_META_HEADER_PREFIX = 'x-amz-meta-'
93102
V2_HEADER_PREFIX = 'x-amz-'
@@ -176,7 +185,11 @@
176185
'x-workflow-execution-state',
177186
'x-workflow-execution-type',
178187
'x-workflow-next-marker',
179-
'obsworkflowtriggerpolicy'
188+
'obsworkflowtriggerpolicy',
189+
190+
# virtual bucket api
191+
'obsbucketalias',
192+
'obsalias'
180193
)
181194

182195
ALLOWED_REQUEST_HTTP_HEADER_METADATA_NAMES = (
@@ -203,7 +216,8 @@
203216
'if-match',
204217
'if-none-match',
205218
'last-modified',
206-
'content-range'
219+
'content-range',
220+
'x-auth-token'
207221
)
208222

209223
ALLOWED_RESPONSE_HTTP_HEADER_METADATA_NAMES = (

src/obs/convertor.py

Lines changed: 121 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import xml.etree.cElementTree as ET
1717
except Exception:
1818
import xml.etree.ElementTree as ET
19+
1920
import json
2021
from obs import util
2122
from obs import const
@@ -36,7 +37,7 @@
3637
from obs.model import DateTime, ListObjectsResponse, Content, CorsRule, ObjectVersionHead, ObjectVersion, \
3738
ObjectDeleteMarker, DeleteObjectResult, NoncurrentVersionExpiration, NoncurrentVersionTransition, Rule, Condition, \
3839
Redirect, FilterRule, FunctionGraphConfiguration, Upload, CompleteMultipartUploadResponse, ListPartsResponse, \
39-
Grant, ReplicationRule, Transition, Grantee
40+
Grant, ReplicationRule, Transition, Grantee, BucketAliasModel, ListBucketAliasModel
4041

4142
if const.IS_PYTHON2:
4243
from urllib import unquote_plus, quote_plus
@@ -87,6 +88,10 @@ def acl_header(self):
8788
def epid_header(self):
8889
return self._get_header_prefix() + 'epid'
8990

91+
@staticmethod
92+
def pfs_header():
93+
return 'x-obs-fs-file-interface'
94+
9095
def date_header(self):
9196
return self._get_header_prefix() + 'date'
9297

@@ -116,6 +121,10 @@ def indicator_header():
116121
def location_header(self):
117122
return self._get_header_prefix() + 'location'
118123

124+
@staticmethod
125+
def queryPFS_header():
126+
return 'x-obs-bucket-type'
127+
119128
def bucket_region_header(self):
120129
return self._get_header_prefix() + 'bucket-location' if self.is_obs \
121130
else self._get_header_prefix() + 'bucket-region'
@@ -207,6 +216,9 @@ def object_type_header():
207216
def request_payer_header(self):
208217
return self._get_header_prefix() + 'request-payer'
209218

219+
def location_clustergroup_id_header(self):
220+
return self._get_header_prefix() + const.LOCATION_CLUSTERGROUP_ID
221+
210222
def oef_marker_header(self):
211223
return self._get_header_prefix() + 'oef-marker'
212224

@@ -305,6 +317,8 @@ def trans_create_bucket(self, **kwargs):
305317
self.ha.adapt_storage_class(header.get('storageClass')))
306318
self._put_key_value(headers, self.ha.az_redundancy_header(), header.get('availableZone'))
307319
self._put_key_value(headers, self.ha.epid_header(), header.get('epid'))
320+
if header.get('isPFS'):
321+
self._put_key_value(headers, self.ha.pfs_header(), "Enabled")
308322
extensionGrants = header.get('extensionGrants')
309323
if extensionGrants is not None and len(extensionGrants) > 0:
310324
grantDict = {}
@@ -331,6 +345,8 @@ def trans_list_buckets(self, **kwargs):
331345
headers = {}
332346
if kwargs.get('isQueryLocation'):
333347
self._put_key_value(headers, self.ha.location_header(), 'true')
348+
if kwargs.get('bucketType'):
349+
self._put_key_value(headers, self.ha.queryPFS_header(), kwargs.get('bucketType'))
334350
return {'headers': headers}
335351

336352
def trans_list_objects(self, **kwargs):
@@ -1049,16 +1065,23 @@ def trans_replication(self, replication):
10491065
ET.SubElement(ruleEle, 'Prefix').text = util.safe_decode(replicationRule['prefix'])
10501066
if replicationRule.get('status') is not None:
10511067
ET.SubElement(ruleEle, 'Status').text = util.to_string(replicationRule['status'])
1068+
if replicationRule.get('historicalObjectReplication') is not None:
1069+
ET.SubElement(ruleEle, 'HistoricalObjectReplication').text = util.to_string(
1070+
replicationRule['historicalObjectReplication'])
10521071

1053-
if replication.get('bucket') is not None:
1072+
if replicationRule.get('bucket') is not None:
10541073
destinationEle = ET.SubElement(ruleEle, 'Destination')
10551074
bucket_name = util.to_string(replicationRule['bucket'])
10561075
bucket_name = bucket_name if self.is_obs else bucket_name if bucket_name.startswith(
10571076
'arn:aws:s3:::') else 'arn:aws:s3:::' + bucket_name
10581077
ET.SubElement(destinationEle, 'Bucket').text = bucket_name
1078+
10591079
if replicationRule.get('storageClass') is not None:
1060-
ET.SubElement(destinationEle, 'Bucket').text = self.ha.adapt_storage_class(
1080+
ET.SubElement(destinationEle, 'StorageClass').text = self.ha.adapt_storage_class(
10611081
replicationRule['storageClass'])
1082+
1083+
if replicationRule.get('deleteData') is not None:
1084+
ET.SubElement(destinationEle, 'DeleteData').text = util.to_string(replicationRule['deleteData'])
10621085
return ET.tostring(root, 'UTF-8')
10631086

10641087
@staticmethod
@@ -1070,7 +1093,9 @@ def trans_bucket_request_payment(payer):
10701093
def trans_get_extension_headers(self, headers):
10711094
_headers = {}
10721095
if headers is not None and len(headers) > 0:
1073-
self._put_key_value(_headers, self.ha.request_payer_header(), (headers.get('requesterPayer')))
1096+
self._put_key_value(_headers, self.ha.request_payer_header(), headers.get('requesterPayer'))
1097+
self._put_key_value(_headers, self.ha.location_clustergroup_id_header(),
1098+
headers.get('locationClusterGroupId'))
10741099
return _headers
10751100

10761101
# OEF trans func
@@ -1113,6 +1138,16 @@ def _find_item(root, item_name, encoding_type=None):
11131138
return util.to_string(unquote_plus(result))
11141139
return util.to_string(result)
11151140

1141+
@staticmethod
1142+
def _find_text(result, encoding_type=None):
1143+
if result is None:
1144+
return None
1145+
if const.IS_PYTHON2:
1146+
result = util.safe_encode(result)
1147+
if encoding_type == "url":
1148+
return util.to_string(unquote_plus(result))
1149+
return util.to_string(result)
1150+
11161151
def parseListBuckets(self, xml, headers=None):
11171152
root = ET.fromstring(xml)
11181153
owner = root.find('Owner')
@@ -1129,8 +1164,9 @@ def parseListBuckets(self, xml, headers=None):
11291164
name = self._find_item(bucket, 'Name')
11301165
d = self._find_item(bucket, 'CreationDate')
11311166
location = self._find_item(bucket, 'Location')
1167+
bucket_type = self._find_item(bucket, 'BucketType')
11321168
create_date = DateTime.UTCToLocal(d)
1133-
curr_bucket = Bucket(name=name, create_date=create_date, location=location)
1169+
curr_bucket = Bucket(name=name, create_date=create_date, location=location, bucket_type=bucket_type)
11341170
entries.append(curr_bucket)
11351171
return ListBucketsResponse(buckets=entries, owner=Owners)
11361172

@@ -1873,8 +1909,11 @@ def parseGetBucketReplication(self, xml, headers=None):
18731909
status = self._find_item(rule, 'Status')
18741910
bucket = self._find_item(rule, 'Destination/Bucket')
18751911
storageClass = self._find_item(rule, 'Destination/StorageClass')
1912+
deleteData = self._find_item(rule, 'Destination/DeleteData')
1913+
historicalObjectReplication = self._find_item(rule, 'Destination/HistoricalObjectReplication')
18761914
_rules.append(
1877-
ReplicationRule(id=_id, prefix=prefix, status=status, bucket=bucket, storageClass=storageClass))
1915+
ReplicationRule(id=_id, prefix=prefix, status=status, bucket=bucket, storageClass=storageClass,
1916+
deleteData=deleteData, historicalObjectReplication=historicalObjectReplication))
18781917
replication = Replication(agency=agency, replicationRules=_rules)
18791918
return replication
18801919

@@ -2066,3 +2105,79 @@ def parseGetTriggerPolicyResponse(jsons, header=None):
20662105
# end workflow related
20672106
# end workflow related
20682107
# end workflow related
2108+
2109+
# begin virtual bucket related
2110+
# begin virtual bucket related
2111+
# begin virtual bucket related
2112+
2113+
def trans_set_bucket_alias(self, **kwargs):
2114+
aliasInfo = kwargs.get('aliasInfo')
2115+
entity = None if aliasInfo is None or len(aliasInfo) == 0 else self.trans_set_aliasInfo(aliasInfo)
2116+
return {'pathArgs': {const.OBSBUCKETALIAS_PARAM: None}, 'entity': entity}
2117+
2118+
def trans_set_aliasInfo(self, aliasInfo):
2119+
root = ET.Element('CreateBucketAlias')
2120+
bucketListEle = ET.SubElement(root, 'BucketList')
2121+
ET.SubElement(bucketListEle, 'Bucket').text = util.to_string(aliasInfo.get('bucket1'))
2122+
ET.SubElement(bucketListEle, 'Bucket').text = util.to_string(aliasInfo.get('bucket2'))
2123+
return ET.tostring(root, 'UTF-8')
2124+
2125+
def trans_bind_bucket_alias(self, **kwargs):
2126+
aliasInfo = kwargs.get('aliasInfo')
2127+
entity = None if aliasInfo is None or len(aliasInfo) == 0 else self.trans_bind_aliasInfo(aliasInfo)
2128+
return {'pathArgs': {const.OBSALIAS_PARAM: None}, 'entity': entity}
2129+
2130+
def trans_bind_aliasInfo(self, aliasInfo):
2131+
root = ET.Element('AliasList')
2132+
ET.SubElement(root, 'Alias').text = util.to_string(aliasInfo.get('alias'))
2133+
return ET.tostring(root, 'UTF-8')
2134+
2135+
def parseGetBucketAlias(self, xml, header=None):
2136+
root = ET.fromstring(xml)
2137+
bucketAliasXml = root.find('BucketAlias')
2138+
alias = self._find_item(bucketAliasXml, 'Alias')
2139+
bucketAlias = BucketAliasModel(alias=alias)
2140+
2141+
bucketListXml = bucketAliasXml.find('BucketList').findall('Bucket')
2142+
bucketNameList = []
2143+
for bucketXml in bucketListXml:
2144+
bucketNameList.append(self._find_text(bucketXml.text))
2145+
2146+
if len(bucketNameList) > 0:
2147+
bucketAlias.bucket1 = bucketNameList[0]
2148+
if len(bucketNameList) > 1:
2149+
bucketAlias.bucket2 = bucketNameList[1]
2150+
2151+
return bucketAlias
2152+
2153+
def parseListBucketAlias(self, xml, header=None):
2154+
root = ET.fromstring(xml)
2155+
ownerXml = root.find('Owner')
2156+
ownerID = self._find_item(ownerXml, 'ID')
2157+
listBucketAlias = ListBucketAliasModel(owner=ownerID)
2158+
2159+
bucketAliasListXml = root.find('BucketAliasList').findall('BucketAlias')
2160+
bucketAliasList = []
2161+
for bucketAliasXml in bucketAliasListXml:
2162+
alias = self._find_item(bucketAliasXml, 'Alias')
2163+
creationDate = self._find_item(bucketAliasXml, 'CreationDate')
2164+
bucketAlias = BucketAliasModel(alias=alias, creationDate=creationDate)
2165+
2166+
bucketListXml = bucketAliasXml.find('BucketList').findall('Bucket')
2167+
bucketNameList = []
2168+
for bucketXml in bucketListXml:
2169+
bucketNameList.append(self._find_text(bucketXml.text))
2170+
2171+
if len(bucketNameList) > 0:
2172+
bucketAlias.bucket1 = bucketNameList[0]
2173+
if len(bucketNameList) > 1:
2174+
bucketAlias.bucket2 = bucketNameList[1]
2175+
2176+
bucketAliasList.append(bucketAlias)
2177+
2178+
listBucketAlias.bucketAlias = bucketAliasList
2179+
return listBucketAlias
2180+
2181+
# end virtual bucket related
2182+
# end virtual bucket related
2183+
# end virtual bucket related

0 commit comments

Comments
 (0)