rest_connection 0.1.2 → 0.1.3

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.
data/Rakefile CHANGED
@@ -3,13 +3,14 @@ require 'jeweler'
3
3
  Jeweler::Tasks.new do |gemspec|
4
4
  gemspec.name = "rest_connection"
5
5
  gemspec.summary = "Modular RESTful API library"
6
- gemspec.description = "Current implemented modules: RightScale API"
6
+ gemspec.description = "A Modular RESTful API library. Current implemented modules: RightScale API"
7
7
  gemspec.email = ["jeremy@rubyonlinux.org", "tw.rodriguez@gmail.com"]
8
- gemspec.homepage = "http://github.com/twrodriguez/rest_connection"
8
+ gemspec.homepage = "http://github.com/rightscale/rest_connection"
9
9
  gemspec.authors = ["Jeremy Deininger", "Timothy Rodriguez"]
10
10
  gemspec.add_dependency('activesupport', "=2.3.10")
11
11
  gemspec.add_dependency('net-ssh', "=2.1.4")
12
12
  gemspec.add_dependency('json')
13
13
  gemspec.add_dependency('highline')
14
+ gemspec.add_dependency('rest-client')
14
15
  end
15
16
  Jeweler::GemcutterTasks.new
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.1.3
@@ -24,55 +24,6 @@ require 'logger'
24
24
  require 'highline/import'
25
25
 
26
26
  module RestConnection
27
- AWS_CLOUDS = [
28
- {"cloud_id" => 1, "name" => "AWS US-East"},
29
- {"cloud_id" => 2, "name" => "AWS EU"},
30
- {"cloud_id" => 3, "name" => "AWS US-West"},
31
- {"cloud_id" => 4, "name" => "AWS AP-Singapore"},
32
- {"cloud_id" => 5, "name" => "AWS AP-Tokyo"},
33
- {"cloud_id" => 6, "name" => "AWS US-Oregon"},
34
- {"cloud_id" => 7, "name" => "AWS SA-Sao Paulo"},
35
- ]
36
-
37
- # Check for API 0.1 Access
38
- def self.api0_1?
39
- unless class_variable_defined?("@@api0_1")
40
- begin
41
- Ec2SshKeyInternal.find_all
42
- @@api0_1 = true
43
- rescue
44
- @@api0_1 = false
45
- end
46
- end
47
- return @@api0_1
48
- end
49
-
50
- # Check for API 1.0 Access
51
- def self.api1_0?
52
- unless class_variable_defined?("@@api1_0")
53
- begin
54
- Ec2SecurityGroup.find_all
55
- @@api1_0 = true
56
- rescue
57
- @@api1_0 = false
58
- end
59
- end
60
- return @@api1_0
61
- end
62
-
63
- # Check for API 1.5 Beta Access
64
- def self.api1_5?
65
- unless class_variable_defined?("@@api1_5")
66
- begin
67
- Cloud.find_all
68
- @@api1_5 = true
69
- rescue
70
- @@api1_5 = false
71
- end
72
- end
73
- return @@api1_5
74
- end
75
-
76
27
  class Connection
77
28
  # Settings is a hash of options for customizing the connection.
78
29
  # settings.merge! {
@@ -94,15 +45,23 @@ module RestConnection
94
45
  @@user = nil
95
46
  @@pass = nil
96
47
  etc_config = File.join("#{File::SEPARATOR}etc", "rest_connection", "rest_api_config.yaml")
97
- if File.exists?(config_yaml)
48
+ app_bin_dir = File.expand_path(File.dirname(caller.last))
49
+ app_yaml = File.join(app_bin_dir,"..","config","rest_api_config.yaml")
50
+ if config_yaml.is_a?(Hash)
51
+ @settings = config_yaml
52
+ elsif File.exists?(app_yaml)
53
+ @settings = YAML::load(IO.read(app_yaml))
54
+ elsif File.exists?(config_yaml)
98
55
  @settings = YAML::load(IO.read(config_yaml))
99
56
  elsif File.exists?(etc_config)
100
57
  @settings = YAML::load(IO.read(etc_config))
101
58
  else
102
- logger("\nWARNING: you must setup config file rest_api_config.yaml in #{config_yaml} or #{etc_config}")
59
+ logger("\nWARNING: you must setup config file rest_api_config.yaml in #{app_yaml} or #{config_yaml} or #{etc_config}")
103
60
  logger("WARNING: see GEM_HOME/rest_connection/config/rest_api_config.yaml for example config")
104
61
  @settings = {}
105
62
  end
63
+ @settings.keys.each { |k| @settings[k.to_sym] = @settings[k] if String === k }
64
+
106
65
  @settings[:extension] = ".js"
107
66
  @settings[:api_href] = @settings[:api_url] unless @settings[:api_href]
108
67
  unless @settings[:user]
@@ -13,6 +13,9 @@ class Hash
13
13
  def deep_merge(second)
14
14
  target = dup
15
15
  return target unless second
16
+ unless Hash === second
17
+ raise TypeError.new("can't convert #{second.class} into #{self.class}")
18
+ end
16
19
  second.keys.each do |k|
17
20
  if second[k].is_a? Array and self[k].is_a? Array
18
21
  target[k] = target[k].deep_merge(second[k])
@@ -32,6 +35,9 @@ class Hash
32
35
 
33
36
  def deep_merge!(second)
34
37
  return nil unless second
38
+ unless Hash === second
39
+ raise TypeError.new("can't convert #{second.class} into #{self.class}")
40
+ end
35
41
  second.each_pair do |k,v|
36
42
  if self[k].is_a?(Array) and second[k].is_a?(Array)
37
43
  self[k].deep_merge!(second[k])
@@ -50,6 +56,9 @@ class Array
50
56
  def deep_merge(second)
51
57
  target = dup
52
58
  return target unless second
59
+ unless Array === second
60
+ raise TypeError.new("can't convert #{second.class} into #{self.class}")
61
+ end
53
62
  second.each_index do |k|
54
63
  if second[k].is_a? Array and self[k].is_a? Array
55
64
  target[k] = target[k].deep_merge(second[k])
