rest_connection 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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