deltacloud-core 1.0.5 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) hide show
  1. data/Rakefile +10 -2
  2. data/bin/deltacloudd +10 -10
  3. data/config.ru +2 -1
  4. data/config/drivers/digitalocean.yaml +3 -0
  5. data/deltacloud-core.gemspec +13 -6
  6. data/lib/cimi/collections.rb +1 -1
  7. data/lib/cimi/collections/address_templates.rb +27 -3
  8. data/lib/cimi/collections/addresses.rb +1 -1
  9. data/lib/cimi/collections/base.rb +1 -0
  10. data/lib/cimi/collections/cloud_entry_point.rb +4 -0
  11. data/lib/cimi/collections/credentials.rb +2 -2
  12. data/lib/cimi/collections/machine_images.rb +20 -0
  13. data/lib/cimi/collections/machine_templates.rb +72 -0
  14. data/lib/cimi/collections/machines.rb +50 -41
  15. data/lib/cimi/collections/network_ports.rb +3 -3
  16. data/lib/cimi/collections/networks.rb +4 -4
  17. data/lib/cimi/collections/resource_metadata.rb +1 -1
  18. data/lib/cimi/collections/volume_configurations.rb +25 -0
  19. data/lib/cimi/collections/volume_images.rb +21 -1
  20. data/lib/cimi/collections/volume_templates.rb +69 -0
  21. data/lib/cimi/collections/volumes.rb +5 -10
  22. data/lib/cimi/dependencies.rb +0 -1
  23. data/lib/cimi/helpers.rb +4 -1
  24. data/lib/cimi/helpers/cimi_helper.rb +62 -0
  25. data/lib/cimi/helpers/database_helper.rb +95 -0
  26. data/lib/cimi/models.rb +15 -1
  27. data/lib/cimi/models/address.rb +10 -5
  28. data/lib/cimi/models/address_template.rb +67 -3
  29. data/lib/cimi/models/base.rb +8 -5
  30. data/lib/cimi/models/cloud_entry_point.rb +6 -1
  31. data/lib/cimi/models/collection.rb +9 -4
  32. data/lib/cimi/models/disk.rb +6 -1
  33. data/lib/cimi/models/errors.rb +8 -0
  34. data/lib/cimi/models/machine.rb +68 -42
  35. data/lib/cimi/models/machine_configuration.rb +2 -2
  36. data/lib/cimi/models/machine_image.rb +41 -6
  37. data/lib/cimi/models/machine_template.rb +58 -0
  38. data/lib/cimi/models/machine_volume.rb +51 -3
  39. data/lib/cimi/models/resource_metadata.rb +88 -25
  40. data/lib/cimi/models/schema.rb +19 -5
  41. data/lib/cimi/models/volume.rb +66 -30
  42. data/lib/cimi/models/volume_configuration.rb +53 -21
  43. data/lib/cimi/models/volume_image.rb +24 -9
  44. data/lib/cimi/models/volume_template.rb +61 -0
  45. data/lib/cimi/server.rb +0 -6
  46. data/lib/db.rb +82 -0
  47. data/lib/db/address_template.rb +15 -0
  48. data/lib/db/entity.rb +22 -0
  49. data/lib/db/machine_template.rb +10 -0
  50. data/lib/db/provider.rb +13 -0
  51. data/lib/db/volume_configuration.rb +10 -0
  52. data/lib/db/volume_template.rb +10 -0
  53. data/lib/deltacloud/collections/addresses.rb +1 -1
  54. data/lib/deltacloud/collections/base.rb +12 -1
  55. data/lib/deltacloud/collections/buckets.rb +41 -8
  56. data/lib/deltacloud/collections/drivers.rb +1 -1
  57. data/lib/deltacloud/collections/firewalls.rb +2 -2
  58. data/lib/deltacloud/collections/images.rb +1 -1
  59. data/lib/deltacloud/collections/instances.rb +7 -1
  60. data/lib/deltacloud/collections/keys.rb +1 -1
  61. data/lib/deltacloud/collections/load_balancers.rb +4 -4
  62. data/lib/deltacloud/collections/storage_snapshots.rb +5 -1
  63. data/lib/deltacloud/collections/storage_volumes.rb +7 -3
  64. data/lib/deltacloud/drivers/base_driver.rb +10 -9
  65. data/lib/deltacloud/drivers/cimi_features.rb +42 -0
  66. data/lib/deltacloud/drivers/digitalocean/digitalocean_driver.rb +307 -0
  67. data/lib/deltacloud/drivers/ec2/ec2_driver.rb +40 -14
  68. data/lib/deltacloud/drivers/exceptions.rb +8 -0
  69. data/lib/deltacloud/drivers/features.rb +19 -2
  70. data/lib/deltacloud/drivers/fgcp/fgcp_client.rb +11 -0
  71. data/lib/deltacloud/drivers/fgcp/fgcp_driver.rb +83 -11
  72. data/lib/deltacloud/drivers/gogrid/gogrid_client.rb +1 -1
  73. data/lib/deltacloud/drivers/mock/mock_client.rb +2 -4
  74. data/lib/deltacloud/drivers/mock/mock_driver.rb +29 -0
  75. data/lib/deltacloud/drivers/openstack/openstack_driver.rb +153 -36
  76. data/lib/deltacloud/drivers/rackspace/anti_cache_monkey_patch.rb +20 -0
  77. data/lib/deltacloud/drivers/rackspace/rackspace_driver.rb +1 -0
  78. data/lib/deltacloud/drivers/rhevm/rhevm_driver.rb +30 -12
  79. data/lib/deltacloud/drivers/sbc/sbc_client.rb +0 -1
  80. data/lib/deltacloud/drivers/sbc/sbc_driver.rb +5 -1
  81. data/lib/deltacloud/drivers/vsphere/vsphere_client.rb +1 -1
  82. data/lib/deltacloud/drivers/vsphere/vsphere_driver.rb +19 -9
  83. data/lib/deltacloud/helpers/blob_stream_helper.rb +42 -3
  84. data/lib/deltacloud/helpers/deltacloud_helper.rb +31 -14
  85. data/lib/deltacloud/models/address.rb +9 -0
  86. data/lib/deltacloud/models/base_model.rb +4 -0
  87. data/lib/deltacloud/models/blob.rb +12 -0
  88. data/lib/deltacloud/models/bucket.rb +9 -0
  89. data/lib/deltacloud/models/firewall.rb +13 -1
  90. data/lib/deltacloud/models/firewall_rule.rb +14 -0
  91. data/lib/deltacloud/models/hardware_profile.rb +14 -0
  92. data/lib/deltacloud/models/image.rb +15 -0
  93. data/lib/deltacloud/models/instance.rb +40 -1
  94. data/lib/deltacloud/models/instance_address.rb +9 -0
  95. data/lib/deltacloud/models/key.rb +15 -0
  96. data/lib/deltacloud/models/load_balancer.rb +20 -0
  97. data/lib/deltacloud/models/metric.rb +15 -0
  98. data/lib/deltacloud/models/provider.rb +8 -0
  99. data/lib/deltacloud/models/realm.rb +9 -0
  100. data/lib/deltacloud/models/state_machine.rb +8 -0
  101. data/lib/deltacloud/models/storage_snapshot.rb +11 -0
  102. data/lib/deltacloud/models/storage_volume.rb +24 -0
  103. data/lib/deltacloud/server.rb +1 -3
  104. data/lib/deltacloud/version.rb +2 -1
  105. data/lib/deltacloud_rack.rb +1 -1
  106. data/tests/cimi/db/database_helper_test.rb +190 -0
  107. data/tests/cimi/db/db_helper.rb +30 -0
  108. data/tests/cimi/db/schema_test.rb +94 -0
  109. data/tests/cimi/model/collection_spec.rb +0 -1
  110. data/tests/cimi/model/machine_spec.rb +17 -0
  111. data/tests/cimi/spec_helper.rb +3 -2
  112. data/tests/deltacloud/collections/buckets_collection_test.rb +3 -0
  113. data/tests/deltacloud/collections/drivers_collection_test.rb +10 -0
  114. data/tests/deltacloud/collections/hardware_profiles_collection_test.rb +4 -0
  115. data/tests/deltacloud/collections/images_collection_test.rb +4 -0
  116. data/tests/deltacloud/collections/instances_collection_test.rb +14 -1
  117. data/tests/deltacloud/collections/keys_collection_test.rb +4 -0
  118. data/tests/deltacloud/collections/realms_collection_test.rb +47 -0
  119. data/tests/deltacloud/collections/storage_snapshots_collection_test.rb +47 -0
  120. data/tests/deltacloud/collections/storage_volumes_collection_test.rb +47 -0
  121. data/tests/deltacloud/common.rb +15 -0
  122. data/tests/deltacloud/deltacloud_helper_test.rb +0 -4
  123. data/tests/deltacloud/launcher_test.rb +108 -0
  124. data/tests/drivers/ec2/buckets_test.rb +2 -1
  125. data/tests/drivers/mock/buckets_test.rb +27 -0
  126. data/tests/drivers/mock/instances_test.rb +6 -0
  127. data/tests/drivers/openstack/common.rb +1 -1
  128. data/tests/drivers/openstack/hardware_profiles_test.rb +2 -1
  129. data/tests/drivers/openstack/instances_test.rb +18 -17
  130. data/tests/drivers/rhevm/common.rb +1 -0
  131. data/tests/drivers/rhevm/images_test.rb +1 -1
  132. data/tests/drivers/rhevm/instance_test.rb +7 -7
  133. data/tests/helpers/rack/rack_matrix_params_test.rb +0 -2
  134. data/tests/test_helper.rb +2 -1
  135. data/views/errors/403.xml.haml +6 -0
  136. data/views/errors/409.html.haml +47 -0
  137. data/views/errors/409.xml.haml +11 -0
  138. data/views/errors/502.html.haml +6 -5
  139. data/views/images/show.xml.haml +3 -2
  140. data/views/instances/new.html.haml +1 -1
  141. metadata +77 -30
