fog 0.0.84 → 0.0.85

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. data/Gemfile +1 -0
  2. data/Gemfile.lock +47 -37
  3. data/bin/fog +9 -10
  4. data/fog.gemspec +23 -4
  5. data/lib/fog.rb +19 -1
  6. data/lib/fog/aws.rb +23 -0
  7. data/lib/fog/aws/bin.rb +4 -0
  8. data/lib/fog/aws/ec2.rb +20 -27
  9. data/lib/fog/aws/elb.rb +115 -0
  10. data/lib/fog/aws/models/ec2/server.rb +7 -1
  11. data/lib/fog/aws/models/s3/directories.rb +4 -4
  12. data/lib/fog/aws/models/s3/directory.rb +13 -11
  13. data/lib/fog/aws/parsers/elb/deregister_instances_from_load_balancer.rb +26 -0
  14. data/lib/fog/aws/parsers/elb/describe_instance_health.rb +30 -0
  15. data/lib/fog/aws/parsers/elb/describe_load_balancers.rb +101 -0
  16. data/lib/fog/aws/parsers/elb/disable_availability_zones_for_load_balancer.rb +26 -0
  17. data/lib/fog/aws/parsers/elb/enable_availability_zones_for_load_balancer.rb +26 -0
  18. data/lib/fog/aws/parsers/elb/register_instances_with_load_balancer.rb +26 -0
  19. data/lib/fog/aws/requests/ec2/detach_volume.rb +2 -2
  20. data/lib/fog/aws/requests/elb/deregister_instances_from_load_balancer.rb +45 -0
  21. data/lib/fog/aws/requests/elb/describe_instance_health.rb +44 -0
  22. data/lib/fog/aws/requests/elb/describe_load_balancers.rb +57 -0
  23. data/lib/fog/aws/requests/elb/disable_availability_zones_for_load_balancer.rb +44 -0
  24. data/lib/fog/aws/requests/elb/enable_availability_zones_for_load_balancer.rb +44 -0
  25. data/lib/fog/aws/requests/elb/register_instances_with_load_balancer.rb +45 -0
  26. data/lib/fog/aws/s3.rb +8 -1
  27. data/lib/fog/aws/simpledb.rb +9 -18
  28. data/lib/fog/bin.rb +11 -1
  29. data/lib/fog/credentials.rb +1 -0
  30. data/lib/fog/local.rb +72 -0
  31. data/lib/fog/local/bin.rb +34 -0
  32. data/lib/fog/local/models/directories.rb +43 -0
  33. data/lib/fog/local/models/directory.rb +47 -0
  34. data/lib/fog/local/models/file.rb +58 -0
  35. data/lib/fog/local/models/files.rb +74 -0
  36. data/lib/fog/model.rb +2 -8
  37. data/lib/fog/rackspace/models/files/directories.rb +3 -3
  38. data/lib/fog/rackspace/models/files/directory.rb +8 -5
  39. data/lib/fog/rackspace/models/servers/server.rb +7 -3
  40. data/lib/fog/rackspace/requests/servers/create_server.rb +1 -1
  41. data/lib/fog/ssh.rb +91 -25
  42. data/lib/fog/terremark/bin.rb +1 -8
  43. data/lib/fog/terremark/ecloud.rb +14 -5
  44. data/lib/fog/terremark/models/shared/server.rb +54 -3
  45. data/lib/fog/terremark/parsers/shared/vapp.rb +1 -1
  46. data/lib/fog/terremark/requests/shared/get_network.rb +39 -1
  47. data/lib/fog/terremark/requests/shared/get_organization.rb +45 -1
  48. data/lib/fog/terremark/requests/shared/get_organizations.rb +2 -1
  49. data/lib/fog/terremark/requests/shared/get_public_ips.rb +32 -1
  50. data/lib/fog/terremark/requests/shared/get_vdc.rb +83 -1
  51. data/lib/fog/terremark/requests/shared/{reset.rb → power_reset.rb} +1 -1
  52. data/lib/fog/terremark/requests/shared/power_shutdown.rb +32 -0
  53. data/lib/fog/terremark/shared.rb +139 -18
  54. data/lib/fog/terremark/vcloud.rb +14 -5
  55. data/spec/aws/models/ec2/address_spec.rb +1 -3
  56. data/spec/aws/models/ec2/snapshot_spec.rb +25 -49
  57. data/spec/aws/models/ec2/snapshots_spec.rb +25 -31
  58. data/spec/aws/models/ec2/volume_spec.rb +9 -3
  59. data/spec/aws/models/s3/directory_spec.rb +14 -14
  60. data/spec/aws/requests/ec2/associate_address_spec.rb +4 -5
  61. data/spec/aws/requests/ec2/attach_volume_spec.rb +14 -16
  62. data/spec/aws/requests/ec2/create_snapshot_spec.rb +2 -3
  63. data/spec/aws/requests/ec2/delete_snapshot_spec.rb +5 -6
  64. data/spec/aws/requests/ec2/describe_instances_spec.rb +3 -2
  65. data/spec/aws/requests/ec2/describe_snapshots_spec.rb +21 -25
  66. data/spec/aws/requests/ec2/detach_volume_spec.rb +14 -16
  67. data/spec/aws/requests/ec2/disassociate_address_spec.rb +3 -4
  68. data/spec/aws/requests/ec2/get_console_output_spec.rb +1 -0
  69. data/spec/aws/requests/s3/get_service_spec.rb +5 -6
  70. data/spec/spec_helper.rb +0 -20
  71. data/tests/helper.rb +0 -10
  72. data/tests/rackspace/requests/servers/create_image_tests.rb +2 -2
  73. data/tests/rackspace/requests/servers/create_server_tests.rb +3 -2
  74. data/tests/rackspace/requests/servers/delete_image_tests.rb +2 -2
  75. data/tests/rackspace/requests/servers/delete_server_tests.rb +1 -1
  76. data/tests/rackspace/requests/servers/get_server_details_tests.rb +1 -1
  77. data/tests/rackspace/requests/servers/list_addresses_tests.rb +1 -1
  78. data/tests/rackspace/requests/servers/list_private_addresses_tests.rb +1 -1
  79. data/tests/rackspace/requests/servers/list_public_addresses_tests.rb +1 -1
  80. data/tests/rackspace/requests/servers/list_servers_detail_tests.rb +1 -1
  81. data/tests/rackspace/requests/servers/list_servers_tests.rb +1 -1
  82. data/tests/rackspace/requests/servers/reboot_server_tests.rb +3 -3
  83. data/tests/rackspace/requests/servers/update_server_tests.rb +1 -1
  84. data/tests/slicehost/requests/create_slice_tests.rb +1 -1
  85. data/tests/slicehost/requests/delete_slice_tests.rb +1 -1
  86. data/tests/slicehost/requests/get_slice_tests.rb +1 -1
  87. data/tests/slicehost/requests/reboot_slice_tests.rb +2 -2
  88. metadata +24 -5
  89. data/lib/fog/terremark/requests/shared/shutdown.rb +0 -43
