rest_connection 0.0.23 → 0.1.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 (73) hide show
  1. data/README.rdoc +3 -3
  2. data/Rakefile +5 -4
  3. data/VERSION +1 -1
  4. data/git_hooks/post-commit.disabled +4 -0
  5. data/git_hooks/post-merge.disabled +4 -0
  6. data/git_hooks/pre-commit +53 -0
  7. data/lib/rest_connection.rb +75 -12
  8. data/lib/rest_connection/patches.rb +106 -0
  9. data/lib/rest_connection/rightscale/account.rb +27 -0
  10. data/lib/rest_connection/rightscale/alert_spec.rb +2 -2
  11. data/lib/rest_connection/rightscale/audit_entry.rb +5 -5
  12. data/lib/rest_connection/rightscale/child_account.rb +27 -0
  13. data/lib/rest_connection/rightscale/cloud.rb +26 -0
  14. data/lib/rest_connection/rightscale/credential.rb +1 -1
  15. data/lib/rest_connection/rightscale/deployment.rb +33 -7
  16. data/lib/rest_connection/rightscale/ec2_ebs_snapshot.rb +3 -1
  17. data/lib/rest_connection/rightscale/ec2_ebs_volume.rb +3 -1
  18. data/lib/rest_connection/rightscale/ec2_elastic_ip.rb +1 -1
  19. data/lib/rest_connection/rightscale/ec2_security_group.rb +2 -2
  20. data/lib/rest_connection/rightscale/ec2_server_array.rb +7 -5
  21. data/lib/rest_connection/rightscale/ec2_ssh_key.rb +11 -2
  22. data/lib/rest_connection/rightscale/ec2_ssh_key_internal.rb +2 -2
  23. data/lib/rest_connection/rightscale/executable.rb +4 -4
  24. data/lib/rest_connection/rightscale/instance.rb +5 -3
  25. data/lib/rest_connection/rightscale/instance_type.rb +31 -0
  26. data/lib/rest_connection/rightscale/macro.rb +19 -0
  27. data/lib/rest_connection/rightscale/mc_datacenter.rb +53 -0
  28. data/lib/rest_connection/rightscale/mc_deployment.rb +60 -0
  29. data/lib/rest_connection/rightscale/mc_image.rb +42 -0
  30. data/lib/rest_connection/rightscale/mc_instance.rb +170 -0
  31. data/lib/rest_connection/rightscale/mc_instance_type.rb +47 -0
  32. data/lib/rest_connection/rightscale/mc_multi_cloud_image.rb +58 -0
  33. data/lib/rest_connection/rightscale/mc_multi_cloud_image_setting.rb +46 -0
  34. data/lib/rest_connection/rightscale/mc_security_group.rb +42 -0
  35. data/lib/rest_connection/rightscale/mc_server.rb +250 -6
  36. data/lib/rest_connection/rightscale/mc_server_array.rb +44 -0
  37. data/lib/rest_connection/rightscale/mc_server_template.rb +53 -0
  38. data/lib/rest_connection/rightscale/mc_ssh_key.rb +50 -0
  39. data/lib/rest_connection/rightscale/mc_tag.rb +69 -0
  40. data/lib/rest_connection/rightscale/mc_volume.rb +53 -0
  41. data/lib/rest_connection/rightscale/mc_volume_attachment.rb +48 -0
  42. data/lib/rest_connection/rightscale/mc_volume_snapshot.rb +55 -0
  43. data/lib/rest_connection/rightscale/mc_volume_type.rb +47 -0
  44. data/lib/rest_connection/rightscale/monitoring_metric.rb +35 -0
  45. data/lib/rest_connection/rightscale/multi_cloud_image.rb +16 -2
  46. data/lib/rest_connection/rightscale/multi_cloud_image_cloud_setting_internal.rb +2 -2
  47. data/lib/rest_connection/rightscale/multi_cloud_image_internal.rb +25 -1
  48. data/lib/rest_connection/rightscale/permission.rb +27 -0
  49. data/lib/rest_connection/rightscale/right_script.rb +4 -4
  50. data/lib/rest_connection/rightscale/right_script_internal.rb +4 -4
  51. data/lib/rest_connection/rightscale/rightscale_api_base.rb +69 -20
  52. data/lib/rest_connection/rightscale/rightscale_api_gateway.rb +198 -13
  53. data/lib/rest_connection/rightscale/rightscale_api_internal.rb +3 -3
  54. data/lib/rest_connection/rightscale/rightscale_api_mc_input.rb +32 -0
  55. data/lib/rest_connection/rightscale/rightscale_api_mc_taggable.rb +57 -0
  56. data/lib/rest_connection/rightscale/rightscale_api_resources.rb +32 -2
  57. data/lib/rest_connection/rightscale/rightscale_api_taggable.rb +116 -0
  58. data/lib/rest_connection/rightscale/rs_internal.rb +6 -6
  59. data/lib/rest_connection/rightscale/s3_bucket.rb +36 -0
  60. data/lib/rest_connection/rightscale/server.rb +186 -37
  61. data/lib/rest_connection/rightscale/server_interface.rb +264 -0
  62. data/lib/rest_connection/rightscale/server_internal.rb +3 -3
  63. data/lib/rest_connection/rightscale/server_template.rb +15 -4
  64. data/lib/rest_connection/rightscale/server_template_internal.rb +4 -4
  65. data/lib/rest_connection/rightscale/status.rb +2 -2
  66. data/lib/rest_connection/rightscale/tag.rb +2 -2
  67. data/lib/rest_connection/rightscale/task.rb +47 -0
  68. data/lib/rest_connection/rightscale/user.rb +27 -0
  69. data/lib/rest_connection/ssh_hax.rb +42 -40
  70. data/rest_connection.gemspec +5 -5
  71. data/spec/mcserver_spec.rb +17 -0
  72. data/spec/multi.rb +16 -0
  73. metadata +65 -12
