fog 1.2.0 → 1.3.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.
Files changed (93) hide show
  1. data/Rakefile +1 -0
  2. data/changelog.txt +91 -0
  3. data/fog.gemspec +3 -3
  4. data/lib/fog.rb +1 -1
  5. data/lib/fog/aws/compute.rb +5 -4
  6. data/lib/fog/aws/models/compute/security_group.rb +7 -1
  7. data/lib/fog/aws/models/compute/subnet.rb +0 -1
  8. data/lib/fog/aws/parsers/compute/create_security_group.rb +24 -0
  9. data/lib/fog/aws/requests/cloud_watch/get_metric_statistics.rb +1 -1
  10. data/lib/fog/aws/requests/compute/authorize_security_group_ingress.rb +19 -11
  11. data/lib/fog/aws/requests/compute/create_security_group.rb +5 -3
  12. data/lib/fog/aws/requests/compute/describe_security_groups.rb +1 -1
  13. data/lib/fog/aws/requests/storage/get_object_http_url.rb +2 -2
  14. data/lib/fog/aws/requests/storage/get_object_https_url.rb +2 -2
  15. data/lib/fog/aws/simpledb.rb +6 -1
  16. data/lib/fog/bin.rb +1 -0
  17. data/lib/fog/bin/ibm.rb +34 -0
  18. data/lib/fog/compute.rb +3 -0
  19. data/lib/fog/core/errors.rb +2 -0
  20. data/lib/fog/ibm.rb +176 -0
  21. data/lib/fog/ibm/compute.rb +233 -0
  22. data/lib/fog/ibm/models/compute/address.rb +62 -0
  23. data/lib/fog/ibm/models/compute/addresses.rb +28 -0
  24. data/lib/fog/ibm/models/compute/image.rb +61 -0
  25. data/lib/fog/ibm/models/compute/images.rb +27 -0
  26. data/lib/fog/ibm/models/compute/instance-type.rb +14 -0
  27. data/lib/fog/ibm/models/compute/instance-types.rb +15 -0
  28. data/lib/fog/ibm/models/compute/key.rb +35 -0
  29. data/lib/fog/ibm/models/compute/keys.rb +35 -0
  30. data/lib/fog/ibm/models/compute/location.rb +15 -0
  31. data/lib/fog/ibm/models/compute/locations.rb +27 -0
  32. data/lib/fog/ibm/models/compute/server.rb +193 -0
  33. data/lib/fog/ibm/models/compute/servers.rb +27 -0
  34. data/lib/fog/ibm/models/storage/offering.rb +18 -0
  35. data/lib/fog/ibm/models/storage/offerings.rb +19 -0
  36. data/lib/fog/ibm/models/storage/volume.rb +95 -0
  37. data/lib/fog/ibm/models/storage/volumes.rb +27 -0
  38. data/lib/fog/ibm/requests/compute/clone_image.rb +48 -0
  39. data/lib/fog/ibm/requests/compute/create_address.rb +50 -0
  40. data/lib/fog/ibm/requests/compute/create_image.rb +56 -0
  41. data/lib/fog/ibm/requests/compute/create_instance.rb +80 -0
  42. data/lib/fog/ibm/requests/compute/create_key.rb +61 -0
  43. data/lib/fog/ibm/requests/compute/delete_address.rb +46 -0
  44. data/lib/fog/ibm/requests/compute/delete_image.rb +43 -0
  45. data/lib/fog/ibm/requests/compute/delete_instance.rb +52 -0
  46. data/lib/fog/ibm/requests/compute/delete_key.rb +41 -0
  47. data/lib/fog/ibm/requests/compute/get_image.rb +67 -0
  48. data/lib/fog/ibm/requests/compute/get_image_agreement.rb +66 -0
  49. data/lib/fog/ibm/requests/compute/get_image_manifest.rb +39 -0
  50. data/lib/fog/ibm/requests/compute/get_instance.rb +76 -0
  51. data/lib/fog/ibm/requests/compute/get_instance_logs.rb +25 -0
  52. data/lib/fog/ibm/requests/compute/get_key.rb +49 -0
  53. data/lib/fog/ibm/requests/compute/get_location.rb +55 -0
  54. data/lib/fog/ibm/requests/compute/get_request.rb +78 -0
  55. data/lib/fog/ibm/requests/compute/list_address_offerings.rb +58 -0
  56. data/lib/fog/ibm/requests/compute/list_addresses.rb +53 -0
  57. data/lib/fog/ibm/requests/compute/list_images.rb +58 -0
  58. data/lib/fog/ibm/requests/compute/list_instances.rb +57 -0
  59. data/lib/fog/ibm/requests/compute/list_keys.rb +57 -0
  60. data/lib/fog/ibm/requests/compute/list_locations.rb +37 -0
  61. data/lib/fog/ibm/requests/compute/list_vlans.rb +52 -0
  62. data/lib/fog/ibm/requests/compute/modify_instance.rb +71 -0
  63. data/lib/fog/ibm/requests/compute/modify_key.rb +52 -0
  64. data/lib/fog/ibm/requests/storage/create_volume.rb +66 -0
  65. data/lib/fog/ibm/requests/storage/delete_volume.rb +42 -0
  66. data/lib/fog/ibm/requests/storage/get_volume.rb +72 -0
  67. data/lib/fog/ibm/requests/storage/list_offerings.rb +76 -0
  68. data/lib/fog/ibm/requests/storage/list_volumes.rb +47 -0
  69. data/lib/fog/ibm/storage.rb +82 -0
  70. data/lib/fog/ovirt/compute.rb +1 -0
  71. data/lib/fog/ovirt/models/compute/server.rb +5 -0
  72. data/lib/fog/ovirt/requests/compute/vm_ticket.rb +21 -0
  73. data/lib/fog/providers.rb +1 -0
  74. data/lib/fog/storage.rb +3 -0
  75. data/tests/aws/requests/compute/security_group_tests.rb +37 -39
  76. data/tests/compute/helper.rb +4 -0
  77. data/tests/compute/models/flavors_tests.rb +1 -1
  78. data/tests/helper.rb +1 -1
  79. data/tests/helpers/mock_helper.rb +2 -0
  80. data/tests/ibm/models/compute/image_tests.rb +10 -0
  81. data/tests/ibm/models/compute/key_tests.rb +23 -0
  82. data/tests/ibm/models/compute/keys_tests.rb +35 -0
  83. data/tests/ibm/models/compute/locations_tests.rb +18 -0
  84. data/tests/ibm/models/compute/server_tests.rb +88 -0
  85. data/tests/ibm/models/compute/servers_tests.rb +37 -0
  86. data/tests/ibm/models/storage/volume_tests.rb +60 -0
  87. data/tests/ibm/requests/compute/address_tests.rb +44 -0
  88. data/tests/ibm/requests/compute/image_tests.rb +110 -0
  89. data/tests/ibm/requests/compute/instance_tests.rb +102 -0
  90. data/tests/ibm/requests/compute/key_tests.rb +50 -0
  91. data/tests/ibm/requests/compute/location_tests.rb +28 -0
  92. data/tests/ibm/requests/storage/volume_tests.rb +100 -0
  93. metadata +122 -43