data/Rakefile CHANGED
@@ -128,7 +128,14 @@ task :routes do
128
128
  Rake::Task['deltacloud:routes'].invoke
129
129
  end
130
130
 
131
- DRIVERS = [:mock, :ec2, :rhevm, :google, :gogrid, :openstack]
131
+ # TODO: The 'google' driver tests are failing under jRuby
132
+ # need to investigate in future.
133
+ #
134
+ if RUBY_PLATFORM == 'java'
135
+ DRIVERS = [:mock, :ec2, :rhevm, :gogrid, :openstack]
136
+ else
137
+ DRIVERS = [:mock, :ec2, :rhevm, :google, :gogrid, :openstack]
138
+ end
132
139
 
133
140
  desc 'Run all tests'
134
141
  task :test do
@@ -160,7 +167,7 @@ namespace :test do
160
167
 
161
168
  DRIVERS.each do |driver|
162
169
  Rake::TestTask.new(driver) do |t|
163
- t.ruby_opts << '-r./tests/test_helper.rb' # Load SimpleCov when COVERAGE=1 is set
170
+ #t.ruby_opts << '-r./tests/test_helper.rb' # Load SimpleCov when COVERAGE=1 is set
164
171
  unless RUBY_VERSION < '1.9.0'
165
172
  t.loader = :testrb