@@ -1,4 +1,4 @@
1
- # This file is part of RestConnection
1
+ # This file is part of RestConnection
2
2
  #
3
3
  # RestConnection is free software: you can redistribute it and/or modify
4
4
  # it under the terms of the GNU General Public License as published by
@@ -37,7 +37,7 @@ module SshHax
37
37
  ssh_keys
38
38
  end
39
39
 
40
- def run_and_tail(run_this, tail_command, expect, ssh_key=nil, host_dns=self.dns_name)
40
+ def run_and_tail(run_this, tail_command, expect, ssh_key=nil, host_dns=self.reachable_ip)
41
41
  status = nil
42
42
  result = nil
43
43
  output = ""
@@ -75,7 +75,7 @@ module SshHax
75
75
  ch.on_extended_data do |c, type, data|
76
76
  #STDERR.print data
77
77
  end
78
- ch.on_close do
78
+ ch.on_close do
79
79
  end
80
80
  ch.on_process do |c|
81
81
  if result
@@ -84,7 +84,7 @@ module SshHax
84
84
  end
85
85
  end
86
86
  end
87
- end
87
+ end
88
88
  cmd_channel.wait
89
89
  log_channel.wait
90
90
  end
@@ -96,16 +96,16 @@ module SshHax
96
96
 
97
97
  # script is an Executable object with minimally nick or id set
98
98
  def run_executable_with_ssh(script, options={}, ssh_key=nil)
99
- raise "FATAL: run_executable called on a server with no dns_name. You need to run .settings on the server to populate this attribute." unless self.dns_name
99
+ raise "FATAL: run_executable called on a server with no reachable_ip. You need to run .settings on the server to populate this attribute." unless self.reachable_ip
100
100
  if script.is_a?(Executable)
101
101
  script = script.right_script
102
102
  end
103
103
 
104
104
  raise "FATAL: unrecognized format for script. Must be an Executable or RightScript with href or name attributes" unless (script.is_a?(RightScript)) && (script.href || script.name)
105
105
  if script.href
106
- run_this = "rs_run_right_script -i #{script.href.split(/\//).last}"
106
+ run_this = "rs_run_right_script -i #{script.href.split(/\//).last}"
107
107
  elsif script.name
