rest_connection 0.0.23 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,264 @@
1
+ # This file is part of RestConnection
2
+ #
3
+ # RestConnection is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # RestConnection is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with RestConnection. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require 'rest_connection/ssh_hax'
17
+
18
+ class ServerInterface
19
+ attr_reader :multicloud
20
+
21
+ def initialize(cid = nil, params = {}, deployment_id = nil)
22
+ if cid
23
+ @multicloud = (cid.to_i > 10 ? true : false)
24
+ elsif params["href"]
25
+ @multicloud = false
26
+ else
27
+ @multicloud = true
28
+ end
29
+ if @multicloud
30
+ if deployment_id
31
+ name = params["nickname"] || params["name"] || params[:nickname] || params[:name]
32
+ @impl = McServer.find_by(:name, deployment_id) { |n| n == name }.first
33
+ else
34
+ @impl = McServer.new(params)
35
+ end
36
+ else
37
+ @impl = Server.new(params)
38
+ end
39
+ self
40
+ end
41
+
42
+ def create(opts)
43
+ location = connection.post(resource_plural_name, translate_create_opts(opts))
44
+ @impl = (@multicloud ? McServer.new('href' => location) : Server.new('href' => location))
45
+ settings
46
+ self
47
+ end
48
+
49
+ def name
50
+ nickname
51
+ end
52
+
53
+ def inspect
54
+ @impl.inspect
55
+ end
56
+
57
+ def self.[](*args)
58
+ begin
59
+ ret = Server[*args]
60
+ raise "" if ret.empty?
61
+ rescue
62
+ ret = McServer[*args]
63
+ end
64
+ return ret
65
+ end
66
+
67
+ def nickname
68
+ return @impl.nickname unless @multicloud
69
+ return @impl.name if @multicloud
70
+ end
71
+
72
+ def method_missing(method_name, *args, &block)
73
+ @impl.__send__(method_name, *args, &block)
74
+ end
75
+
76
+ def clean_and_translate_server_params(it)
77
+ it.each do |k, v|
78
+ clean_and_translate_server_params(v) if v.is_a?(Hash)
79
+ end
80
+ it.reject! { |k, v| v == nil or v == "" }
81
+ it.each { |k, v| it[k] = translate_href(v) if k.to_s =~ /href/ }
82
+ it
83
+ end
84
+
85
+ def translate_create_opts(old_opts, instance_only=false)
86
+ fields = [{"1.0" => [:server_template_href], "1.5" => [:server_template_href]},
87
+ {"1.0" => [:cloud_id], "fn" => :map_cloud_id, "1.5" => [:cloud_href]},
88
+ {"1.0" => [:ec2_image_href], "1.5" => [:image_href]},
89
+ {"1.0" => [:ec2_user_data], "1.5" => [:user_data]},
90
+ {"1.0" => [:instance_type], "fn" => :map_instance, "1.5" => [:instance_type_href]},
91
+ {"1.0" => [:ec2_security_groups_href], "1.5" => [:security_group_hrefs]},
92
+ {"1.0" => [:ec2_ssh_key_href], "1.5" => [:ssh_key_href]},
93
+ {"1.0" => [:vpc_subnet_href]},
94
+ {"1.0" => [:ec2_availability_zone]},
95
+ {"1.0" => [:pricing]},
96
+ {"1.0" => [:max_spot_price]},
97
+ { "1.5" => [:inputs]},
98
+ { "1.5" => [:mci_href, :multi_cloud_image_href]},
99
+ { "1.5" => [:datacenter_href]},
100
+ {"1.0" => [:aki_image_href], "1.5" => [:kernel_image_href]},
101
+ {"1.0" => [:ari_image_href], "1.5" => [:ramdisk_image_href]}]
102
+
103
+ opts = old_opts.dup
104
+ if @multicloud
105
+ to = "1.5"
106
+ if instance_only
107
+ ret = {"instance" => {}}
108
+ server = ret["instance"]
109
+ else
110
+ ret = {"server" => {"instance" => {}}}
111
+ ret["server"]["name"] = (opts["name"] ? opts["name"] : opts["nickname"])
112
+ ret["server"]["description"] = opts["description"]
113
+ ret["server"]["deployment_href"] = opts["deployment_href"]
114
+ server = ret["server"]["instance"]
115
+ end
116
+ else
117
+ to = "1.0"
118
+ server = {"nickname" => (opts["nickname"] ? opts["nickname"] : opts["name"])}
119
+ server["deployment_href"] = opts["deployment_href"]
120
+ ret = {"server" => server}
121
+ begin
122
+ ret["cloud_id"] = opts["cloud_href"].split(/\/clouds\//).last
123
+ rescue Exception => e
124
+ ret["cloud_id"] = opts["cloud_id"]
125
+ end
126
+ end
127
+
128
+ fields.each { |hsh|
129
+ next unless hsh[to]
130
+ hsh[to].each { |field|
131
+ vals = opts.select {|k,v| [[hsh["1.0"]] + [hsh["1.5"]]].flatten.include?(k.to_sym) }
132
+ vals.flatten!
133
+ vals.compact!
134
+ if hsh["fn"]
135
+ server[field.to_s] = __send__(hsh["fn"], to, opts[vals.first]) unless vals.first.nil?
136
+ else
137
+ server[field.to_s] = opts[vals.first] unless vals.first.nil?
138
+ end
139
+ server.delete("inputs") if server["inputs"] && server["inputs"].empty? # Inputs cannot be empty for 1.5
140
+ }
141
+ }
142
+ clean_and_translate_server_params(ret)
143
+ return ret
144
+ end
145
+
146
+ def map_cloud_id(to, val)
147
+ if val.is_a?(String)
148
+ begin
149
+ val = val.split(/\//).last
150
+ rescue Exception => e
151
+ end
152
+ end
153
+ if to == "1.5"
154
+ return "https://my.rightscale.com/api/clouds/#{val}"
155
+ elsif to == "1.0"
156
+ return "#{val}"
157
+ end
158
+ end
159
+
160
+ def map_instance(to, val)
161
+ if to == "1.0"
162
+ return val
163
+ end
164
+ val
165
+ end
166
+
167
+ def translate_href(old_href)
168
+ if old_href.is_a?(Array)
169
+ new_array = []
170
+ old_href.each { |url| new_array << translate_href(url) }
171
+ return new_array
172
+ else
173
+ href = old_href.dup
174
+ if @multicloud
175
+ href.gsub!(/ec2_/,'')
176
+ href.gsub!(/\/acct\/[0-9]*/,'')
177
+ end
178
+ return href
179
+ end
180
+ # if href.include?("acct")
181
+ # my_base_href, @account = href.split(/\/acct\//)
182
+ # @account, *remaining = @account.split(/\//)
183
+ # if @multicloud
184
+ # return my_base_href + "/" + remaining.join("/").gsub(/ec2_/,'')
185
+ # else
186
+ # return href
187
+ # end
188
+ # else #API 1.5
189
+ # end
190
+ end
191
+
192
+ # Since RightScale hands back the parameters with a "name" and "value" tags we should
193
+ # transform them into the proper hash. This it the same for setting and getting.
194
+ def parameters
195
+ return @impl.parameters unless @multicloud
196
+ return @impl.inputs if @multicloud
197
+ end
198
+
199
+ def inputs
200
+ parameters
201
+ end
202
+
203
+ def start
204
+ launch
205
+ end
206
+
207
+ def stop
208
+ terminate
209
+ end
210
+
211
+ def launch
212
+ return @impl.launch if @multicloud
213
+ return @impl.start unless @multicloud
214
+ end
215
+
216
+ def terminate
217
+ return @impl.terminate if @multicloud
218
+ return @impl.stop unless @multicloud
219
+ end
220
+
221
+ def start_ebs
222
+ return connection.logger("WARNING: Gateway Servers do not support start_ebs. Ignoring.") if @multicloud
223
+ return @impl.start_ebs unless @multicloud
224
+ end
225
+
226
+ def stop_ebs
227
+ return connection.logger("WARNING: Gateway Servers do not support stop_ebs. Ignoring.") if @multicloud
228
+ return @impl.stop_ebs unless @multicloud
229
+ end
230
+
231
+ # This should be used with v4 images only.
232
+ def run_script(script,opts=nil)
233
+ return connection.logger("WARNING: Gateway Servers do not support run_script. Did you mean run_executable?") if @multicloud
234
+ return @impl.run_script(script,opts) unless @multicloud
235
+ end
236
+
237
+ def attach_volume(params)
238
+ return connection.logger("WARNING: Gateway Servers do not support attach_volume. Ignoring.") if @multicloud
239
+ return @impl.attach_volume(params) unless @multicloud
240
+ end
241
+
242
+ def wait_for_state(st,timeout=1200)
243
+ if @multicloud and st == "stopped"
244
+ st = "inactive"
245
+ end
246
+ @impl.wait_for_state(st,timeout)
247
+ end
248
+
249
+ def save(new_params = nil)
250
+ if new_params
251
+ @impl.settings
252
+ if @multicloud
253
+ @impl.next_instance.params.merge!(translate_create_opts(new_params, :instance_only)["instance"])
254
+ else
255
+ @impl.params.merge!(translate_create_opts(new_params)["server"])
256
+ end
257
+ end
258
+ @impl.save
259
+ end
260
+
261
+ def update(new_params = nil)
262
+ save(new_params)
263
+ end
264
+ end
@@ -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
@@ -13,9 +13,9 @@
13
13
  # You should have received a copy of the GNU General Public License
14
14
  # along with RestConnection. If not, see <http://www.gnu.org/licenses/>.
15
15
 
16
- #
16
+ #
17
17
  # You must have special API access to use these internal API calls.
18
- #
18
+ #
19
19
  class ServerInternal
20
20
  include RightScale::Api::Base
21
21
  extend RightScale::Api::BaseExtend
@@ -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
@@ -13,9 +13,12 @@
13
13
  # You should have received a copy of the GNU General Public License
14
14
  # along with RestConnection. If not, see <http://www.gnu.org/licenses/>.
15
15
 
16
- class ServerTemplate
16
+ class ServerTemplate
17
17
  include RightScale::Api::Base
18
18
  extend RightScale::Api::BaseExtend
19
+ include RightScale::Api::Taggable
20
+ extend RightScale::Api::TaggableExtend
21
+
19
22
  def initialize(params)
20
23
  @params = params
21
24
  end
@@ -42,7 +45,7 @@ class ServerTemplate
42
45
  end
43
46
  @params["alert_specs"] = as
44
47
  end
45
-
48
+
46
49
  def multi_cloud_images
47
50
  unless @params["multi_cloud_images"]
48
51
  fetch_multi_cloud_images
@@ -60,7 +63,15 @@ class ServerTemplate
60
63
  end
61
64
 
62
65
  def fetch_multi_cloud_images
63
- @params["multi_cloud_images"] = RsInternal.get_server_template_multi_cloud_images(self.href)
66
+ @params["multi_cloud_images"] = []
67
+ ServerTemplateInternal.new(:href => self.href).multi_cloud_images.each { |mci_params|
68
+ @params["multi_cloud_images"] << MultiCloudImageInternal.new(mci_params)
69
+ }
70
+ mcis = McServerTemplate.find(self.rs_id.to_i).multi_cloud_images
71
+ @params["multi_cloud_images"].each_index { |i|
72
+ @params["multi_cloud_images"][i]["multi_cloud_image_cloud_settings"] += mcis[i].settings
73
+ }
74
+ @params["multi_cloud_images"]
64
75
  end
65
76
 
66
77
  # The RightScale api calls this 'duplicate' but is more popularly known as 'clone' from a users perspective
@@ -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
@@ -13,7 +13,7 @@
13
13
  # You should have received a copy of the GNU General Public License
14
14
  # along with RestConnection. If not, see <http://www.gnu.org/licenses/>.
15
15
 
16
- class ServerTemplateInternal
16
+ class ServerTemplateInternal
17
17
  include RightScale::Api::Base
18
18
  extend RightScale::Api::BaseExtend
19
19
  include RightScale::Api::Internal
@@ -39,7 +39,7 @@ class ServerTemplateInternal
39
39
  t = URI.parse(self.href)
40
40
  connection.put(t.path + "/add_multi_cloud_image", :multi_cloud_image_href => mci_href)
41
41
  end
42
-
42
+
43
43
  def delete_multi_cloud_image(mci_href)
44
44
  t = URI.parse(self.href)
45
45
  connection.put(t.path + "/delete_multi_cloud_image", :multi_cloud_image_href => mci_href)
@@ -75,7 +75,7 @@ class ServerTemplateInternal
75
75
  connection.post(t.path + "/add_executable", params)
76
76
  end
77
77
 
78
- # <~Executable> executable, an Executable object to delete
78
+ # <~Executable> executable, an Executable object to delete
79
79
  # <~String> Apply, a string designating the type of executable: "boot", "operational", "decommission". Default is operational
80
80
  def delete_executable(executable, apply="operational")
81
81
  t = URI.parse(self.href)
@@ -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
@@ -17,7 +17,7 @@
17
17
 
18
18
  #This is the v4 image only work status api.
19
19
  # was used by Server#run_script (depricating..)
20
- class Status
20
+ class Status
21
21
  include RightScale::Api::Base
22
22
  extend RightScale::Api::BaseExtend
23
23
  def wait_for_completed(audit_link = "no audit link available", timeout = 900)
@@ -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
@@ -13,7 +13,7 @@
13
13
  # You should have received a copy of the GNU General Public License
14
14
  # along with RestConnection. If not, see <http://www.gnu.org/licenses/>.
15
15
 
16
- class Tag
16
+ class Tag
17
17
  include RightScale::Api::Base
18
18
  extend RightScale::Api::BaseExtend
19
19
 
@@ -0,0 +1,47 @@
1
+ # This file is part of RestConnection
2
+ #
3
+ # RestConnection is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # RestConnection is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with RestConnection. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ #
17
+ # You must have Beta v1.5 API access to use these internal API calls.
18
+ #
19
+ class Task
20
+ include RightScale::Api::Gateway
21
+ extend RightScale::Api::GatewayExtend
22
+
23
+ def self.parse_args(cloud_id, instance_id)
24
+ "clouds/#{cloud_id}/instances/#{instance_id}/live/"
25
+ end
26
+
27
+ def show
28
+ url = URI.parse(self.href)
29
+ @params.merge! connection.get(url.path)#, 'view' => "extended")
30
+ end
31
+
32
+ def wait_for_state(state, timeout=900)
33
+ while(timeout > 0)
34
+ show
35
+ return true if self.summary.include?(state)
36
+ connection.logger("state is #{self.summary}, waiting for #{state}")
37
+ raise "FATAL error:\n\n #{self.summary} \n\n" if self.summary.include?('failed') # TODO #{self.detail}
38
+ sleep 30
39
+ timeout -= 30
40
+ end
41
+ raise "FATAL: Timeout waiting for Executable to complete. State was #{self.summary}" if timeout <= 0
42
+ end
43
+
44
+ def wait_for_completed(legacy=nil)
45
+ wait_for_state("completed")
46
+ end
47
+ end
@@ -0,0 +1,27 @@
1
+ # This file is part of RestConnection
2
+ #
3
+ # RestConnection is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # RestConnection is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with RestConnection. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ #
17
+ # You must have Beta v1.5 API access to use these internal API calls.
18
+ #
19
+
20
+ #
21
+ # User Resource requires "admin" role
22
+ #
23
+
24
+ class User
25
+ include RightScale::Api::Gateway
26
+ extend RightScale::Api::GatewayExtend
27
+ end