fog 0.7.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. data/.gitignore +1 -1
  2. data/Rakefile +43 -0
  3. data/changelog.txt +39 -0
  4. data/docs/_config.yml +39 -0
  5. data/docs/_layouts/default.html +96 -0
  6. data/docs/_posts/2011-01-01-cdn.markdown +82 -0
  7. data/docs/_posts/2011-01-01-contributing.markdown +228 -0
  8. data/docs/_posts/2011-01-01-dns.markdown +79 -0
  9. data/docs/_posts/2011-01-01-press.markdown +32 -0
  10. data/docs/_posts/2011-01-01-start.markdown +21 -0
  11. data/docs/_posts/2011-01-01-storage.markdown +145 -0
  12. data/docs/_posts/2011-01-01-structure.markdown +78 -0
  13. data/docs/_posts/2011-01-01-users.markdown +33 -0
  14. data/docs/index.markdown +94 -0
  15. data/docs/public/crossdomain.xml +25 -0
  16. data/docs/public/css/fog.css +129 -0
  17. data/docs/public/css/handheld.css +8 -0
  18. data/docs/public/css/style.css +129 -0
  19. data/docs/public/images/.gitignore +3 -0
  20. data/docs/public/js/libs/dd_belatedpng.js +13 -0
  21. data/docs/public/js/libs/jquery-1.4.2.js +6240 -0
  22. data/docs/public/js/libs/jquery-1.4.2.min.js +154 -0
  23. data/docs/public/js/libs/modernizr-1.6.min.js +30 -0
  24. data/docs/public/js/mylibs/.gitignore +3 -0
  25. data/docs/public/js/plugins.js +34 -0
  26. data/docs/public/js/profiling/config.js +59 -0
  27. data/docs/public/js/profiling/yahoo-profiling.css +7 -0
  28. data/docs/public/js/profiling/yahoo-profiling.min.js +39 -0
  29. data/docs/public/js/script.js +26 -0
  30. data/docs/public/robots.txt +5 -0
  31. data/fog.gemspec +6 -5
  32. data/lib/fog.rb +1 -1
  33. data/lib/fog/aws/cloud_formation.rb +1 -1
  34. data/lib/fog/compute/aws.rb +24 -0
  35. data/lib/fog/compute/models/aws/key_pair.rb +19 -1
  36. data/lib/fog/compute/models/aws/server.rb +6 -12
  37. data/lib/fog/compute/models/rackspace/server.rb +7 -7
  38. data/lib/fog/compute/requests/aws/attach_volume.rb +4 -0
  39. data/lib/fog/compute/requests/aws/create_security_group.rb +3 -3
  40. data/lib/fog/compute/requests/aws/create_tags.rb +2 -0
  41. data/lib/fog/compute/requests/aws/create_volume.rb +4 -0
  42. data/lib/fog/compute/requests/aws/delete_tags.rb +43 -0
  43. data/lib/fog/compute/requests/aws/describe_instances.rb +3 -7
  44. data/lib/fog/compute/requests/aws/describe_snapshots.rb +4 -6
  45. data/lib/fog/compute/requests/aws/describe_volumes.rb +2 -6
  46. data/lib/fog/core.rb +1 -0
  47. data/lib/fog/core/connection.rb +1 -1
  48. data/lib/fog/core/credentials.rb +5 -1
  49. data/lib/fog/core/parser.rb +1 -2
  50. data/lib/fog/core/ssh.rb +2 -3
  51. data/lib/fog/dns/models/aws/record.rb +1 -1
  52. data/lib/fog/dns/models/bluebox/zone.rb +1 -0
  53. data/lib/fog/storage/models/rackspace/directory.rb +8 -2
  54. data/lib/fog/storage/rackspace.rb +3 -1
  55. data/lib/fog/storage/requests/rackspace/delete_container.rb +1 -1
  56. data/lib/fog/storage/requests/rackspace/delete_object.rb +1 -1
  57. data/lib/fog/storage/requests/rackspace/get_container.rb +1 -1
  58. data/lib/fog/storage/requests/rackspace/get_object.rb +1 -1
  59. data/lib/fog/storage/requests/rackspace/head_container.rb +1 -1
  60. data/lib/fog/storage/requests/rackspace/head_object.rb +2 -2
  61. data/lib/fog/storage/requests/rackspace/put_container.rb +1 -1
  62. data/lib/fog/storage/requests/rackspace/put_object.rb +1 -1
  63. data/spec/spec_helper.rb +0 -4
  64. data/tests/aws/requests/cloud_formation/stack_tests.rb +16 -5
  65. data/tests/aws/requests/rds/instance_tests.rb +4 -2
  66. data/tests/compute/models/aws/address_tests.rb +16 -0
  67. data/tests/compute/models/aws/addresses_tests.rb +5 -0
  68. data/tests/compute/models/aws/key_pair_tests.rb +27 -0
  69. data/tests/compute/models/aws/key_pairs_tests.rb +5 -0
  70. data/tests/compute/models/aws/security_group_tests.rb +5 -0
  71. data/tests/compute/models/aws/security_groups.rb +5 -0
  72. data/tests/compute/models/aws/server_tests.rb +39 -0
  73. data/tests/compute/models/aws/snapshot_tests.rb +10 -0
  74. data/tests/compute/models/aws/snapshots_tests.rb +10 -0
  75. data/tests/compute/models/aws/volume_tests.rb +26 -0
  76. data/tests/compute/models/aws/volumes_tests.rb +5 -0
  77. data/tests/core/credential_tests.rb +36 -0
  78. data/tests/storage/requests/aws/object_tests.rb +1 -1
  79. data/tests/storage/requests/google/object_tests.rb +1 -1
  80. data/tests/storage/requests/rackspace/object_tests.rb +8 -0
  81. metadata +118 -75
  82. data/spec/aws/models/compute/address_spec.rb +0 -103
  83. data/spec/aws/models/compute/addresses_spec.rb +0 -70
  84. data/spec/aws/models/compute/key_pair_spec.rb +0 -86
  85. data/spec/aws/models/compute/key_pairs_spec.rb +0 -71
  86. data/spec/aws/models/compute/security_group_spec.rb +0 -88
  87. data/spec/aws/models/compute/security_groups_spec.rb +0 -71
  88. data/spec/aws/models/compute/server_spec.rb +0 -105
  89. data/spec/aws/models/compute/snapshot_spec.rb +0 -79
  90. data/spec/aws/models/compute/snapshots_spec.rb +0 -85
  91. data/spec/aws/models/compute/volume_spec.rb +0 -174
  92. data/spec/aws/models/compute/volumes_spec.rb +0 -71
  93. data/tests/compute/models/aws/server_monitor_tests.rb +0 -47