108
- run_this = "rs_run_right_script -n #{script.name}"
108
+ run_this = "rs_run_right_script -n #{script.name}"
109
109
  end
110
110
  tail_command ="tail -f -n1 /var/log/messages"
111
111
  expect = /RightLink.*RS> ([completed|failed]+:)/
@@ -116,9 +116,9 @@ module SshHax
116
116
  end
117
117
 
118
118
  # recipe can be either a String, or an Executable
119
- # host_dns is optional and will default to objects self.dns_name
120
- def run_recipe_with_ssh(recipe, ssh_key=nil, host_dns=self.dns_name)
121
- raise "FATAL: run_script called on a server with no dns_name. You need to run .settings on the server to populate this attribute." unless self.dns_name
119
+ # host_dns is optional and will default to objects self.reachable_ip
120
+ def run_recipe_with_ssh(recipe, ssh_key=nil, host_dns=self.reachable_ip)
121
+ raise "FATAL: run_script called on a server with no reachable_ip. You need to run .settings on the server to populate this attribute." unless self.reachable_ip
122
122
  if recipe.is_a?(Executable)
123
123
  recipe = recipe.recipe
124
124
  end
@@ -128,59 +128,61 @@ module SshHax
128
128
  run_and_tail(run_this, tail_command, expect, ssh_key)
129
129
  end
130
130
 
131
- def spot_check(command, ssh_key=nil, host_dns=self.dns_name, &block)
131
+ def spot_check(command, ssh_key=nil, host_dns=self.reachable_ip, &block)
132
132
  connection.logger "SSHing to #{host_dns}"
133
133
  Net::SSH.start(host_dns, 'root', :keys => ssh_key_config(ssh_key)) do |ssh|
134
134
  result = ssh.exec!(command)
135
135
  yield result
136
136
  end
137
- end
137
+ end
138
138
 
139
139
  # returns true or false based on command success
140
- def spot_check_command?(command, ssh_key=nil, host_dns=self.dns_name)
140
+ def spot_check_command?(command, ssh_key=nil, host_dns=self.reachable_ip)
141
141
  results = spot_check_command(command, ssh_key, host_dns)
142
142
  return results[:status] == 0
143
143
  end
144
144
 
145
145
 
146
146
  # returns hash of exit_status and output from command
147
- def spot_check_command(command, ssh_key=nil, host_dns=self.dns_name)
148
- raise "FATAL: spot_check_command called on a server with no dns_name. You need to run .settings on the server to populate this attribute." unless host_dns
147
+ def spot_check_command(command, ssh_key=nil, host_dns=self.reachable_ip, do_not_log_result=false)
148
+ raise "FATAL: spot_check_command called on a server with no reachable_ip. You need to run .settings on the server to populate this attribute." unless host_dns
149
149
  connection.logger "SSHing to #{host_dns} using key(s) #{ssh_key_config(ssh_key)}"
150
150
  status = nil
151
151
  output = ""
152
152
  success = false
153
153
  retry_count = 0
154
154
  while (!success && retry_count < SSH_RETRY_COUNT) do
155
- begin
156
- Net::SSH.start(host_dns, 'root', :keys => ssh_key_config(ssh_key), :user_known_hosts_file => "/dev/null") do |ssh|
157
- cmd_channel = ssh.open_channel do |ch1|
158
- ch1.on_request('exit-status') do |ch, data|
159
- status = data.read_long
160
- end
161
- ch1.exec(command) do |ch2, success|
162
- unless success
163
- status = 1
164
- end
165
- ch2.on_data do |ch, data|
166
- output += data
167
- end
168
- ch2.on_extended_data do |ch, type, data|
169
- output += data
155
+ begin
156
+ # Test for ability to connect; Net::SSH.start sometimes hangs under certain server-side sshd configs
157
+ test_ssh = `ssh -o \"BatchMode=yes\" -o \"ConnectTimeout 5\" root@#{host_dns} -C \"exit\" 2>&1`.chomp
158
+ raise test_ssh unless test_ssh =~ /permission denied/i or test_ssh.empty?
159
+
160
+ Net::SSH.start(host_dns, 'root', :keys => ssh_key_config(ssh_key), :user_known_hosts_file => "/dev/null") do |ssh|
161
+ cmd_channel = ssh.open_channel do |ch1|
162
+ ch1.on_request('exit-status') do |ch, data|
163
+ status = data.read_long
164
+ end
165
+ ch1.exec(command) do |ch2, success|
166
+ unless success
167
+ status = 1
168
+ end
169
+ ch2.on_data do |ch, data|
170
+ output += data
171
+ end
172
+ ch2.on_extended_data do |ch, type, data|
173
+ output += data
174
+ end
175
+ end
170
176
  end
