rest_connection 0.0.3 → 0.0.4

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/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ *.swp
2
+ *.swo
data/Rakefile CHANGED
@@ -9,6 +9,7 @@ Jeweler::Tasks.new do |gemspec|
9
9
  gemspec.authors = ["Jeremy Deininger"]
10
10
  gemspec.add_dependency('activesupport')
11
11
  gemspec.add_dependency('net-ssh')
12
+ gemspec.add_dependency('json')
12
13
  end
13
14
  Jeweler::GemcutterTasks.new
14
15
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.3
1
+ 0.0.4
@@ -1,7 +1,10 @@
1
1
  ---
2
+ :ssh_keys:
3
+ - ~/.ssh/my_server_key
4
+ - ~/.ssh/my_server_key-eu
5
+ - ~/.ssh/my_server_key-west
2
6
  :pass: myUltraSecurePasswordz
3
7
  :user: myUserEmail@MyMailDomain.com
4
8
  :api_url: https://my.rightscale.com/api/acct/00000000
5
- :ssh_key: ~/.ssh/my-server-key
6
9
  :common_headers:
7
10
  X_API_VERSION: "1.0"
data/examples/console.rb CHANGED
@@ -2,8 +2,6 @@ require 'rubygems'
2
2
  require 'rest_connection'
3
3
  require 'ruby-debug'
4
4
 
5
- s=Server.find(746271)
6
- s.relaunch
7
-
5
+ debugger
8
6
  puts "done!"
9
7
 
@@ -7,6 +7,7 @@ require 'net/ssh'
7
7
  opts = Trollop::options do
8
8
  opt :deployment, "deployment nickname", :type => :string, :required => true
9
9
  opt :only, "regex string matching the nickname of the servers you want to relaunch. This excludes servers that do not match\nExample --only ubuntu", :type => :string, :required => false
10
+ opt :hard, "hard reset, uninstalls right_resources premium gem (for code update), and restarts the instance agent", :type => :bool, :required => false
10
11
  end
11
12
 
12
13
  # find all servers in the deployment (the fast way)