@@ -0,0 +1,58 @@
1
+ require 'fog/model'
2
+
3
+ module Fog
4
+ module Local
5
+
6
+ class File < Fog::Model
7
+
8
+ identity :key, 'Key'
9
+
10
+ attr_accessor :body
11
+ attribute :content_length, 'Content-Length'
12
+ # attribute :content_type, 'Content-Type'
13
+ attribute :last_modified, 'Last-Modified'
14
+
15
+ def body
16
+ @body ||= if last_modified
17
+ collection.get(identity).body
18
+ else
19
+ ''
20
+ end
21
+ end
22
+
23
+ def directory
24
+ @directory
25
+ end
26
+
27
+ def destroy
28
+ requires :directory, :key
29
+ ::File.delete(path)
30
+ true
31
+ end
32
+
33
+ def save(options = {})
34
+ requires :body, :directory, :key
35
+ file = ::File.new(path, 'w')
36
+ file.write(body)
37
+ file.close
38
+ merge_attributes(
39
+ :content_length => ::File.size(path),
40
+ :last_modified => ::File.mtime(path)
41
+ )
42
+ true
43
+ end
44
+
45
+ private
46
+
47
+ def directory=(new_directory)
48
+ @directory = new_directory
49
+ end
50
+
51
+ def path
52
+ connection.path_to(::File.join(directory.name, key))
53
+ end
54
+
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,74 @@
1
+ require 'fog/collection'
2
+ require 'fog/local/models/file'
3
+
4
+ module Fog
5
+ module Local
6
+
7
+ class Files < Fog::Collection
8
+
9
+ model Fog::Local::File
10
+
11
+ def all
12
+ if directory.collection.get(directory.name)
13
+ data = Dir.entries(connection.path_to(directory.name)).select do |key|
14
+ key[0...1] != '.' && !::File.directory?(connection.path_to(key))
15
+ end.map do |key|
16
+ path = file_path(key)
17
+ {
18
+ :content_length => ::File.size(path),
19
+ :key => key,
20
+ :last_modified => ::File.mtime(path)
21
+ }
22
+ end
23
+ load(data)
24
+ else
25
+ nil
26
+ end
27
+ end
28
+
29
+ def directory
30
+ @directory
31
+ end
32
+
33
+ def get(key, &block)
34
+ path = file_path(key)
35
+ if ::File.exists?(path)
36
+ data = {
37
+ :content_length => ::File.size(path),
38
+ :key => key,
39
+ :last_modified => ::File.mtime(path)
40
+ }
41
+ if block_given?
42
+ file = ::File.open(path)
43
+ while (chunk = file.read(Excon::CHUNK_SIZE)) && yield(chunk); end
44
+ file.close
45
+ new(data)
46
+ else
47
+ body = nil
48
+ ::File.open(path) do |file|
49
+ body = file.read
50
+ end
51
+ new(data.merge!(:body => body))
52
+ end
53
+ else
54
+ nil
55
+ end
56
+ end
57
+
58
+ def new(attributes = {})
59
+ super({ :directory => directory }.merge!(attributes))
60
+ end
61
+
62
+ private
63
+
64
+ def directory=(new_directory)
65
+ @directory = new_directory
66
+ end
67
+
68
+ def file_path(key)
69
+ connection.path_to(::File.join(directory.name, key))
70
+ end
71
+
72
+ end
73
+ end
74
+ end
@@ -110,14 +110,8 @@ module Fog
110
110
  end
