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
@@ -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