@@ -0,0 +1,27 @@
1
+ require 'fog/core/collection'
2
+ require 'fog/ibm/models/compute/server'
3
+
4
+ module Fog
5
+ module Compute
6
+ class IBM
7
+
8
+ class Servers < Fog::Collection
9
+
10
+ model Fog::Compute::IBM::Server
11
+
12
+ def all
13
+ load(connection.list_instances.body['instances'])
14
+ end
15
+
16
+ def get(server_id)
17
+ begin
18
+ new(connection.get_instance(server_id).body)
19
+ rescue Fog::Compute::IBM::NotFound
20
+ nil
21
+ end
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,18 @@
1
+ require 'fog/core/model'
2
+
3
+ module Fog
4
+ module Storage
5
+ class IBM
6
+ class Offering < Fog::Model
7
+ identity :id
8
+ attribute :location
9
+ attribute :name
10
+ attribute :label
11
+ attribute :capacity
12
+ attribute :supported_sizes, :aliases => 'supportedSizes'
13
+ attribute :supported_formats, :aliases => 'formats'
14
+ attribute :price
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,19 @@
1
+ require 'fog/core/collection'
2
+ require 'fog/ibm/models/storage/offering'
3
+
4
+ module Fog
5
+ module Storage
6
+ class IBM
7
+
8
+ class Offerings < Fog::Collection
9
+
10
+ model Fog::Storage::IBM::Offering
11
+
12
+ def all
13
+ load(connection.list_offerings.body['volumes'])
14
+ end
15
+
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,95 @@
1
+ require 'fog/core/model'
2
+
3
+ module Fog
4
+ module Storage
5
+ class IBM
6
+ class Volume < Fog::Model
7
+
8
+ STATUS = [
9
+ "New", # => 0
10
+ "Creating", # => 1
11
+ "Deleting", # => 2
12
+ "Deleted", # => 3
13
+ "Detached", # => 4
14
+ "Attached", # => 5
15
+ "Failed", # => 6
16
+ "Deletion pending", # => 7
17
+ "Being cloned", # => 8
18
+ "Cloning", # => 9
19
+ "Attaching", # => 10
20
+ "Detaching", # => 11
21
+ "Copying", # => 12
22
+ "Importing", # => 13
23
+ "Transfer retrying" # => 14
24
+ ]
25
+
26
+ identity :id
27
+
28
+ attribute :instance_id, :aliases => "instanceId"
29
+ attribute :io_price, :aliases => "ioPrice"
30
+ attribute :name
31
+ attribute :state
32
+ attribute :size
33
+ attribute :offering_id, :aliases => "offeringId"
34
+ attribute :owner
35
+ attribute :created_at, :aliases => "createdTime"
36
+ attribute :location_id, :aliases => "location"
37
+ attribute :product_codes, :aliases => "productCodes"
38
+ attribute :format
39
+
40
+ def attached?
41
+ status == "Attached"
42
+ end
43
+
44
+ def attach(instance_id)
45
+ requires :id
46
+ connection.attach_volume(instance_id, id).body['success']
47
+ end
48
+
49
+ def detach(instance_id)
50
+ requires :id
51
+ connection.detach_volume(instance_id, id).body['success']
52
+ end
53
+
54
+ def created_at
55
+ Time.at(attributes[:created_at].to_f / 1000)
56
+ end
57
+
58
+ def destroy
59
+ requires :id
60
+ connection.delete_volume(id)
61
+ true
62
+ end
63
+
64
+ def instance
65
+ return nil if instance_id.nil? || instance_id == "0" || instance_id == ""
66
+ Fog::Compute[:ibm].servers.get(instance_id)
67
+ end
68
+
69
+ def location
70
+ requires :location_id
71
+ Fog::Compute[:ibm].locations.get(location_id)
72
+ end
73
+
74
+ # Are we ready to be attached to an instance?
75
+ def ready?
76
+ # TODO: Not sure if this is the only status we should be matching.
77
+ status == "Detached"
78
+ end
79
+
80
+ def save
81
+ raise Fog::Errors::Error.new('Resaving an existing object may create a duplicate') if identity
82
+ requires :name, :offering_id, :format, :location_id, :size
83
+ data = connection.create_volume(name, offering_id, format, location_id, size)
84
+ merge_attributes(data.body)
85
+ true
86
+ end
87
+
88
+ def status
89
+ STATUS[attributes[:state].to_i]
90
+ end
91
+
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,27 @@
1
+ require 'fog/core/collection'
2
+ require 'fog/ibm/models/storage/volume'
3
+
4
+ module Fog
5
+ module Storage
6
+ class IBM
7
+
8
+ class Volumes < Fog::Collection
9
+
10
+ model Fog::Storage::IBM::Volume
11
+
12
+ def all
13
+ load(connection.list_volumes.body['volumes'])
14
+ end
15
+
16
+ def get(volume_id)
17
+ begin
18
+ new(connection.get_volume(volume_id).body)
19
+ rescue Fog::Storage::IBM::NotFound
20
+ nil
21
+ end
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,48 @@
1
+ module Fog
2
+ module Compute
3
+ class IBM
4
+ class Real
5
+
6
+ # Clones image specified by image_id
7
+ #
8
+ # ==== Parameters
9
+ # * image_id<~String> - id of image to be cloned
10
+ # * name<~String> - name of new image
11
+ # * description<~String> - description of new image
12
+ #
13
+ # ==== Returns
14
+ # * response<~Excon::Response>:
15
+ # * body<~Hash>:
16
+ # * 'ImageID'<~String>: id of new image
17
+ def clone_image(image_id, name, description)
18
+ request(
19
+ :method => 'POST',
20
+ :expects => 200,
21
+ :path => "/offerings/image/#{image_id}",
22
+ :body => {
23
+ 'name' => name,
24
+ 'description' => description
25
+ }
26
+ )
27
+ end
28
+
29
+ end
30
+ class Mock
31
+
32
+ def clone_image(image_id, name, description)
33
+ response = Excon::Response.new
34
+ if image_exists? image_id
35
+ id = Fog::IBM::Mock.instance_id
36
+ self.data[:images][id] = self.data[:images][image_id].dup
37
+ response.status = 200
38
+ response.body = { "ImageID" => id }
39
+ else
40
+ response.status = 404
41
+ end
42
+ response
43
+ end
44
+
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,50 @@
1
+ module Fog
2
+ module Compute
3
+ class IBM
4
+ class Real
5
+
6
+ # Requests a new static IP address to be created
7
+ #
8
+ # ==== Parameters
9
+ # * location_id<~String> - id of location
10
+ # * offering_id<~String> - id for offering
11
+ # * vlan_id<~String> - id of vlan
12
+ #
13
+ # ==== Returns
14
+ # * response<~Excon::Response>:
15
+ # * body<~Hash>:
16
+ # * 'location'<~String>: location of new address
17
+ # * 'offeringId'<~String>: offering id of new address
18
+ # * 'id'<~String>: id
19
+ # * 'ip'<~String>: returns string of spaces (ip not yet allocated right after creation)
20
+ # * 'state'<~Integer>: status of address (0 when new)
21
+ def create_address(location, offering_id, options={})
22
+ request(
23
+ :method => 'POST',
24
+ :expects => 200,
25
+ :path => '/addresses',
26
+ :body => {
27
+ 'offeringID' => offering_id,
28
+ 'location' => location,
29
+ 'vlanID' => options[:vlan_id]
30
+ }
31
+ )
32
+ end
33
+
34
+ end
35
+
36
+ class Mock
37
+
38
+ def create_address(location_id, offering_id="20001223", options={})
39
+ address = Fog::IBM::Mock.create_address(location_id, offering_id, options)
40
+ self.data[:addresses][address['id']] = address
41
+ response = Excon::Response.new
42
+ response.status = 200
43
+ response.body = address
44
+ response
45
+ end
46
+
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,56 @@
1
+ module Fog
2
+ module Compute
3
+ class IBM
4
+ class Real
5
+
6
+ # Requests an image to be created from an Instance
7
+ #
8
+ # ==== Parameters
9
+ # * instance_id<~String> - id of instance to save
10
+ # * name<~String> - name of image to be created
11
+ # * description<~String> - description of image to be created
12
+ #
13
+ # ==== Returns
14
+ # * response<~Excon::Response>:
15
+ # * body<~Hash>:
16
+ # * 'name'<~String>: name of new image
17
+ # * 'createdTime'<~Integer>: epoch time at creation
18
+ # * 'productCodes'<~Array>:
19
+ # * 'id'<~String>: id of new image
20
+ # * 'description'<~String>: description
21
+ # * 'visibility'<~String>: visibility level ("PRIVATE", etc)
22
+ # * 'state'<~Integer>: status of image
23
+ def create_image(instance_id, name, description)
24
+ request(
25
+ :method => 'PUT',
26
+ :expects => 200,
27
+ :path => "/instances/#{instance_id}",
28
+ :body => {
29
+ 'state' => 'save',
30
+ 'name' => name,
31
+ 'description' => description
32
+ }
33
+ )
34
+ end
35
+
36
+ end
37
+
38
+ class Mock
39
+
40
+ def create_image(instance_id, name, description)
41
+ response = Excon::Response.new
42
+ if instance_exists? instance_id
43
+ image = Fog::IBM::Mock.private_image(name, description)
44
+ self.data[:images][image["id"]] = image
45
+ response.status = 200
46
+ response.body = image
47
+ else
48
+ response.status = 404
49
+ end
50
+ response
51
+ end
52
+
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,80 @@
1
+ module Fog
2
+ module Compute
3
+ class IBM
4
+ class Real
5
+
6
+ # Requests a new Instance to be created.
7
+ #
8
+ # ==== Parameters
9
+ # * name<~String> - The alias to use to reference this instance
10
+ # * image_id<~String> - The id of the image to create this instance from
11
+ # * instance_type<~String> - The instance type to use for this instance
12
+ # * location<~String> - The id of the Location where this instance will be created
13
+ # * options<~Hash>:
14
+ # * :key_name<~String> - The public key to use for accessing the created instance
15
+ # * :ip<~String> - The ID of a static IP address to associate with this instance
16
+ # * :volume_id<~String> - The ID of a storage volume to associate with this instance
17
+ # * :vlan_id<~String> - The ID of a Vlan offering to associate with this instance.
18
+ # * :secondary_ip<~String> - The ID of a static IP address to associate with this instance as secondary IP
19
+ # * :is_mini_ephermal<~Boolean> - Whether or not the instance should be provisioned with the root segment only
20
+ # * :configuration_data<~Hash> - Arbitrary name/value pairs defined by the image being created
21
+ # * :anti_collocation_instance<~String> - The ID of an existing anti-collocated instance.
22
+ #
23
+ # ==== Returns
24
+ # * response<~Excon::Response>:
25
+ # * body<~Hash>:
26
+ # * 'name'<~String>: instance name
27
+ # * 'location'<~String>: instance location id
28
+ # * 'keyName'<~String>: instance assigned keypair
29
+ # * 'primaryIP'<~Hash>: assigned ip address, type, and hostname
30
+ # * 'productCodes'<~Array>: associated product codes
31
+ # * 'requestId'<~String>:
32
+ # * 'imageId'<~String>:
33
+ # * 'launchTime'<~Integer>: epoch time in ms representing when the instance was launched
34
+ def create_instance(name, image_id, instance_type, location, options={})
35
+ request(
36
+ :method => 'POST',
37
+ :expects => 200,
38
+ :path => '/instances',
39
+ :body => {
40
+ 'name' => name,
41
+ 'imageID' => image_id,
42
+ 'instanceType' => instance_type,
43
+ 'location' => location,
44
+ 'publicKey' => options[:key_name],
45
+ 'ip' => options[:ip],
46
+ 'volumeID' => options[:volume_id],
47
+ 'vlanID' => options[:vlan_id],
48
+ 'SecondaryIP' => options[:secondary_ip],
49
+ 'isMiniEphemermal' => options[:is_mini_ephemeral],
50
+ 'Configuration Data' => options[:configuration_data],
51
+ 'antiCollocationInstance' => options[:anti_collocation_instance],
52
+ }
53
+ )
54
+ end
55
+
56
+ end
57
+
58
+ class Mock
59
+
60
+ def create_instance(name, image_id, instance_type, location, options={})
61
+ response = Excon::Response.new
62
+ # Since we want to test error conditions, we have a little regex that traps specially formed
63
+ # instance type strings.
64
+ case name
65
+ when /FAIL:\ (\d{3})/
66
+ response.status = $1.to_i
67
+ raise Excon::Errors.status_error({:expects => 200}, response)
68
+ else
69
+ instance = Fog::IBM::Mock.create_instance(name, image_id, instance_type, location, options)
70
+ self.data[:instances][instance['id']] = instance
71
+ response.status = 200
72
+ response.body = {"instances" => [ instance ]}
73
+ response
74
+ end
75
+ end
76
+
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,61 @@
1
+ module Fog
2
+ module Compute
3
+ class IBM
4
+ class Real
5
+
6
+ # Requests a new keypair to be created
7
+ #
8
+ # ==== Parameters
9
+ # * name<~String> - name to give new key
10
+ #
11
+ # ==== Returns
12
+ # * response<~Excon::Response>:
13
+ # * body<~Hash>:
14
+ # * 'keyName'<~String>: name of new key
15
+ # * 'lastModifiedTime'<~Integer>: epoch time of last modification
16
+ # * 'default'<~Bool>: is default?
17
+ # * 'instanceIds'<~Array>: id's of instances using key (should be empty upon creation)
18
+ # * 'keyMaterial'<~String>: private key contents
19
+ def create_key(name, public_key=nil)
20
+ request(
21
+ :method => 'POST',
22
+ :expects => 200,
23
+ :path => '/keys',
24
+ :body => {
25
+ 'name' => name,
26
+ 'publicKey' => public_key
27
+ }
28
+ )
29
+ end
30
+
31
+ end
32
+
33
+ class Mock
34
+
35
+ # SmartCloud returns the private key when create_key is called
36
+ # We need to store both the private and public key for later use
37
+ def create_key(name, public_key=nil)
38
+ response = Excon::Response.new
39
+ response.status = 200
40
+ attributes = {
41
+ "keyName" => name,
42
+ "lastModifiedTime" => Fog::IBM::Mock.launch_time,
43
+ "default" => false,
44
+ "instanceIds" => [],
45
+ }
46
+ if public_key.nil?
47
+ private_key = Fog::IBM::Mock.key_material
48
+ public_key = private_key.public_key
49
+ response.body = attributes.merge("keyMaterial" => private_key.to_s)
50
+ else
51
+ response.body = { 'success' => true }
52
+ end
53
+ self.data[:keys][name] = attributes.merge("keyMaterial" => public_key.to_s)
54
+ self.data[:private_keys][name] = attributes.merge("keyMaterial" => private_key.to_s)
55
+ response
56
+ end
57
+
58
+ end
59
+ end
60
+ end
61
+ end