111
111
 
112
112
  def wait_for(timeout = 600, &block)
113
- start = Time.now
114
- until instance_eval(&block)
115
- if Time.now - start > timeout
116
- break
117
- end
118
- reload
119
- sleep(1)
120
- end
113
+ reload
114
+ Fog.wait_for(timeout) { reload && instance_eval(&block) }
121
115
  end
122
116
 
123
117
  private
@@ -26,9 +26,9 @@ module Fog
26
26
  load(data)
27
27
  end
28
28
 
29
- def get(name, options = {})
30
- data = connection.get_container(name, options).body
31
- directory = new(:name => name)
29
+ def get(key, options = {})
30
+ data = connection.get_container(key, options).body
31
+ directory = new(:key => key)
32
32
  directory.files.merge_attributes(options)
33
33
  directory.files.instance_variable_set(:@loaded, true)
34
34
  data.each do |file|
@@ -1,19 +1,22 @@
1
1
  require 'fog/model'
2
+ require 'fog/rackspace/models/files/files'
2
3
 
3
4
  module Fog
4
5
  module Rackspace
5
6
  module Files
6
7
 
7
8
  class Directory < Fog::Model
9
+ extend Fog::Deprecation
10
+ deprecate(:name, :key)
8
11
 
9
- identity :name
12
+ identity :key, 'name'
10
13
 
11
14
  attribute :bytes
12
15
  attribute :count
13
16
 
14
17
  def destroy
15
- requires :name
16
- connection.delete_container(@name)
18
+ requires :key
19
+ connection.delete_container(key)
17
20
  true
18
21
  rescue Excon::Errors::NotFound
19
22
  false
@@ -29,8 +32,8 @@ module Fog
29
32
  end
30
33
 
31
34
  def save
32
- requires :name
33
- connection.put_container(@name)
35
+ requires :key
36
+ connection.put_container(key)
34
37
  true
35
38
  end
36
39
 
@@ -51,10 +51,14 @@ module Fog
51
51
  end
52
52
 
53
53
  def save
54
- requires :flavor_id, :image_id, :name
55
- options = { 'metadata' => @metadata, 'personality' => @personality }
54
+ requires :flavor_id, :image_id
55
+ options = {
56
+ 'metadata' => @metadata,
57
+ 'name' => @name,
58
+ 'personality' => @personality
59
+ }
56
60
  options = options.reject {|key, value| value.nil?}
57
- data = connection.create_server(@flavor_id, @image_id, @name, options)
61
+ data = connection.create_server(@flavor_id, @image_id, options)
58
62
  merge_attributes(data.body['server'])
59
63
  true
60
64
  end
@@ -33,7 +33,7 @@ module Fog
33
33
  # * 'name<~String> - Name of server
34
34
  # * 'progress'<~Integer> - Progress through current status
35
35
  # * 'status'<~String> - Current server status
