bbrowning-deltacloud-core 0.0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. data/COPYING +502 -0
  2. data/Rakefile +85 -0
  3. data/bin/deltacloudd +88 -0
  4. data/config.ru +5 -0
  5. data/deltacloud.rb +14 -0
  6. data/lib/deltacloud/base_driver.rb +19 -0
  7. data/lib/deltacloud/base_driver/base_driver.rb +189 -0
  8. data/lib/deltacloud/base_driver/features.rb +159 -0
  9. data/lib/deltacloud/base_driver/mock_driver.rb +37 -0
  10. data/lib/deltacloud/drivers/ec2/ec2_driver.rb +340 -0
  11. data/lib/deltacloud/drivers/ec2/ec2_mock_driver.rb +170 -0
  12. data/lib/deltacloud/drivers/gogrid/gogrid_client.rb +45 -0
  13. data/lib/deltacloud/drivers/gogrid/gogrid_driver.rb +322 -0
  14. data/lib/deltacloud/drivers/mock/mock_driver.rb +275 -0
  15. data/lib/deltacloud/drivers/opennebula/cloud_client.rb +116 -0
  16. data/lib/deltacloud/drivers/opennebula/occi_client.rb +204 -0
  17. data/lib/deltacloud/drivers/opennebula/opennebula_driver.rb +241 -0
  18. data/lib/deltacloud/drivers/rackspace/rackspace_client.rb +129 -0
  19. data/lib/deltacloud/drivers/rackspace/rackspace_driver.rb +150 -0
  20. data/lib/deltacloud/drivers/rhevm/rhevm_driver.rb +254 -0
  21. data/lib/deltacloud/drivers/rimuhosting/rimuhosting_client.rb +84 -0
  22. data/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb +144 -0
  23. data/lib/deltacloud/drivers/terremark/terremark_driver.rb +261 -0
  24. data/lib/deltacloud/hardware_profile.rb +153 -0
  25. data/lib/deltacloud/helpers.rb +5 -0
  26. data/lib/deltacloud/helpers/application_helper.rb +56 -0
  27. data/lib/deltacloud/helpers/conversion_helper.rb +38 -0
  28. data/lib/deltacloud/helpers/hardware_profiles_helper.rb +35 -0
  29. data/lib/deltacloud/method_serializer.rb +84 -0
  30. data/lib/deltacloud/models/base_model.rb +58 -0
  31. data/lib/deltacloud/models/image.rb +26 -0
  32. data/lib/deltacloud/models/instance.rb +37 -0
  33. data/lib/deltacloud/models/instance_profile.rb +47 -0
  34. data/lib/deltacloud/models/realm.rb +25 -0
  35. data/lib/deltacloud/models/storage_snapshot.rb +26 -0
  36. data/lib/deltacloud/models/storage_volume.rb +27 -0
  37. data/lib/deltacloud/state_machine.rb +84 -0
  38. data/lib/deltacloud/validation.rb +70 -0
  39. data/lib/drivers.rb +38 -0
  40. data/lib/sinatra/accept_media_types.rb +128 -0
  41. data/lib/sinatra/lazy_auth.rb +56 -0
  42. data/lib/sinatra/rabbit.rb +272 -0
  43. data/lib/sinatra/respond_to.rb +269 -0
  44. data/lib/sinatra/static_assets.rb +83 -0
  45. data/lib/sinatra/url_for.rb +51 -0
  46. data/public/favicon.ico +0 -0
  47. data/public/images/grid.png +0 -0
  48. data/public/images/logo-wide.png +0 -0
  49. data/public/images/rails.png +0 -0
  50. data/public/images/topbar-bg.png +0 -0
  51. data/public/javascripts/application.js +32 -0
  52. data/public/javascripts/jquery-1.4.2.min.js +154 -0
  53. data/public/stylesheets/compiled/application.css +613 -0
  54. data/public/stylesheets/compiled/ie.css +31 -0
  55. data/public/stylesheets/compiled/print.css +27 -0
  56. data/public/stylesheets/compiled/screen.css +456 -0
  57. data/server.rb +342 -0
  58. data/support/fedora/deltacloudd +68 -0
  59. data/support/fedora/rubygem-deltacloud-core.spec +91 -0
  60. data/tests/deltacloud_test.rb +60 -0
  61. data/tests/images_test.rb +94 -0
  62. data/tests/instances_test.rb +136 -0
  63. data/tests/realms_test.rb +56 -0
  64. data/tests/storage_snapshots_test.rb +48 -0
  65. data/tests/storage_volumes_test.rb +48 -0
  66. data/torquebox-ec2-config.ru +8 -0
  67. data/views/accounts/index.html.haml +11 -0
  68. data/views/accounts/show.html.haml +30 -0
  69. data/views/api/show.html.haml +15 -0
  70. data/views/api/show.xml.haml +5 -0
  71. data/views/docs/collection.html.haml +37 -0
  72. data/views/docs/collection.xml.haml +14 -0
  73. data/views/docs/index.html.haml +15 -0
  74. data/views/docs/index.xml.haml +5 -0
  75. data/views/docs/operation.html.haml +31 -0
  76. data/views/docs/operation.xml.haml +10 -0
  77. data/views/errors/auth_exception.html.haml +8 -0
  78. data/views/errors/auth_exception.xml.haml +2 -0
  79. data/views/errors/backend_error.html.haml +17 -0
  80. data/views/errors/backend_error.xml.haml +8 -0
  81. data/views/errors/validation_failure.html.haml +11 -0
  82. data/views/errors/validation_failure.xml.haml +7 -0
  83. data/views/hardware_profiles/index.html.haml +25 -0
  84. data/views/hardware_profiles/index.xml.haml +4 -0
  85. data/views/hardware_profiles/show.html.haml +19 -0
  86. data/views/hardware_profiles/show.xml.haml +17 -0
  87. data/views/images/index.html.haml +30 -0
  88. data/views/images/index.xml.haml +7 -0
  89. data/views/images/show.html.haml +21 -0
  90. data/views/images/show.xml.haml +5 -0
  91. data/views/instance_states/show.gv.erb +45 -0
  92. data/views/instance_states/show.html.haml +31 -0
  93. data/views/instance_states/show.xml.haml +8 -0
  94. data/views/instances/index.html.haml +30 -0
  95. data/views/instances/index.xml.haml +23 -0
  96. data/views/instances/new.html.haml +55 -0
  97. data/views/instances/show.html.haml +43 -0
  98. data/views/instances/show.xml.haml +41 -0
  99. data/views/layout.html.haml +26 -0
  100. data/views/realms/index.html.haml +29 -0
  101. data/views/realms/index.xml.haml +12 -0
  102. data/views/realms/show.html.haml +15 -0
  103. data/views/realms/show.xml.haml +10 -0
  104. data/views/root/index.html.haml +4 -0
  105. data/views/storage_snapshots/index.html.haml +20 -0
  106. data/views/storage_snapshots/index.xml.haml +11 -0
  107. data/views/storage_snapshots/show.html.haml +14 -0
  108. data/views/storage_snapshots/show.xml.haml +9 -0
  109. data/views/storage_volumes/index.html.haml +21 -0
  110. data/views/storage_volumes/index.xml.haml +13 -0
  111. data/views/storage_volumes/show.html.haml +20 -0
  112. data/views/storage_volumes/show.xml.haml +13 -0
  113. metadata +361 -0