@@ -31,10 +31,28 @@ module Fog
31
31
  new_attributes = data.reject {|key,value| !['keyFingerprint', 'keyMaterial', 'keyName'].include?(key)}
32
32
  merge_attributes(new_attributes)
33
33
  true
34
+
35
+ end
36
+
37
+ def write(path="#{ENV['HOME']}/.ssh/fog_#{Fog.credential.to_s}_#{name}.pem")
38
+
39
+ if writable?
40
+ split_private_key = private_key.split(/\n/)
41
+ File.open(path, "w") do |f|
42
+ split_private_key.each {|line| f.puts line}
43
+ f.chmod 0600
44
+ end
45
+ "Key file built: #{path}"
46
+ else
47
+ "Invalid private key"
48
+ end
34
49
  end
35
50
 
36
- private
51
+ def writable?
52
+ !!(private_key && ENV.has_key?('HOME'))
53
+ end
37
54
 
55
+ private
38
56
  end
39
57
 
40
58
  end
@@ -82,7 +82,7 @@ module Fog
82
82
  def key_pair
83
83
  requires :key_name
84
84
 
85
- connection.keypairs.all(key_name).first
85
+ connection.key_pairs.all(key_name).first
86
86
  end
87
87
 
88
88
  def key_pair=(new_keypair)
@@ -218,24 +218,18 @@ module Fog
218
218
  #I tried to call it monitoring= and be smart with attributes[]