36
- def create_server(flavor_id, image_id, name, options = {})
36
+ def create_server(flavor_id, image_id, options = {})
37
37
  data = {
38
38
  'server' => {
39
39
  'flavorId' => flavor_id,
@@ -1,42 +1,108 @@
1
1
  module Fog
2
+ module SSH
2
3
 
3
- class SSH
4
-
5
- def initialize(address, username, options = {})
4
+ def self.new(address, username, options = {})
6
5
  unless options[:keys] || options[:password]
7
6
  raise ArgumentError.new(':keys or :password are required to initialize SSH')
8
7
  end
9
- @address = address
10
- @username = username
11
- @options = options.merge!(:paranoid => false)
8
+ if Fog.mocking?
9
+ Fog::SSH::Mock.new(address, username, options)
10
+ else
11
+ Fog::SSH::Real.new(address, username, options)
12
+ end
13
+ end
14
+
15
+ def self.reset_data(keys=Mock.data.keys)
16
+ Mock.reset_data(keys)
12
17
  end
13
18
 
14
- def run(commands)
15
- commands = [*commands]
16
- results = []
17
- Net::SSH.start(@address, @username, @options) do |ssh|
18
- commands.each do |command|
19
- ssh.open_channel do |channel|
20
- channel.request_pty
21
- result = { :command => command }
22
- channel.exec(command.sub(/^sudo/, %q{sudo -p 'fog sudo password:'})) do |channel, success|
23
- channel.on_data do |channel, data|
24
- if data.strip == 'fog sudo password:'
25
- channel.send_data("#{@options[:password]}\n")
26
- else
27
- result[:data] ||= ''
28
- result[:data] << data
19
+ class Mock
20
+
21
+ def self.data
22
+ @data ||= Hash.new do |hash, key|
23
+ hash[key] = {}
24
+ end
25
+ end
26
+
27
+ def initialize(address, username, options)
28
+ @address = address
29
+ @username = username
30
+ @options = options
31
+ end
32
+
33
+ def run(commands)
34
+ raise MockNotImplemented.new("Contributions welcome!")
35
+ end
36
+
37
+ end
38
+
39
+ class Real
40
+
41
+ def initialize(address, username, options)
42
+ @address = address
43
+ @username = username
44
+ @options = options.merge!(:paranoid => false)
45
+ end
46
+
47
+ def run(commands)
48
+ commands = [*commands]
49
+ results = []
50
+ begin
51
+ Net::SSH.start(@address, @username, @options) do |ssh|
52
+ commands.each do |command|
53
+ ssh.open_channel do |channel|
54
+ sudoable_command = command.sub(/^sudo/, %{sudo -p 'fog sudo password:'})
55
+ escaped_command = sudoable_command.sub(/'/, %{'"'"'})
56
+ channel.request_pty
57
+ result = Result.new(command)
58
+ channel.exec(%{bash -lc '#{escaped_command}'}) do |channel, success|
59
+ unless success
60
+ raise "Could not execute command: #{command.inspect}"
61
+ end
62
+
63
+ channel.on_data do |channel, data|
64
+ result.stdout << data
65
+ end
66
+
67
+ channel.on_extended_data do |channel, type, data|
68
+ next unless type == 1
69
+ result.stderr << data
70
+ end
71
+
72
+ channel.on_request('exit-status') do |channel, data|
73
+ result.status = data.read_long
74
+ end
75
+
76
+ channel.on_request('exit-signal') do |channel, data|
77
+ result.status = 255
78
+ end
29
79
  end
80
+ results << result
30
81
  end
82
+ ssh.loop
31
83
  end
32
- results << result
33
84
  end
34
- ssh.loop
85
+ rescue Net::SSH::HostKeyMismatch => exception
86
+ exception.remember_host!
87
+ sleep 0.2
88
+ retry
35
89
  end
90
+ results
91
+ end
92
+
93
+ end
94
+
95
+ class Result
96
+
97
+ attr_accessor :command, :stderr, :stdout, :status
98
+
99
+ def initialize(command)
100
+ @command = command
101
+ @stderr = ''
102
+ @stdout = ''
36
103
  end
37
- results
104
+
38
105
  end
39
106
 
40
107
  end
41
-
42
108
  end
@@ -28,14 +28,7 @@ module Terremark
28
28
  !Fog::Terremark::VCLOUD_OPTIONS.include?(k)
29
29
  end
30
30
  end
31
- case key
32
- when :ecloud
33
- hash[key] = Fog::Terremark::Ecloud.new(credentials)
34
- when :vcloud
35
- hash[key] = Fog::Terremark::Vcloud.new(credentials)
36
- else
37
- raise "Unsupported Terremark Service"
38
- end
31
+ hash[key] = terremark_service(key).new(credentials)
39
32
  end
40
33
  @@connections[service]
41
34
  end
@@ -5,6 +5,13 @@ module Fog
5
5
  module Bin
6
6
  end
7
7
 
8
+ module Defaults
9
+ HOST = 'services.enterprisecloud.terremark.com'
10
+ PATH = '/api/v0.8a-ext2.0'
11
+ PORT = 443
12
+ SCHEME = 'https'
13
+ end
14
+
8
15
  extend Fog::Terremark::Shared
9
16
 
10
17
  def self.new(options={})
@@ -31,11 +38,10 @@ module Fog
31
38
  def initialize(options={})
32
39
  @terremark_password = options[:terremark_ecloud_password]
33
40
  @terremark_username = options[:terremark_ecloud_username]
34
- @host = options[:host] || "services.enterprisecloud.terremark.com"
35
- @path = options[:path] || "/api/v0.8a-ext2.0"
36
- @port = options[:port] || 443
37
- @scheme = options[:scheme] || 'https'
38
- @cookie = get_organizations.headers['Set-Cookie']
41
+ @host = options[:host] || Fog::Terremark::Ecloud::Defaults::HOST
42
+ @path = options[:path] || Fog::Terremark::Ecloud::Defaults::PATH
43
+ @port = options[:port] || Fog::Terremark::Ecloud::Defaults::PORT
44
+ @scheme = options[:scheme] || Fog::Terremark::Ecloud::Defaults::SCHEME
39
45
  end
40
46
 
41
47
  end
@@ -46,6 +52,9 @@ module Fog
46
52
 
47
53
  def initialize(option = {})
48
54
  super
55
+ @base_url = Fog::Terremark::Ecloud::Defaults::SCHEME + "://" +
56
+ Fog::Terremark::Ecloud::Defaults::HOST +
57
+ Fog::Terremark::Ecloud::Defaults::PATH
49
58
  @data = self.class.data[:terremark_ecloud_username]
50
59
  end
51
60
  end
@@ -25,12 +25,60 @@ module Fog
25
25
  @status == '2'
26
26
  end
27
27
 
28
- def reboot
28
+ def on?
29
+ @status == '4'
30
+ end
31
+
32
+ def off?
33
+ @status == '2'
34
+ end
35
+
36
+ def power_on(options = {})
37
+ requires :id
38
+ begin
39
+ connection.power_on(@id)
40
+ rescue Excon::Errors::InternalServerError => e
41
+ #Frankly we shouldn't get here ...
42
+ raise e unless e.to_s =~ /because it is already powered on/
43
+ end
44
+ true
45
+ end
46
+
47
+ def power_off
48
+ requires :id
49
+ begin
50
+ connection.power_off(@id)
51
+ rescue Excon::Errors::InternalServerError => e
52
+ #Frankly we shouldn't get here ...
53
+ raise e unless e.to_s =~ /because it is already powered off/
54
+ end
55
+ true
56
+ end
57
+
58
+ def shutdown
59
+ requires :id
60
+ begin
61
+ connection.power_shutdown(@id)
62
+ rescue Excon::Errors::InternalServerError => e
63
+ #Frankly we shouldn't get here ...
64
+ raise e unless e.to_s =~ /because it is already powered off/
65
+ end
66
+ true
67
+ end
68
+
69
+ def power_reset
29
70
  requires :id
30
- connection.reset(@id)
71
+ connection.power_reset(@id)
31
72
  true
32
73
  end
33
74
 
75
+ def graceful_restart
76
+ requires :id
77
+ shutdown
78
+ wait_for { off? }
79
+ power_on
80
+ end
81
+
34
82
  def save
35
83
  requires :name
36
84
  data = connection.instantiate_vapp(@name)
@@ -48,7 +96,10 @@ module Fog
48
96
  @id = new_href.split('/').last.to_i
49
97
  end
50
98
 
51
- def type=(new_type); end
99
+ def type=(new_type); @type = new_type; end
100
+ def size=(new_size); @size = new_size; end
101
+ def IpAddress=(new_ipaddress); @IpAddress = new_ipaddress; end
102
+ def Links=(new_links); @Links = new_links; end
52
103
 
53
104
  end
54
105