171
177
  end
178
+ rescue Exception => e
179
+ retry_count += 1 # opening the ssh channel failed -- try again.
180
+ connection.logger "ERROR during SSH session to #{host_dns}, retrying #{retry_count}: #{e} #{e.backtrace}"
181
+ sleep 10
172
182
  end
173
183
  end
174
- rescue Exception => e
175
- retry_count += 1 # opening the ssh channel failed -- try again.
176
- connection.logger "ERROR during SSH session to #{host_dns}, retrying #{retry_count}: #{e} #{e.backtrace}"
177
- sleep 10
178
- end
179
- end
180
- connection.logger "SSH Run: #{command} on #{host_dns}. Retry was #{retry_count}. Exit status was #{status}. Output below ---\n#{output}\n---"
184
+ connection.logger "SSH Run: #{command} on #{host_dns}. Retry was #{retry_count}. Exit status was #{status}. Output below ---\n#{output}\n---" unless do_not_log_result
181
185
  return {:status => status, :output => output}
182
- end
186
+ end
183
187
 
184
188
  end
185
-
186
-
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rest_connection}
8
- s.version = "0.0.23"
8
+ s.version = "0.0.22"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jeremy Deininger"]
12
- s.date = %q{2011-10-26}
12
+ s.date = %q{2011-09-10}
13
13
  s.description = %q{provides rest_connection}
14
14
  s.email = %q{jeremy@rubyonlinux.org}