166
173
  end
@@ -199,6 +206,7 @@ namespace :test do
199
206
  t.loader = :testrb
200
207
  end
201
208
  t.test_files = FileList[
209
+ 'tests/cimi/db/*test.rb', # CIMI frontend database tests
202
210
  'tests/cimi/model/*spec.rb', # CIMI frontend serialization API tests
203
211
  'tests/cimi/collections/*test.rb', # CIMI frontend API tests
204
212
  ]
@@ -85,7 +85,7 @@ BANNER
85
85
  opts.on( '-V', '--verbose', 'Set verbose logging on') do |verbose|
86
86
  ENV["API_VERBOSE"] ||= 'true'
87
87
  end
88
- opts.on( nil, '--webrick', 'Force the use of WEBRick as a server') do |opt|
88
+ opts.on( '-w', '--webrick', 'Force the use of WEBRick as a server') do |opt|
89
89
  options[:webrick] = true
90
90
  end
91
91
  opts.on('--logdir LOGDIR', "Directory for log files, defaults to #{options[:logdir]}") do |opt|
@@ -165,7 +165,10 @@ end
165
165
  ENV["API_HOST"] = "localhost" unless ENV["API_HOST"]
166
166
  ENV["API_PORT"] = "3001" unless ENV["API_PORT"]