@@ -65,6 +74,9 @@ class Array
65
74
 
66
75
  def deep_merge!(second)
67
76
  return nil unless second
77
+ unless Array === second
78
+ raise TypeError.new("can't convert #{second.class} into #{self.class}")
79
+ end
68
80
  second.each_index do |k|
69
81
  if self[k].is_a?(Array) and second[k].is_a?(Array)
70
82
  self[k].deep_merge!(second[k])
@@ -0,0 +1,70 @@
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 Backup
20
+ include RightScale::Api::Gateway
21
+ extend RightScale::Api::GatewayExtend
22
+
23
+ deny_methods :index
24
+
25
+ def self.filters
26
+ [:cloud_href, :committed, :completed, :from_master, :latest_before]
27
+ end
28
+
29
+ def self.find_all(lineage)
30
+ index(lineage)
31
+ end
32
+
33
+ def self.find_with_filter(lineage, filter={})
34
+ index(lineage, filter)
35
+ end
36
+
37
+ def self.index(lineage, filter={})
38
+ filter_params = []
39
+ filter.each { |key,val|
40
+ unless self.filters.include?(key.to_sym)
41
+ raise ArgumentError.new("#{key} is not a valid filter for resource #{self.resource_singular_name}")
42
+ end
43
+ filter_params << "#{key}==#{val}"
44
+ }
45
+
46
+ a = Array.new
47
+ url = self.resource_plural_name
48
+ hsh = {'lineage' => lineage}
49
+ hsh.merge(:filter => filter_params) unless filter_params.empty?
50
+ connection.get(url, hsh).each do |object|
51
+ a << self.new(object)
52
+ end
53
+
54
+ return a
55
+ end
56
+
57
+ def self.cleanup(lineage, keep_last, params={})
58
+ params.merge!('keep_last' => keep_last, 'lineage' => lineage)
59
+ connection.post(resource_plural_name + "/cleanup", params)
60
+ end
61
+
62
+ def restore(instance_href, name=nil, description=nil)
63
+ uri = URI.parse(self.href)
64
+ params = {'instance_href' => instance_href}
65
+ params.deep_merge!({'backup' => {'name' => name}}) if name
66
+ params.deep_merge!({'backup' => {'description' => description}}) if description
67
+ location = connection.post(uri.path + "/restore", params)
68
+ Task.new('href' => location)
69
+ end
70
+ end
@@ -19,6 +19,15 @@ class Ec2ServerArray
19
19
  include RightScale::Api::Taggable
20
20
  extend RightScale::Api::TaggableExtend
21
21
 
22
+ attr_accessor :internal
23
+
24
+ def initialize(*args, &block)
25
+ super(*args, &block)
26
+ if RightScale::Api::api0_1?
27
+ @internal = Ec2ServerArrayInternal.new(*args, &block)
28
+ end
29
+ end
30
+
22
31
  # Example:
23
32
  # right_script = @server_template.executables.first
24
33
  # result = @my_array.run_script_on_all(right_script, [@server_template.href])
@@ -0,0 +1,43 @@
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
+ class Ec2ServerArray
17
+ include RightScale::Api::Base
18
+ extend RightScale::Api::BaseExtend
19
+ include RightScale::Api::Taggable
20
+ extend RightScale::Api::TaggableExtend
21
+
22
+ deny_methods :index, :show, :create, :update, :destroy
23
+
24
+ def run_script_on_instances(script, ec2_instance_hrefs=[], opts={})
25
+ uri = URI.parse(self.href)
26
+ case script
27
+ when Executable then script = script.right_script
28
+ when String then script = RightScript.new('href' => script)
29
+ end
30
+
31
+ params = {:right_script_href => script.href}
32
+ unless ec2_instance_hrefs.nil? || ec2_instance_hrefs.empty?
33
+ params[:ec2_instance_hrefs] = ec2_instance_hrefs
34
+ end
35
+ unless opts.nil? || opts.empty?
36
+ params[:parameters] = opts
37
+ end
38
+ params = {:ec2_server_array => params}
39
+ connection.post(uri.path + "/run_script_on_instances", params).map do |work_unit|
40
+ Status.new('href' => location)
41
+ end
42
+ end
43
+ end
@@ -19,6 +19,8 @@ class Ec2SshKey
19
19
 
20
20
  deny_methods :index, :update
21
21
 
22
+ attr_accessor :internal
23
+
22
24
  def self.create(opts)
23
25
  create_opts = { self.resource_singular_name.to_sym => opts }
24
26
  create_opts['cloud_id'] = opts['cloud_id'] if opts['cloud_id']
@@ -27,4 +29,11 @@ class Ec2SshKey
27
29
  newrecord.reload
28
30
  newrecord
29
31
  end
32
+
33
+ def initialize(*args, &block)
34
+ super(*args, &block)
35
+ if RightScale::Api::api0_1?
36
+ @internal = Ec2SshKeyInternal.new(*args, &block)
37
+ end
38
+ end
30
39
  end
@@ -16,10 +16,11 @@
16
16
  class Ec2SshKeyInternal
17
17
  include RightScale::Api::Base
18
18
  extend RightScale::Api::BaseExtend
19
-
20
19
  include RightScale::Api::Internal
21
20
  extend RightScale::Api::InternalExtend
22
21
 
22
+ deny_methods :show, :create, :update, :destroy
23
+
23
24
  def resource_plural_name
24
25
  "ec2_ssh_keys"
25
26
  end
@@ -35,5 +36,4 @@ class Ec2SshKeyInternal
35
36
  def self.resource_singular_name
36
37
  "ec2_ssh_key"
37
38
  end
38
-
39
39
  end