219
219
  #but in #save a merge_attribute is called after run_instance
220
220
  #thus making an un-necessary request. Use this until finding a clever solution
221
- def monitor=(boolean)
222
-
223
- #we don't have a server yet. the status silently goes in the attributes for run_instances
224
- if !identity
225
- self.monitoring=boolean
226
- end
227
-
228
- case boolean
221
+ def monitor=(new_monitor)
222
+ if identity
223
+ case new_monitor
229
224
  when true
230
225
  response = connection.monitor_instances(identity)
231
226
  when false
232
227
  response = connection.unmonitor_instances(identity)
233
228
  else
234
229
  raise ArgumentError.new("only Boolean allowed here")
230
+ end
235
231
  end
236
-
237
- #set the attribute, there is only one instance_id here
238
- response.body['instancesSet'][0]['monitoring'] == 'enabled' ? self.monitoring=true : self.monitoring=false
232
+ self.monitoring = new_monitor
239
233
  end
240
234
 
241
235
  end
@@ -61,7 +61,7 @@ module Fog
61
61
  end
62
62
 
63
63
  def public_ip_address
64
- addresses.first
64
+ addresses['public'].first
65
65
  end
66
66
 
67
67
  def public_key_path
@@ -98,8 +98,8 @@ module Fog
98
98
  end
99
99
 
100
100
  def setup(credentials = {})
