fog-xiaozhu 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.rubocop.yml +5 -0
- data/.rubocop_todo.yml +149 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +4 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +312 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/fog-aliyun.gemspec +33 -0
- data/lib/fog/aliyun/compute.rb +424 -0
- data/lib/fog/aliyun/models/compute/eip_address.rb +57 -0
- data/lib/fog/aliyun/models/compute/eip_addresses.rb +28 -0
- data/lib/fog/aliyun/models/compute/image.rb +66 -0
- data/lib/fog/aliyun/models/compute/images.rb +25 -0
- data/lib/fog/aliyun/models/compute/route_entry.rb +26 -0
- data/lib/fog/aliyun/models/compute/route_entrys.rb +41 -0
- data/lib/fog/aliyun/models/compute/route_table.rb +30 -0
- data/lib/fog/aliyun/models/compute/route_tables.rb +27 -0
- data/lib/fog/aliyun/models/compute/security_group.rb +81 -0
- data/lib/fog/aliyun/models/compute/security_group_rule.rb +47 -0
- data/lib/fog/aliyun/models/compute/security_group_rules.rb +23 -0
- data/lib/fog/aliyun/models/compute/security_groups.rb +32 -0
- data/lib/fog/aliyun/models/compute/server.rb +70 -0
- data/lib/fog/aliyun/models/compute/servers.rb +42 -0
- data/lib/fog/aliyun/models/compute/snapshot.rb +52 -0
- data/lib/fog/aliyun/models/compute/snapshots.rb +38 -0
- data/lib/fog/aliyun/models/compute/volume.rb +101 -0
- data/lib/fog/aliyun/models/compute/volumes.rb +135 -0
- data/lib/fog/aliyun/models/compute/vpc.rb +77 -0
- data/lib/fog/aliyun/models/compute/vpcs.rb +80 -0
- data/lib/fog/aliyun/models/compute/vrouter.rb +35 -0
- data/lib/fog/aliyun/models/compute/vrouters.rb +61 -0
- data/lib/fog/aliyun/models/compute/vswitch.rb +70 -0
- data/lib/fog/aliyun/models/compute/vswitches.rb +80 -0
- data/lib/fog/aliyun/models/storage/directories.rb +39 -0
- data/lib/fog/aliyun/models/storage/directory.rb +48 -0
- data/lib/fog/aliyun/models/storage/file.rb +192 -0
- data/lib/fog/aliyun/models/storage/files.rb +193 -0
- data/lib/fog/aliyun/requests/compute/allocate_eip_address.rb +54 -0
- data/lib/fog/aliyun/requests/compute/allocate_public_ip_address.rb +39 -0
- data/lib/fog/aliyun/requests/compute/associate_eip_address.rb +49 -0
- data/lib/fog/aliyun/requests/compute/attach_disk.rb +79 -0
- data/lib/fog/aliyun/requests/compute/create_disk.rb +137 -0
- data/lib/fog/aliyun/requests/compute/create_image.rb +79 -0
- data/lib/fog/aliyun/requests/compute/create_security_group.rb +77 -0
- data/lib/fog/aliyun/requests/compute/create_security_group_egress_ip_rule.rb +63 -0
- data/lib/fog/aliyun/requests/compute/create_security_group_egress_sg_rule.rb +71 -0
- data/lib/fog/aliyun/requests/compute/create_security_group_ip_rule.rb +63 -0
- data/lib/fog/aliyun/requests/compute/create_security_group_sg_rule.rb +71 -0
- data/lib/fog/aliyun/requests/compute/create_server.rb +186 -0
- data/lib/fog/aliyun/requests/compute/create_snapshot.rb +46 -0
- data/lib/fog/aliyun/requests/compute/create_vpc.rb +46 -0
- data/lib/fog/aliyun/requests/compute/create_vpn_connection.rb +58 -0
- data/lib/fog/aliyun/requests/compute/create_vpn_customergateway.rb +48 -0
- data/lib/fog/aliyun/requests/compute/create_vswitch.rb +54 -0
- data/lib/fog/aliyun/requests/compute/delete_disk.rb +41 -0
- data/lib/fog/aliyun/requests/compute/delete_image.rb +31 -0
- data/lib/fog/aliyun/requests/compute/delete_security_group.rb +51 -0
- data/lib/fog/aliyun/requests/compute/delete_security_group_egress_ip_rule.rb +63 -0
- data/lib/fog/aliyun/requests/compute/delete_security_group_egress_sg_rule.rb +71 -0
- data/lib/fog/aliyun/requests/compute/delete_security_group_ip_rule.rb +63 -0
- data/lib/fog/aliyun/requests/compute/delete_security_group_sg_rule.rb +71 -0
- data/lib/fog/aliyun/requests/compute/delete_server.rb +48 -0
- data/lib/fog/aliyun/requests/compute/delete_snapshot.rb +31 -0
- data/lib/fog/aliyun/requests/compute/delete_vpc.rb +35 -0
- data/lib/fog/aliyun/requests/compute/delete_vpn_connection.rb +35 -0
- data/lib/fog/aliyun/requests/compute/delete_vpn_customergateway.rb +35 -0
- data/lib/fog/aliyun/requests/compute/delete_vswitch.rb +35 -0
- data/lib/fog/aliyun/requests/compute/detach_disk.rb +41 -0
- data/lib/fog/aliyun/requests/compute/join_security_group.rb +40 -0
- data/lib/fog/aliyun/requests/compute/leave_security_group.rb +40 -0
- data/lib/fog/aliyun/requests/compute/list_disks.rb +150 -0
- data/lib/fog/aliyun/requests/compute/list_eip_addresses.rb +55 -0
- data/lib/fog/aliyun/requests/compute/list_images.rb +82 -0
- data/lib/fog/aliyun/requests/compute/list_route_tables.rb +64 -0
- data/lib/fog/aliyun/requests/compute/list_security_group_rules.rb +73 -0
- data/lib/fog/aliyun/requests/compute/list_security_groups.rb +78 -0
- data/lib/fog/aliyun/requests/compute/list_server_types.rb +77 -0
- data/lib/fog/aliyun/requests/compute/list_servers.rb +71 -0
- data/lib/fog/aliyun/requests/compute/list_snapshots.rb +97 -0
- data/lib/fog/aliyun/requests/compute/list_vpcs.rb +47 -0
- data/lib/fog/aliyun/requests/compute/list_vpn_connections.rb +49 -0
- data/lib/fog/aliyun/requests/compute/list_vpn_customergateways.rb +43 -0
- data/lib/fog/aliyun/requests/compute/list_vpn_gateways.rb +49 -0
- data/lib/fog/aliyun/requests/compute/list_vrouters.rb +61 -0
- data/lib/fog/aliyun/requests/compute/list_vswitchs.rb +50 -0
- data/lib/fog/aliyun/requests/compute/list_zones.rb +44 -0
- data/lib/fog/aliyun/requests/compute/modify_vpc.rb +73 -0
- data/lib/fog/aliyun/requests/compute/modify_vswitch.rb +45 -0
- data/lib/fog/aliyun/requests/compute/reboot_server.rb +43 -0
- data/lib/fog/aliyun/requests/compute/release_eip_address.rb +29 -0
- data/lib/fog/aliyun/requests/compute/start_server.rb +41 -0
- data/lib/fog/aliyun/requests/compute/stop_server.rb +41 -0
- data/lib/fog/aliyun/requests/compute/unassociate_eip_address.rb +49 -0
- data/lib/fog/aliyun/requests/storage/copy_object.rb +39 -0
- data/lib/fog/aliyun/requests/storage/delete_bucket.rb +30 -0
- data/lib/fog/aliyun/requests/storage/delete_container.rb +35 -0
- data/lib/fog/aliyun/requests/storage/delete_object.rb +51 -0
- data/lib/fog/aliyun/requests/storage/get_bucket.rb +141 -0
- data/lib/fog/aliyun/requests/storage/get_container.rb +60 -0
- data/lib/fog/aliyun/requests/storage/get_containers.rb +64 -0
- data/lib/fog/aliyun/requests/storage/get_object.rb +45 -0
- data/lib/fog/aliyun/requests/storage/get_object_http_url.rb +43 -0
- data/lib/fog/aliyun/requests/storage/get_object_https_url.rb +43 -0
- data/lib/fog/aliyun/requests/storage/head_object.rb +34 -0
- data/lib/fog/aliyun/requests/storage/list_buckets.rb +40 -0
- data/lib/fog/aliyun/requests/storage/list_objects.rb +91 -0
- data/lib/fog/aliyun/requests/storage/put_bucket.rb +22 -0
- data/lib/fog/aliyun/requests/storage/put_container.rb +35 -0
- data/lib/fog/aliyun/requests/storage/put_object.rb +189 -0
- data/lib/fog/aliyun/storage.rb +233 -0
- data/lib/fog/aliyun/version.rb +5 -0
- data/lib/fog/aliyun.rb +19 -0
- data/lib/fog/bin/aliyun.rb +31 -0
- metadata +311 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
module Fog
|
2
|
+
module Storage
|
3
|
+
class Aliyun
|
4
|
+
class Real
|
5
|
+
def list_buckets(options = {})
|
6
|
+
prefix = options[:prefix]
|
7
|
+
marker = options[:marker]
|
8
|
+
maxKeys = options[:maxKeys]
|
9
|
+
|
10
|
+
path = ''
|
11
|
+
if prefix
|
12
|
+
path += '?prefix=' + prefix
|
13
|
+
path += '&marker=' + marker if marker
|
14
|
+
path += '&max-keys=' + maxKeys if maxKeys
|
15
|
+
|
16
|
+
elsif marker
|
17
|
+
path += '?marker=' + marker
|
18
|
+
path += '&max-keys=' + maxKeys if maxKeys
|
19
|
+
|
20
|
+
elsif maxKeys
|
21
|
+
path += '?max-keys=' + maxKeys
|
22
|
+
end
|
23
|
+
|
24
|
+
ret = request(
|
25
|
+
expects: [200, 203],
|
26
|
+
method: 'GET',
|
27
|
+
path: path
|
28
|
+
)
|
29
|
+
xml = ret.data[:body]
|
30
|
+
result = XmlSimple.xml_in(xml)['Buckets'][0]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class Mock
|
35
|
+
def list_buckets(options = {})
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Fog
|
2
|
+
module Storage
|
3
|
+
class Aliyun
|
4
|
+
class Real
|
5
|
+
def list_objects(options = {})
|
6
|
+
bucket = options[:bucket]
|
7
|
+
bucket ||= @aliyun_oss_bucket
|
8
|
+
prefix = options[:prefix]
|
9
|
+
marker = options[:marker]
|
10
|
+
maxKeys = options[:maxKeys]
|
11
|
+
delimiter = options[:delimiter]
|
12
|
+
|
13
|
+
path = ''
|
14
|
+
if prefix
|
15
|
+
path += '?prefix=' + prefix
|
16
|
+
path += '&marker=' + marker if marker
|
17
|
+
path += '&max-keys=' + maxKeys if maxKeys
|
18
|
+
path += '&delimiter=' + delimiter if delimiter
|
19
|
+
|
20
|
+
elsif marker
|
21
|
+
path += '?marker=' + marker
|
22
|
+
path += '&max-keys=' + maxKeys if maxKeys
|
23
|
+
path += '&delimiter=' + delimiter if delimiter
|
24
|
+
|
25
|
+
elsif maxKeys
|
26
|
+
path += '?max-keys=' + maxKeys
|
27
|
+
path += '&delimiter=' + delimiter if delimiter
|
28
|
+
elsif delimiter
|
29
|
+
path += '?delimiter=' + delimiter
|
30
|
+
end
|
31
|
+
|
32
|
+
location = get_bucket_location(bucket)
|
33
|
+
endpoint = 'http://' + location + '.aliyuncs.com'
|
34
|
+
resource = bucket + '/'
|
35
|
+
ret = request(
|
36
|
+
expects: [200, 203, 400],
|
37
|
+
method: 'GET',
|
38
|
+
path: path,
|
39
|
+
resource: resource,
|
40
|
+
bucket: bucket
|
41
|
+
)
|
42
|
+
xml = ret.data[:body]
|
43
|
+
result = XmlSimple.xml_in(xml)
|
44
|
+
end
|
45
|
+
|
46
|
+
def list_multipart_uploads(bucket, endpoint, _options = {})
|
47
|
+
if nil == endpoint
|
48
|
+
location = get_bucket_location(bucket)
|
49
|
+
endpoint = 'http://' + location + '.aliyuncs.com'
|
50
|
+
end
|
51
|
+
path = '?uploads'
|
52
|
+
resource = bucket + '/' + path
|
53
|
+
|
54
|
+
ret = request(
|
55
|
+
expects: 200,
|
56
|
+
method: 'GET',
|
57
|
+
path: path,
|
58
|
+
bucket: bucket,
|
59
|
+
resource: resource,
|
60
|
+
endpoint: endpoint
|
61
|
+
)
|
62
|
+
uploadid = XmlSimple.xml_in(ret.data[:body])['Upload']
|
63
|
+
end
|
64
|
+
|
65
|
+
def list_parts(bucket, object, endpoint, uploadid, _options = {})
|
66
|
+
if nil == endpoint
|
67
|
+
location = get_bucket_location(bucket)
|
68
|
+
endpoint = 'http://' + location + '.aliyuncs.com'
|
69
|
+
end
|
70
|
+
path = object + '?uploadId=' + uploadid
|
71
|
+
resource = bucket + '/' + path
|
72
|
+
|
73
|
+
ret = request(
|
74
|
+
expects: 200,
|
75
|
+
method: 'GET',
|
76
|
+
path: path,
|
77
|
+
bucket: bucket,
|
78
|
+
resource: resource,
|
79
|
+
endpoint: endpoint
|
80
|
+
)
|
81
|
+
parts = XmlSimple.xml_in(ret.data[:body])['Part']
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
class Mock
|
86
|
+
def list_objects(options = {})
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Fog
|
2
|
+
module Storage
|
3
|
+
class Aliyun
|
4
|
+
class Real
|
5
|
+
def put_bucket(bucketName)
|
6
|
+
resource = bucketName + '/'
|
7
|
+
ret = request(
|
8
|
+
expects: [200, 203],
|
9
|
+
method: 'PUT',
|
10
|
+
resource: resource,
|
11
|
+
bucket: bucketName
|
12
|
+
)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class Mock
|
17
|
+
def put_bucket(bucketName)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Fog
|
2
|
+
module Storage
|
3
|
+
class Aliyun
|
4
|
+
class Real
|
5
|
+
# Create a new container
|
6
|
+
#
|
7
|
+
# ==== Parameters
|
8
|
+
# * name<~String> - Name for container
|
9
|
+
#
|
10
|
+
def put_container(name, options = {})
|
11
|
+
bucket = options[:bucket]
|
12
|
+
bucket ||= @aliyun_oss_bucket
|
13
|
+
location = get_bucket_location(bucket)
|
14
|
+
endpoint = 'http://' + location + '.aliyuncs.com'
|
15
|
+
|
16
|
+
path = name + '/'
|
17
|
+
resource = bucket + '/' + name + '/'
|
18
|
+
request(
|
19
|
+
expects: [200, 203],
|
20
|
+
method: 'PUT',
|
21
|
+
path: path,
|
22
|
+
bucket: bucket,
|
23
|
+
resource: resource,
|
24
|
+
endpoint: endpoint
|
25
|
+
)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class Mock
|
30
|
+
def put_container(name, options = {})
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
module Fog
|
2
|
+
module Storage
|
3
|
+
class Aliyun
|
4
|
+
class Real
|
5
|
+
# Put details for object
|
6
|
+
#
|
7
|
+
# ==== Parameters
|
8
|
+
# * object<~String> - Name of object to look for
|
9
|
+
#
|
10
|
+
def put_object(object, file = nil, options = {})
|
11
|
+
bucket = options[:bucket]
|
12
|
+
bucket ||= @aliyun_oss_bucket
|
13
|
+
location = get_bucket_location(bucket)
|
14
|
+
endpoint = 'http://' + location + '.aliyuncs.com'
|
15
|
+
return put_folder(bucket, object, endpoint) if nil == file
|
16
|
+
|
17
|
+
# put multiparts if object's size is over 100m
|
18
|
+
if file.size > 104_857_600
|
19
|
+
return put_multipart_object(bucket, object, file)
|
20
|
+
end
|
21
|
+
|
22
|
+
body = file.read
|
23
|
+
|
24
|
+
resource = bucket + '/' + object
|
25
|
+
ret = request(
|
26
|
+
expects: [200, 203],
|
27
|
+
method: 'PUT',
|
28
|
+
path: object,
|
29
|
+
bucket: bucket,
|
30
|
+
resource: resource,
|
31
|
+
body: body,
|
32
|
+
endpoint: endpoint
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
def put_object_with_body(object, body, options = {})
|
37
|
+
bucket = options[:bucket]
|
38
|
+
bucket ||= @aliyun_oss_bucket
|
39
|
+
location = get_bucket_location(bucket)
|
40
|
+
endpoint = 'http://' + location + '.aliyuncs.com'
|
41
|
+
|
42
|
+
resource = bucket + '/' + object
|
43
|
+
ret = request(
|
44
|
+
expects: [200, 203],
|
45
|
+
method: 'PUT',
|
46
|
+
path: object,
|
47
|
+
bucket: bucket,
|
48
|
+
resource: resource,
|
49
|
+
body: body,
|
50
|
+
endpoint: endpoint
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
54
|
+
def put_folder(bucket, folder, endpoint)
|
55
|
+
if nil == endpoint
|
56
|
+
location = get_bucket_location(bucket)
|
57
|
+
endpoint = 'http://' + location + '.aliyuncs.com'
|
58
|
+
end
|
59
|
+
path = folder + '/'
|
60
|
+
resource = bucket + '/' + folder + '/'
|
61
|
+
ret = request(
|
62
|
+
expects: [200, 203],
|
63
|
+
method: 'PUT',
|
64
|
+
path: path,
|
65
|
+
bucket: bucket,
|
66
|
+
resource: resource,
|
67
|
+
endpoint: endpoint
|
68
|
+
)
|
69
|
+
end
|
70
|
+
|
71
|
+
def put_multipart_object(bucket, object, file)
|
72
|
+
location = get_bucket_location(bucket)
|
73
|
+
endpoint = 'http://' + location + '.aliyuncs.com'
|
74
|
+
|
75
|
+
# find the right uploadid
|
76
|
+
uploads = list_multipart_uploads(bucket, endpoint)
|
77
|
+
if nil != uploads
|
78
|
+
upload = uploads.find { |tmpupload| tmpupload['Key'][0] == object }
|
79
|
+
else
|
80
|
+
upload = nil
|
81
|
+
end
|
82
|
+
|
83
|
+
parts = nil
|
84
|
+
uploadedSize = 0
|
85
|
+
start_partNumber = 1
|
86
|
+
if nil != upload
|
87
|
+
uploadId = upload['UploadId'][0]
|
88
|
+
parts = list_parts(bucket, object, endpoint, uploadId)
|
89
|
+
if (nil != parts) && !parts.empty?
|
90
|
+
if parts[-1]['Size'][0].to_i != 5_242_880
|
91
|
+
# the part is the last one, if its size is over 5m, then finish this upload
|
92
|
+
complete_multipart_upload(bucket, object, endpoint, uploadId)
|
93
|
+
return
|
94
|
+
end
|
95
|
+
uploadedSize = (parts[0]['Size'][0].to_i * (parts.size - 1)) + parts[-1]['Size'][0].to_i
|
96
|
+
start_partNumber = parts[-1]['PartNumber'][0].to_i + 1
|
97
|
+
end
|
98
|
+
else
|
99
|
+
# create upload ID
|
100
|
+
uploadId = initiate_multipart_upload(bucket, object, endpoint)
|
101
|
+
end
|
102
|
+
|
103
|
+
if file.size <= uploadedSize
|
104
|
+
complete_multipart_upload(bucket, object, endpoint, uploadId)
|
105
|
+
return
|
106
|
+
end
|
107
|
+
|
108
|
+
end_partNumber = (file.size + 5_242_880 - 1) / 5_242_880
|
109
|
+
file.seek(uploadedSize)
|
110
|
+
|
111
|
+
for i in start_partNumber..end_partNumber
|
112
|
+
body = file.read(5_242_880)
|
113
|
+
upload_part(bucket, object, endpoint, i.to_s, uploadId, body)
|
114
|
+
end
|
115
|
+
|
116
|
+
complete_multipart_upload(bucket, object, endpoint, uploadId)
|
117
|
+
end
|
118
|
+
|
119
|
+
def initiate_multipart_upload(bucket, object, endpoint)
|
120
|
+
if nil == endpoint
|
121
|
+
location = get_bucket_location(bucket)
|
122
|
+
endpoint = 'http://' + location + '.aliyuncs.com'
|
123
|
+
end
|
124
|
+
path = object + '?uploads'
|
125
|
+
resource = bucket + '/' + path
|
126
|
+
ret = request(
|
127
|
+
expects: 200,
|
128
|
+
method: 'POST',
|
129
|
+
path: path,
|
130
|
+
bucket: bucket,
|
131
|
+
resource: resource,
|
132
|
+
endpoint: endpoint
|
133
|
+
)
|
134
|
+
uploadid = XmlSimple.xml_in(ret.data[:body])['UploadId'][0]
|
135
|
+
end
|
136
|
+
|
137
|
+
def upload_part(bucket, object, endpoint, partNumber, uploadId, body)
|
138
|
+
if nil == endpoint
|
139
|
+
location = get_bucket_location(bucket)
|
140
|
+
endpoint = 'http://' + location + '.aliyuncs.com'
|
141
|
+
end
|
142
|
+
path = object + '?partNumber=' + partNumber + '&uploadId=' + uploadId
|
143
|
+
resource = bucket + '/' + path
|
144
|
+
ret = request(
|
145
|
+
expects: [200, 203],
|
146
|
+
method: 'PUT',
|
147
|
+
path: path,
|
148
|
+
bucket: bucket,
|
149
|
+
resource: resource,
|
150
|
+
body: body,
|
151
|
+
endpoint: endpoint
|
152
|
+
)
|
153
|
+
end
|
154
|
+
|
155
|
+
def complete_multipart_upload(bucket, object, endpoint, uploadId)
|
156
|
+
if nil == endpoint
|
157
|
+
location = get_bucket_location(bucket)
|
158
|
+
endpoint = 'http://' + location + '.aliyuncs.com'
|
159
|
+
end
|
160
|
+
parts = list_parts(bucket, object, endpoint, uploadId, options = {})
|
161
|
+
request_part = []
|
162
|
+
return if parts.empty?
|
163
|
+
for i in 0..(parts.size - 1)
|
164
|
+
part = parts[i]
|
165
|
+
request_part[i] = { 'PartNumber' => part['PartNumber'], 'ETag' => part['ETag'] }
|
166
|
+
end
|
167
|
+
body = XmlSimple.xml_out({ 'Part' => request_part }, 'RootName' => 'CompleteMultipartUpload')
|
168
|
+
|
169
|
+
path = object + '?uploadId=' + uploadId
|
170
|
+
resource = bucket + '/' + path
|
171
|
+
ret = request(
|
172
|
+
expects: 200,
|
173
|
+
method: 'POST',
|
174
|
+
path: path,
|
175
|
+
bucket: bucket,
|
176
|
+
resource: resource,
|
177
|
+
endpoint: endpoint,
|
178
|
+
body: body
|
179
|
+
)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
class Mock
|
184
|
+
def put_object(object, file = nil, options = {})
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
@@ -0,0 +1,233 @@
|
|
1
|
+
require 'xmlsimple'
|
2
|
+
|
3
|
+
module Fog
|
4
|
+
module Storage
|
5
|
+
class Aliyun < Fog::Service
|
6
|
+
|
7
|
+
DEFAULT_REGION = 'cn-hangzhou'
|
8
|
+
|
9
|
+
DEFAULT_SCHEME = 'http'
|
10
|
+
DEFAULT_SCHEME_PORT = {
|
11
|
+
'http' => 80,
|
12
|
+
'https' => 443
|
13
|
+
}
|
14
|
+
|
15
|
+
recognizes :aliyun_oss_endpoint,
|
16
|
+
:aliyun_oss_location,
|
17
|
+
:aliyun_region_id
|
18
|
+
requires :aliyun_accesskey_id,
|
19
|
+
:aliyun_accesskey_secret,
|
20
|
+
:aliyun_oss_bucket
|
21
|
+
|
22
|
+
model_path 'fog/aliyun/models/storage'
|
23
|
+
model :directory
|
24
|
+
collection :directories
|
25
|
+
model :file
|
26
|
+
collection :files
|
27
|
+
|
28
|
+
request_path 'fog/aliyun/requests/storage'
|
29
|
+
request :copy_object
|
30
|
+
request :delete_bucket
|
31
|
+
request :delete_object
|
32
|
+
request :get_bucket
|
33
|
+
request :get_object
|
34
|
+
request :get_object_http_url
|
35
|
+
request :get_object_https_url
|
36
|
+
request :head_object
|
37
|
+
request :put_bucket
|
38
|
+
request :put_object
|
39
|
+
request :list_buckets
|
40
|
+
request :list_objects
|
41
|
+
request :get_containers
|
42
|
+
request :get_container
|
43
|
+
request :delete_container
|
44
|
+
request :put_container
|
45
|
+
|
46
|
+
class Real
|
47
|
+
# Initialize connection to OSS
|
48
|
+
#
|
49
|
+
# ==== Notes
|
50
|
+
# options parameter must include values for :aliyun_accesskey_id, :aliyun_secret_access_key and :aliyun_oss_bucket in order to create a connection.
|
51
|
+
# :aliyun_oss_location will be replaced by :aliyun_region_id, and it has a default value cn-hangzhou
|
52
|
+
# if :aliyun_oss_endpoint is not specified, it will be generated by method region_to_endpoint
|
53
|
+
#
|
54
|
+
# ==== Examples
|
55
|
+
# sdb = Fog::Storage.new(:provider=>'aliyun',
|
56
|
+
# :aliyun_accesskey_id => your_:aliyun_accesskey_id,
|
57
|
+
# :aliyun_secret_access_key => your_aliyun_secret_access_key
|
58
|
+
# )
|
59
|
+
#
|
60
|
+
# ==== Parameters
|
61
|
+
# * options<~Hash> - config arguments for connection. Defaults to {}.
|
62
|
+
#
|
63
|
+
# ==== Returns
|
64
|
+
# * OSS object with connection to aliyun.
|
65
|
+
attr_reader :aliyun_accesskey_id
|
66
|
+
attr_reader :aliyun_accesskey_secret
|
67
|
+
attr_reader :aliyun_oss_endpoint
|
68
|
+
attr_reader :aliyun_region_id
|
69
|
+
attr_reader :aliyun_oss_bucket
|
70
|
+
|
71
|
+
def initialize(options = {})
|
72
|
+
# initialize the parameters
|
73
|
+
@aliyun_region_id = options[:aliyun_region_id] || options[:aliyun_oss_location] || DEFAULT_REGION
|
74
|
+
@aliyun_oss_endpoint = options[:aliyun_oss_endpoint] || region_to_endpoint(@aliyun_region_id)
|
75
|
+
@aliyun_accesskey_id = options[:aliyun_accesskey_id]
|
76
|
+
@aliyun_accesskey_secret = options[:aliyun_accesskey_secret]
|
77
|
+
@aliyun_oss_bucket = options[:aliyun_oss_bucket]
|
78
|
+
|
79
|
+
# check for the parameters
|
80
|
+
missing_credentials = []
|
81
|
+
missing_credentials << :aliyun_oss_bucket unless @aliyun_oss_bucket
|
82
|
+
missing_credentials << :aliyun_accesskey_id unless @aliyun_accesskey_id
|
83
|
+
missing_credentials << :aliyun_accesskey_secret unless @aliyun_accesskey_secret
|
84
|
+
raise ArgumentError, "Missing required arguments: #{missing_credentials.join(', ')}" unless missing_credentials.empty?
|
85
|
+
|
86
|
+
@connection_options = options[:connection_options] || {}
|
87
|
+
|
88
|
+
endpoint = @aliyun_oss_endpoint
|
89
|
+
|
90
|
+
if !endpoint.start_with?(DEFAULT_SCHEME)
|
91
|
+
@aliyun_oss_endpoint = "#{DEFAULT_SCHEME}://#{endpoint}"
|
92
|
+
end
|
93
|
+
|
94
|
+
uri = URI.parse(@aliyun_oss_endpoint)
|
95
|
+
@host = uri.host
|
96
|
+
@path = uri.path
|
97
|
+
@scheme = uri.scheme || DEFAULT_SCHEME
|
98
|
+
@port = uri.port || DEFAULT_SCHEME_PORT[@scheme]
|
99
|
+
|
100
|
+
@persistent = options[:persistent] || false
|
101
|
+
end
|
102
|
+
|
103
|
+
def reload
|
104
|
+
@connection.reset
|
105
|
+
end
|
106
|
+
|
107
|
+
def region_to_endpoint(region=nil)
|
108
|
+
case region.to_s
|
109
|
+
when ''
|
110
|
+
"oss-#{DEFAULT_REGION}.aliyuncs.com"
|
111
|
+
else
|
112
|
+
"oss-#{region}.aliyuncs.com"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def request(params)
|
117
|
+
method = params[:method]
|
118
|
+
time = Time.new.utc
|
119
|
+
date = time.strftime('%a, %d %b %Y %H:%M:%S GMT')
|
120
|
+
|
121
|
+
endpoint = params[:endpoint]
|
122
|
+
if endpoint
|
123
|
+
uri = URI.parse(endpoint)
|
124
|
+
host = uri.host
|
125
|
+
path = uri.path
|
126
|
+
port = uri.port
|
127
|
+
scheme = uri.scheme
|
128
|
+
else
|
129
|
+
host = @host
|
130
|
+
path = @path
|
131
|
+
port = @port
|
132
|
+
scheme = @scheme
|
133
|
+
end
|
134
|
+
|
135
|
+
bucket = params[:bucket]
|
136
|
+
tmpHost = if bucket
|
137
|
+
bucket + '.' + host
|
138
|
+
else
|
139
|
+
host
|
140
|
+
end
|
141
|
+
|
142
|
+
@connection = Fog::Core::Connection.new("#{scheme}://#{tmpHost}", @persistent, @connection_options)
|
143
|
+
contentType = params[:contentType]
|
144
|
+
|
145
|
+
begin
|
146
|
+
headers = ''
|
147
|
+
if params[:headers]
|
148
|
+
params[:headers].each do |k, v|
|
149
|
+
headers += "#{k}:#{v}\n" if k != 'Range'
|
150
|
+
end
|
151
|
+
end
|
152
|
+
signature = sign(method, date, contentType, params[:resource], headers)
|
153
|
+
response = @connection.request(params.merge(headers: {
|
154
|
+
'Content-Type' => contentType,
|
155
|
+
'Authorization' => 'OSS ' + @aliyun_accesskey_id + ':' + signature,
|
156
|
+
'Date' => date
|
157
|
+
}.merge!(params[:headers] || {}),
|
158
|
+
path: "#{path}/#{params[:path]}",
|
159
|
+
query: params[:query]))
|
160
|
+
rescue Excon::Errors::HTTPStatusError => error
|
161
|
+
raise case error
|
162
|
+
when Excon::Errors::NotFound
|
163
|
+
Fog::Storage::Aliyun::NotFound.slurp(error)
|
164
|
+
else
|
165
|
+
error
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
response
|
170
|
+
end
|
171
|
+
|
172
|
+
# copmute signature
|
173
|
+
def sign(method, date, contentType, resource = nil, headers = nil)
|
174
|
+
contentmd5 = ''
|
175
|
+
|
176
|
+
canonicalizedResource = if resource
|
177
|
+
'/' + resource
|
178
|
+
else
|
179
|
+
'/'
|
180
|
+
end
|
181
|
+
|
182
|
+
canonicalizedOSSHeaders = if headers
|
183
|
+
headers
|
184
|
+
else
|
185
|
+
''
|
186
|
+
end
|
187
|
+
|
188
|
+
contentTypeStr = if contentType
|
189
|
+
contentType
|
190
|
+
else
|
191
|
+
''
|
192
|
+
end
|
193
|
+
|
194
|
+
stringToSign = method + "\n" + contentmd5 + "\n" + contentTypeStr + "\n" + date + "\n" + canonicalizedOSSHeaders + canonicalizedResource
|
195
|
+
|
196
|
+
digVer = OpenSSL::Digest.new('sha1')
|
197
|
+
digest = OpenSSL::HMAC.digest(digVer, @aliyun_accesskey_secret, stringToSign)
|
198
|
+
signature = Base64.encode64(digest)
|
199
|
+
signature[-1] = ''
|
200
|
+
|
201
|
+
signature
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
class Mock
|
206
|
+
def initialize(options = {})
|
207
|
+
@aliyun_oss_endpoint = options[:aliyun_oss_endpoint]
|
208
|
+
@aliyun_region_id = options[:aliyun_region_id]
|
209
|
+
@aliyun_accesskey_id = options[:aliyun_accesskey_id]
|
210
|
+
@aliyun_accesskey_secret = options[:aliyun_accesskey_secret]
|
211
|
+
@aliyun_oss_bucket = options[:aliyun_oss_bucket]
|
212
|
+
|
213
|
+
# missing_credentials = Array.new
|
214
|
+
# missing_credentials << :aliyun_oss_endpoint unless @aliyun_oss_endpoint
|
215
|
+
# missing_credentials << :aliyun_region_id unless @aliyun_region_id
|
216
|
+
# missing_credentials << :aliyun_accesskey_id unless @aliyun_accesskey_id
|
217
|
+
# missing_credentials << :aliyun_accesskey_secret unless @aliyun_accesskey_secret
|
218
|
+
# raise ArgumentError, "Missing required arguments: #{missing_credentials.join(', ')}" unless missing_credentials.empty?
|
219
|
+
|
220
|
+
@connection_options = options[:connection_options] || {}
|
221
|
+
|
222
|
+
# uri = URI.parse(@aliyun_oss_endpoint)
|
223
|
+
# @host = uri.host
|
224
|
+
# @path = uri.path
|
225
|
+
# @port = uri.port
|
226
|
+
# @scheme = uri.scheme
|
227
|
+
|
228
|
+
# @persistent = options[:persistent] || false
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
data/lib/fog/aliyun.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'fog/core'
|
2
|
+
require 'fog/json'
|
3
|
+
require 'fog/aliyun/version'
|
4
|
+
|
5
|
+
module Fog
|
6
|
+
module Compute
|
7
|
+
ret = autoload :Aliyun, 'fog/aliyun/compute'
|
8
|
+
end
|
9
|
+
|
10
|
+
module Storage
|
11
|
+
ret = autoload :Aliyun, 'fog/aliyun/storage'
|
12
|
+
end
|
13
|
+
|
14
|
+
module Aliyun
|
15
|
+
extend Fog::Provider
|
16
|
+
service(:compute, 'Compute')
|
17
|
+
service(:storage, 'Storage')
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class Aliyun < Fog::Bin
|
2
|
+
class << self
|
3
|
+
def class_for(key)
|
4
|
+
case key
|
5
|
+
when :storage
|
6
|
+
Fog::Storage::Aliyun
|
7
|
+
when :compute
|
8
|
+
Fog::Compute::Aliyun
|
9
|
+
else
|
10
|
+
raise ArgumentError, "Unrecognized service: #{key}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def [](service)
|
15
|
+
@@connections ||= Hash.new do |hash, key|
|
16
|
+
hash[key] = case key
|
17
|
+
when :storage
|
18
|
+
Fog::Logger.warning('Aliyun[:storage] is not recommended, use Storage[:openstack] for portability')
|
19
|
+
Fog::Storage.new(provider: 'aliyun')
|
20
|
+
else
|
21
|
+
raise ArgumentError, "Unrecognized service: #{key.inspect}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
@@connections[service]
|
25
|
+
end
|
26
|
+
|
27
|
+
def services
|
28
|
+
Fog::Aliyun.services
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|