@@ -16,13 +17,13 @@ servers = servers.select { |s| s.nickname =~ /#{opts[:only]}/ } if opts[:only]
16
17
 
17
18
  servers.each do |s|
18
19
  s.wait_for_operational_with_dns
19
- # s.spot_check("/opt/rightscale/sandbox/bin/gem uninstall right_resources_premium") do |result|
20
- # puts result
21
- # end
22
- # monit will restart it
23
- # OR-- monit -c /opt/rightscale/etc/monitrc restart instance
24
- # s.spot_check("rnac --stop instance") do |result|
25
- # puts result
26
- # end
27
- s.run_recipe("database_test::dev_pristine_restore")
20
+ if opts[:hard]
21
+ s.spot_check("gem uninstall right_resources_premium") do |result|
22
+ puts result
23
+ end
24
+ s.spot_check("monit restart instance") do |result|
25
+ puts result
26
+ end
27
+ end
28
+ s.run_recipe("database_test::dev_pristine_restore")
28
29
  end
@@ -169,13 +169,10 @@ module RestConnection
169
169
  def logger(message)
170
170
  init_message = "Initializing Logging using "
171
171
  if @@logger.nil?
172
- if @settings[:log_file]
173
- @@logger = Logger.new(@settings[:log_file])
174
- init_message += @settings[:log_file]
175
- elsif ENV['REST_CONNECTION_LOG']
172
+ if ENV['REST_CONNECTION_LOG']
176
173
  @@logger = Logger.new(ENV['REST_CONNECTION_LOG'])
177
174
  init_message += ENV['REST_CONNECTION_LOG']
178
- else @settings[:log_file]
175
+ else
179
176
  @@logger = Logger.new(STDOUT)
180
177
  init_message += "STDOUT"
181
178
  end
@@ -0,0 +1,44 @@
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 AuditEntry
17
+ # attr_accessor :status, :output
18
+ # def initialize(opts)
19
+ # @status = opts[:status]
20
+ # @output = opts[:output]
21
+ # end
22
+ # def wait_for_completed(audit_link = "no audit link available")
23
+ # raise "FATAL: script failed. see audit #{audit_link}" unless @status
24
+ # end
25
+ #end
26
+
27
+ class AuditEntry
28
+ include RightScale::Api::Base
29
+ extend RightScale::Api::BaseExtend
30
+
31
+ def wait_for_state(state)
32
+ while(1)
33
+ reload
34
+ connection.logger("state is #{self.state}, waiting for #{state}")
35
+ raise "FATAL error, script failed\nSee Audit: #{self.href}" if self.state == 'failed'
36
+ sleep 5
37
+ return true if state == self.state
38
+ end
39
+ end
40
+
41
+ def wait_for_completed(legacy=nil)
42
+ wait_for_state("completed")
43
+ end
44
+ end
@@ -13,7 +13,10 @@
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 Deployment < RightScale::Api::Base
16
+ class Deployment
17
+ include RightScale::Api::Base
18
+ extend RightScale::Api::BaseExtend
19
+
17
20
  def set_input(name, value)
18
21
  deploy_href = URI.parse(self.href)
19
22
  connection.put(deploy_href.path, :deployment => {:parameters => {name => value} })
@@ -13,5 +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 Ec2SecurityGroup < RightScale::Api::Base
16
+ class Ec2SecurityGroup
17
+ include RightScale::Api::Base
18
+ extend RightScale::Api::BaseExtend
17
19
  end
@@ -19,7 +19,9 @@
19
19
  # st.executables.find(:nickname
20
20
  # a.run_script_on_all(
21
21
 
22
- class Ec2ServerArray < RightScale::Api::Base
22
+ class Ec2ServerArray
23
+ include RightScale::Api::Base
24
+ extend RightScale::Api::BaseExtend
23
25
  def run_script_on_all(script, server_template_hrefs, inputs=nil)
24
26
  serv_href = URI.parse(self.href)
25
27
  options = Hash.new
@@ -13,5 +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 Ec2SshKey < RightScale::Api::Base
16
+ class Ec2SshKey
17
+ include RightScale::Api::Base
18
+ extend RightScale::Api::BaseExtend
17
19
  end
@@ -1,4 +1,6 @@
1
- class Executable < RightScale::Api::Base
1
+ class Executable
2
+ include RightScale::Api::Base
3
+ extend RightScale::Api::BaseExtend
2
4
 
3
5
  # executable can be EITHER a right_script or recipe
4
6
  # executable example params format:
@@ -16,7 +16,9 @@
16
16
  # This is an instance facing api and can only be used with
17
17
  # an authentication URL normally found in the instance's userdata called
18
18
  # RS_API_URL
19
- class Instance < RightScale::Api::Base
19
+ class Instance
20
+ include RightScale::Api::Base
21
+ extend RightScale::Api::BaseExtend
20
22
  #def create_ebs_volume_from_snap(snap_aws_id)
21
23
  # connection.post('create_ebs_volume.js', :aws_id => snap_aws_id )
22
24
  #end
@@ -13,5 +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 MultiCloudImage < RightScale::Api::Base
16
+ class MultiCloudImage
17
+ include RightScale::Api::Base
18
+ extend RightScale::Api::BaseExtend
17
19
  end
@@ -14,7 +14,9 @@
14
14
  # along with RestConnection. If not, see <http://www.gnu.org/licenses/>.
15
15
 
16
16
 
17
- class RightScript < RightScale::Api::Base
17
+ class RightScript
18
+ include RightScale::Api::Base
19
+ extend RightScale::Api::BaseExtend
18
20
  def self.from_yaml(yaml)
19
21
  scripts = []
20
22
  x = YAML.load(yaml)
@@ -17,51 +17,27 @@ require 'active_support'
17
17
 
18
18
  module RightScale
19
19
  module Api
20
- class Base
21
- # The params hash of attributes for direct manipulation
22
- attr_accessor :params
23
-
24
- def self.connection()
25
- @@connection ||= RestConnection::Connection.new
26
- end
20
+ module BaseExtend
27
21
  def connection()
28
22
  @@connection ||= RestConnection::Connection.new
29
23
  end
30
24
 
31
- def initialize(params = {})
32
- @params = params
33
- end
34
-
35
- def self.resource_plural_name
25
+ def resource_plural_name
36
26
  self.to_s.underscore.pluralize
37
27
  end
38
28
 
39
- def self.resource_singluar_name
29
+ def resource_singluar_name
40
30
  self.to_s.underscore
41
31
  end
42
-
43
- def resource_plural_name
44
- self.class.to_s.underscore.pluralize
45
- end
46
-
47
- def resource_singular_name
48
- self.class.to_s.underscore
49
- end
50
-
51
- def save
52
- uri = URI.parse(self.href)
53
- connection.put(uri.path, resource_singular_name.to_sym => @params)
54
- end
55
-
56
32
  # matches using result of block match expression
57
33
  # ex: Server.find_by(:nickname) { |n| n =~ /production/ }
58
- def self.find_by(attrib, &block)
34
+ def find_by(attrib, &block)
59
35
  self.find_all.select do |s|
60
36
  yield(s[attrib.to_s])
61
37
  end
62
38
  end
63
39
 
64
- def self.find_all
40
+ def find_all
65
41
  a = Array.new
66
42
  connection.get(self.resource_plural_name).each do |object|
67
43
  a << self.new(object)
@@ -69,21 +45,16 @@ module RightScale
69
45
  return a
70
46
  end
71
47
 
72
- def self.find_by_nickname(nickname)
48
+ def find_by_nickname(nickname)
73
49
  connection.logger("DEPRICATION WARNING: use of find_by_nickname is depricated, please use find_by(:nickname) { |n| n == '#{nickname}' } ")
74
50
  self.find_by(:nickname) { |n| n == nickname }
75
51
  end
76
52
 
77
- def reload
78
- uri = URI.parse(self.href)
79
- @params ? @params.merge!(connection.get(uri.path)) : @params = connection.get(uri.path)
80
- end
81
-
82
53
  # the argument can be
83
54
  # 1) takes href (URI),
84
55
  # 2) or id (Integer)
85
56
  # 3) or symbol :all, :first, :last
86
- def self.find(href, &block)
57
+ def find(href, &block)
87
58
  if href.is_a?(Integer)
88
59
  return self.new(connection.get(self.resource_plural_name + "/#{href}"))
89
60
  elsif href.is_a?(Symbol)
@@ -104,12 +75,12 @@ module RightScale
104
75
  nil
105
76
  end
106
77
 
107
- def self.find_by_id(id)
78
+ def find_by_id(id)
108
79
  connection.logger("DEPRICATION WARNING: use of find_by_id is depricated, please use find(id) ")
109
80
  self.find(id)
110
81
  end
111
82
 
112
- def self.create(opts)
83
+ def create(opts)
113
84
  location = connection.post(self.resource_plural_name, self.resource_singluar_name.to_sym => opts)
114
85
  newrecord = self.new('href' => location)
115
86
  newrecord.reload
@@ -117,12 +88,12 @@ module RightScale
117
88
  end
118
89
 
119
90
  # filter is only implemented on some api endpoints
120
- def self.find_by_nickname_speed(nickname)
91
+ def find_by_nickname_speed(nickname)
121
92
  self.find_with_filter('nickname' => nickname)
122
93
  end
123
94
 
124
95
  # filter is only implemented on some api endpoints
125
- def self.find_with_filter(filter = {})
96
+ def find_with_filter(filter = {})
126
97
  filter_params = ""
127
98
  filter.each {|key,val| filter_params += "filter[]=#{key}=#{val}&"}
128
99
  a = Array.new
@@ -131,6 +102,36 @@ module RightScale
131
102
  end
132
103
  return a
133
104
  end
105
+ end
106
+
107
+ module Base
108
+ # The params hash of attributes for direct manipulation
109
+ attr_accessor :params
110
+ def initialize(params = {})
111
+ @params = params
112
+ end
113
+
114
+ def connection()
115
+ @@connection ||= RestConnection::Connection.new
116
+ end
117
+
118
+ def resource_plural_name
119
+ self.class.to_s.underscore.pluralize
120
+ end
121
+
122
+ def resource_singular_name
123
+ self.class.to_s.underscore
124
+ end
125
+
126
+ def save
127
+ uri = URI.parse(self.href)
128
+ connection.put(uri.path, resource_singular_name.to_sym => @params)
129
+ end
130
+
131
+ def reload
132
+ uri = URI.parse(self.href)
133
+ @params ? @params.merge!(connection.get(uri.path)) : @params = connection.get(uri.path)
134
+ end
134
135
 
135
136
  def destroy
136
137
  my_href = URI.parse(self.href)
@@ -148,8 +149,11 @@ module RightScale
148
149
  elsif @params[mn_dash]
149
150
  @params[mn_dash] = args[0] if assignment
150
151
  return @params[mn_dash]
152
+ elsif @params[mn.to_sym]
153
+ return @params[mn.to_sym]
151
154
  else
152
- raise "called unknown method #{method_name} with #{args.inspect}"
155
+ return nil
156
+ #raise "called unknown method #{method_name} with #{args.inspect}"
153
157
  end
154
158
  end
155
159
 
@@ -24,3 +24,5 @@ require 'rest_connection/rightscale/ec2_security_group'
24
24
  require 'rest_connection/rightscale/ec2_ssh_key'
25
25
  require 'rest_connection/rightscale/multi_cloud_image'
26
26
  require 'rest_connection/rightscale/tag'
27
+ require 'rest_connection/rightscale/rs_internal'
28
+ require 'rest_connection/rightscale/audit_entry'
@@ -0,0 +1,42 @@
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 special API access to use these internal API calls.
18
+ #
19
+ class RsInternal
20
+ include RightScale::Api::Base
21
+ extend RightScale::Api::BaseExtend
22
+
23
+ def connection
24
+ @@little_brother_connection ||= RestConnection::Connection.new
25
+ @@little_brother_connection.settings[:common_headers] = { 'X-API-VERSION' => '0.1' }
26
+ @@little_brother_connection
27
+ end
28
+
29
+ def self.connection
30
+ @@little_brother_connection ||= RestConnection::Connection.new
31
+ @@little_brother_connection.settings[:common_headers] = { 'X-API-VERSION' => '0.1' }
32
+ @@little_brother_connection
33
+ end
34
+
35
+ def self.get_server_template_multi_cloud_images(server_template_href)
36
+ connection.get("rs_internal/get_server_template_multi_cloud_images","server_template_href=#{server_template_href}")
37
+ end
38
+
39
+ def self.set_server_multi_cloud_image(server_href, mci_href)
40
+ connection.put("rs_internal/set_server_multi_cloud_image", {:server_href => server_href, :multi_cloud_image_href => mci_href})
41
+ end
42
+ end
@@ -15,8 +15,11 @@
15
15
 
16
16
  require 'rest_connection/ssh_hax'
17
17
 
18
- class Server < RightScale::Api::Base
18
+ class Server
19
+ include RightScale::Api::Base
20
+ extend RightScale::Api::BaseExtend
19
21
  include SshHax
22
+
20
23
  def self.create(opts)
21
24
  create_options = Hash.new
22
25
  create_options[self.resource_singluar_name.to_sym] = opts
@@ -74,8 +77,34 @@ class Server < RightScale::Api::Base
74
77
  end
75
78
  end
76
79
 
77
- # This method takes a RightScript or Executable, and optional run time parameters in an options hash.
80
+ # This should be used with v5 images only.
81
+ # executable to run can be an Executable or RightScript object
82
+ def run_executable(executable, opts=nil)
83
+ script_options = Hash.new
84
+ script_options[:server] = Hash.new
85
+ if executable.is_a?(Executable)
86
+ if executable.recipe?
87
+ script_options[:server][:recipe] = executable.recipe
88
+ else
89
+ script_options[:server][:right_script_href] = executable.right_script.href
90
+ end
91
+ elsif executable.is_a?(RightScript)
92
+ script_options[:server][:right_script_href] = executable.href
93
+ else
94
+ raise "Invalid class passed to run_executable, needs Executable or RightScript, was:#{executable.class}"
95
+ end
96
+
97
+ serv_href = URI.parse(self.href)
98
+ script_options[:server][:parameters] = opts unless opts.nil?
99
+ location = connection.post(serv_href.path + '/run_executable', script_options)
100
+ AuditEntry.new('href' => location)
101
+ end
102
+
103
+ # This should be used with v4 images only.
78
104
  def run_script(script,opts=nil)
105
+ if script.is_a?(Executable)
106
+ script = script.right_script
107
+ end
79
108
  serv_href = URI.parse(self.href)
80
109
  script_options = Hash.new
81
110
  script_options[:server] = Hash.new
@@ -127,6 +156,7 @@ class Server < RightScale::Api::Base
127
156
  self.start
128
157
  end
129
158
 
159
+
130
160
  # DOES NOT WORK: fragile web scraping
131
161
  # def relaunch
132
162
  # unless state == "stopped"
@@ -13,7 +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
- class ServerTemplate < RightScale::Api::Base
16
+ class ServerTemplate
17
+ include RightScale::Api::Base
18
+ extend RightScale::Api::BaseExtend
17
19
  def initialize(params)
18
20
  @params = params
19
21
  fetch_executables
@@ -28,4 +30,9 @@ class ServerTemplate < RightScale::Api::Base
28
30
  end
29
31
  @params["executables"] = ex
30
32
  end
33
+
34
+ def fetch_multi_cloud_images
35
+ @params["multi_cloud_images"] = RsInternal.get_server_template_multi_cloud_images(self.href)
36
+ end
37
+
31
38
  end
@@ -12,8 +12,14 @@
12
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
+ #
16
+ # For now this is a stub for using with the ssh enabled Server#run_script
15
17
 
16
- class Status < RightScale::Api::Base
18
+ #This is the v4 image only work status api.
19
+ # was used by Server#run_script (depricating..)
20
+ class Status
21
+ include RightScale::Api::Base
22
+ extend RightScale::Api::BaseExtend
17
23
  def wait_for_completed(audit_link = "no audit link available")
18
24
  while(1)
19
25
  reload
@@ -13,7 +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
- class Tag < RightScale::Api::Base
16
+ class Tag
17
+ include RightScale::Api::Base
18
+ extend RightScale::Api::BaseExtend
17
19
 
18
20
  def self.search(resource_name, tags)
19
21
  result = connection.get("/tags/search", :resource_type => resource_name.to_s, :tags => tags )
@@ -35,18 +35,11 @@ module SshHax
35
35
  ssh_keys
36
36
  end
37
37
 
38
- # recipe can be either a String, or an Executable
39
- # host_dns is optional and will default to objects self.dns_name
40
- def run_recipe(recipe, ssh_key=nil, host_dns=self.dns_name)
41
- if recipe.is_a?(Executable)
42
- recipe = recipe.recipe
43
- end
38
+ def run_and_tail(run_this, tail_command, expect, ssh_key=nil, host_dns=self.dns_name)
44
39
  status = nil
45
40
  result = nil
46
41
  output = ""
47
- tail_command ="tail -f -n1 /var/log/messages"
48
- expect = /RightLink.*RS> ([completed|failed]+: < #{recipe} >)/
49
- run_this = "rs_run_recipe -n '#{recipe}'"
42
+ connection.logger("Running: #{run_this}")
50
43
  Net::SSH.start(host_dns, 'root', :keys => ssh_key_config(ssh_key)) do |ssh|
51
44
  cmd_channel = ssh.open_channel do |ch1|
52
45
  ch1.on_request('exit-status') do |ch, data|
@@ -93,12 +86,46 @@ module SshHax
93
86
  cmd_channel.wait
94
87
  log_channel.wait
95
88
  end
96
- success = result.include?('completed')
97
89
  connection.logger output
90
+ success = result.include?('completed')
98
91
  connection.logger "Converge failed. See server audit: #{self.audit_link}" unless success
99
92
  return {:status => success, :output => output}
100
93
  end
101
94
 
95
+ # script is an Executable object with minimally nick or id set
96
+ def run_executable_with_ssh(script, options={}, ssh_key=nil)
97
+ raise "FATAL: run_executable called on a server with no dns_name. You need to run .settings on the server to populate this attribute." unless self.dns_name
98
+ if script.is_a?(Executable)
99
+ script = script.right_script
100
+ end
101
+
102
+ raise "FATAL: unrecognized format for script. Must be an Executable or RightScript with href or name attributes" unless (script.is_a?(RightScript)) && (script.href || script.name)
103
+ if script.href
104
+ run_this = "rs_run_right_script -i #{script.href.split(/\//).last}"
105
+ elsif script.name
106
+ run_this = "rs_run_right_script -n #{script.name}"
107
+ end
108
+ tail_command ="tail -f -n1 /var/log/messages"
109
+ expect = /RightLink.*RS> ([completed|failed]+:)/
110
+ options.each do |key, value|
111
+ run_this += " -p #{key}=#{value}"
112
+ end
113
+ AuditEntry.new(run_and_tail(run_this, tail_command, expect))
114
+ end
115
+
116
+ # recipe can be either a String, or an Executable
117
+ # host_dns is optional and will default to objects self.dns_name
118
+ def run_recipe_with_ssh(recipe, ssh_key=nil, host_dns=self.dns_name)
119
+ raise "FATAL: run_script called on a server with no dns_name. You need to run .settings on the server to populate this attribute." unless self.dns_name
120
+ if recipe.is_a?(Executable)
121
+ recipe = recipe.recipe
122
+ end
123
+ tail_command ="tail -f -n1 /var/log/messages"
124
+ expect = /RightLink.*RS> ([completed|failed]+: < #{recipe} >)/
125
+ run_this = "rs_run_recipe -n '#{recipe}'"
126
+ run_and_tail(run_this, tail_command, expect, ssh_key)
127
+ end
128
+
102
129
  def spot_check(command, ssh_key=nil, host_dns=self.dns_name, &block)
103
130
  connection.logger "SSHing to #{host_dns}"
104
131
  Net::SSH.start(host_dns, 'root', :keys => ssh_key_config(ssh_key)) do |ssh|
@@ -116,7 +143,7 @@ module SshHax
116
143
 
117
144
  # returns hash of exit_status and output from command
118
145
  def spot_check_command(command, ssh_key=nil, host_dns=self.dns_name)
119
- connection.logger "SSHing to #{host_dns} using key #{ssh_key}"
146
+ connection.logger "SSHing to #{host_dns} using key(s) #{ssh_key_config(ssh_key)}"
120
147
  status = nil
121
148
  output = ""
122
149
  Net::SSH.start(host_dns, 'root', :keys => ssh_key_config(ssh_key)) do |ssh|
@@ -131,6 +158,7 @@ module SshHax
131
158
  status = 1
132
159
  end
133
160
  ch2.on_data do |ch, data|
161
+
134
162
  output += data
135
163
  end
136
164
  ch2.on_extended_data do |ch, type, data|
@@ -5,18 +5,19 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rest_connection}
8
- s.version = "0.0.3"
8
+ s.version = "0.0.4"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jeremy Deininger"]
12
- s.date = %q{2010-03-18}
12
+ s.date = %q{2010-04-15}
13
13
  s.description = %q{provides rest_connection}
14
14
  s.email = %q{jeremy@rubyonlinux.org}
15
15
  s.extra_rdoc_files = [
16
16
  "README"
17
17
  ]
18
18
  s.files = [
19
- "README",
19
+ ".gitignore",
20
+ "README",
20
21
  "Rakefile",
21
22
  "VERSION",
22
23
  "config/rest_api_config.yaml.sample",
@@ -31,6 +32,7 @@ Gem::Specification.new do |s|
31
32
  "examples/run_php_chef_sequence.rb",
32
33
  "examples/set_deployment_template_href.rb",
33
34
  "lib/rest_connection.rb",
35
+ "lib/rest_connection/rightscale/audit_entry.rb",
34
36
  "lib/rest_connection/rightscale/deployment.rb",
35
37
  "lib/rest_connection/rightscale/ec2_security_group.rb",
36
38
  "lib/rest_connection/rightscale/ec2_server_array.rb",
@@ -41,12 +43,15 @@ Gem::Specification.new do |s|
41
43
  "lib/rest_connection/rightscale/right_script.rb",
42
44
  "lib/rest_connection/rightscale/rightscale_api_base.rb",
43
45
  "lib/rest_connection/rightscale/rightscale_api_resources.rb",
46
+ "lib/rest_connection/rightscale/rs_internal.rb",
44
47
  "lib/rest_connection/rightscale/server.rb",
45
48
  "lib/rest_connection/rightscale/server_template.rb",
46
49
  "lib/rest_connection/rightscale/status.rb",
47
50
  "lib/rest_connection/rightscale/tag.rb",
48
51
  "lib/rest_connection/ssh_hax.rb",
49
- "rest_connection.gemspec"
52
+ "rest_connection.gemspec",
53
+ "spec/rs_internal_spec.rb",
54
+ "spec/server_spec.rb"
50
55
  ]
51
56
  s.homepage = %q{http://github.com/jeremyd/rest_connection}
52
57
  s.rdoc_options = ["--charset=UTF-8"]
@@ -54,17 +59,18 @@ Gem::Specification.new do |s|
54
59
  s.rubygems_version = %q{1.3.6}
55
60
  s.summary = %q{lib for restful connections to the rightscale api}
56
61
  s.test_files = [
57
- "examples/console.rb",
58
- "examples/dev_setup.rb",
59
- "examples/relaunch_deployment.rb",
62
+ "spec/server_spec.rb",
63
+ "spec/rs_internal_spec.rb",
60
64
  "examples/restart_instance_agent.rb",
65
+ "examples/console.rb",
66
+ "examples/run_php_chef_sequence.rb",
67
+ "examples/set_deployment_template_href.rb",
68
+ "examples/dev_setup.rb",
61
69
  "examples/right_scale_ec2_instances_api_test.rb",
62
- "examples/run_ebs_sequence.rb",
70
+ "examples/relaunch_deployment.rb",
63
71
  "examples/run_ebs_terminate.rb",
64
72
  "examples/run_mysql_chef_sequence.rb",
65
- "examples/run_php_chef_sequence.rb",
66
- "examples/set_deployment_images.rb",
67
- "examples/set_deployment_template_href.rb"
73
+ "examples/run_ebs_sequence.rb"
68
74
  ]
69
75
 
70
76
  if s.respond_to? :specification_version then
@@ -74,13 +80,16 @@ Gem::Specification.new do |s|
74
80
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
75
81
  s.add_runtime_dependency(%q<activesupport>, [">= 0"])
76
82
  s.add_runtime_dependency(%q<net-ssh>, [">= 0"])
83
+ s.add_runtime_dependency(%q<json>, [">= 0"])
77
84
  else
78
85
  s.add_dependency(%q<activesupport>, [">= 0"])
79
86
  s.add_dependency(%q<net-ssh>, [">= 0"])
87
+ s.add_dependency(%q<json>, [">= 0"])
80
88
  end
81
89
  else
82
90
  s.add_dependency(%q<activesupport>, [">= 0"])
83
91
  s.add_dependency(%q<net-ssh>, [">= 0"])
92
+ s.add_dependency(%q<json>, [">= 0"])
84
93
  end
85
94
  end
86
95
 
@@ -0,0 +1,26 @@
1
+ require 'rubygems'
2
+ require 'rest_connection'
3
+ require 'spec'
4
+ require 'ruby-debug'
5
+
6
+ describe RsInternal, "exercises the rs_internal api" do
7
+ before(:all) do
8
+ @st = ServerTemplate.find(27418)
9
+ end
10
+
11
+ # this will never be checked in, these tests are too hardwired
12
+ # (doesn't mean it's not useful)
13
+ it "should get all the mcis for this hardcoded template and set this hardcoded server" do
14
+ mcis = RsInternal.get_server_template_multi_cloud_images(@st.href)
15
+ mcis.empty?.should_not == true
16
+ mcis.first['href'].include?("https://").should == true
17
+
18
+ server = "/servers/752944"
19
+ success = RsInternal.set_server_multi_cloud_image(server, mcis.first['href'])
20
+
21
+ debugger
22
+ puts "blah"
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,34 @@
1
+ require 'rubygems'
2
+ require 'rest_connection'
3
+ require 'spec'
4
+ require 'ruby-debug'
5
+
6
+ describe Server, "server api object exercise" do
7
+ before(:all) do
8
+ @server_v4_right_script = Server.find(752616) # a v4 server
9
+ @server_v5_recipe = Server.find(697640) # a v5 server
10
+ @server_v5_right_script = Server.find() # a v5 server
11
+ end
12
+
13
+ it "should run a right_script on a v4 server" do
14
+ this_template = ServerTemplate.find(@server_v4_right_script.server_template_href)
15
+ run_first = this_template.executables.first
16
+ location = @server_v4_right_script.run_executable(run_first)
17
+ audit = AuditEntry.new(:href => location)
18
+ audit.wait_for_completed
19
+ end
20
+
21
+ it "should run a recipe on a v5 server" do
22
+ this_template = ServerTemplate.find(@server_v5_recipe.server_template_href)
23
+ run_first = this_template.executables.first
24
+ audit = @server_v5_recipe.run_executable(run_first)
25
+ audit.wait_for_completed
26
+ end
27
+
28
+ it "should run a right_script on a v5 server" do
29
+ this_template = ServerTemplate.find(@server_v5_right_script.server_template_href)
30
+ run_first = this_template.executables.first
31
+ audit = @server_v5_right_script.run_executable(run_first)
32
+ audit.wait_for_completed
33
+ end
34
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 3
9
- version: 0.0.3
8
+ - 4
9
+ version: 0.0.4
10
10
  platform: ruby
11
11
  authors:
12
12
  - Jeremy Deininger
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-03-18 00:00:00 -07:00
17
+ date: 2010-04-15 00:00:00 +00:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -41,6 +41,18 @@ dependencies:
41
41
  version: "0"
42
42
  type: :runtime
43
43
  version_requirements: *id002
44
+ - !ruby/object:Gem::Dependency
45
+ name: json
46
+ prerelease: false
47
+ requirement: &id003 !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ segments:
52
+ - 0
53
+ version: "0"
54
+ type: :runtime
55
+ version_requirements: *id003
44
56
  description: provides rest_connection
45
57
  email: jeremy@rubyonlinux.org
46
58
  executables: []
@@ -50,6 +62,7 @@ extensions: []
50
62
  extra_rdoc_files:
51
63
  - README
52
64
  files:
65
+ - .gitignore
53
66
  - README
54
67
  - Rakefile
55
68
  - VERSION
@@ -65,6 +78,7 @@ files:
65
78
  - examples/run_php_chef_sequence.rb
66
79
  - examples/set_deployment_template_href.rb
67
80
  - lib/rest_connection.rb
81
+ - lib/rest_connection/rightscale/audit_entry.rb
68
82
  - lib/rest_connection/rightscale/deployment.rb
69
83
  - lib/rest_connection/rightscale/ec2_security_group.rb
70
84
  - lib/rest_connection/rightscale/ec2_server_array.rb
@@ -75,12 +89,15 @@ files:
75
89
  - lib/rest_connection/rightscale/right_script.rb
76
90
  - lib/rest_connection/rightscale/rightscale_api_base.rb
77
91
  - lib/rest_connection/rightscale/rightscale_api_resources.rb
92
+ - lib/rest_connection/rightscale/rs_internal.rb
78
93
  - lib/rest_connection/rightscale/server.rb
79
94
  - lib/rest_connection/rightscale/server_template.rb
80
95
  - lib/rest_connection/rightscale/status.rb
81
96
  - lib/rest_connection/rightscale/tag.rb
82
97
  - lib/rest_connection/ssh_hax.rb
83
98
  - rest_connection.gemspec
99
+ - spec/rs_internal_spec.rb
100
+ - spec/server_spec.rb
84
101
  has_rdoc: true
85
102
  homepage: http://github.com/jeremyd/rest_connection
86
103
  licenses: []
@@ -112,14 +129,15 @@ signing_key:
112
129
  specification_version: 3
113
130
  summary: lib for restful connections to the rightscale api
114
131
  test_files:
132
+ - spec/server_spec.rb
133
+ - spec/rs_internal_spec.rb
134
+ - examples/restart_instance_agent.rb
115
135
  - examples/console.rb
136
+ - examples/run_php_chef_sequence.rb
137
+ - examples/set_deployment_template_href.rb
116
138
  - examples/dev_setup.rb
117
- - examples/relaunch_deployment.rb
118
- - examples/restart_instance_agent.rb
119
139
  - examples/right_scale_ec2_instances_api_test.rb
120
- - examples/run_ebs_sequence.rb
140
+ - examples/relaunch_deployment.rb
121
141
  - examples/run_ebs_terminate.rb
122
142
  - examples/run_mysql_chef_sequence.rb
123
- - examples/run_php_chef_sequence.rb
124
- - examples/set_deployment_images.rb
125
- - examples/set_deployment_template_href.rb
143
+ - examples/run_ebs_sequence.rb
File without changes