@@ -0,0 +1,101 @@
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 McAuditEntry
20
+ include RightScale::Api::Gateway
21
+ extend RightScale::Api::GatewayExtend
22
+
23
+ deny_methods :destroy, :index
24
+
25
+ def resource_plural_name
26
+ "audit_entries"
27
+ end
28
+
29
+ def resource_singular_name
30
+ "audit_entry"
31
+ end
32
+
33
+ def self.resource_plural_name
34
+ "audit_entries"
35
+ end
36
+
37
+ def self.resource_singular_name
38
+ "audit_entry"
39
+ end
40
+
41
+ def self.filters
42
+ [:auditee_href, :user_email]
43
+ end
44
+
45
+ def self.find_all(start_date=nil, end_date=nil, limit=1000)
46
+ start_date ||= (Time.now.utc - (60*60*24*31)).strftime(RightScale::Api::DATETIME_FMT)
47
+ end_date ||= Time.now.utc.strftime(RightScale::Api::DATETIME_FMT)
48
+ index(start_date, end_date, limit)
49
+ end
50
+
51
+ def self.find_with_filter(start_date, end_date, limit, filter)
52
+ index(start_date, end_date, limit, filter)
53
+ end
54
+
55
+ def self.index(start_date, end_date, limit=1000, filter={})
56
+ # Validate index params
57
+ ex_fmt = "2011/06/25 00:00:00 +0000"
58
+ regex = /^(\d{4})\/(\d{2})\/(\d{2}) (\d{2}):(\d{2}):(\d{2}) ([+-]\d{4})$/
59
+ unless start_date =~ regex
60
+ raise ArgumentError.new("start_date doesn't match format. e.g., #{ex_fmt}")
61
+ end
62
+ unless end_date =~ regex
63
+ raise ArgumentError.new("end_date doesn't match format. e.g., #{ex_fmt}")
64
+ end
65
+ unless (1..1000) === limit.to_i
66
+ raise ArgumentError.new("limit is not within the range of 1..1000")
67
+ end
68
+ filter_params = []
69
+ filter.each { |key,val|
70
+ unless self.filters.include?(key.to_sym)
71
+ raise ArgumentError.new("#{key} is not a valid filter for resource #{self.resource_singular_name}")
72
+ end
73
+ filter_params << "#{key}==#{val}"
74
+ }
75
+
76
+ a = Array.new
77
+ url = self.resource_plural_name
78
+ if filter_params.empty?
79
+ connection.get(url).each do |object|
80
+ a << self.new(object)
81
+ end
82
+ else
83
+ connection.get(url, :filter => filter_params).each do |object|
84
+ a << self.new(object)
85
+ end
86
+ end
87
+
88
+ return a
89
+ end
90
+
91
+ def append(detail, offset)
92
+ uri = URI.parse(self.href)
93
+ connection.post(uri.path + "/append", 'detail' => detail, 'offset' => offset)
94
+ end
95
+
96
+ def detail
97
+ uri = URI.parse(self.href)
98
+ res = connection.post(uri.path + "/detail")
99
+ return res.body
100
+ end
101
+ end
@@ -181,37 +181,26 @@ class McServer < Server
181
181
  return cloud_href.split("/").last.to_i
182
182
  end
183
183
 
184
- =begin
185
- def wait_for_operational_with_dns(state_wait_timeout=1200)
186
- timeout = 600
187
- wait_for_state("operational", state_wait_timeout)
188
- step = 15
189
- while(timeout > 0)
190
- self.settings
191
- break if self.reachable_ip
192
- connection.logger "waiting for any IP for #{self.nickname}"
193
- sleep step
194
- timeout -= step
195
- end
196
- connection.logger "got IP: #{self.reachable_ip}"
197
- raise "FATAL, this server #{self.audit_link} timed out waiting for an IP" if timeout <= 0
198
- end
199
- =end
200
-
201
184
  def dns_name
202
185
  self.settings
186
+ ret = nil
203
187
  if @current_instance
204
- return @current_instance.public_ip_addresses.first || @current_instance.public_dns_names.first
188
+ ret ||= @current_instance.public_ip_addresses.first
189
+ ret ||= @current_instance.public_dns_names.first
190
+ ret ||= get_tags_by_namespace("server")["current_instance"]["public_ip_0"]
205
191
  end
206
- nil
192
+ ret
207
193
  end
208
194
 
209
195
  def private_ip
210
196
  self.settings
197
+ ret = nil
211
198
  if @current_instance
212
- return @current_instance.private_ip_addresses.first || @current_instance.private_dns_names.first
199
+ ret ||= @current_instance.private_ip_addresses.first
200
+ ret ||= @current_instance.private_dns_names.first
201
+ ret ||= get_tags_by_namespace("server")["current_instance"]["private_ip_0"]
213
202
  end
214
- nil
203
+ ret
215
204
  end
216
205
 
217
206
  def save
@@ -19,17 +19,30 @@ class MultiCloudImage
19
19
 
20
20
  deny_methods :create, :destroy, :update
21
21
 
22
+ attr_accessor :internal
23
+
22
24
  def supported_cloud_ids
23
25
  @params["multi_cloud_image_cloud_settings"].map { |mcics| mcics.cloud_id }
24
26
  end
25
27
 
26
28
  # You must have access to multiple APIs for this (0.1, and 1.5)
27
29
  def find_and_flatten_settings()
28
- some_settings = McMultiCloudImage.find(rs_id.to_i).get_settings
29
30
  internal = MultiCloudImageInternal.new("href" => self.href)
30
31
  internal.reload
31
- more_settings = internal.settings
32
- @params["multi_cloud_image_cloud_settings"] = some_settings + more_settings
32
+ total_image_count = internal.multi_cloud_image_cloud_settings.size
33
+ # The .settings call filters out non-ec2 images
34
+ more_settings = []
35
+ if total_image_count > internal.settings.size
36
+ more_settings = McMultiCloudImage.find(rs_id.to_i).get_settings
37
+ end
38
+ @params["multi_cloud_image_cloud_settings"] = internal.settings + more_settings
39
+ end
40
+
41
+ def initialize(*args, &block)
42
+ super(*args, &block)
43
+ if RightScale::Api::api0_1?
44
+ @internal = MultiCloudImageInternal.new(*args, &block)
45
+ end
33
46
  end
34
47
 
35
48
  end
@@ -19,6 +19,8 @@ class MultiCloudImageCloudSettingInternal
19
19
  include RightScale::Api::Internal
20
20
  extend RightScale::Api::InternalExtend
