fog 1.7.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +2 -2
- data/README.md +9 -10
- data/Rakefile +15 -299
- data/changelog.txt +153 -0
- data/docs/about/contributing.markdown +1 -0
- data/docs/dns/index.markdown +1 -1
- data/docs/index.markdown +8 -3
- data/fog.gemspec +3 -3
- data/lib/fog.rb +0 -5
- data/lib/fog/aws/auto_scaling.rb +1 -1
- data/lib/fog/aws/cloud_watch.rb +1 -1
- data/lib/fog/aws/compute.rb +2 -1
- data/lib/fog/aws/dynamodb.rb +30 -64
- data/lib/fog/aws/elb.rb +1 -1
- data/lib/fog/aws/glacier.rb +1 -1
- data/lib/fog/aws/iam.rb +1 -0
- data/lib/fog/aws/models/auto_scaling/group.rb +1 -1
- data/lib/fog/aws/models/compute/server.rb +2 -0
- data/lib/fog/aws/models/compute/volume.rb +0 -1
- data/lib/fog/aws/models/iam/user.rb +1 -1
- data/lib/fog/aws/parsers/compute/describe_instances.rb +3 -1
- data/lib/fog/aws/parsers/compute/describe_reserved_instances_offerings.rb +1 -1
- data/lib/fog/aws/parsers/storage/delete_multiple_objects.rb +50 -0
- data/lib/fog/aws/rds.rb +2 -2
- data/lib/fog/aws/requests/compute/describe_availability_zones.rb +3 -0
- data/lib/fog/aws/requests/compute/describe_reserved_instances_offerings.rb +11 -8
- data/lib/fog/aws/requests/compute/modify_volume_attribute.rb +51 -0
- data/lib/fog/aws/requests/dns/change_resource_record_sets.rb +1 -0
- data/lib/fog/aws/requests/storage/delete_multiple_objects.rb +172 -0
- data/lib/fog/aws/signaturev4.rb +1 -1
- data/lib/fog/aws/sqs.rb +1 -1
- data/lib/fog/aws/storage.rb +2 -0
- data/lib/fog/bluebox/requests/compute/create_block.rb +1 -3
- data/lib/fog/brightbox/compute.rb +239 -84
- data/lib/fog/brightbox/models/compute/account.rb +9 -3
- data/lib/fog/brightbox/models/compute/server.rb +2 -1
- data/lib/fog/brightbox/models/compute/servers.rb +33 -1
- data/lib/fog/brightbox/oauth2.rb +164 -0
- data/lib/fog/brightbox/requests/compute/activate_console_server.rb +9 -2
- data/lib/fog/brightbox/requests/compute/add_listeners_load_balancer.rb +11 -2
- data/lib/fog/brightbox/requests/compute/add_nodes_load_balancer.rb +11 -2
- data/lib/fog/brightbox/requests/compute/add_servers_server_group.rb +9 -11
- data/lib/fog/brightbox/requests/compute/apply_to_firewall_policy.rb +11 -2
- data/lib/fog/brightbox/requests/compute/create_api_client.rb +11 -2
- data/lib/fog/brightbox/requests/compute/create_application.rb +11 -2
- data/lib/fog/brightbox/requests/compute/create_cloud_ip.rb +11 -1
- data/lib/fog/brightbox/requests/compute/create_firewall_policy.rb +13 -2
- data/lib/fog/brightbox/requests/compute/create_firewall_rule.rb +17 -2
- data/lib/fog/brightbox/requests/compute/create_image.rb +18 -2
- data/lib/fog/brightbox/requests/compute/create_load_balancer.rb +14 -2
- data/lib/fog/brightbox/requests/compute/create_server.rb +17 -2
- data/lib/fog/brightbox/requests/compute/create_server_group.rb +11 -2
- data/lib/fog/brightbox/requests/compute/destroy_api_client.rb +9 -2
- data/lib/fog/brightbox/requests/compute/destroy_application.rb +9 -2
- data/lib/fog/brightbox/requests/compute/destroy_cloud_ip.rb +9 -2
- data/lib/fog/brightbox/requests/compute/destroy_firewall_policy.rb +9 -2
- data/lib/fog/brightbox/requests/compute/destroy_firewall_rule.rb +9 -2
- data/lib/fog/brightbox/requests/compute/destroy_image.rb +9 -2
- data/lib/fog/brightbox/requests/compute/destroy_load_balancer.rb +9 -2
- data/lib/fog/brightbox/requests/compute/destroy_server.rb +9 -2
- data/lib/fog/brightbox/requests/compute/destroy_server_group.rb +9 -2
- data/lib/fog/brightbox/requests/compute/get_account.rb +7 -15
- data/lib/fog/brightbox/requests/compute/get_api_client.rb +9 -2
- data/lib/fog/brightbox/requests/compute/get_application.rb +9 -2
- data/lib/fog/brightbox/requests/compute/get_authenticated_user.rb +1 -3
- data/lib/fog/brightbox/requests/compute/get_cloud_ip.rb +9 -2
- data/lib/fog/brightbox/requests/compute/get_firewall_policy.rb +9 -2
- data/lib/fog/brightbox/requests/compute/get_firewall_rule.rb +9 -2
- data/lib/fog/brightbox/requests/compute/get_image.rb +9 -2
- data/lib/fog/brightbox/requests/compute/get_interface.rb +9 -2
- data/lib/fog/brightbox/requests/compute/get_load_balancer.rb +9 -2
- data/lib/fog/brightbox/requests/compute/get_scoped_account.rb +1 -5
- data/lib/fog/brightbox/requests/compute/get_server.rb +9 -2
- data/lib/fog/brightbox/requests/compute/get_server_group.rb +9 -2
- data/lib/fog/brightbox/requests/compute/get_server_type.rb +9 -2
- data/lib/fog/brightbox/requests/compute/get_user.rb +7 -15
- data/lib/fog/brightbox/requests/compute/get_zone.rb +9 -2
- data/lib/fog/brightbox/requests/compute/list_accounts.rb +6 -2
- data/lib/fog/brightbox/requests/compute/list_api_clients.rb +8 -2
- data/lib/fog/brightbox/requests/compute/list_applications.rb +8 -2
- data/lib/fog/brightbox/requests/compute/list_cloud_ips.rb +8 -2
- data/lib/fog/brightbox/requests/compute/list_firewall_policies.rb +8 -2
- data/lib/fog/brightbox/requests/compute/list_images.rb +8 -2
- data/lib/fog/brightbox/requests/compute/list_load_balancers.rb +8 -2
- data/lib/fog/brightbox/requests/compute/list_server_groups.rb +8 -2
- data/lib/fog/brightbox/requests/compute/list_server_types.rb +8 -2
- data/lib/fog/brightbox/requests/compute/list_servers.rb +8 -2
- data/lib/fog/brightbox/requests/compute/list_users.rb +8 -2
- data/lib/fog/brightbox/requests/compute/list_zones.rb +8 -2
- data/lib/fog/brightbox/requests/compute/map_cloud_ip.rb +11 -2
- data/lib/fog/brightbox/requests/compute/move_servers_server_group.rb +10 -12
- data/lib/fog/brightbox/requests/compute/remove_firewall_policy.rb +11 -2
- data/lib/fog/brightbox/requests/compute/remove_listeners_load_balancer.rb +11 -2
- data/lib/fog/brightbox/requests/compute/remove_nodes_load_balancer.rb +11 -2
- data/lib/fog/brightbox/requests/compute/remove_servers_server_group.rb +9 -10
- data/lib/fog/brightbox/requests/compute/reset_ftp_password_account.rb +22 -3
- data/lib/fog/brightbox/requests/compute/reset_ftp_password_scoped_account.rb +18 -0
- data/lib/fog/brightbox/requests/compute/reset_secret_api_client.rb +13 -1
- data/lib/fog/brightbox/requests/compute/reset_secret_application.rb +9 -2
- data/lib/fog/brightbox/requests/compute/shutdown_server.rb +9 -2
- data/lib/fog/brightbox/requests/compute/snapshot_server.rb +9 -2
- data/lib/fog/brightbox/requests/compute/start_server.rb +9 -2
- data/lib/fog/brightbox/requests/compute/stop_server.rb +9 -2
- data/lib/fog/brightbox/requests/compute/unmap_cloud_ip.rb +9 -2
- data/lib/fog/brightbox/requests/compute/update_account.rb +32 -34
- data/lib/fog/brightbox/requests/compute/update_api_client.rb +12 -2
- data/lib/fog/brightbox/requests/compute/update_application.rb +12 -2
- data/lib/fog/brightbox/requests/compute/update_cloud_ip.rb +13 -2
- data/lib/fog/brightbox/requests/compute/update_firewall_rule.rb +16 -1
- data/lib/fog/brightbox/requests/compute/update_image.rb +17 -2
- data/lib/fog/brightbox/requests/compute/update_load_balancer.rb +15 -2
- data/lib/fog/brightbox/requests/compute/update_scoped_account.rb +12 -19
- data/lib/fog/brightbox/requests/compute/update_server.rb +12 -2
- data/lib/fog/brightbox/requests/compute/update_server_group.rb +12 -2
- data/lib/fog/brightbox/requests/compute/update_user.rb +15 -2
- data/lib/fog/cloudstack/models/compute/server.rb +3 -1
- data/lib/fog/core.rb +1 -0
- data/lib/fog/core/connection.rb +1 -0
- data/lib/fog/google/storage.rb +13 -2
- data/lib/fog/libvirt/models/compute/server.rb +1 -0
- data/lib/fog/libvirt/requests/compute/list_domains.rb +2 -2
- data/lib/fog/openstack.rb +57 -58
- data/lib/fog/openstack/compute.rb +15 -14
- data/lib/fog/openstack/identity.rb +10 -2
- data/lib/fog/openstack/image.rb +1 -1
- data/lib/fog/openstack/models/compute/flavor.rb +5 -1
- data/lib/fog/openstack/models/compute/security_group.rb +1 -1
- data/lib/fog/openstack/models/compute/server.rb +5 -0
- data/lib/fog/openstack/models/identity/users.rb +1 -2
- data/lib/fog/openstack/requests/compute/create_flavor.rb +4 -1
- data/lib/fog/openstack/requests/compute/create_security_group.rb +1 -1
- data/lib/fog/openstack/requests/compute/get_limits.rb +93 -0
- data/lib/fog/openstack/requests/compute/list_tenants.rb +1 -0
- data/lib/fog/openstack/requests/compute/release_address.rb +13 -1
- data/lib/fog/openstack/requests/compute/reset_server_state.rb +24 -0
- data/lib/fog/openstack/requests/identity/create_role.rb +1 -1
- data/lib/fog/openstack/requests/identity/set_tenant.rb +21 -0
- data/lib/fog/openstack/volume.rb +2 -1
- data/lib/fog/rackspace/models/compute_v2/server.rb +27 -0
- data/lib/fog/rackspace/models/compute_v2/servers.rb +8 -0
- data/lib/fog/rackspace/models/dns/record.rb +14 -1
- data/lib/fog/rackspace/models/storage/file.rb +68 -2
- data/lib/fog/rackspace/requests/compute_v2/create_server.rb +3 -0
- data/lib/fog/version.rb +5 -0
- data/lib/fog/vsphere/compute.rb +74 -8
- data/lib/fog/vsphere/models/compute/cluster.rb +31 -0
- data/lib/fog/vsphere/models/compute/clusters.rb +26 -0
- data/lib/fog/vsphere/models/compute/datacenter.rb +35 -0
- data/lib/fog/vsphere/models/compute/datacenters.rb +23 -0
- data/lib/fog/vsphere/models/compute/datastore.rb +24 -0
- data/lib/fog/vsphere/models/compute/datastores.rb +25 -0
- data/lib/fog/vsphere/models/compute/folder.rb +28 -0
- data/lib/fog/vsphere/models/compute/folders.rb +27 -0
- data/lib/fog/vsphere/models/compute/interface.rb +39 -0
- data/lib/fog/vsphere/models/compute/interfaces.rb +33 -0
- data/lib/fog/vsphere/models/compute/network.rb +21 -0
- data/lib/fog/vsphere/models/compute/networks.rb +25 -0
- data/lib/fog/vsphere/models/compute/resource_pool.rb +23 -0
- data/lib/fog/vsphere/models/compute/resource_pools.rb +26 -0
- data/lib/fog/vsphere/models/compute/server.rb +78 -12
- data/lib/fog/vsphere/models/compute/servers.rb +16 -20
- data/lib/fog/vsphere/models/compute/template.rb +13 -0
- data/lib/fog/vsphere/models/compute/templates.rb +23 -0
- data/lib/fog/vsphere/models/compute/volume.rb +45 -0
- data/lib/fog/vsphere/models/compute/volumes.rb +33 -0
- data/lib/fog/vsphere/requests/compute/create_vm.rb +114 -0
- data/lib/fog/vsphere/requests/compute/get_cluster.rb +25 -0
- data/lib/fog/vsphere/requests/compute/get_datacenter.rb +29 -0
- data/lib/fog/vsphere/requests/compute/get_datastore.rb +25 -0
- data/lib/fog/vsphere/requests/compute/get_folder.rb +73 -0
- data/lib/fog/vsphere/requests/compute/get_network.rb +25 -0
- data/lib/fog/vsphere/requests/compute/get_resource_pool.rb +26 -0
- data/lib/fog/vsphere/requests/compute/get_virtual_machine.rb +62 -0
- data/lib/fog/vsphere/requests/compute/list_clusters.rb +37 -0
- data/lib/fog/vsphere/requests/compute/list_datacenters.rb +34 -0
- data/lib/fog/vsphere/requests/compute/list_datastores.rb +40 -0
- data/lib/fog/vsphere/requests/compute/list_folders.rb +45 -0
- data/lib/fog/vsphere/requests/compute/list_networks.rb +38 -0
- data/lib/fog/vsphere/requests/compute/list_resource_pools.rb +39 -0
- data/lib/fog/vsphere/requests/compute/list_virtual_machines.rb +132 -166
- data/lib/fog/vsphere/requests/compute/list_vm_interfaces.rb +52 -0
- data/lib/fog/vsphere/requests/compute/list_vm_volumes.rb +51 -0
- data/lib/fog/vsphere/requests/compute/vm_clone.rb +6 -8
- data/lib/fog/vsphere/requests/compute/vm_destroy.rb +1 -8
- data/lib/fog/vsphere/requests/compute/vm_reconfig_hardware.rb +1 -2
- data/lib/tasks/changelog_task.rb +98 -0
- data/lib/tasks/documentation_task.rb +155 -0
- data/lib/tasks/test_task.rb +46 -0
- data/tests/aws/models/iam/users_tests.rb +16 -2
- data/tests/aws/requests/auto_scaling/notification_configuration_tests.rb +1 -0
- data/tests/aws/requests/auto_scaling/tag_tests.rb +1 -0
- data/tests/aws/requests/compute/instance_tests.rb +2 -0
- data/tests/aws/requests/compute/volume_tests.rb +8 -0
- data/tests/aws/requests/storage/object_tests.rb +18 -1
- data/tests/aws/requests/storage/versioning_tests.rb +70 -0
- data/tests/brightbox/compute_tests.rb +96 -4
- data/tests/brightbox/models/compute/account_tests.rb +15 -0
- data/tests/brightbox/oauth2_tests.rb +103 -0
- data/tests/brightbox/requests/compute/account_tests.rb +9 -2
- data/tests/brightbox/requests/compute/interface_tests.rb +18 -4
- data/tests/dns/models/record_tests.rb +17 -3
- data/tests/openstack/requests/compute/address_tests.rb +22 -19
- data/tests/openstack/requests/compute/flavor_tests.rb +4 -2
- data/tests/openstack/requests/compute/limit_tests.rb +60 -0
- data/tests/openstack/requests/compute/quota_tests.rb +16 -3
- data/tests/openstack/requests/compute/security_group_tests.rb +1 -1
- data/tests/rackspace/models/compute_v2/servers_tests.rb +6 -0
- data/tests/rackspace/models/storage/file_tests.rb +172 -0
- data/tests/rackspace/requests/dns/helper.rb +12 -26
- data/tests/vsphere/compute_tests.rb +3 -3
- data/tests/vsphere/models/compute/server_tests.rb +1 -2
- data/tests/vsphere/requests/compute/list_virtual_machines_tests.rb +5 -13
- data/tests/vsphere/requests/compute/vm_clone_tests.rb +2 -2
- metadata +59 -11
- data/lib/fog/vsphere/requests/compute/datacenters.rb +0 -34
- data/lib/fog/vsphere/requests/compute/find_vm_by_ref.rb +0 -41
- data/lib/fog/vsphere/requests/compute/vm_create.rb +0 -97
- data/tests/vsphere/requests/compute/find_vm_by_ref_tests.rb +0 -26
- data/tests/vsphere/requests/compute/vm_create_tests.rb +0 -20
|
@@ -198,6 +198,7 @@ module Fog
|
|
|
198
198
|
@elb_hosted_zone_mapping ||= {
|
|
199
199
|
"ap-northeast-1" => "Z2YN17T5R711GT",
|
|
200
200
|
"ap-southeast-1" => "Z1WI8VXHPB1R38",
|
|
201
|
+
"ap-southeast-2" => "Z2999QAZ9SRTIC",
|
|
201
202
|
"eu-west-1" => "Z3NF1Z3NOM5OY2",
|
|
202
203
|
"sa-east-1" => "Z2ES78Y61JGQKS",
|
|
203
204
|
"us-east-1" => "Z3DZXE0Q79N41H",
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
module Fog
|
|
2
|
+
module Storage
|
|
3
|
+
class AWS
|
|
4
|
+
class Real
|
|
5
|
+
|
|
6
|
+
require 'fog/aws/parsers/storage/delete_multiple_objects'
|
|
7
|
+
|
|
8
|
+
# Delete multiple objects from S3
|
|
9
|
+
#
|
|
10
|
+
# ==== Parameters
|
|
11
|
+
# * bucket_name<~String> - Name of bucket containing object to delete
|
|
12
|
+
# * object_names<~Array> - Array of object names to delete
|
|
13
|
+
#
|
|
14
|
+
# ==== Returns
|
|
15
|
+
# * response<~Excon::Response>:
|
|
16
|
+
# * body<~Hash>:
|
|
17
|
+
# * 'DeleteResult'<~Array>:
|
|
18
|
+
# * 'Deleted'<~Hash>:
|
|
19
|
+
# * 'Key'<~String> - Name of the object that was deleted
|
|
20
|
+
# * 'VersionId'<~String> - ID for the versioned onject in case of a versioned delete
|
|
21
|
+
# * 'DeleteMarker'<~Boolean> - Indicates if the request accessed a delete marker
|
|
22
|
+
# * 'DeleteMarkerVersionId'<~String> - Version ID of the delete marker accessed
|
|
23
|
+
# * 'Error'<~Hash>:
|
|
24
|
+
# * 'Key'<~String> - Name of the object that failed to be deleted
|
|
25
|
+
# * 'VersionId'<~String> - ID of the versioned object that was attempted to be deleted
|
|
26
|
+
# * 'Code'<~String> - Status code for the result of the failed delete
|
|
27
|
+
# * 'Message'<~String> - Error description
|
|
28
|
+
#
|
|
29
|
+
# ==== See Also
|
|
30
|
+
# http://docs.amazonwebservices.com/AmazonS3/latest/API/multiobjectdeleteapi.html
|
|
31
|
+
|
|
32
|
+
# bucket_name -- name of the bucket to use
|
|
33
|
+
# object_names -- filename
|
|
34
|
+
# For versioned deletes, options should include a version_ids hash, which
|
|
35
|
+
# maps from filename to an array of versions.
|
|
36
|
+
# The semantics are that for each (object_name, version) tuple, the
|
|
37
|
+
# caller must insert the object_name and an associated version (if
|
|
38
|
+
# desired), so for n versions, the object must be inserted n times.
|
|
39
|
+
def delete_multiple_objects(bucket_name, object_names, options = {})
|
|
40
|
+
data = "<Delete>"
|
|
41
|
+
data << "<Quiet>true</Quiet>" if options.delete(:quiet)
|
|
42
|
+
version_ids = options.delete('versionId')
|
|
43
|
+
object_names.each do |object_name|
|
|
44
|
+
data << "<Object>"
|
|
45
|
+
data << "<Key>#{CGI.escape(object_name)}</Key>"
|
|
46
|
+
object_version = version_ids.nil? ? nil : version_ids[object_name]
|
|
47
|
+
if object_version
|
|
48
|
+
data << "<VersionId>#{CGI.escape(object_version)}</VersionId>"
|
|
49
|
+
end
|
|
50
|
+
data << "</Object>"
|
|
51
|
+
end
|
|
52
|
+
data << "</Delete>"
|
|
53
|
+
|
|
54
|
+
headers = options
|
|
55
|
+
headers['Content-Length'] = data.length
|
|
56
|
+
headers['Content-MD5'] = Base64.encode64(Digest::MD5.digest(data)).
|
|
57
|
+
gsub("\n", '')
|
|
58
|
+
|
|
59
|
+
request({
|
|
60
|
+
:body => data,
|
|
61
|
+
:expects => 200,
|
|
62
|
+
:headers => headers,
|
|
63
|
+
:host => "#{bucket_name}.#{@host}",
|
|
64
|
+
:method => 'POST',
|
|
65
|
+
:parser => Fog::Parsers::Storage::AWS::DeleteMultipleObjects.new,
|
|
66
|
+
:query => {'delete' => nil}
|
|
67
|
+
})
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
class Mock # :nodoc:all
|
|
73
|
+
|
|
74
|
+
def delete_multiple_objects(bucket_name, object_names, options = {})
|
|
75
|
+
response = Excon::Response.new
|
|
76
|
+
if bucket = self.data[:buckets][bucket_name]
|
|
77
|
+
response.status = 200
|
|
78
|
+
response.body = { 'DeleteResult' => [] }
|
|
79
|
+
version_ids = options.delete('versionId')
|
|
80
|
+
object_names.each do |object_name|
|
|
81
|
+
object_version = version_ids.nil? ? nil : version_ids[object_name]
|
|
82
|
+
response.body['DeleteResult'] << delete_object_helper(bucket,
|
|
83
|
+
object_name,
|
|
84
|
+
object_version)
|
|
85
|
+
end
|
|
86
|
+
else
|
|
87
|
+
response.status = 404
|
|
88
|
+
raise(Excon::Errors.status_error({:expects => 200}, response))
|
|
89
|
+
end
|
|
90
|
+
response
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
private
|
|
94
|
+
|
|
95
|
+
def delete_object_helper(bucket, object_name, version_id)
|
|
96
|
+
response = { 'Deleted' => {} }
|
|
97
|
+
if bucket[:versioning]
|
|
98
|
+
bucket[:objects][object_name] ||= []
|
|
99
|
+
|
|
100
|
+
if version_id
|
|
101
|
+
version = bucket[:objects][object_name].find { |object| object['VersionId'] == version_id}
|
|
102
|
+
|
|
103
|
+
# S3 special cases the 'null' value to not error out if no such version exists.
|
|
104
|
+
if version || (version_id == 'null')
|
|
105
|
+
bucket[:objects][object_name].delete(version)
|
|
106
|
+
bucket[:objects].delete(object_name) if bucket[:objects][object_name].empty?
|
|
107
|
+
|
|
108
|
+
response['Deleted'] = { 'Key' => object_name,
|
|
109
|
+
'VersionId' => version_id,
|
|
110
|
+
'DeleteMarker' => 'true',
|
|
111
|
+
'DeleteMarkerVersionId' => version_id
|
|
112
|
+
}
|
|
113
|
+
else
|
|
114
|
+
response = delete_error_body(object_name,
|
|
115
|
+
version_id,
|
|
116
|
+
'InvalidVersion',
|
|
117
|
+
'Invalid version ID specified')
|
|
118
|
+
end
|
|
119
|
+
else
|
|
120
|
+
delete_marker = {
|
|
121
|
+
:delete_marker => true,
|
|
122
|
+
'Key' => object_name,
|
|
123
|
+
'VersionId' => bucket[:versioning] == 'Enabled' ? Fog::Mock.random_base64(32) : 'null',
|
|
124
|
+
'Last-Modified' => Fog::Time.now.to_date_header
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
# When versioning is suspended, a delete marker is placed if the last object ID is not the value 'null',
|
|
128
|
+
# otherwise the last object is replaced.
|
|
129
|
+
if bucket[:versioning] == 'Suspended' && bucket[:objects][object_name].first['VersionId'] == 'null'
|
|
130
|
+
bucket[:objects][object_name].shift
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
bucket[:objects][object_name].unshift(delete_marker)
|
|
134
|
+
|
|
135
|
+
response['Deleted'] = { 'Key' => object_name,
|
|
136
|
+
'VersionId' => delete_marker['VersionId'],
|
|
137
|
+
'DeleteMarkerVersionId' =>
|
|
138
|
+
delete_marker['VersionId'],
|
|
139
|
+
'DeleteMarker' => 'true',
|
|
140
|
+
}
|
|
141
|
+
end
|
|
142
|
+
else
|
|
143
|
+
if version_id && version_id != 'null'
|
|
144
|
+
response = delete_error_body(object_name,
|
|
145
|
+
version_id,
|
|
146
|
+
'InvalidVersion',
|
|
147
|
+
'Invalid version ID specified')
|
|
148
|
+
response = invalid_version_id_payload(version_id)
|
|
149
|
+
else
|
|
150
|
+
bucket[:objects].delete(object_name)
|
|
151
|
+
response['Deleted'] = { 'Key' => object_name }
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
response
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def delete_error_body(key, version_id, message, code)
|
|
158
|
+
{
|
|
159
|
+
'Error' => {
|
|
160
|
+
'Code' => code,
|
|
161
|
+
'Message' => message,
|
|
162
|
+
'VersionId' => version_id,
|
|
163
|
+
'Key' => key,
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
data/lib/fog/aws/signaturev4.rb
CHANGED
data/lib/fog/aws/sqs.rb
CHANGED
|
@@ -40,7 +40,7 @@ module Fog
|
|
|
40
40
|
setup_credentials(options)
|
|
41
41
|
@region = options[:region] || 'us-east-1'
|
|
42
42
|
|
|
43
|
-
unless ['ap-northeast-1', 'ap-southeast-1', 'eu-west-1', 'us-east-1', 'us-west-1', 'us-west-2', 'sa-east-1'].include?(@region)
|
|
43
|
+
unless ['ap-northeast-1', 'ap-southeast-1', 'ap-southeast-2', 'eu-west-1', 'us-east-1', 'us-west-1', 'us-west-2', 'sa-east-1'].include?(@region)
|
|
44
44
|
raise ArgumentError, "Unknown region: #{@region.inspect}"
|
|
45
45
|
end
|
|
46
46
|
end
|
data/lib/fog/aws/storage.rb
CHANGED
|
@@ -26,6 +26,7 @@ module Fog
|
|
|
26
26
|
request :delete_bucket_policy
|
|
27
27
|
request :delete_bucket_website
|
|
28
28
|
request :delete_object
|
|
29
|
+
request :delete_multiple_objects
|
|
29
30
|
request :get_bucket
|
|
30
31
|
request :get_bucket_acl
|
|
31
32
|
request :get_bucket_lifecycle
|
|
@@ -337,6 +338,7 @@ DATA
|
|
|
337
338
|
for key in (params[:query] || {}).keys.sort
|
|
338
339
|
if %w{
|
|
339
340
|
acl
|
|
341
|
+
delete
|
|
340
342
|
lifecycle
|
|
341
343
|
location
|
|
342
344
|
logging
|
|
@@ -30,14 +30,12 @@ module Fog
|
|
|
30
30
|
'location' => location_id
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
body = URI.encode options.map {|k,v| "#{k}=#{v}"}.join('&')
|
|
34
|
-
|
|
35
33
|
request(
|
|
36
34
|
:expects => 200,
|
|
37
35
|
:method => 'POST',
|
|
38
36
|
:path => '/api/blocks.json',
|
|
39
37
|
:query => query,
|
|
40
|
-
:body =>
|
|
38
|
+
:body => options.map {|k,v| "#{CGI.escape(k)}=#{CGI.escape(v)}"}.join('&')
|
|
41
39
|
)
|
|
42
40
|
end
|
|
43
41
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require 'fog/brightbox'
|
|
2
2
|
require 'fog/compute'
|
|
3
|
+
require 'fog/brightbox/oauth2'
|
|
3
4
|
|
|
4
5
|
module Fog
|
|
5
6
|
module Compute
|
|
@@ -16,6 +17,12 @@ module Fog
|
|
|
16
17
|
# User credentials (still requires client details)
|
|
17
18
|
recognizes :brightbox_username, :brightbox_password, :brightbox_account
|
|
18
19
|
|
|
20
|
+
# Cached tokens
|
|
21
|
+
recognizes :brightbox_access_token, :brightbox_refresh_token
|
|
22
|
+
|
|
23
|
+
# Automatic token management
|
|
24
|
+
recognizes :brightbox_token_management
|
|
25
|
+
|
|
19
26
|
# Excon connection settings
|
|
20
27
|
recognizes :persistent
|
|
21
28
|
|
|
@@ -106,6 +113,7 @@ module Fog
|
|
|
106
113
|
request :remove_nodes_load_balancer
|
|
107
114
|
request :remove_servers_server_group
|
|
108
115
|
request :reset_ftp_password_account
|
|
116
|
+
request :reset_ftp_password_scoped_account
|
|
109
117
|
request :reset_secret_api_client
|
|
110
118
|
request :reset_secret_application
|
|
111
119
|
request :shutdown_server
|
|
@@ -126,6 +134,139 @@ module Fog
|
|
|
126
134
|
request :update_user
|
|
127
135
|
|
|
128
136
|
module Shared
|
|
137
|
+
include Fog::Brightbox::OAuth2
|
|
138
|
+
|
|
139
|
+
# Creates a new instance of the Brightbox Compute service
|
|
140
|
+
#
|
|
141
|
+
# @note If you open a connection using just a refresh token when it
|
|
142
|
+
# expires the service will no longer be able to authenticate.
|
|
143
|
+
#
|
|
144
|
+
# @param [Hash] options
|
|
145
|
+
# @option options [String] :brightbox_api_url Override the default (or configured) API endpoint
|
|
146
|
+
# @option options [String] :brightbox_auth_url Override the default (or configured) API authentication endpoint
|
|
147
|
+
# @option options [String] :brightbox_client_id Client identifier to authenticate with (overrides configured)
|
|
148
|
+
# @option options [String] :brightbox_secret Client secret to authenticate with (overrides configured)
|
|
149
|
+
# @option options [String] :brightbox_username Email or user identifier for user based authentication
|
|
150
|
+
# @option options [String] :brightbox_password Password for user based authentication
|
|
151
|
+
# @option options [String] :brightbox_account Account identifier to scope this connection to
|
|
152
|
+
# @option options [String] :connection_options Settings to pass to underlying {Fog::Connection}
|
|
153
|
+
# @option options [Boolean] :persistent Sets a persistent HTTP {Fog::Connection}
|
|
154
|
+
# @option options [String] :brightbox_access_token Sets the OAuth access token to use rather than requesting a new token
|
|
155
|
+
# @option options [String] :brightbox_refresh_token Sets the refresh token to use when requesting a newer access token
|
|
156
|
+
# @option options [String] :brightbox_token_management Overide the existing behaviour to request access tokens if expired (default is `true`)
|
|
157
|
+
#
|
|
158
|
+
def initialize(options)
|
|
159
|
+
# Currently authentication and api endpoints are the same but may change
|
|
160
|
+
@auth_url = options[:brightbox_auth_url] || Fog.credentials[:brightbox_auth_url] || API_URL
|
|
161
|
+
@auth_connection = Fog::Connection.new(@auth_url)
|
|
162
|
+
|
|
163
|
+
@api_url = options[:brightbox_api_url] || Fog.credentials[:brightbox_api_url] || API_URL
|
|
164
|
+
@connection_options = options[:connection_options] || {}
|
|
165
|
+
@persistent = options[:persistent] || false
|
|
166
|
+
@connection = Fog::Connection.new(@api_url, @persistent, @connection_options)
|
|
167
|
+
|
|
168
|
+
# Authentication options
|
|
169
|
+
client_id = options[:brightbox_client_id] || Fog.credentials[:brightbox_client_id]
|
|
170
|
+
client_secret = options[:brightbox_secret] || Fog.credentials[:brightbox_secret]
|
|
171
|
+
|
|
172
|
+
username = options[:brightbox_username] || Fog.credentials[:brightbox_username]
|
|
173
|
+
password = options[:brightbox_password] || Fog.credentials[:brightbox_password]
|
|
174
|
+
@configured_account = options[:brightbox_account] || Fog.credentials[:brightbox_account]
|
|
175
|
+
# Request account can be changed at anytime and changes behaviour of future requests
|
|
176
|
+
@scoped_account = @configured_account
|
|
177
|
+
|
|
178
|
+
credential_options = {:username => username, :password => password}
|
|
179
|
+
@credentials = CredentialSet.new(client_id, client_secret, credential_options)
|
|
180
|
+
|
|
181
|
+
# If existing tokens have been cached, allow continued use of them in the service
|
|
182
|
+
@credentials.update_tokens(options[:brightbox_access_token], options[:brightbox_refresh_token])
|
|
183
|
+
|
|
184
|
+
@token_management = options.fetch(:brightbox_token_management, true)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# Sets the scoped account for future requests
|
|
188
|
+
# @param [String] scoped_account Identifier of the account to scope request to
|
|
189
|
+
def scoped_account=(scoped_account)
|
|
190
|
+
@scoped_account = scoped_account
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# This returns the account identifier that the request should be scoped by
|
|
194
|
+
# based on the options passed to the request and current configuration
|
|
195
|
+
#
|
|
196
|
+
# @param [String] options_account Any identifier passed into the request
|
|
197
|
+
#
|
|
198
|
+
# @return [String, nil] The account identifier to scope the request to or nil
|
|
199
|
+
def scoped_account(options_account = nil)
|
|
200
|
+
[options_account, @scoped_account].compact.first
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# Resets the scoped account back to intially configured one
|
|
204
|
+
def scoped_account_reset
|
|
205
|
+
@scoped_account = @configured_account
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Returns the scoped account being used for requests
|
|
209
|
+
#
|
|
210
|
+
# * For API clients this is the owning account
|
|
211
|
+
# * For User applications this is the account specified by either +account_id+
|
|
212
|
+
# option on a connection or the +brightbox_account+ setting in your configuration
|
|
213
|
+
#
|
|
214
|
+
# @return [Fog::Compute::Brightbox::Account]
|
|
215
|
+
#
|
|
216
|
+
def account
|
|
217
|
+
Fog::Compute::Brightbox::Account.new(get_scoped_account).tap do |acc|
|
|
218
|
+
# Connection is more like the compute 'service'
|
|
219
|
+
acc.connection = self
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# Returns true if authentication is being performed as a user
|
|
224
|
+
# @return [Boolean]
|
|
225
|
+
def authenticating_as_user?
|
|
226
|
+
@credentials.user_details?
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# Returns true if an access token is set
|
|
230
|
+
# @return [Boolean]
|
|
231
|
+
def access_token_available?
|
|
232
|
+
!! @credentials.access_token
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
# Returns the current access token or nil
|
|
236
|
+
# @return [String,nil]
|
|
237
|
+
def access_token
|
|
238
|
+
@credentials.access_token
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# Returns the current refresh token or nil
|
|
242
|
+
# @return [String,nil]
|
|
243
|
+
def refresh_token
|
|
244
|
+
@credentials.refresh_token
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
# Requests a new access token
|
|
248
|
+
#
|
|
249
|
+
# @return [String] New access token
|
|
250
|
+
def get_access_token
|
|
251
|
+
begin
|
|
252
|
+
get_access_token!
|
|
253
|
+
rescue Excon::Errors::Unauthorized, Excon::Errors::BadRequest
|
|
254
|
+
@credentials.update_tokens(nil, nil)
|
|
255
|
+
end
|
|
256
|
+
@credentials.access_token
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
# Requests a new access token and raises if there is a problem
|
|
260
|
+
#
|
|
261
|
+
# @return [String] New access token
|
|
262
|
+
# @raise [Excon::Errors::BadRequest] The credentials are expired or incorrect
|
|
263
|
+
#
|
|
264
|
+
def get_access_token!
|
|
265
|
+
response = request_access_token(@auth_connection, @credentials)
|
|
266
|
+
update_credentials_from_response(@credentials, response)
|
|
267
|
+
@credentials.access_token
|
|
268
|
+
end
|
|
269
|
+
|
|
129
270
|
# Returns an identifier for the default image for use
|
|
130
271
|
#
|
|
131
272
|
# Currently tries to find the latest version Ubuntu LTS (i686) widening
|
|
@@ -139,119 +280,133 @@ module Fog
|
|
|
139
280
|
return @default_image_id unless @default_image_id.nil?
|
|
140
281
|
@default_image_id = Fog.credentials[:brightbox_default_image] || select_default_image
|
|
141
282
|
end
|
|
283
|
+
|
|
284
|
+
private
|
|
285
|
+
|
|
286
|
+
# This makes a request of the API based on the configured setting for
|
|
287
|
+
# token management.
|
|
288
|
+
#
|
|
289
|
+
# @param [Hash] options Excon compatible options
|
|
290
|
+
# @see https://github.com/geemus/excon/blob/master/lib/excon/connection.rb
|
|
291
|
+
#
|
|
292
|
+
# @return [Hash] Data of response body
|
|
293
|
+
#
|
|
294
|
+
def make_request(options)
|
|
295
|
+
if @token_management
|
|
296
|
+
managed_token_request(options)
|
|
297
|
+
else
|
|
298
|
+
authenticated_request(options)
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
# This request checks for access tokens and will ask for a new one if
|
|
303
|
+
# it receives Unauthorized from the API before repeating the request
|
|
304
|
+
#
|
|
305
|
+
# @param [Hash] options Excon compatible options
|
|
306
|
+
#
|
|
307
|
+
# @return [Excon::Response]
|
|
308
|
+
def managed_token_request(options)
|
|
309
|
+
begin
|
|
310
|
+
get_access_token unless access_token_available?
|
|
311
|
+
response = authenticated_request(options)
|
|
312
|
+
rescue Excon::Errors::Unauthorized
|
|
313
|
+
get_access_token
|
|
314
|
+
response = authenticated_request(options)
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
# This request makes an authenticated request of the API using currently
|
|
319
|
+
# setup credentials.
|
|
320
|
+
#
|
|
321
|
+
# @param [Hash] options Excon compatible options
|
|
322
|
+
#
|
|
323
|
+
# @return [Excon::Response]
|
|
324
|
+
def authenticated_request(options)
|
|
325
|
+
headers = options[:headers] || {}
|
|
326
|
+
headers.merge!("Authorization" => "OAuth #{@credentials.access_token}", "Content-Type" => "application/json")
|
|
327
|
+
options[:headers] = headers
|
|
328
|
+
# TODO This is just a wrapper around a call to Excon::Connection#request
|
|
329
|
+
# so can be extracted from Compute by passing in the connection,
|
|
330
|
+
# credentials and options
|
|
331
|
+
@connection.request(options)
|
|
332
|
+
end
|
|
142
333
|
end
|
|
143
334
|
|
|
335
|
+
# The Mock Service allows you to run a fake instance of the Service
|
|
336
|
+
# which makes no real connections.
|
|
337
|
+
#
|
|
338
|
+
# @todo Implement
|
|
339
|
+
#
|
|
144
340
|
class Mock
|
|
145
341
|
include Shared
|
|
146
342
|
|
|
147
|
-
def
|
|
148
|
-
|
|
149
|
-
@brightbox_secret = options[:brightbox_secret] || Fog.credentials[:brightbox_secret]
|
|
343
|
+
def request(method, path, expected_responses, parameters = {})
|
|
344
|
+
_request
|
|
150
345
|
end
|
|
151
346
|
|
|
152
|
-
def
|
|
153
|
-
|
|
347
|
+
def request_access_token(connection, credentials)
|
|
348
|
+
_request
|
|
154
349
|
end
|
|
155
350
|
|
|
156
351
|
private
|
|
352
|
+
|
|
353
|
+
def _request
|
|
354
|
+
raise Fog::Errors::MockNotImplemented
|
|
355
|
+
end
|
|
356
|
+
|
|
157
357
|
def select_default_image
|
|
158
358
|
"img-mockd"
|
|
159
359
|
end
|
|
160
360
|
end
|
|
161
361
|
|
|
362
|
+
# The Real Service actually makes real connections to the Brightbox
|
|
363
|
+
# service.
|
|
364
|
+
#
|
|
162
365
|
class Real
|
|
163
366
|
include Shared
|
|
164
367
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
368
|
+
# Makes an API request to the given path using passed options or those
|
|
369
|
+
# set with the service setup
|
|
370
|
+
#
|
|
371
|
+
# @todo Standard Fog behaviour is to return the Excon::Response but
|
|
372
|
+
# this was unintentionally changed to be the Hash version of the
|
|
373
|
+
# data in the body. This loses access to some details and should
|
|
374
|
+
# be corrected in a backwards compatible manner
|
|
375
|
+
#
|
|
376
|
+
# @param [String] method HTTP method to use for the request
|
|
377
|
+
# @param [String] path The absolute path for the request
|
|
378
|
+
# @param [Array<Fixnum>] expected_responses HTTP response codes that have been successful
|
|
379
|
+
# @param [Hash] parameters Keys and values for JSON
|
|
380
|
+
# @option parameters [String] :account_id The scoping account if required
|
|
381
|
+
#
|
|
382
|
+
# @return [Hash]
|
|
383
|
+
def request(method, path, expected_responses, parameters = {})
|
|
180
384
|
request_options = {
|
|
181
385
|
:method => method.to_s.upcase,
|
|
182
|
-
:path =>
|
|
386
|
+
:path => path,
|
|
183
387
|
:expects => expected_responses
|
|
184
388
|
}
|
|
185
|
-
options[:account_id] = @brightbox_account if options[:account_id].nil? && @brightbox_account
|
|
186
|
-
request_options[:body] = Fog::JSON.encode(options) unless options.empty?
|
|
187
|
-
make_request(request_options)
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
# Returns the scoped account being used for requests
|
|
191
|
-
#
|
|
192
|
-
# API Clients:: This is the owning account
|
|
193
|
-
# User Apps:: This is the account specified by either +account_id+
|
|
194
|
-
# option on a connection or the +brightbox_account+
|
|
195
|
-
# setting in your configuration
|
|
196
|
-
#
|
|
197
|
-
# === Returns:
|
|
198
|
-
#
|
|
199
|
-
# <tt>Fog::Compute::Brightbox::Account</tt>
|
|
200
|
-
#
|
|
201
|
-
def account
|
|
202
|
-
Fog::Compute::Brightbox::Account.new(get_scoped_account)
|
|
203
|
-
end
|
|
204
389
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
connection = Fog::Connection.new(auth_url)
|
|
210
|
-
authentication_body_hash = if @brightbox_username && @brightbox_password
|
|
211
|
-
{
|
|
212
|
-
'client_id' => @brightbox_client_id,
|
|
213
|
-
'grant_type' => 'password',
|
|
214
|
-
'username' => @brightbox_username,
|
|
215
|
-
'password' => @brightbox_password
|
|
216
|
-
}
|
|
217
|
-
else
|
|
218
|
-
{'client_id' => @brightbox_client_id, 'grant_type' => 'none'}
|
|
390
|
+
# Select the account to scope for this request
|
|
391
|
+
account = scoped_account(parameters.fetch(:account_id, nil))
|
|
392
|
+
if account
|
|
393
|
+
request_options[:query] = { :account_id => account }
|
|
219
394
|
end
|
|
220
|
-
@authentication_body = Fog::JSON.encode(authentication_body_hash)
|
|
221
|
-
|
|
222
|
-
response = connection.request({
|
|
223
|
-
:path => "/token",
|
|
224
|
-
:expects => 200,
|
|
225
|
-
:headers => {
|
|
226
|
-
'Authorization' => "Basic " + Base64.encode64("#{@brightbox_client_id}:#{@brightbox_secret}").chomp,
|
|
227
|
-
'Content-Type' => 'application/json'
|
|
228
|
-
},
|
|
229
|
-
:method => 'POST',
|
|
230
|
-
:body => @authentication_body
|
|
231
|
-
})
|
|
232
|
-
@oauth_token = Fog::JSON.decode(response.body)["access_token"]
|
|
233
|
-
return @oauth_token
|
|
234
|
-
end
|
|
235
395
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
response = authenticated_request(params)
|
|
243
|
-
end
|
|
396
|
+
request_options[:body] = Fog::JSON.encode(parameters) unless parameters.empty?
|
|
397
|
+
|
|
398
|
+
response = make_request(request_options)
|
|
399
|
+
|
|
400
|
+
# FIXME We should revert to returning the Excon::Request after a suitable
|
|
401
|
+
# configuration option is in place to switch back to this incorrect behaviour
|
|
244
402
|
unless response.body.empty?
|
|
245
|
-
|
|
403
|
+
Fog::JSON.decode(response.body)
|
|
404
|
+
else
|
|
405
|
+
response
|
|
246
406
|
end
|
|
247
407
|
end
|
|
248
408
|
|
|
249
|
-
|
|
250
|
-
headers = options[:headers] || {}
|
|
251
|
-
headers.merge!("Authorization" => "OAuth #{@oauth_token}", "Content-Type" => "application/json")
|
|
252
|
-
options[:headers] = headers
|
|
253
|
-
@connection.request(options)
|
|
254
|
-
end
|
|
409
|
+
private
|
|
255
410
|
|
|
256
411
|
# Queries the API and tries to select the most suitable official Image
|
|
257
412
|
# to use if the user chooses not to select their own.
|