167
167
 
168
- unless options[:daemon]
168
+ have_thin = options[:webrick].nil? && library_present?('thin')
169
+ have_rerun = library_present?('rerun')
170
+
171
+ if !options[:daemon] || options[:daemon] && !have_thin
169
172
  msg = "Starting Deltacloud API :: #{ENV["API_DRIVER"]} "
170
173
  msg << ":: #{ENV['API_PROVIDER']} " if ENV['API_PROVIDER']
171
174
  api_uri = ENV['API_FRONTEND'] == 'cimi' ? 'cimi/cloudEntryPoint' : 'api'
@@ -184,12 +187,11 @@ if ENV['API_USER'] && ENV['API_PASSWORD']
184
187
  puts
185
188
  end
186
189
 
187
- have_thin = options[:webrick].nil? && library_present?('thin')
188
- have_rerun = library_present?('rerun')
189
-
190
190
  unless have_thin
191
191
  require 'rack'
192
192
 
193
+ puts "To start Deltacloud as a daemon, install 'thin' (gem install thin)\n\n" if options[:daemon]
194
+
193
195
  # Read in config.ru and convert it to an instance of Rack::Builder
194
196
  cfgfile = File.read(File.join($top_srcdir, 'config.ru'))
195
197
  inner_app = eval("Rack::Builder.new {(" + cfgfile + "\n )}.to_app",
@@ -197,19 +199,17 @@ unless have_thin
197
199
 
198
200
  app = Rack::Builder.new {
199
201
  use Rack::CommonLogger # apache-like logging
200
- use Rack::Reloader if options[:env] == "development"
201
- unless RUBY_PLATFORM == 'java'
202
- set :root, $top_srcdir # Set Sinatra root since we can't chdir to ../
203
- end
202
+ use Rack::Reloader #if options[:env] == "development"
204
203
  run inner_app
205
204
  }.to_app
206
205
 
207
206
  # There's a bug with string ports on JRuby so convert to int
208
207
  # http://jira.codehaus.org/browse/JRUBY-4868
209
208
  port = ENV["API_PORT"].to_i
210
-
211
209
  puts "=> Ctrl-C to shutdown server"
210
+ Dir::chdir($top_srcdir)
212
211
  Rack::Server::start(:app => app,
212
+ :server => :webrick,
213
213
  :Host => ENV["API_HOST"],
214
214
  :Port => port,
215
215
  :AccessLog => [])
data/config.ru CHANGED
@@ -30,7 +30,7 @@ end
30
30
 
31
31
  Deltacloud::configure(:cimi) do |server|
32
32
  server.root_url '/cimi'
33
- server.version Deltacloud::API_VERSION
33
+ server.version Deltacloud::CIMI_API_VERSION
34
34
  server.klass 'CIMI::API'
35
35
  end
36
36
 
@@ -54,6 +54,7 @@ end
54
54
  # different root_url's
55
55
  #
56
56
  frontends.each do |frontend|
57
+ frontend = frontend.strip
57
58
  if Deltacloud[frontend.to_sym].nil?
58
59
  puts "ERROR: Unknown frontend (#{frontend}). Valid values are 'deltacloud,cimi,ec2'"
59
60
  exit(1)
@@ -0,0 +1,3 @@
1
+ ---
2
+ :digitalocean:
3
+ :name: Digitalocean
@@ -14,7 +14,7 @@
14
14
  # License for the specific language governing permissions and limitations
15
15
  # under the License.
16
16
 
17
- Kernel::load File::join(File::dirname(__FILE__), './lib/deltacloud/version.rb')
17
+ require File::expand_path(File::join(File::dirname(__FILE__), './lib/deltacloud/version.rb'))
18
18
 
19
19
  Gem::Specification.new do |s|
20
20
  s.author = 'The Apache Software Foundation'
@@ -70,22 +70,29 @@ Gem::Specification.new do |s|
70
70
  s.add_dependency('haml', '>= 2.2.17')
71
71
  s.add_dependency('sinatra', '>= 1.3.0')
72
72
  s.add_dependency('sinatra-rabbit', '>= 1.0.11')
73
- s.add_dependency('crack')
74
73
  s.add_dependency('rack', '>= 1.0.0')
75
74
  s.add_dependency('rack-accept')
76
75
  s.add_dependency('json', '>= 1.1.9')
77
76
  s.add_dependency('net-ssh', '>= 2.0.0')
78
- s.add_dependency('thin', '>= 1.2.5') unless RUBY_PLATFORM == 'java'
79
77
  s.add_dependency('nokogiri', '>= 1.4.3')
80
78
  s.add_dependency('require_relative') if RUBY_VERSION < '1.9'
81
79
 
80
+ s.add_dependency('sequel', '<= 3.42.0')
81
+
82
+ if RUBY_PLATFORM == 'java'
83
+ s.add_dependency('jdbc-sqlite3')
84
+ else
85
+ s.add_dependency('sqlite3')
86
+ s.add_dependency('thin', '>= 1.2.5')
87
+ end
88
+
82
89
  # dependencies for various cloud providers:
83
90
 
84
91
  # RHEV-M and oVirt
85
- s.add_dependency('rbovirt', '>=0.0.13')
92
+ s.add_dependency('rbovirt', '>=0.0.16')
86
93
 
87
94
  # Amazon EC2 S3
88
- s.add_dependency('aws', '>=2.5.4')
95
+ s.add_dependency('aws', '>=2.6.0')
89
96
  # Microsoft Azure
90
97
  s.add_dependency('waz-storage', '>=1.1.0')
91
98
 
@@ -104,7 +111,7 @@ Gem::Specification.new do |s|
104
111
  s.add_dependency('uuidtools', '>= 2.1.1')
105
112
 
106
113
  # Openstack Compute and Object-Storage
107
- s.add_dependency('openstack', '>= 1.0.6')
114
+ s.add_dependency('openstack', '>= 1.0.7')
108
115
 
109
116
  # Aruba Cloud
110
117
  s.add_dependency('savon', '>= 1.0.0')
@@ -39,7 +39,7 @@ module CIMI
39
39
  Dir[File.join(File::dirname(__FILE__), "collections", "*.rb")].each do |collection|
40
40
  base_collection_name = File.basename(collection).gsub('.rb', '')
41
41
  next if base_collection_name == 'base'
42
- require_relative collection
42
+ require collection
43
43
  cimi_module_class = CIMI::Collections.const_get(base_collection_name.camelize)
44
44
  cimi_modules << cimi_module_class
45
45
  unless cimi_module_class.collections.nil?
@@ -16,11 +16,11 @@
16
16
  module CIMI::Collections
17
17
  class AddressTemplates < Base
18
18
 
19
- set :capability, lambda { |m| driver.respond_to? m }
19
+ set :capability, lambda { |t| true }
20
20
 
21
21
  collection :address_templates do
22
22
 
23
- operation :index, :with_capability => :address_templates do
23
+ operation :index do
24
24
  description 'List all AddressTemplates in the AddressTemplateCollection'
25
25
  control do
26
26
  address_templates = AddressTemplate.list(self).filter_by(params['$select'])
@@ -31,7 +31,7 @@ module CIMI::Collections
31
31
  end
32
32
  end
33
33
 
34
- operation :show, :with_capability => :address_templates do
34
+ operation :show do
35
35
  description 'Show a specific AddressTemplate'
36
36
  control do
37
37
  address_template = CIMI::Model::AddressTemplate.find(params[:id], self)
@@ -42,6 +42,30 @@ module CIMI::Collections
42
42
  end
43
43
  end
44
44
 
45
+ operation :create do
46
+ description "Create new AddressTemplate"
47
+ control do
48
+ if grab_content_type(request.content_type, request.body) == :json
49
+ new_address_template = CIMI::Model::AddressTemplate.create_from_json(request.body.read, self)
50
+ else
51
+ new_address_template = CIMI::Model::AddressTemplate.create_from_xml(request.body.read, self)
52
+ end
53
+ headers_for_create new_address_template
54
+ respond_to do |format|
55
+ format.json { new_address_template.to_json }
56
+ format.xml { new_address_template.to_xml }
57
+ end
58
+ end
59
+ end
60
+
61
+ operation :destroy do
62
+ description "Delete a specified AddressTemplate"
63
+ control do
64
+ CIMI::Model::AddressTemplate.delete!(params[:id], self)
65
+ no_content_with_status(200)
66
+ end
67
+ end
68
+
45
69
  end
46
70
 
47
71
  end
@@ -47,7 +47,7 @@ module CIMI::Collections
47
47
  operation :create, :with_capability => :create_address do
48
48
  description "Create a new Address"
49
49
  control do
50
- if request.content_type.end_with?("json")
50
+ if grab_content_type(request.content_type, request.body) == :json
51
51
  address = CIMI::Model::Address.create(request.body.read, self, :json)
52
52
  else
53
53
  address = CIMI::Model::Address.create(request.body.read, self, :xml)
@@ -23,6 +23,7 @@ module CIMI::Collections
23
23
  include CIMI::Model
24
24
 
25
25
  helpers Deltacloud::Helpers::Drivers
26
+ helpers Deltacloud::Helpers::Database
26
27
  helpers Sinatra::AuthHelper
27
28
  helpers Sinatra::Rabbit::URLHelper
28
29
  helpers Deltacloud::Helpers::Application
@@ -16,6 +16,10 @@
16
16
  module CIMI::Collections
17
17
  class CloudEntryPoint < Base
18
18
 
19
+ get '/' do
20
+ redirect url('/cloudEntryPoint'), 301
21
+ end
22
+
19
23
  collection :cloudEntryPoint do
20
24
  description 'Cloud entry point'
21
25
  operation :index do
@@ -46,12 +46,12 @@ module CIMI::Collections
46
46
  operation :create, :with_capability => :create_key do
47
47
  description "Show specific machine admin"
48
48
  control do
49
- if request.content_type.end_with?("json")
49
+ if grab_content_type(request.content_type, request.body) == :json
50
50
  new_admin = Credential.create_from_json(request.body.read, self)
51
51
  else
52
52
  new_admin = Credential.create_from_xml(request.body.read, self)
53
53
  end
54
- status 201 # Created
54
+ headers_for_create new_admin
55
55
  respond_to do |format|
56
56
  format.json { new_admin.to_json }
57
57
  format.xml { new_admin.to_xml }
@@ -43,6 +43,26 @@ module CIMI::Collections
43
43
  end
44
44
  end
45
45
 
46
+ operation :create, :with_capability => :create_image do
47
+ description "Create a new machine image."
48
+ control do
49
+ machine_image = CIMI::Model::MachineImage.create(request.body, self)
50
+ headers_for_create machine_image
51
+ respond_to do |format|
52
+ format.xml { machine_image.to_xml }
53
+ format.json { machine_image.to_json }
54
+ end
55
+ end
56
+ end
57
+
58
+ operation :destroy, :with_capability => :destroy_image do
59
+ description "Delete a specified MachineImage"
60
+ control do
61
+ CIMI::Model::MachineImage.delete!(params[:id], self)
62
+ no_content_with_status 200
63
+ end
64
+ end
65
+
46
66
  end
47
67
 
48
68
  end
@@ -0,0 +1,72 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright ownership. The
4
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the
6
+ # License. You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations
14
+ # under the License.
15
+
16
+ module CIMI::Collections
17
+ class MachineTemplates < Base
18
+
19
+ set :capability, lambda { |t| true }
20
+
21
+ collection :machine_templates do
22
+
23
+ operation :index do
24
+ description "List all machine templates"
25
+ control do
26
+ machine_templates = CIMI::Model::MachineTemplate.list(self).filter_by(params['$select'])
27
+ respond_to do |format|
28
+ format.xml { machine_templates.to_xml }
29
+ format.json { machine_templates.to_json }
30
+ end
31
+ end
32
+ end
33
+
34
+ operation :show do
35
+ description "Show specific machine template"
36
+ control do
37
+ machine_template = CIMI::Model::MachineTemplate.find(params[:id], self)
38
+ respond_to do |format|
39
+ format.xml { machine_template.to_xml }
40
+ format.json { machine_template.to_json }
41
+ end
42
+ end
43
+ end
44
+
45
+ operation :create do
46
+ description "Create new machine template"
47
+ control do
48
+ if grab_content_type(request.content_type, request.body) == :json
49
+ new_machine_template = CIMI::Model::MachineTemplate.create_from_json(request.body.read, self)
50
+ else
51
+ new_machine_template = CIMI::Model::MachineTemplate.create_from_xml(request.body.read, self)
52
+ end
53
+ headers_for_create new_machine_template
54
+ respond_to do |format|
55
+ format.json { new_machine_template.to_json }
56
+ format.xml { new_machine_template.to_xml }
57
+ end
58
+ end
59
+ end
60
+
61
+ operation :destroy do
62
+ description "Delete a specified machine template"
63
+ control do
64
+ CIMI::Model::MachineTemplate.delete!(params[:id], self)
65
+ no_content_with_status(200)
66
+ end
67
+ end
68
+
69
+ end
70
+
71
+ end
72
+ end
@@ -46,13 +46,12 @@ module CIMI::Collections
46
46
  operation :create, :with_capability => :create_instance do
47
47
  description "Create a new Machine entity."
48
48
  control do
49
- if request.content_type.end_with?("json")
49
+ if grab_content_type(request.content_type, request.body) == :json
50
50
  new_machine = Machine.create_from_json(request.body.read, self)
51
51
  else
52
52
  new_machine = Machine.create_from_xml(request.body.read, self)
53
53
  end
54
- status 201 # Created
55
- headers 'Location' => new_machine.id
54
+ headers_for_create new_machine
56
55
  respond_to do |format|
57
56
  format.json { new_machine.to_json }
58
57
  format.xml { new_machine.to_xml }
@@ -73,7 +72,7 @@ module CIMI::Collections
73
72
  param :id, :string, :required
74
73
  control do
75
74
  machine = Machine.find(params[:id], self)
76
- if request.content_type.end_with?("json")
75
+ if grab_content_type(request.content_type, request.body) == :json
77
76
  action = Action.from_json(request.body.read)
78
77
  else
79
78
  action = Action.from_xml(request.body.read)
@@ -85,15 +84,15 @@ module CIMI::Collections
85
84
  end
86
85
  end
87
86
 
88
- action :restart, :with_capability => :restart_instance do
87
+ action :restart, :with_capability => :reboot_instance do
89
88
  description "Start specific machine."
90
89
  param :id, :string, :required
91
90
  control do
92
91
  machine = Machine.find(params[:id], self)
93
- if request.content_type.end_with?("json")
94
- action = Action.from_json(request.body.read)
92
+ if grab_content_type(request.content_type, request.body) == :json
93
+ action = Action.from_json(request.body.read.gsub("restart", "reboot"))
95
94
  else
96
- action = Action.from_xml(request.body.read)
95
+ action = Action.from_xml(request.body.read.gsub("restart", "reboot"))
97
96
  end
98
97
  machine.perform(action, self) do |operation|
99
98
  no_content_with_status(202) if operation.success?
@@ -107,7 +106,7 @@ module CIMI::Collections
107
106
  param :id, :string, :required
108
107
  control do
109
108
  machine = Machine.find(params[:id], self)
110
- if request.content_type.end_with?("json")
109
+ if grab_content_type(request.content_type, request.body) == :json
111
110
  action = Action.from_json(request.body.read)
112
111
  else
113
112
  action = Action.from_xml(request.body.read)
@@ -131,54 +130,64 @@ module CIMI::Collections
131
130
  end
132
131
  end
133
132
 
134
- operation :volumes, :with_capability => :storage_volumes do
135
- description "Retrieve the Machine's MachineVolumeCollection"
136
- param :id, :string, :required
137
- control do
138
- volumes = MachineVolumeCollection.default(params[:id], self)
139
- respond_to do |format|
140
- format.json {volumes.to_json}
141
- format.xml {volumes.to_xml}
133
+ #use rabbit subcollections for volumes index/show:
134
+ collection :volumes, :with_id => :vol_id do
135
+
136
+ operation :index, :with_capability => :storage_volumes do
137
+ description "Retrieve the Machine's MachineVolumeCollection"
138
+ control do
139
+ volumes = CIMI::Model::MachineVolume.collection_for_instance(params[:id], self)
140
+ respond_to do |format|
141
+ format.json {volumes.to_json}
142
+ format.xml {volumes.to_xml}
143
+ end
142
144
  end
143
145
  end
144
- end
145
146
 
146
- #NOTE: The routes for attach/detach used here are NOT as specified by CIMI
147
- #will likely move later. CIMI specifies PUT of the whole Machine description
148
- #with inclusion/ommission of the volumes you want [att|det]ached
149
- action :attach_volume, :http_method => :put, :with_capability => :attach_storage_volume do
150
- description "Attach CIMI Volume(s) to a machine."
151
- param :id, :string, :required
152
- control do
153
- if request.content_type.end_with?("json")
154
- volumes_to_attach = Volume.find_to_attach_from_json(request.body.read, self)
155
- else
156
- volumes_to_attach = Volume.find_to_attach_from_xml(request.body.read, self)
147
+ operation :show, :with_capability => :storage_volumes do
148
+ description "Retrieve a Machine's specific MachineVolume"
149
+ control do
150
+ volume = CIMI::Model::MachineVolume.find(params[:id], self, params[:vol_id])
151
+ respond_to do |format|
152
+ format.json {volume.to_json}
153
+ format.xml {volume.to_xml}
154
+ end
157
155
  end
158
- machine = Machine.attach_volumes(volumes_to_attach, self)
159
- respond_to do |format|
160
- format.json{ machine.to_json}
161
- format.xml{machine.to_xml}
156
+ end
157
+
158
+ operation :destroy, :with_capability => :detach_storage_volume do
159
+ description "Remove/detach a volume from the Machine's MachineVolumeCollection"
160
+ control do
161
+ machine_volume = CIMI::Model::MachineVolume.find(params[:id], self, params[:vol_id])
162
+ location = machine_volume.initial_location
163
+ machine_volumes = Machine.detach_volume(params[:vol_id], location, self)
164
+ respond_to do |format|
165
+ format.json{ machine_volumes.to_json}
166
+ format.xml{ machine_volumes.to_xml}
167
+ end
162
168
  end
163
169
  end
170
+
164
171
  end
165
172
 
166
- action :detach_volume, :http_method => :put, :with_capability => :detach_storage_volume do
167
- description "Detach CIMI Volume(s) from a machine."
173
+ operation :volume_attach, :http_method => :post, :with_capability => :attach_storage_volume do
174
+ description "Attach CIMI Volume(s) to a machine."
168
175
  param :id, :string, :required
169
176
  control do
170
- if request.content_type.end_with?("json")
171
- volumes_to_detach = Volume.find_to_attach_from_json(request.body.read, self)
177
+ if grab_content_type(request.content_type, request.body) == :json
178
+ volume_to_attach, location = MachineVolume.find_to_attach_from_json(request.body.read, self)
172
179
  else
173
- volumes_to_detach = Volume.find_to_attach_from_xml(request.body.read, self)
180
+ volume_to_attach, location = MachineVolume.find_to_attach_from_xml(request.body.read, self)
174
181
  end
175
- machine = Machine.detach_volumes(volumes_to_detach, self)
182
+ machine_volume = Machine.attach_volume(volume_to_attach,location, self)
183
+ headers_for_create machine_volume
176
184
  respond_to do |format|
177
- format.json{ machine.to_json}
178
- format.xml{machine.to_xml}
185
+ format.json{ machine_volume.to_json}
186
+ format.xml{machine_volume.to_xml}
179
187
  end
180
188
  end
181
189
  end
190
+
182
191
  end
183
192
 
184
193
  end