21
21
 
22
+ deny_methods :index, :show, :update
23
+
22
24
  def resource_plural_name
23
25
  "multi_cloud_image_cloud_settings"
24
26
  end
@@ -20,6 +20,8 @@ class RightScript
20
20
 
21
21
  deny_methods :create, :destroy, :update
22
22
 
23
+ attr_accessor :internal
24
+
23
25
  def self.from_yaml(yaml)
24
26
  scripts = []
25
27
  x = YAML.load(yaml)
@@ -44,4 +46,10 @@ class RightScript
44
46
  scripts
45
47
  end
46
48
 
49
+ def initialize(*args, &block)
50
+ super(*args, &block)
51
+ if RightScale::Api::api0_1?
52
+ @internal = RightScriptInternal.new(*args, &block)
53
+ end
54
+ end
47
55
  end
@@ -0,0 +1,92 @@
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-client'
17
+ RestClient.log = ENV["REST_CONNECTION_LOG"] || "stdout"
18
+
19
+ class RightScriptAttachmentInternal
20
+ include RightScale::Api::Base
21
+ extend RightScale::Api::BaseExtend
22
+ include RightScale::Api::Internal
23
+ extend RightScale::Api::InternalExtend
24
+
25
+ deny_methods :index, :create, :update
26
+
27
+ def resource_plural_name
28
+ "right_script_attachments"
29
+ end
30
+
31
+ def resource_singular_name
32
+ "right_script_attachment"
33
+ end
34
+
35
+ def self.resource_plural_name
36
+ "right_script_attachments"
37
+ end
38
+
39
+ def self.resource_singular_name
40
+ "right_script_attachment"
41
+ end
42
+
43
+ def self.get_s3_upload_params(right_script_href)
44
+ url = self.resource_plural_name + "/get_s3_upload_params"
45
+ params = {"right_script_href" => right_script_href}
46
+ params = {self.resource_singular_name => params}
47
+ connection.get(url, params)
48
+ end
49
+
50
+ =begin
51
+ def self.upload(filepath, right_script_href)
52
+ hsh = get_s3_upload_params(right_script_href)
53
+ params = {}
54
+ hsh.keys.each { |k| params[k.gsub(/-/,"_").to_sym] = hsh[k] }
55
+ params[:file] = File.new(filepath, 'rb')
56
+ req = RestClient::Request.new({
57
+ :method => :post,
58
+ :url => hsh["url"],
59
+ :payload => params,
60
+ :multipart => true,
61
+ })
62
+ s = req.payload.to_s
63
+ splitter = s.split("\r\n").first
64
+ a = s.split(/#{splitter}-?-?\r\n/)
65
+ a.push(a.delete(a.detect { |n| n =~ %r{name="file";} }))
66
+ new_payload = a.join(splitter + "\r\n") + splitter + "--\r\n"
67
+
68
+ uri = URI.parse(hsh["url"])
69
+ net_http = Net::HTTP::Post.new(uri.request_uri)
70
+ req.transmit(uri, net_http, new_payload)
71
+ # TODO: Precondition Failing
72
+
73
+ callback_uri = URI.parse(hsh["success_action_redirect"])
74
+ connection.get(callback_uri.request_uri)
75
+ end
76
+ =end
77
+
78
+ def download
79
+ self.reload unless @params["authenticated_s3_url"]
80
+ RestClient.get(@params["authenticated_s3_url"])
81
+ end
82
+
83
+ def download_to_file(path=Dir.pwd)
84
+ data = self.download
85
+ File.open(File.join(path, @params["filename"]), 'w') { |f| f.write(data) }
86
+ end
87
+
88
+ def reload
89
+ uri = URI.parse(self.href || "#{resource_plural_name}/#{@params["id"]}")
90
+ @params ? @params.merge!(connection.get(uri.path)) : @params = connection.get(uri.path)
91
+ end
92
+ end
@@ -20,6 +20,8 @@ class RightScriptInternal
20
20
  include RightScale::Api::Internal
21
21
  extend RightScale::Api::InternalExtend
22
22
 
23
+ deny_methods :index, :show
24
+
23
25
  def resource_plural_name
24
26
  "right_scripts"
25
27
  end
@@ -36,6 +38,9 @@ class RightScriptInternal
36
38
  "right_script"
37
39
  end
38
40
 
41
+ # NOTE: only RightScriptInternal.create() allows you to pass the ["script"] param.
42
+ # Need to request that .save() allows update to "script"
43
+
39
44
  # commits a rightscript
40
45
  def commit(message)
41
46
  t = URI.parse(self.href)
@@ -48,4 +53,23 @@ class RightScriptInternal
48
53
  RightScript.new(:href => connection.post(t.path + "/clone"))
49
54
  end
50
55
 
56
+ def fetch_right_script_attachments
57
+ t = URI.parse(self.href)
58
+ @params["attachments"] = []
59
+ connection.get(t.path + "/right_script_attachments").each { |obj|
60
+ obj.merge!("right_script_href" => self.href)
61
+ @params["attachments"] << RightScriptAttachmentInternal.new(obj)
62
+ }
63
+ @params["attachments"]
64
+ end
65
+
66
+ def attachments
67
+ @params["attachments"] ||= fetch_right_script_attachments
68
+ end
69
+
70
+ =begin
71
+ def upload_attachment(file) # TODO
72
+ filedata = (File.exists?(file) ? IO.read(file) : file)
73
+ end
74
+ =end
51
75
  end
@@ -17,6 +17,17 @@ require 'active_support/inflector'
17
17
 
18
18
  module RightScale
19
19
  module Api
20
+ DATETIME_FMT = "%Y/%m/%d %H:%M:%S +0000"
21
+ AWS_CLOUDS = [
22
+ {"cloud_id" => 1, "name" => "AWS US-East"},
23
+ {"cloud_id" => 2, "name" => "AWS EU"},
24
+ {"cloud_id" => 3, "name" => "AWS US-West"},
25
+ {"cloud_id" => 4, "name" => "AWS AP-Singapore"},
26
+ {"cloud_id" => 5, "name" => "AWS AP-Tokyo"},
27
+ {"cloud_id" => 6, "name" => "AWS US-Oregon"},
28
+ {"cloud_id" => 7, "name" => "AWS SA-Sao Paulo"},
29
+ ]
30
+
20
31
  BASE_COOKIE_REFRESH = proc do
21
32
  def refresh_cookie
22
33
  # login
@@ -30,9 +41,60 @@ module RightScale
30
41
  end
31
42
  end
32
43
 
33
- module BaseExtend
34
- def connection()
35
- @@connection ||= RestConnection::Connection.new
44
+ # Pass no arguments to reset to the default configuration,
45
+ # pass a hash to update the settings for all API Versions
46
+ def self.update_connection_settings(*settings)
47
+ if settings.size > 1
48
+ raise ArgumentError.new("wrong number of arguments (#{settings.size} for 1)")
49
+ end
50
+ konstants = constants.map { |c| const_get(c) }
51
+ konstants.reject! { |c| !(Module === c) }
52
+ konstants.reject! { |c| !(c.instance_methods.include?("connection")) }
53
+ konstants.each do |c|
54
+ c.instance_exec(settings) do |opts|
55
+ class_variable_set("@@connection", RestConnection::Connection.new(*opts))
56
+ end
57
+ end
58
+ @@api0_1, @@api1_0, @@api1_5 = nil, nil, nil
59
+ true
60
+ end
61
+
62
+ # Check for API 0.1 Access
63
+ def self.api0_1?
64
+ if class_variable_defined?("@@api0_1")
65
+ return @@api0_1 unless @@api0_1.nil?
66
+ end
67
+ Ec2SshKeyInternal.find_all
68
+ @@api0_1 = true
69
+ rescue RestConnection::Errors::Forbidden
70
+ @@api0_1 = false
71
+ end
72
+
73
+ # Check for API 1.0 Access
74
+ def self.api1_0?
75
+ if class_variable_defined?("@@api1_0")
76
+ return @@api1_0 unless @@api1_0.nil?
77
+ end
78
+ Ec2SecurityGroup.find_all
79
+ @@api1_0 = true
80
+ rescue RestConnection::Errors::Forbidden
81
+ @@api1_0 = false
82
+ end
83
+
84
+ # Check for API 1.5 Beta Access
85
+ def self.api1_5?
86
+ if class_variable_defined?("@@api1_5")
87
+ return @@api1_5 unless @@api1_5.nil?
88
+ end
89
+ Cloud.find_all
90
+ @@api1_5 = true
91
+ rescue RestConnection::Errors::Forbidden
92
+ @@api1_5 = false
93
+ end
94
+
95
+ module BaseConnection
96
+ def connection(*opts)
97
+ @@connection ||= RestConnection::Connection.new(*opts)
36
98
  settings = @@connection.settings
37
99
  settings[:common_headers]["X_API_VERSION"] = "1.0"
38
100
  settings[:api_href] = settings[:api_url]
@@ -45,6 +107,10 @@ module RightScale
45
107
  @@connection.refresh_cookie unless @@connection.cookie
46
108
  @@connection
47
109
  end
110
+ end
111
+
112
+ module BaseExtend
113
+ include RightScale::Api::BaseConnection
48
114
 
49
115
  def resource_plural_name
50
116
  self.to_s.underscore.pluralize
@@ -56,6 +122,10 @@ module RightScale
56
122
  # matches using result of block match expression
57
123
  # ex: Server.find_by(:nickname) { |n| n =~ /production/ }
58
124
  def find_by(attrib, &block)
125
+ attrib = attrib.to_sym
126
+ if self.filters.include?(attrib)
127
+ connection.logger("#{self} includes the filter '#{attrib}', you might be able to speed up this API call")
128
+ end
59
129
  self.find_all.select do |s|
60
130
  yield(s[attrib.to_s])
61
131
  end
@@ -204,27 +274,14 @@ module RightScale
204
274
  end
205
275
 
206
276
  module Base
277
+ include RightScale::Api::BaseConnection
278
+
207
279
  # The params hash of attributes for direct manipulation
208
280
  attr_accessor :params
209
281
  def initialize(params = {})
210
282
  @params = params
211
283
  end
212
284
 
213
- def connection()
214
- @@connection ||= RestConnection::Connection.new
215
- settings = @@connection.settings
216
- settings[:common_headers]["X_API_VERSION"] = "1.0"
217
- settings[:api_href] = settings[:api_url]
218
- settings[:extension] = ".js"
219
-
220
- unless @@connection.respond_to?(:refresh_cookie)
221
- @@connection.instance_exec(&(RightScale::Api::BASE_COOKIE_REFRESH))
222
- end
223
-
224
- @@connection.refresh_cookie unless @@connection.cookie
225
- @@connection
226
- end
227
-
228
285
  def resource_plural_name
229
286
  self.class.to_s.underscore.pluralize
230
287
  end
@@ -24,8 +24,26 @@ module RightScale
24
24
  end
25
25
  end
26
26
 
27
+ module GatewayConnection
28
+ def connection(*opts)
29
+ @@gateway_connection ||= RestConnection::Connection.new(*opts)
30
+ settings = @@gateway_connection.settings
31
+ settings[:common_headers]["X_API_VERSION"] = "1.5"
32
+ settings[:api_href], account = settings[:api_url].split(/\/acct\//) if settings[:api_url].include?("acct")
33
+ settings[:extension] = ".json"
34
+
35
+ unless @@gateway_connection.respond_to?(:refresh_cookie)
36
+ @@gateway_connection.instance_exec(&(RightScale::Api::GATEWAY_COOKIE_REFRESH))
37
+ end
38
+
39
+ @@gateway_connection.refresh_cookie unless @@gateway_connection.cookie
40
+ @@gateway_connection
41
+ end
42
+ end
43
+
27
44
  module Gateway
28
45
  include RightScale::Api::Base
46
+ include RightScale::Api::GatewayConnection
29
47
 
30
48
  def initialize(params = {})
31
49
  @params = parse_params(params)
@@ -35,27 +53,23 @@ module RightScale
35
53
  params
36
54
  end
37
55
 
38
- def connection
39
- @@gateway_connection ||= RestConnection::Connection.new
40
- settings = @@gateway_connection.settings
41
- settings[:common_headers]["X_API_VERSION"] = "1.5"
42
- settings[:api_href], account = settings[:api_url].split(/\/acct\//) if settings[:api_url].include?("acct")
43
- settings[:extension] = ".json"
56
+ def nickname
57
+ @params["nickname"] || @params["name"]
58
+ end
44
59
 
45
- unless @@gateway_connection.respond_to?(:refresh_cookie)
46
- @@gateway_connection.instance_exec(&(RightScale::Api::GATEWAY_COOKIE_REFRESH))
60
+ def rediscover
61
+ self.reload if @params['href']
62
+ raise "Cannot find attribute 'nickname' or 'name' in #{self.inspect}. Aborting." unless self.nickname
63
+ if self.class.filters.include?(:name)
64
+ @params = self.class.find_with_filter(:name => self.nickname).first.params
65
+ else
66
+ @params = self.class.find_by(:name) { |n| n == self.nickname }.first.params
47
67
  end
48
-
49
- @@gateway_connection.refresh_cookie unless @@gateway_connection.cookie
50
- @@gateway_connection
51
68
  end
52
69
 
53
70
  def hash_of_links
54
71
  ret = {}
55
- unless @params['links']# and not (@params['nickname'] or @params['name'])
56
- @params = Kernel.const_get(self.class.to_s).find_by(:name) { |n| n == self.nickname }.first.params
57
- connection.logger("in hash_of_links: @params = #{@params.inspect}") if ENV['REST_CONNECT_DEBUG']
58
- end
72
+ self.rediscover unless @params['links']
59
73
  @params['links'].each { |link| ret[link['rel']] = link['href'] } if @params['links']
60
74
  ret
61
75
  end
@@ -63,22 +77,14 @@ module RightScale
63
77
  def href
64
78
  return @params['href'] if @params['href']
65
79
  ret = nil
66
- unless @params['links']
67
- raise "Cannot find attribute 'nickname' or 'name' in #{self.inspect}. Aborting." unless self.nickname
68
- @params = Kernel.const_get(self.class.to_s).find_by(:name) { |n| n == self.nickname }.first.params
69
- connection.logger("in href: @params = #{@params.inspect}") if ENV['REST_CONNECT_DEBUG']
70
- end
80
+ self.rediscover unless @params['links']
71
81
  @params['links'].each { |link| ret = link['href'] if link['rel'] == 'self' }
72
82
  ret
73
83
  end
74
84
 
75
85
  def actions
76
86
  ret = []
77
- unless @params['actions']
78
- raise "Cannot find attribute 'nickname' or 'name' in #{self.inspect}. Aborting." unless self.nickname
79
- @params = Kernel.const_get(self.class.to_s).find_by(:name) { |n| n == self.nickname }.first.params
80
- connection.logger("in actions: @params = #{@params.inspect}") if ENV['REST_CONNECT_DEBUG']
81
- end
87
+ self.rediscover unless @params['actions']
82
88
  @params['actions'].each { |action| ret << action['rel'] }
83
89
  ret
84
90
  end
@@ -179,23 +185,14 @@ module RightScale
179
185
 
180
186
  module GatewayExtend
181
187
  include RightScale::Api::BaseExtend
182
- def connection
183
- @@gateway_connection ||= RestConnection::Connection.new
184
- settings = @@gateway_connection.settings
185
- settings[:common_headers]["X_API_VERSION"] = "1.5"
186
- settings[:api_href], account = settings[:api_url].split(/\/acct\//) if settings[:api_url].include?("acct")
187
- settings[:extension] = ".json"
188
-
189
- unless @@gateway_connection.respond_to?(:refresh_cookie)
190
- @@gateway_connection.instance_exec(&(RightScale::Api::GATEWAY_COOKIE_REFRESH))
191
- end
192
-
193
- @@gateway_connection.refresh_cookie unless @@gateway_connection.cookie
194
- @@gateway_connection
195
- end
188
+ include RightScale::Api::GatewayConnection
196
189
 
197
190
  def find_by(attrib, *args, &block)
191
+ attrib = attrib.to_sym
198
192
  attrib = :name if attrib == :nickname
193
+ if self.filters.include?(attrib)
194
+ connection.logger("#{self} includes the filter '#{attrib}', you might be able to speed up this API call")
195
+ end
199
196
  self.find_all(*args).select do |s|
200
197
  yield(s[attrib.to_s])
201
198
  end
@@ -212,7 +209,6 @@ module RightScale
212
209
  end
213
210
 
214
211
  def find_all(*args)
215
- # self.find_with_filter(*args, {})
216
212
  a = Array.new
217
213
  url = "#{parse_args(*args)}#{self.resource_plural_name}"
218
214
  connection.get(url).each do |object|
@@ -1,8 +1,8 @@
1
1
  module RightScale
2
2
  module Api
3
- module Internal
4
- def connection
5
- @@little_brother_connection ||= RestConnection::Connection.new
3
+ module InternalConnection
4
+ def connection(*opts)
5
+ @@little_brother_connection ||= RestConnection::Connection.new(*opts)
6
6
  settings = @@little_brother_connection.settings
7
7
  settings[:common_headers]["X_API_VERSION"] = "0.1"
8
8
  settings[:api_href] = settings[:api_url]
@@ -11,16 +11,12 @@ module RightScale
11
11
  end
12
12
  end
13
13
 
14
+ module Internal
15
+ include RightScale::Api::InternalConnection
16
+ end
17
+
14
18
  module InternalExtend
15
- def connection
16
- @@little_brother_connection ||= RestConnection::Connection.new
17
- settings = @@little_brother_connection.settings
18
- settings[:common_headers]["X_API_VERSION"] = "0.1"
19
- settings[:api_href] = settings[:api_url]
20
- settings[:extension] = ".js"
21
- @@little_brother_connection
22
- end
19
+ include RightScale::Api::InternalConnection
23
20
  end
24
21
  end
25
22
  end
26
-
@@ -20,24 +20,28 @@ require 'rest_connection/rightscale/rightscale_api_gateway'
20
20
  require 'rest_connection/rightscale/rightscale_api_taggable'
21
21
  require 'rest_connection/rightscale/rightscale_api_mc_taggable'
22
22
  require 'rest_connection/rightscale/rightscale_api_mc_input'
23
+ require 'rest_connection/ssh_hax'
23
24
  require 'rest_connection/rightscale/alert_spec_subject'
24
25
  require 'rest_connection/rightscale/server_ec2_ebs_volume'
25
26
  require 'rest_connection/rightscale/sqs_queue'
26
27
  require 'rest_connection/rightscale/executable'
27
28
  require 'rest_connection/rightscale/cloud_account'
29
+ require 'rest_connection/rightscale/server_internal'
28
30
  require 'rest_connection/rightscale/server'
29
31
  require 'rest_connection/rightscale/deployment'
30
32
  require 'rest_connection/rightscale/status'
33
+ require 'rest_connection/rightscale/server_template_internal'
31
34
  require 'rest_connection/rightscale/server_template'
32
- require 'rest_connection/rightscale/right_script'
33
35
  require 'rest_connection/rightscale/instance'
34
36
  require 'rest_connection/rightscale/ec2_security_group'
35
37
  require 'rest_connection/rightscale/vpc_dhcp_option'
38
+ require 'rest_connection/rightscale/ec2_ssh_key_internal'
36
39
  require 'rest_connection/rightscale/ec2_ssh_key'
37
- require 'rest_connection/rightscale/multi_cloud_image'
38
40
  require 'rest_connection/rightscale/tag'
39
41
  require 'rest_connection/rightscale/mc_tag'
40
42
  require 'rest_connection/rightscale/task'
43
+ require 'rest_connection/rightscale/backup'
44
+ require 'rest_connection/rightscale/mc_audit_entry'
41
45
  require 'rest_connection/rightscale/rs_internal'
42
46
  require 'rest_connection/rightscale/audit_entry'
43
47
  require 'rest_connection/rightscale/alert_spec'
@@ -47,7 +51,6 @@ require 'rest_connection/rightscale/mc_volume_attachment'
47
51
  require 'rest_connection/rightscale/mc_volume'
48
52
  require 'rest_connection/rightscale/mc_volume_snapshot'
49
53
  require 'rest_connection/rightscale/mc_volume_type'
50
- require 'rest_connection/rightscale/server_internal'
51
54
  require 'rest_connection/rightscale/mc_server'
52
55
  require 'rest_connection/rightscale/server_interface'
53
56
  require 'rest_connection/rightscale/mc_instance'
@@ -57,11 +60,13 @@ require 'rest_connection/rightscale/mc_multi_cloud_image_setting'
57
60
  require 'rest_connection/rightscale/mc_multi_cloud_image'
58
61
  require 'rest_connection/rightscale/mc_server_template_multi_cloud_image'
59
62
  require 'rest_connection/rightscale/mc_server_template'
60
- require 'rest_connection/rightscale/ec2_ssh_key_internal'
61
- require 'rest_connection/rightscale/server_template_internal'
63
+ require 'rest_connection/rightscale/right_script_attachment_internal'
62
64
  require 'rest_connection/rightscale/right_script_internal'
65
+ require 'rest_connection/rightscale/right_script'
63
66
  require 'rest_connection/rightscale/multi_cloud_image_cloud_setting_internal'
64
67
  require 'rest_connection/rightscale/multi_cloud_image_internal'
68
+ require 'rest_connection/rightscale/multi_cloud_image'
69
+ require 'rest_connection/rightscale/ec2_server_array_internal'
65
70
  require 'rest_connection/rightscale/ec2_server_array'
66
71
  require 'rest_connection/rightscale/mc_server_array'
67
72
  require 'rest_connection/rightscale/security_group_rule'
@@ -13,8 +13,6 @@
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
- require 'rest_connection/ssh_hax'
17
-
18
16
  class Server
19
17
  include RightScale::Api::Base
20
18
  extend RightScale::Api::BaseExtend
@@ -22,6 +20,8 @@ class Server
22
20
  include RightScale::Api::Taggable
23
21
  extend RightScale::Api::TaggableExtend
24
22
 
23
+ attr_accessor :internal
24
+
25
25
  def self.filters
26
26
  [
27
27
  :aws_id,
@@ -47,6 +47,13 @@ class Server
47
47
  newrecord
48
48
  end
49
49
 
50
+ def initialize(*args, &block)
51
+ super(*args, &block)
52
+ if RightScale::Api::api0_1?
53
+ @internal = ServerInternal.new(*args, &block)
54
+ end
55
+ end
56
+
50
57
  # The RightScale api returns the server parameters as a hash with "name" and "value".
51
58
  # This must be transformed into a hash in case we want to PUT this back to the API.
52
59
  def transform_parameters(parameters)
@@ -328,16 +335,10 @@ class Server
328
335
  if self.state == "operational"
329
336
  return self["cloud_id"]
330
337
  end
331
- cloud_ids = RestConnection::AWS_CLOUDS.map { |hsh| hsh["cloud_id"] }
332
-
333
- api0_1 = false
334
- begin
335
- api0_1 = true if Ec2SshKeyInternal.find_all
336
- rescue
337
- end
338
+ cloud_ids = RightScale::Api::AWS_CLOUDS.map { |hsh| hsh["cloud_id"] }
338
339
 
339
340
  # Try ssh keys
340
- if self.ec2_ssh_key_href and api0_1
341
+ if self.ec2_ssh_key_href and RightScale::Api::api0_1?
341
342
  ref = self.ec2_ssh_key_href
342
343
  cloud_ids.each { |cloud|
343
344
  if Ec2SshKeyInternal.find_by_cloud_id(cloud.to_s).select { |o| o.href == ref }.first
@@ -366,17 +367,26 @@ class Server
366
367
 
367
368
  def dns_name
368
369
  self.settings unless self["dns_name"]
370
+ if self.current_instance_href
371
+ self["dns_name"] ||= get_tags_by_namespace("server")["current_instance"]["public_ip_0"]
372
+ end
369
373
  self["dns_name"]
370
374
  end
371
375
 
372
376
  def private_ip
373
377
  self.settings unless @params["private-ip-address"]
378
+ if self.current_instance_href
379
+ self["private-ip-address"] ||= get_tags_by_namespace("server")["current_instance"]["private_ip_0"]
380
+ end
374
381
  @params["private-ip-address"]
375
382
  end
376
383
 
377
384
  def reachable_ip
378
- return self.dns_name if self.dns_name
379
- return self.private_ip if self.private_ip
385
+ if ret = self.dns_name
386
+ return ret
387
+ elsif ret = self.private_ip
388
+ return ret
389
+ end
380
390
  nil
381
391
  end
382
392
 
@@ -20,10 +20,11 @@ class ServerInternal
20
20
  include RightScale::Api::Base
21
21
  extend RightScale::Api::BaseExtend
22
22
  include SshHax
23
-
24
23
  include RightScale::Api::Internal
25
24
  extend RightScale::Api::InternalExtend
26
25
 
26
+ deny_methods :index, :show, :create, :destroy, :update
27
+
27
28
  def resource_plural_name
28
29
  "servers"
29
30
  end
@@ -19,8 +19,13 @@ class ServerTemplate
19
19
  include RightScale::Api::Taggable
20
20
  extend RightScale::Api::TaggableExtend
21
21
 
22
- def initialize(params)
23
- @params = params
22
+ attr_accessor :internal
23
+
24
+ def initialize(*args, &block)
25
+ super(*args, &block)
26
+ if RightScale::Api::api0_1?
27
+ @internal = ServerTemplateInternal.new(*args, &block)
28
+ end
24
29
  end
25
30
 
26
31
  def reload
@@ -19,6 +19,8 @@ class ServerTemplateInternal
19
19
  include RightScale::Api::Internal
20
20
  extend RightScale::Api::InternalExtend
21
21
 
22
+ deny_methods :index, :create, :show, :update, :destroy
23
+
22
24
  def resource_plural_name
23
25
  "server_templates"
24
26
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rest_connection
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 29
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 2
10
- version: 0.1.2
9
+ - 3
10
+ version: 0.1.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jeremy Deininger
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2012-01-26 00:00:00 Z
19
+ date: 2012-02-10 00:00:00 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: activesupport
@@ -78,7 +78,21 @@ dependencies:
78
78
  version: "0"
79
79
  type: :runtime
80
80
  version_requirements: *id004
81
- description: "Current implemented modules: RightScale API"
81
+ - !ruby/object:Gem::Dependency
82
+ name: rest-client
83
+ prerelease: false
84
+ requirement: &id005 !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ hash: 3
90
+ segments:
91
+ - 0
92
+ version: "0"
93
+ type: :runtime
94
+ version_requirements: *id005
95
+ description: "A Modular RESTful API library. Current implemented modules: RightScale API"
82
96
  email:
83
97
  - jeremy@rubyonlinux.org
84
98
  - tw.rodriguez@gmail.com
@@ -112,6 +126,7 @@ files:
112
126
  - lib/rest_connection/rightscale/alert_spec.rb
113
127
  - lib/rest_connection/rightscale/alert_spec_subject.rb
114
128
  - lib/rest_connection/rightscale/audit_entry.rb
129
+ - lib/rest_connection/rightscale/backup.rb
115
130
  - lib/rest_connection/rightscale/child_account.rb
116
131
  - lib/rest_connection/rightscale/cloud.rb
117
132
  - lib/rest_connection/rightscale/cloud_account.rb
@@ -122,12 +137,14 @@ files:
122
137
  - lib/rest_connection/rightscale/ec2_elastic_ip.rb
123
138
  - lib/rest_connection/rightscale/ec2_security_group.rb
124
139
  - lib/rest_connection/rightscale/ec2_server_array.rb
140
+ - lib/rest_connection/rightscale/ec2_server_array_internal.rb
125
141
  - lib/rest_connection/rightscale/ec2_ssh_key.rb
126
142
  - lib/rest_connection/rightscale/ec2_ssh_key_internal.rb
127
143
  - lib/rest_connection/rightscale/executable.rb
128
144
  - lib/rest_connection/rightscale/instance.rb
129
145
  - lib/rest_connection/rightscale/instance_type.rb
130
146
  - lib/rest_connection/rightscale/macro.rb
147
+ - lib/rest_connection/rightscale/mc_audit_entry.rb
131
148
  - lib/rest_connection/rightscale/mc_datacenter.rb
132
149
  - lib/rest_connection/rightscale/mc_deployment.rb
133
150
  - lib/rest_connection/rightscale/mc_image.rb
@@ -152,6 +169,7 @@ files:
152
169
  - lib/rest_connection/rightscale/multi_cloud_image_internal.rb
153
170
  - lib/rest_connection/rightscale/permission.rb
154
171
  - lib/rest_connection/rightscale/right_script.rb
172
+ - lib/rest_connection/rightscale/right_script_attachment_internal.rb
155
173
  - lib/rest_connection/rightscale/right_script_internal.rb
156
174
  - lib/rest_connection/rightscale/rightscale_api_base.rb
157
175
  - lib/rest_connection/rightscale/rightscale_api_gateway.rb
@@ -191,7 +209,7 @@ files:
191
209
  - spec/server_template_internal.rb
192
210
  - spec/spec_helper.rb
193
211
  - spec/tag_spec.rb
194
- homepage: http://github.com/twrodriguez/rest_connection
212
+ homepage: http://github.com/rightscale/rest_connection
195
213
  licenses: []
196
214
 
197
215
  post_install_message:
@@ -220,7 +238,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
220
238
  requirements: []
221
239
 
222
240
  rubyforge_project:
223
- rubygems_version: 1.8.10
241
+ rubygems_version: 1.7.2
224
242
  signing_key:
225
243
  specification_version: 3
226
244
  summary: Modular RESTful API library