101
- requires :addresses, :identity, :public_key, :username
102
- Fog::SSH.new(addresses['public'].first, username, credentials).run([
101
+ requires :public_ip_address, :identity, :public_key, :username
102
+ Fog::SSH.new(public_ip_address, username, credentials).run([
103
103
  %{mkdir .ssh},
104
104
  %{echo "#{public_key}" >> ~/.ssh/authorized_keys},
105
105
  %{passwd -l #{username}},
@@ -112,19 +112,19 @@ module Fog
112
112
  end
113
113
 
114
114
  def ssh(commands)
115
- requires :addresses, :identity, :username
115
+ requires :public_ip_address, :identity, :username
116
116
 
117
117
  options = {}
118
118
  options[:key_data] = [private_key] if private_key
119
- Fog::SSH.new(addresses['public'].first, username, options).run(commands)
119
+ Fog::SSH.new(public_ip_address, username, options).run(commands)
120
120
  end
121
121
 
122
122
  def scp(local_path, remote_path)
123
- requires :addresses, :username
123
+ requires :public_ip_address, :username
124
124
 
125
125
  options = {}
126
126
  options[:key_data] = [private_key] if private_key
127
- Fog::SCP.new(addresses['public'].first, username, options).upload(local_path, remote_path)
127
+ Fog::SCP.new(public_ip_address, username, options).upload(local_path, remote_path)
128
128
  end
129
129
 
130
130
  def username
@@ -43,6 +43,10 @@ module Fog
43
43
  instance = @data[:instances][instance_id]
44
44
  volume = @data[:volumes][volume_id]
45
45
  if instance && volume
46
+ unless volume['status'] == 'available'
47
+ raise Fog::AWS::Compute::Error.new("Client.VolumeInUse => Volume #{volume_id} is unavailable")
48
+ end
49
+
46
50
  data = {
47
51
  'attachTime' => Time.now,
48
52
  'device' => device,
@@ -20,7 +20,7 @@ module Fog
20
20
  request(
21
21
  'Action' => 'CreateSecurityGroup',
22
22
  'GroupName' => name,
23
- 'GroupDescription' => CGI.escape(description),
23
+ 'GroupDescription' => description,
24
24
  :parser => Fog::Parsers::AWS::Compute::Basic.new
25
25
  )
26
26
  end
@@ -33,8 +33,8 @@ module Fog
33
33
  response = Excon::Response.new
34
34
  unless @data[:security_groups][name]
35
35
  data = {
36
- 'groupDescription' => CGI.escape(description).gsub('%20', '+'),
37
- 'groupName' => CGI.escape(name).gsub('%20', '+'),
36
+ 'groupDescription' => description,
37
+ 'groupName' => name,
38
38
  'ipPermissions' => [],
39
39
  'ownerId' => @owner_id
40
40
  }
@@ -62,6 +62,8 @@ module Fog
62
62
  @data[:tags][key] ||= {}
63
63
  @data[:tags][key][value] ||= []
64
64
  @data[:tags][key][value] = @data[:tags][key][value] & tagged
65
+
66
+ tagged.each {|resource| @data[:"#{resource['resourceType']}s"][resource['resourceId']]['tagSet'][key] = value}
65
67
  end
66
68
 
67
69
  response = Excon::Response.new
@@ -38,6 +38,10 @@ module Fog
38
38
  def create_volume(availability_zone, size, snapshot_id = nil)
39
39
  response = Excon::Response.new
40
40
  if availability_zone && size
41
+ if snapshot_id && !@data[:snapshots][snapshot_id]
42
+ raise Fog::AWS::Compute::NotFound.new("The snapshot '#{snapshot_id}' does not exist.")
43
+ end
44
+
41
45
  response.status = 200
42
46
  volume_id = Fog::AWS::Mock.volume_id
43
47
  data = {
@@ -37,6 +37,49 @@ module Fog
37
37
  end
38
38
 
39
39
  end
40
+
41
+ class Mock
42
+ def delete_tags(resources, tags)
43
+ tagged = resources.map do |resource_id|
44
+ type = case resource_id
45
+ when /^ami\-[a-z0-9]{8}$/i
46
+ 'image'
47
+ when /^i\-[a-z0-9]{8}$/i
48
+ 'instance'
49
+ when /^snap\-[a-z0-9]{8}$/i
50
+ 'snapshot'
51
+ when /^vol\-[a-z0-9]{8}$/i
52
+ 'volume'
53
+ end
54
+ if type && @data[:"#{type}s"][resource_id]
55
+ { 'resourceId' => resource_id, 'resourceType' => type }
56
+ else
57
+ raise(Fog::Service::NotFound.new("The #{type} ID '#{resource_id}' does not exist"))
58
+ end
59
+ end
60
+
61
+ tags.each do |key, value|
62
+ @data[:tags][key][value] = @data[:tags][key][value] - tagged
63
+ end
64
+
65
+ tagged.each do |resource|
66
+ object = @data[:"#{resource['resourceType']}s"][resource['resourceId']]
67
+ tags.each do |key, value|
68
+ tagset = object['tagSet']
69
+ tagset.delete(key) if tagset.has_key?(key) && (value.nil? || tagset[key] == value)
70
+ end
71
+ end
72
+
73
+ response = Excon::Response.new
74
+ response.status = true
75
+ response.body = {
76
+ 'requestId' => Fog::AWS::Mock.request_id,
77
+ 'return' => true
78
+ }
79
+ response
80
+ end
81
+ end
82
+
40
83
  end
41
84
  end
42
85
  end
@@ -74,20 +74,16 @@ module Fog
74
74
  filters = {'instance-id' => [*filters]}
75
75
  end
76
76
 
77
- if filters.keys.any? {|key| key =~ /^tag/}
78
- Formatador.display_line("[yellow][WARN] describe_instances tag filters are not yet mocked[/] [light_black](#{caller.first})[/]")
79
- Fog::Mock.not_implemented
80
- end
81
-
82
77
  response = Excon::Response.new
83
78
 
84
79
  instance_set = @data[:instances].values
85
-
80
+ instance_set = apply_tag_filters(instance_set, filters)
81
+
86
82
  aliases = {
87
83
  'architecture' => 'architecture',
88
84
  'availability-zone' => 'availabilityZone',
89
85
  'client-token' => 'clientToken',
90
- 'dns-token' => 'dnsName',
86
+ 'dns-name' => 'dnsName',
91
87
  'group-id' => 'groupId',
92
88
  'image-id' => 'imageId',
93
89
  'instance-id' => 'instanceId',
@@ -59,11 +59,6 @@ module Fog
59
59
  Formatador.display_line("[yellow][WARN] describe_snapshots with a second param is deprecated, use describe_snapshots(options) instead[/] [light_black](#{caller.first})[/]")
60
60
  end
61
61
 
62
- if filters.keys.any? {|key| key =~ /^tag/}
63
- Formatador.display_line("[yellow][WARN] describe_snapshots tag filters are not yet mocked[/] [light_black](#{caller.first})[/]")
64
- Fog::Mock.not_implemented
65
- end
66
-
67
62
  response = Excon::Response.new
68
63
 
69
64
  snapshot_set = @data[:snapshots].values
@@ -75,6 +70,8 @@ module Fog
75
70
  Formatador.display_line("[yellow][WARN] describe_snapshots with RestorableBy is not mocked[/] [light_black](#{caller.first})[/]")
76
71
  end
77
72
 
73
+ snapshot_set = apply_tag_filters(snapshot_set, filters)
74
+
78
75
  aliases = {
79
76
  'description' => 'description',
80
77
  'owner-id' => 'ownerId',
@@ -85,11 +82,12 @@ module Fog
85
82
  'volume-id' => 'volumeId',
86
83
  'volume-size' => 'volumeSize'
87
84
  }
85
+
88
86
  for filter_key, filter_value in filters
89
87
  aliased_key = aliases[filter_key]
90
88
  snapshot_set = snapshot_set.reject{|snapshot| ![*filter_value].include?(snapshot[aliased_key])}
91
89
  end
92
-
90
+
93
91
  snapshot_set.each do |snapshot|
94
92
  case snapshot['status']
95
93
  when 'in progress', 'pending'
@@ -50,15 +50,11 @@ module Fog
50
50
  filters = {'volume-id' => [*filters]}
51
51
  end
52
52
 
53
- if filters.keys.any? {|key| key =~ /^tag/}
54
- Formatador.display_line("[yellow][WARN] describe_volumes tag filters are not yet mocked[/] [light_black](#{caller.first})[/]")
55
- Fog::Mock.not_implemented
56
- end
57
-
58
53
  response = Excon::Response.new
59
54
 
60
55
  volume_set = @data[:volumes].values
61
-
56
+ volume_set = apply_tag_filters(volume_set, filters)
57
+
62
58
  aliases = {
63
59
  'availability-zone' => 'availabilityZone',
64
60
  'create-time' => 'createTime',
@@ -8,6 +8,7 @@ $LOAD_PATH.unshift __LIB_DIR__ unless
8
8
  require 'rubygems'
9
9
  require 'base64'
10
10
  require 'cgi'
11
+ require 'uri'
11
12
  require 'excon'
12
13
  require 'fileutils'
13
14
  require 'formatador'
@@ -13,7 +13,7 @@ module Fog
13
13
  unless block_given?
14
14
  if (parser = params.delete(:parser))
15
15
  body = Nokogiri::XML::SAX::PushParser.new(parser)
16
- block = lambda { |chunk| body << chunk }
16
+ block = lambda { |chunk, remaining, total| body << chunk }
17
17
  end
18
18
  end
19
19
 
@@ -18,7 +18,10 @@ module Fog
18
18
 
19
19
  # @return [String] The path for configuration_file
20
20
  def self.credentials_path
21
- @credential_path ||= File.expand_path(ENV["FOG_RC"] || (ENV['HOME'] && '~/.fog'))
21
+ @credential_path ||= begin
22
+ path = ENV["FOG_RC"] || (ENV['HOME'] && '~/.fog')
23
+ File.expand_path(path) if path
24
+ end
22
25
  end
23
26
 
24
27
  # @return [String] The new path for credentials file
@@ -85,6 +88,7 @@ An alternate file may be used by placing its path in the FOG_RC environment vari
85
88
  :rackspace_api_key:
86
89
  :rackspace_username:
87
90
  :rackspace_servicenet:
91
+ :rackspace_cdn_ssl:
88
92
  :slicehost_password:
89
93
  :terremark_username:
90
94
  :terremark_password:
@@ -15,8 +15,7 @@ module Fog
15
15
  end
16
16
 
17
17
  def characters(string)
18
- @value ||= ''
19
- @value << string.strip
18
+ @value = string
20
19
  end
21
20
 
22
21
  def start_element(name, attrs = [])
@@ -51,11 +51,10 @@ module Fog
51
51
  begin
52
52
  Net::SSH.start(@address, @username, @options) do |ssh|
53
53
  commands.each do |command|
54
- escaped_command = command.sub(/'/, %{'"'"'})
55
- result = Result.new(escaped_command)
54
+ result = Result.new(command)
56
55
  ssh.open_channel do |ssh_channel|
57
56
  ssh_channel.request_pty
58
- ssh_channel.exec(%{bash -lc '#{escaped_command}'}) do |channel, success|
57
+ ssh_channel.exec(command) do |channel, success|
59
58
  unless success
60
59
  raise "Could not execute command: #{command.inspect}"
61
60
  end
@@ -16,7 +16,7 @@ module Fog
16
16
  attribute :created_at, :aliases => ['SubmittedAt']
17
17
 
18
18
  def initialize(attributes={})
19
- self.ttl ||= 3600
19
+ self.ttl ||= 3600
20
20
  super
21
21
  end
22
22
 
@@ -19,6 +19,7 @@ module Fog
19
19
  attribute :minimum
20
20
 
21
21
  def initialize(attributes = {})
22
+ self.ttl ||= 3600
22
23
  super(attributes)
23
24
  end
24
25
 
@@ -38,7 +38,13 @@ module Fog
38
38
  requires :key
39
39
  @public_url ||= begin
40
40
  begin response = connection.cdn.head_container(key)
41
- response.headers['X-CDN-Enabled'] == 'True' && response.headers['X-CDN-URI']
41
+ if response.headers['X-CDN-Enabled'] == 'True'
42
+ if connection.rackspace_cdn_ssl == true
43
+ response.headers['X-CDN-SSL-URI']
44
+ else
45
+ response.headers['X-CDN-URI']
46
+ end
47
+ end
42
48
  rescue Fog::Service::NotFound
43
49
  nil
44
50
  end
@@ -56,7 +62,7 @@ module Fog
56
62
  end
57
63
  true
58
64
  end
59
-
65
+
60
66
  end
61
67
 
62
68
  end
@@ -3,7 +3,7 @@ module Fog
3
3
  class Storage < Fog::Service
4
4
 
5
5
  requires :rackspace_api_key, :rackspace_username
6
- recognizes :rackspace_auth_url, :rackspace_servicenet, :persistent
6
+ recognizes :rackspace_auth_url, :rackspace_servicenet, :rackspace_cdn_ssl, :persistent
7
7
  recognizes :provider # remove post deprecation
8
8
 
9
9
  model_path 'fog/storage/models/rackspace'
@@ -68,6 +68,7 @@ module Fog
68
68
 
69
69
  class Real
70
70
  include Utils
71
+ attr_reader :rackspace_cdn_ssl
71
72
 
72
73
  def initialize(options={})
73
74
  unless options.delete(:provider)
@@ -81,6 +82,7 @@ module Fog
81
82
  require 'json'
82
83
  @rackspace_api_key = options[:rackspace_api_key]
83
84
  @rackspace_username = options[:rackspace_username]
85
+ @rackspace_cdn_ssl = options[:rackspace_cdn_ssl]
84
86
  credentials = Fog::Rackspace.authenticate(options)
85
87
  @auth_token = credentials['X-Auth-Token']
86
88
 
@@ -12,7 +12,7 @@ module Fog
12
12
  response = request(
13
13
  :expects => 204,
14
14
  :method => 'DELETE',
15
- :path => CGI.escape(name)
15
+ :path => URI.escape(name)
16
16
  )
17
17
  response
18
18
  end
@@ -13,7 +13,7 @@ module Fog
13
13
  response = request(
14
14
  :expects => 204,
15
15
  :method => 'DELETE',
16
- :path => "#{CGI.escape(container)}/#{CGI.escape(object)}"
16
+ :path => "#{URI.escape(container)}/#{URI.escape(object)}"
17
17
  )
18
18
  response
19
19
  end