15
15
  s.extra_rdoc_files = [
@@ -84,16 +84,16 @@ Gem::Specification.new do |s|
84
84
 
85
85
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
86
86
  s.add_runtime_dependency(%q<activesupport>, ["= 2.3.10"])
87
- s.add_runtime_dependency(%q<net-ssh>, [">= 0"])
87
+ s.add_runtime_dependency(%q<net-ssh>, ["= 2.1.4"])
88
88
  s.add_runtime_dependency(%q<json>, [">= 0"])
89
89
  else
90
90
  s.add_dependency(%q<activesupport>, ["= 2.3.10"])
91
- s.add_dependency(%q<net-ssh>, [">= 0"])
91
+ s.add_dependency(%q<net-ssh>, ["= 2.1.4"])
92
92
  s.add_dependency(%q<json>, [">= 0"])
93
93
  end
94
94
  else
95
95
  s.add_dependency(%q<activesupport>, ["= 2.3.10"])
96
- s.add_dependency(%q<net-ssh>, [">= 0"])
96
+ s.add_dependency(%q<net-ssh>, ["= 2.1.4"])
97
97
  s.add_dependency(%q<json>, [">= 0"])
98
98
  end
99
99
  end
@@ -0,0 +1,17 @@
1
+ require 'rubygems'
2
+ require 'rest_connection'
3
+ require 'spec'
4
+ require 'ruby-debug'
5
+
6
+ describe McServer, "server api object exercise" do
7
+ before(:all) do
8
+ @mcserver_v5 = McServer.find("/api/clouds/850/instances/AA5AOKVUOJPC9") # a v5 server
9
+ end
10
+
11
+ it "should run a recipe on a v5 server" do
12
+ this_template = ServerTemplate.find(@mcserver_v5.server_template_href)
13
+ run_first = this_template.executables.first
14
+ audit = @mcserver_v5.run_executable(run_first)
15
+ audit.wait_for_completed
16
+ end
17
+ end
data/spec/multi.rb ADDED
@@ -0,0 +1,16 @@
1
+ require 'rubygems'
2
+ require 'rest_connection'
3
+ require 'spec'
4
+ require 'ruby-debug'
5
+
6
+ describe MultiCloudImage do
7
+ it "goes" do
8
+
9
+ mci = MultiCloudImage.find(46563)
10
+ mci = MultiCloudImage.find(57499)
11
+ settings = mci.find_and_flatten_settings
12
+ debugger
13
+ puts "blah"
14
+
15
+ end
16
+ end
metadata CHANGED
@@ -1,22 +1,22 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rest_connection
3
3
  version: !ruby/object:Gem::Version
4
- hash: 49
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
+ - 1
8
9
  - 0
9
- - 23
10
- version: 0.0.23
10
+ version: 0.1.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jeremy Deininger
14
+ - Timothy Rodriguez
14
15
  autorequire:
15
16
  bindir: bin
16
17
  cert_chain: []
17
18
 
18
- date: 2011-10-26 00:00:00 -07:00
19
- default_executable:
19
+ date: 2011-11-01 00:00:00 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: activesupport
@@ -40,12 +40,14 @@ dependencies:
40
40
  requirement: &id002 !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
- - - ">="
43
+ - - "="
44
44
  - !ruby/object:Gem::Version
45
45
  hash: 3
46
46
  segments:
47
- - 0
48
- version: "0"
47
+ - 2
48
+ - 1
49
+ - 4
50
+ version: 2.1.4
49
51
  type: :runtime
50
52
  version_requirements: *id002
51
53
  - !ruby/object:Gem::Dependency
@@ -62,8 +64,24 @@ dependencies:
62
64
  version: "0"
63
65
  type: :runtime
64
66
  version_requirements: *id003
67
+ - !ruby/object:Gem::Dependency
68
+ name: highline
69
+ prerelease: false
70
+ requirement: &id004 !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ hash: 3
76
+ segments:
77
+ - 0
78
+ version: "0"
79
+ type: :runtime
80
+ version_requirements: *id004
65
81
  description: provides rest_connection
66
- email: jeremy@rubyonlinux.org
82
+ email:
83
+ - jeremy@rubyonlinux.org
84
+ - tw.rodriguez@gmail.com
67
85
  executables: []
68
86
 
69
87
  extensions: []
@@ -84,9 +102,16 @@ files:
84
102
  - examples/cucumber/step_definitions/spot_check_steps.rb
85
103
  - examples/relaunch_deployment.rb
86
104
  - examples/right_scale_ec2_instances_api_test.rb
105
+ - git_hooks/post-commit.disabled
106
+ - git_hooks/post-merge.disabled
107
+ - git_hooks/pre-commit
87
108
  - lib/rest_connection.rb
109
+ - lib/rest_connection/patches.rb
110
+ - lib/rest_connection/rightscale/account.rb
88
111
  - lib/rest_connection/rightscale/alert_spec.rb
89
112
  - lib/rest_connection/rightscale/audit_entry.rb
113
+ - lib/rest_connection/rightscale/child_account.rb
114
+ - lib/rest_connection/rightscale/cloud.rb
90
115
  - lib/rest_connection/rightscale/credential.rb
91
116
  - lib/rest_connection/rightscale/deployment.rb
92
117
  - lib/rest_connection/rightscale/ec2_ebs_snapshot.rb
@@ -98,29 +123,58 @@ files:
98
123
  - lib/rest_connection/rightscale/ec2_ssh_key_internal.rb
99
124
  - lib/rest_connection/rightscale/executable.rb
100
125
  - lib/rest_connection/rightscale/instance.rb
126
+ - lib/rest_connection/rightscale/instance_type.rb
127
+ - lib/rest_connection/rightscale/macro.rb
128
+ - lib/rest_connection/rightscale/mc_datacenter.rb
129
+ - lib/rest_connection/rightscale/mc_deployment.rb
130
+ - lib/rest_connection/rightscale/mc_image.rb
131
+ - lib/rest_connection/rightscale/mc_instance.rb
132
+ - lib/rest_connection/rightscale/mc_instance_type.rb
133
+ - lib/rest_connection/rightscale/mc_multi_cloud_image.rb
134
+ - lib/rest_connection/rightscale/mc_multi_cloud_image_setting.rb
135
+ - lib/rest_connection/rightscale/mc_security_group.rb
101
136
  - lib/rest_connection/rightscale/mc_server.rb
137
+ - lib/rest_connection/rightscale/mc_server_array.rb
138
+ - lib/rest_connection/rightscale/mc_server_template.rb
139
+ - lib/rest_connection/rightscale/mc_ssh_key.rb
140
+ - lib/rest_connection/rightscale/mc_tag.rb
141
+ - lib/rest_connection/rightscale/mc_volume.rb
142
+ - lib/rest_connection/rightscale/mc_volume_attachment.rb
143
+ - lib/rest_connection/rightscale/mc_volume_snapshot.rb
144
+ - lib/rest_connection/rightscale/mc_volume_type.rb
145
+ - lib/rest_connection/rightscale/monitoring_metric.rb
102
146
  - lib/rest_connection/rightscale/multi_cloud_image.rb
103
147
  - lib/rest_connection/rightscale/multi_cloud_image_cloud_setting_internal.rb
104
148
  - lib/rest_connection/rightscale/multi_cloud_image_internal.rb
149
+ - lib/rest_connection/rightscale/permission.rb
105
150
  - lib/rest_connection/rightscale/right_script.rb
106
151
  - lib/rest_connection/rightscale/right_script_internal.rb
107
152
  - lib/rest_connection/rightscale/rightscale_api_base.rb
108
153
  - lib/rest_connection/rightscale/rightscale_api_gateway.rb
109
154
  - lib/rest_connection/rightscale/rightscale_api_internal.rb
155
+ - lib/rest_connection/rightscale/rightscale_api_mc_input.rb
156
+ - lib/rest_connection/rightscale/rightscale_api_mc_taggable.rb
110
157
  - lib/rest_connection/rightscale/rightscale_api_resources.rb
158
+ - lib/rest_connection/rightscale/rightscale_api_taggable.rb
111
159
  - lib/rest_connection/rightscale/rs_internal.rb
160
+ - lib/rest_connection/rightscale/s3_bucket.rb
112
161
  - lib/rest_connection/rightscale/server.rb
162
+ - lib/rest_connection/rightscale/server_interface.rb
113
163
  - lib/rest_connection/rightscale/server_internal.rb
114
164
  - lib/rest_connection/rightscale/server_template.rb
115
165
  - lib/rest_connection/rightscale/server_template_internal.rb
116
166
  - lib/rest_connection/rightscale/status.rb
117
167
  - lib/rest_connection/rightscale/tag.rb
168
+ - lib/rest_connection/rightscale/task.rb
169
+ - lib/rest_connection/rightscale/user.rb
118
170
  - lib/rest_connection/ssh_hax.rb
119
171
  - rest_connection.gemspec
120
172
  - spec/ec2_server_array_spec.rb
121
173
  - spec/ec2_ssh_key_internal_spec.rb
122
174
  - spec/image_jockey.rb
175
+ - spec/mcserver_spec.rb
123
176
  - spec/method_missing_spec.rb
177
+ - spec/multi.rb
124
178
  - spec/right_script_internal.rb
125
179
  - spec/rs_internal_spec.rb
126
180
  - spec/server_internal_spec.rb
@@ -128,8 +182,7 @@ files:
128
182
  - spec/server_template_internal.rb
129
183
  - spec/spec_helper.rb
130
184
  - spec/tag_spec.rb
131
- has_rdoc: true
132
- homepage: http://github.com/jeremyd/rest_connection
185
+ homepage: http://github.com/twrodriguez/rest_connection
133
186
  licenses: []
134
187
 
135
188
  post_install_message:
@@ -158,7 +211,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
158
211
  requirements: []
159
212
 
160
213
  rubyforge_project:
161
- rubygems_version: 1.6.2
214
+ rubygems_version: 1.7.2
162
215
  signing_key:
163
216
  specification_version: 3
164
217
  summary: lib for restful connections to the rightscale api