@@ -0,0 +1,129 @@
1
+ #
2
+ # Copyright (C) 2009 Red Hat, Inc.
3
+ #
4
+ # This library is free software; you can redistribute it and/or
5
+ # modify it under the terms of the GNU Lesser General Public
6
+ # License as published by the Free Software Foundation; either
7
+ # version 2.1 of the License, or (at your option) any later version.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+ require "net/http"
19
+ require "net/https"
20
+ require 'rubygems'
21
+ require 'json'
22
+
23
+ #
24
+ # author: Michael Neale
25
+ # TODO: catch generic errors in JSON response and throw (probably)
26
+ #
27
+ module Deltacloud
28
+ module Drivers
29
+ module Rackspace
30
+
31
+ class RackspaceClient
32
+
33
+ @@AUTH_API = URI.parse('https://auth.api.rackspacecloud.com/v1.0')
34
+
35
+ def initialize(username, auth_key)
36
+ http = Net::HTTP.new(@@AUTH_API.host,@@AUTH_API.port)
37
+ http.use_ssl = true
38
+ authed = http.get(@@AUTH_API.path, {'X-Auth-User' => username, 'X-Auth-Key' => auth_key})
39
+ if authed.is_a?(Net::HTTPUnauthorized)
40
+ raise Deltacloud::AuthException, "Failed to authenticate to Rackspace"
41
+ elsif !authed.is_a?(Net::HTTPSuccess)
42
+ backend_error!(resp)
43
+ end
44
+ @auth_token = authed.header['X-Auth-Token']
45
+ @service_uri = URI.parse(authed.header['X-Server-Management-Url'])
46
+ @service = Net::HTTP.new(@service_uri.host, @service_uri.port)
47
+ @service.use_ssl = true
48
+ end
49
+
50
+ def list_flavors
51
+ JSON.parse(get('/flavors/detail'))['flavors']
52
+ end
53
+
54
+ def list_images
55
+ JSON.parse(get('/images/detail'))['images']
56
+ end
57
+
58
+ def list_servers
59
+ JSON.parse(get('/servers/detail'))['servers']
60
+ end
61
+
62
+
63
+ def load_server_details( server_id )
64
+ JSON.parse(get("/servers/#{server_id}"))['server']
65
+ end
66
+
67
+
68
+ def start_server(image_id, flavor_id, name)
69
+ json = { :server => { :name => name,
70
+ :imageId => image_id.to_i,
71
+ :flavorId => flavor_id.to_i }}.to_json
72
+ # FIXME: The response has the root password in 'adminPass'; we somehow
73
+ # need to communicate this back since it's the only place where we can
74
+ # get it from
75
+ JSON.parse(post("/servers", json, headers).body)["server"]
76
+ end
77
+
78
+ def delete_server(server_id)
79
+ delete("/servers/#{server_id}", headers)
80
+ end
81
+
82
+ def reboot_server(server_id)
83
+ json = { :reboot => { :type => :SOFT }}.to_json
84
+ post("/servers/#{server_id}/action", json, headers)
85
+ end
86
+
87
+
88
+ def headers
89
+ {"Accept" => "application/json", "X-Auth-Token" => @auth_token, "Content-Type" => "application/json"}
90
+ end
91
+
92
+ private
93
+ def get(path)
94
+ resp = @service.get(@service_uri.path + path, {"Accept" => "application/json", "X-Auth-Token" => @auth_token})
95
+ unless resp.is_a?(Net::HTTPSuccess)
96
+ backend_error!(resp)
97
+ end
98
+ resp.body
99
+ end
100
+
101
+ def post(path, json, headers)
102
+ resp = @service.post(@service_uri.path + path, json, headers)
103
+ unless resp.is_a?(Net::HTTPSuccess)
104
+ backend_error!(resp)
105
+ end
106
+ resp
107
+ end
108
+
109
+ def delete(path, headers)
110
+ resp = @service.delete(@service_uri.path + path, headers)
111
+ unless resp.is_a?(Net::HTTPSuccess)
112
+ backend_error!(resp)
113
+ end
114
+ resp
115
+ end
116
+
117
+ def backend_error!(resp)
118
+ json = JSON.parse(resp.body)
119
+ cause = json.keys[0]
120
+ code = json[cause]["code"]
121
+ message = json[cause]["message"]
122
+ details = json[cause]["details"]
123
+ raise Deltacloud::BackendError.new(code, cause, message, details)
124
+ end
125
+
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,150 @@
1
+ #
2
+ # Copyright (C) 2009 Red Hat, Inc.
3
+ #
4
+ # This library is free software; you can redistribute it and/or
5
+ # modify it under the terms of the GNU Lesser General Public
6
+ # License as published by the Free Software Foundation; either
7
+ # version 2.1 of the License, or (at your option) any later version.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+ require 'deltacloud/base_driver'
19
+ require 'deltacloud/drivers/rackspace/rackspace_client'
20
+
21
+ module Deltacloud
22
+ module Drivers
23
+ module Rackspace
24
+
25
+ class RackspaceDriver < Deltacloud::BaseDriver
26
+
27
+ feature :instances, :user_name
28
+
29
+ def hardware_profiles(credentials, opts = nil)
30
+ racks = new_client( credentials )
31
+ results = racks.list_flavors.map do |flav|
32
+ HardwareProfile.new(flav["id"].to_s) do
33
+ architecture 'x86_64'
34
+ memory flav["ram"].to_i
35
+ storage flav["disk"].to_i
36
+ end
37
+ end
38
+ filter_hardware_profiles(results, opts)
39
+ end
40
+
41
+ def images(credentials, opts=nil)
42
+ racks = new_client( credentials )
43
+ results = racks.list_images.map do |img|
44
+ Image.new( {
45
+ :id=>img["id"].to_s,
46
+ :name=>img["name"],
47
+ :description => img["name"] + " " + img["status"] + "",
48
+ :owner_id=>"root",
49
+ :architecture=>'x86_64'
50
+ } )
51
+ end
52
+ results.sort_by{|e| [e.description]}
53
+ results = filter_on( results, :id, opts )
54
+ results
55
+ end
56
+
57
+ #rackspace does not at this stage have realms... its all US/TX, all the time (at least at time of writing)
58
+ def realms(credentials, opts=nil)
59
+ [Realm.new( {
60
+ :id=>"us",
61
+ :name=>"United States",
62
+ :state=> "AVAILABLE"
63
+ } )]
64
+ end
65
+
66
+ def reboot_instance(credentials, id)
67
+ racks = new_client(credentials)
68
+ racks.reboot_server(id)
69
+ end
70
+
71
+ def stop_instance(credentials, id)
72
+ destroy_instance(credentials, id)
73
+ end
74
+
75
+ def destroy_instance(credentials, id)
76
+ racks = new_client(credentials)
77
+ racks.delete_server(id)
78
+ end
79
+
80
+
81
+ #
82
+ # create instance. Default to flavor 1 - really need a name though...
83
+ # In rackspace, all flavors work with all images.
84
+ #
85
+ def create_instance(credentials, image_id, opts)
86
+ racks = new_client( credentials )
87
+ hwp_id = opts[:hwp_id] || 1
88
+ name = Time.now.to_s
89
+ if (opts[:name]) then name = opts[:name] end
90
+ convert_srv_to_instance(racks.start_server(image_id, hwp_id, name))
91
+ end
92
+
93
+ #
94
+ # Instances
95
+ #
96
+ def instances(credentials, opts=nil)
97
+ racks = new_client(credentials)
98
+ instances = []
99
+ if (opts.nil?)
100
+ instances = racks.list_servers.map do |srv|
101
+ convert_srv_to_instance(srv)
102
+ end
103
+ else
104
+ instances << convert_srv_to_instance(racks.load_server_details(opts[:id]))
105
+ end
106
+ instances = filter_on( instances, :id, opts )
107
+ instances = filter_on( instances, :state, opts )
108
+ instances
109
+ end
110
+
111
+
112
+ def convert_srv_to_instance(srv)
113
+ status = srv["status"] == "ACTIVE" ? "RUNNING" : "PENDING"
114
+ inst = Instance.new(:id => srv["id"].to_s,
115
+ :owner_id => "root",
116
+ :realm_id => "us")
117
+ inst.name = srv["name"]
118
+ inst.state = srv["status"] == "ACTIVE" ? "RUNNING" : "PENDING"
119
+ inst.actions = instance_actions_for(inst.state)
120
+ inst.image_id = srv["imageId"].to_s
121
+ inst.instance_profile = InstanceProfile.new(srv["flavorId"].to_s)
122
+ if srv["addresses"]
123
+ inst.public_addresses = srv["addresses"]["public"]
124
+ inst.private_addresses = srv["addresses"]["private"]
125
+ end
126
+ inst
127
+ end
128
+
129
+ def new_client(credentials)
130
+ RackspaceClient.new(credentials.user, credentials.password)
131
+ end
132
+
133
+ define_instance_states do
134
+ start.to( :pending ) .on( :create )
135
+
136
+ pending.to( :running ) .automatically
137
+
138
+ running.to( :running ) .on( :reboot )
139
+ running.to( :shutting_down ) .on( :stop )
140
+
141
+ shutting_down.to( :stopped ) .automatically
142
+
143
+ stopped.to( :finish ) .automatically
144
+ end
145
+
146
+ end
147
+
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,254 @@
1
+ #
2
+ # Copyright (C) 2009 Red Hat, Inc.
3
+ #
4
+ # This library is free software; you can redistribute it and/or
5
+ # modify it under the terms of the GNU Lesser General Public
6
+ # License as published by the Free Software Foundation; either
7
+ # version 2.1 of the License, or (at your option) any later version.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+ require 'deltacloud/base_driver'
19
+ require 'yaml'
20
+
21
+ module Deltacloud
22
+ module Drivers
23
+ module RHEVM
24
+
25
+ class RHEVMDriver < Deltacloud::BaseDriver
26
+
27
+ SCRIPT_DIR = File.dirname(__FILE__) + '/scripts'
28
+ CONFIG = YAML.load_file(File.dirname(__FILE__) + '/../../../../config/rhevm_config.yml')
29
+ SCRIPT_DIR_ARG = '"' + SCRIPT_DIR + '"'
30
+ DELIM_BEGIN="<_OUTPUT>"
31
+ DELIM_END="</_OUTPUT>"
32
+ POWERSHELL="c:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe"
33
+ NO_OWNER=""
34
+
35
+ feature :instances, :user_name
36
+
37
+ #
38
+ # Execute a Powershell command, and convert the output
39
+ # to YAML in order to get back an array of maps.
40
+ #
41
+ def execute(credentials, command, *args)
42
+ args = args.to_a
43
+ argString = genArgString(credentials, args)
44
+ puts argString
45
+ outputMaps = {}
46
+ output = `#{POWERSHELL} -command "&{#{File.join(SCRIPT_DIR, command)} #{argString}; exit $LASTEXITCODE}`
47
+ exitStatus = $?.exitstatus
48
+ puts(output)
49
+ puts("EXITSTATUS #{exitStatus}")
50
+ st = output.index(DELIM_BEGIN)
51
+ if (st)
52
+ st += DELIM_BEGIN.length
53
+ ed = output.index(DELIM_END)
54
+ output = output.slice(st, (ed-st))
55
+ # Lets make it yaml
56
+ output.strip!
57
+ if (output.length > 0)
58
+ outputMaps = YAML.load(self.toYAML(output))
59
+ end
60
+ end
61
+ outputMaps
62
+ end
63
+
64
+ def genArgString(credentials, args)
65
+ commonArgs = [SCRIPT_DIR_ARG, credentials.user, credentials.password, CONFIG["domain"]]
66
+ commonArgs.concat(args)
67
+ commonArgs.join(" ")
68
+ end
69
+
70
+ def toYAML(output)
71
+ yOutput = "- \n" + output
72
+ yOutput.gsub!(/^(\w*)[ ]*:[ ]*([A-Z0-9a-z._ -:{}]*)/,' \1: "\2"')
73
+ yOutput.gsub!(/^[ ]*$/,"- ")
74
+ puts(yOutput)
75
+ yOutput
76
+ end
77
+
78
+ def statify(state)
79
+ st = state.nil? ? "" : state.upcase()
80
+ return "running" if st == "UP"
81
+ return "stopped" if st == "DOWN"
82
+ return "pending" if st == "POWERING UP"
83
+ st
84
+ end
85
+
86
+ define_hardware_profile 'rhevm'
87
+
88
+ #
89
+ # Realms
90
+ #
91
+
92
+ def realms(credentials, opts=nil)
93
+ domains = execute(credentials, "storageDomains.ps1")
94
+ if (!opts.nil? && opts[:id])
95
+ domains = domains.select{|d| opts[:id] == d["StorageId"]}
96
+ end
97
+
98
+ realms = []
99
+ domains.each do |dom|
100
+ realms << domain_to_realm(dom)
101
+ end
102
+ realms
103
+ end
104
+
105
+ def domain_to_realm(dom)
106
+ Realm.new({
107
+ :id => dom["StorageId"],
108
+ :name => dom["Name"],
109
+ :limit => dom["AvailableDiskSize"]
110
+ })
111
+ end
112
+
113
+
114
+
115
+ #
116
+ # Images
117
+ #
118
+
119
+ def images(credentials, opts=nil )
120
+ templates = []
121
+ if (opts.nil?)
122
+ templates = execute(credentials, "templates.ps1")
123
+ else
124
+ if (opts[:id])
125
+ templates = execute(credentials, "templateById.ps1", opts[:id])
126
+ end
127
+ end
128
+ images = []
129
+ templates.each do |templ|
130
+ images << template_to_image(templ)
131
+ end
132
+ images
133
+ end
134
+
135
+ def template_to_image(templ)
136
+ Image.new({
137
+ :id => templ["TemplateId"],
138
+ :name => templ["Name"],
139
+ :description => templ["Description"],
140
+ :architecture => templ["OperatingSystem"],
141
+ :owner_id => NO_OWNER,
142
+ :mem_size_md => templ["MemSizeMb"],
143
+ :instance_count => templ["ChildCount"],
144
+ :state => templ["Status"],
145
+ :capacity => templ["SizeGB"]
146
+ })
147
+ end
148
+
149
+ #
150
+ # Instances
151
+ #
152
+
153
+ define_instance_states do
154
+ start.to(:stopped) .on( :create )
155
+
156
+ pending.to(:shutting_down) .on( :stop )
157
+ pending.to(:running) .automatically
158
+
159
+ running.to(:pending) .on( :reboot )
160
+ running.to(:shutting_down) .on( :stop )
161
+
162
+ shutting_down.to(:stopped) .automatically
163
+ stopped.to(:pending) .on( :start )
164
+ stopped.to(:finish) .on( :destroy )
165
+ end
166
+
167
+ def instances(credentials, opts=nil)
168
+ vms = []
169
+ if (opts.nil?)
170
+ vms = execute(credentials, "vms.ps1")
171
+ else
172
+ if (opts[:id])
173
+ vms = execute(credentials, "vmById.ps1", opts[:id])
174
+ end
175
+ end
176
+ instances = []
177
+ vms.each do |vm|
178
+ instances << vm_to_instance(vm)
179
+ end
180
+ instances = filter_on( instances, :id, opts )
181
+ instances = filter_on( instances, :state, opts )
182
+ instances
183
+ end
184
+
185
+ def vm_to_instance(vm)
186
+ Instance.new({
187
+ :id => vm["VmId"],
188
+ :description => vm["Description"],
189
+ :name => vm["Name"],
190
+ :architecture => vm["OperatingSystem"],
191
+ :owner_id => NO_OWNER,
192
+ :image_id => vm["TemplateId"],
193
+ :state => statify(vm["Status"]),
194
+ :instance_profile => InstanceProfile.new("rhevm"),
195
+ :actions => instance_actions_for(statify(vm["Status"])),
196
+ })
197
+ end
198
+
199
+ def start_instance(credentials, image_id)
200
+ vm = execute(credentials, "startVm.ps1", image_id)
201
+ vm_to_instance(vm[0])
202
+ end
203
+
204
+ def stop_instance(credentials, image_id)
205
+ vm = execute(credentials, "stopVm.ps1", image_id)
206
+ vm_to_instance(vm[0])
207
+ end
208
+
209
+ def create_instance(credentials, image_id, opts)
210
+ name = opts[:name]
211
+ name = "Inst-#{rand(10000)}" if (name.nil? or name.empty?)
212
+ realm_id = opts[:realm_id]
213
+ if (realm_id.nil?)
214
+ realms = filter_on(realms(credentials, opts), :name, :name => "data")
215
+ puts realms[0]
216
+ realm_id = realms[0].id
217
+ end
218
+ vm = execute(credentials, "addVm.ps1", image_id, name, realm_id)
219
+ vm_to_instance(vm[0])
220
+ end
221
+
222
+ def reboot_instance(credentials, image_id)
223
+ vm = execute(credentials, "rebootVm.ps1", image_id)
224
+ vm_to_instance(vm[0])
225
+ end
226
+
227
+ def destroy_instance(credentials, image_id)
228
+ vm = execute(credentials, "deleteVm.ps1", image_id)
229
+ vm_to_instance(vm[0])
230
+ end
231
+
232
+ #
233
+ # Storage Volumes
234
+ #
235
+
236
+ def storage_volumes(credentials, ids=nil)
237
+ volumes = []
238
+ volumes
239
+ end
240
+
241
+ #
242
+ # Storage Snapshots
243
+ #
244
+
245
+ def storage_snapshots(credentials, ids=nil)
246
+ snapshots = []
247
+ snapshots
248
+ end
249
+
250
+ end
251
+
252
+ end
253
+ end
254
+ end