rightstuff 0.0.4 → 0.0.5

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.
@@ -11,10 +11,17 @@ Here is a typical example:
11
11
  servers = rs.servers
12
12
  servers.each{ |server| puts server.private_ip_address }
13
13
 
14
+ server_arrays = rs.server_arrays
15
+ servers.each{ |array| puts("Array #{array.nickname} is running #{array.active_instances_count || 0} instances.") }
16
+
17
+ active_array = server_arrays.detect{|array| array.active_instances_count.to_i > 0}
18
+ array_instances = active_array.instances
19
+ puts("Array #{active_array.nickname}'s private IP address[es]: #{array_instances.map(&:private_ip_address) * ', '}")
20
+
14
21
  Rightstuff::Credentials assumes you have a YAMl file called ~/.rightstuff
15
22
  It should be of the form:
16
- ---
17
- :main:
23
+ ---
24
+ :main:
18
25
  :credentials:
19
26
  :username: myusername
20
27
  :password: mypass
@@ -36,6 +43,11 @@ It should be of the form:
36
43
  * http://github.com/rightscale/right_aws
37
44
  * http://github.com/moneypools/right_api
38
45
 
46
+ = Contributors
47
+
48
+ * joeyates
49
+ * kwerle
50
+
39
51
  = TODO
40
52
 
41
53
  * Cache connections
data/Rakefile CHANGED
@@ -5,32 +5,7 @@ require 'rake/rdoctask'
5
5
  $:.unshift( File.dirname( __FILE__ ) + '/lib' )
6
6
  require 'rightstuff'
7
7
 
8
- ADMIN_FILES = FileList[ 'COPYING', 'Rakefile', 'README.rdoc' ]
9
- SOURCE_FILES = FileList[ 'lib/**/*.rb' ]
10
- RDOC_FILES = FileList[ 'COPYING', 'README.rdoc' ] + SOURCE_FILES
11
- RDOC_OPTS = [ '--quiet', '--main', 'README.rdoc', '--inline-source' ]
12
- DESCRIPTION = 'Another Ruby Interface for RightScale, providing an OO interface for RightScale accounts'
13
-
14
- spec = Gem::Specification.new do |s|
15
- s.name = 'rightstuff'
16
- s.summary = 'Another Ruby Interface for RightScale'
17
- s.description = DESCRIPTION
18
- s.version = Rightstuff::VERSION::STRING
19
-
20
- s.homepage = 'http://github.com/joeyates/rightstuff'
21
- s.author = 'Joe Yates'
22
- s.email = 'joe.g.yates@gmail.com'
23
-
24
- s.files = ADMIN_FILES +
25
- SOURCE_FILES
26
- s.require_paths = [ 'lib' ]
27
- s.add_dependency( 'nokogiri', '>= 1.4.3.1' )
28
-
29
- s.has_rdoc = true
30
- s.rdoc_options += RDOC_OPTS
31
- s.extra_rdoc_files = RDOC_FILES
32
- s.rubyforge_project = 'nowarning'
33
- end
8
+ spec = eval(File.read("rightstuff.gemspec"))
34
9
 
35
10
  Rake::GemPackageTask.new( spec ) do |pkg|
36
11
  end
@@ -1,167 +1,18 @@
1
- require 'rubygems' if RUBY_VERSION < '1.9'
2
- require 'yaml'
3
- require 'net/https'
4
- require 'uri'
5
- require 'nokogiri'
1
+ require 'rightstuff/credentials'
2
+ require 'rightstuff/client'
3
+ require 'rightstuff/base'
4
+ require 'rightstuff/server'
5
+ require 'rightstuff/server_array'
6
+ require 'rightstuff/array_instance'
6
7
 
7
8
  module Rightstuff
8
9
 
9
10
  module VERSION #:nodoc:
10
11
  MAJOR = 0
11
12
  MINOR = 0
12
- TINY = 4
13
+ TINY = 5
13
14
 
14
15
  STRING = [ MAJOR, MINOR, TINY ].join('.')
15
16
  end
16
17
 
17
- # Rightstuff::Credentials imposes no restrictions on the structure of the data
18
- # It only requires that:
19
- # 1. the user has a file called ~/.credentials,
20
- # 2. the the file does not have any permissions for other users,
21
- # 3. the file contails YAML::load-able data.
22
- module Credentials
23
-
24
- def rightscale_data
25
- return @rightscale_data if @rightscale_data
26
- raise "Missing credentials file '#{ rightscale_data_path }'" if ! File.exist?( rightscale_data_path )
27
- check_permissions
28
- @rightscale_data = YAML.load_file( rightscale_data_path )
29
- end
30
-
31
- private
32
-
33
- def rightscale_data_path
34
- File.expand_path( '~/.rightstuff' )
35
- end
36
-
37
- def check_permissions
38
- mode = File::Stat.new( rightscale_data_path ).mode
39
- if mode & 0066 != 0
40
- raise "Permissions on '#{ rightscale_data_path }' too open (currently 0%o), should be 0600" % ( mode & 0666 )
41
- end
42
- end
43
-
44
- end
45
-
46
- class Base
47
-
48
- def self.load_collection( client, doc )
49
- doc.xpath( self.collection_xpath ).collect do | item |
50
- self.new( client, item )
51
- end
52
- end
53
-
54
- def self.extract_attributes( parent )
55
- elements = parent.children.collect do | node |
56
- node.class == Nokogiri::XML::Element ? node : nil
57
- end
58
- elements.compact!
59
- elements.reduce( {} ) do | memo, element |
60
- name = element.name
61
- name.gsub!( /-/, '_' )
62
- memo[ name.intern ] = element.children[ 0 ].to_s
63
- memo
64
- end
65
- end
66
-
67
- def initialize( client, item )
68
- @client = client
69
- @attributes = Base.extract_attributes( item )
70
- end
71
-
72
- def method_missing( name, *args, &block )
73
- return @attributes[ name ]
74
- end
75
-
76
- end
77
-
78
- class Server < Base
79
-
80
- attr_reader :attributes
81
-
82
- def initialize( client, item )
83
- @settings = nil
84
- @inputs = nil
85
- super
86
- end
87
-
88
- def self.collection_xpath
89
- '/servers/server'
90
- end
91
-
92
- def method_missing( name , *args, &block )
93
- result = super
94
- return result unless result.nil?
95
- return nil unless @attributes[ :state ] == 'operational'
96
- settings unless @settings
97
- return @attributes[ name ]
98
- end
99
-
100
- def id
101
- @attributes[ :href ].split( '/' ).last
102
- end
103
-
104
- def inputs
105
- return @inputs if @inputs
106
- # Add inputs to instance data
107
- # @client.get( @attributes[ 'href' ] )
108
- end
109
-
110
- def settings
111
- return @settings if @settings
112
- doc = @client.get_rest( 'servers/' + id + '/settings' )
113
- xml = Nokogiri::XML( doc )
114
- @settings = Base.extract_attributes( xml.children )
115
- @attributes.merge!( settings )
116
- end
117
-
118
- end
119
-
120
- class Client
121
-
122
- def initialize( options = {} )
123
- @username = options[ :username ] or raise 'no username supplied'
124
- @password = options[ :password ] or raise 'no password supplied'
125
- @account = options[ :account ] or raise 'no account id supplied'
126
- @account = @account.to_s
127
-
128
- @base_url = 'https://my.rightscale.com/api/acct'
129
- url = URI.parse( @base_url )
130
- @connection = Net::HTTP.new( url.host, url.port )
131
- @connection.use_ssl = true
132
- @connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
133
- end
134
-
135
- def get_rest( rest )
136
- get( account_url( rest ) )
137
- end
138
-
139
- def get( address )
140
- url = URI.parse( address )
141
- request = Net::HTTP::Get.new( url.request_uri )
142
- request.add_field( 'X-API-VERSION', '1.0' )
143
- request.basic_auth @username, @password
144
-
145
- response = @connection.request( request )
146
-
147
- case response.code
148
- when '200'
149
- return response.body
150
- else
151
- raise "Request '#{ address }' failed with response code #{ response.code }\n#{ response.body }"
152
- end
153
- end
154
-
155
- def servers
156
- return @servers if @servers
157
- body = Nokogiri::XML( get_rest( 'servers' ) )
158
- @servers = Server.load_collection( self, body )
159
- end
160
-
161
- def account_url( rest )
162
- @base_url + '/' + @account + '/' + rest
163
- end
164
-
165
- end
166
-
167
18
  end
@@ -0,0 +1,35 @@
1
+ module Rightstuff
2
+ # http://support.rightscale.com/15-References/RightScale_API_Reference_Guide/02-Management/09-Server_Arrays
3
+ class ArrayInstance < Base
4
+
5
+ attr_reader :attributes
6
+
7
+ def initialize( client, item )
8
+ @inputs = nil
9
+ super
10
+ end
11
+
12
+ def self.collection_xpath
13
+ '/instances/instance'
14
+ end
15
+
16
+ def method_missing( name , *args, &block )
17
+ result = super
18
+ return result unless result.nil?
19
+ return nil if @attributes[ :state ] == 'stopped'
20
+ return @attributes[ name ]
21
+ end
22
+
23
+ def id
24
+ @attributes[ :href ].split( '/' ).last
25
+ end
26
+
27
+ def inputs
28
+ return @inputs if @inputs
29
+ # Add inputs to instance data
30
+ # @client.get( @attributes[ 'href' ] )
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -0,0 +1,38 @@
1
+ require 'rubygems' if RUBY_VERSION < '1.9'
2
+ require 'nokogiri'
3
+
4
+ module Rightstuff
5
+
6
+ class Base
7
+
8
+ def self.load_collection( client, doc )
9
+ doc.xpath( self.collection_xpath ).collect do | item |
10
+ self.new( client, item )
11
+ end
12
+ end
13
+
14
+ def self.extract_attributes( parent )
15
+ elements = parent.children.collect do | node |
16
+ node.class == Nokogiri::XML::Element ? node : nil
17
+ end
18
+ elements.compact!
19
+ elements.reduce( {} ) do | memo, element |
20
+ name = element.name
21
+ name.gsub!( /-/, '_' )
22
+ memo[ name.intern ] = element.children[ 0 ].to_s
23
+ memo
24
+ end
25
+ end
26
+
27
+ def initialize( client, item )
28
+ @client = client
29
+ @attributes = Base.extract_attributes( item )
30
+ end
31
+
32
+ def method_missing( name, *args, &block )
33
+ return @attributes[ name ]
34
+ end
35
+
36
+ end
37
+
38
+ end
@@ -0,0 +1,63 @@
1
+ require 'rubygems' if RUBY_VERSION < '1.9'
2
+ require 'nokogiri'
3
+ require 'net/https'
4
+ require 'uri'
5
+
6
+ module Rightstuff
7
+
8
+ class Client
9
+
10
+ def initialize( options = {} )
11
+ @username = options[ :username ] or raise 'no username supplied'
12
+ @password = options[ :password ] or raise 'no password supplied'
13
+ @account = options[ :account ] or raise 'no account id supplied'
14
+ @account = @account.to_s
15
+
16
+ @base_url = 'https://my.rightscale.com/api/acct'
17
+ url = URI.parse( @base_url )
18
+ @connection = Net::HTTP.new( url.host, url.port )
19
+ @connection.use_ssl = true
20
+ @connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
21
+ end
22
+
23
+ def get_rest( rest )
24
+ get( account_url( rest ) )
25
+ end
26
+
27
+ def servers
28
+ return @servers if @servers
29
+ body = Nokogiri::XML( get_rest( 'servers' ) )
30
+ @servers = Rightstuff::Server.load_collection( self, body )
31
+ end
32
+
33
+ def server_arrays
34
+ return @server_arrays if @server_arrays
35
+ body = Nokogiri::XML( get_rest( 'server_arrays' ) )
36
+ @server_arrays = Rightstuff::ServerArray.load_collection( self, body )
37
+ end
38
+
39
+ private
40
+
41
+ def get( address )
42
+ url = URI.parse( address )
43
+ request = Net::HTTP::Get.new( url.request_uri )
44
+ request.add_field( 'X-API-VERSION', '1.0' )
45
+ request.basic_auth( @username, @password )
46
+
47
+ response = @connection.request( request )
48
+
49
+ case response.code
50
+ when '200'
51
+ return response.body
52
+ else
53
+ raise "Request '#{ address }' failed with response code #{ response.code }\n#{ response.body }"
54
+ end
55
+ end
56
+
57
+ def account_url( rest )
58
+ @base_url + '/' + @account + '/' + rest
59
+ end
60
+
61
+ end
62
+
63
+ end
@@ -0,0 +1,34 @@
1
+ require 'yaml'
2
+
3
+ module Rightstuff
4
+
5
+ # Rightstuff::Credentials imposes no restrictions on the structure of the data
6
+ # It only requires that:
7
+ # 1. the user has a file called ~/.credentials,
8
+ # 2. the the file does not have any permissions for other users,
9
+ # 3. the file contails YAML::load-able data.
10
+ module Credentials
11
+
12
+ def rightscale_data
13
+ return @rightscale_data if @rightscale_data
14
+ raise "Missing credentials file '#{ rightscale_data_path }'" if ! File.exist?( rightscale_data_path )
15
+ check_permissions
16
+ @rightscale_data = YAML.load_file( rightscale_data_path )
17
+ end
18
+
19
+ private
20
+
21
+ def rightscale_data_path
22
+ File.expand_path( '~/.rightstuff' )
23
+ end
24
+
25
+ def check_permissions
26
+ mode = File::Stat.new( rightscale_data_path ).mode
27
+ if mode & 0066 != 0
28
+ raise "Permissions on '#{ rightscale_data_path }' too open (currently 0%o), should be 0600" % ( mode & 0666 )
29
+ end
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -0,0 +1,45 @@
1
+ module Rightstuff
2
+
3
+ class Server < Base
4
+
5
+ attr_reader :attributes
6
+
7
+ def initialize( client, item )
8
+ @settings = nil
9
+ @inputs = nil
10
+ super
11
+ end
12
+
13
+ def self.collection_xpath
14
+ '/servers/server'
15
+ end
16
+
17
+ def method_missing( name , *args, &block )
18
+ result = super
19
+ return result unless result.nil?
20
+ return nil unless @attributes[ :state ] == 'operational'
21
+ settings unless @settings
22
+ return @attributes[ name ]
23
+ end
24
+
25
+ def id
26
+ @attributes[ :href ].split( '/' ).last
27
+ end
28
+
29
+ def inputs
30
+ return @inputs if @inputs
31
+ # Add inputs to instance data
32
+ # @client.get( @attributes[ 'href' ] )
33
+ end
34
+
35
+ def settings
36
+ return @settings if @settings
37
+ doc = @client.get_rest( 'servers/' + id + '/settings' )
38
+ xml = Nokogiri::XML( doc )
39
+ @settings = Base.extract_attributes( xml.children )
40
+ @attributes.merge!( @settings )
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -0,0 +1,41 @@
1
+ module Rightstuff
2
+ # http://support.rightscale.com/15-References/RightScale_API_Reference_Guide/02-Management/09-Server_Arrays
3
+ class ServerArray < Base
4
+
5
+ attr_reader :attributes
6
+
7
+ def initialize( client, item )
8
+ @inputs = nil
9
+ @instances = nil
10
+ super
11
+ end
12
+
13
+ def self.collection_xpath
14
+ '/server-arrays/server-array'
15
+ end
16
+
17
+ def method_missing( name , *args, &block )
18
+ result = super
19
+ return result unless result.nil?
20
+ return nil if @attributes[ :state ] == 'stopped'
21
+ return @attributes[ name ]
22
+ end
23
+
24
+ def id
25
+ @attributes[ :href ].split( '/' ).last
26
+ end
27
+
28
+ def inputs
29
+ return @inputs if @inputs
30
+ # Add inputs to instance data
31
+ # @client.get( @attributes[ 'href' ] )
32
+ end
33
+
34
+ def instances
35
+ return @instances if @instances
36
+ body = Nokogiri::XML( @client.get_rest( "server_arrays/#{id}/instances" ) )
37
+ @instances = Rightstuff::ArrayInstance.load_collection( @client, body )
38
+ end
39
+ end
40
+
41
+ end
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rightstuff
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
5
4
  prerelease: false
6
5
  segments:
7
6
  - 0
8
7
  - 0
9
- - 4
10
- version: 0.0.4
8
+ - 5
9
+ version: 0.0.5
11
10
  platform: ruby
12
11
  authors:
13
12
  - Joe Yates
@@ -15,7 +14,7 @@ autorequire:
15
14
  bindir: bin
16
15
  cert_chain: []
17
16
 
18
- date: 2010-10-13 00:00:00 +01:00
17
+ date: 2010-10-30 00:00:00 +02:00
19
18
  default_executable:
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
@@ -26,7 +25,6 @@ dependencies:
26
25
  requirements:
27
26
  - - ">="
28
27
  - !ruby/object:Gem::Version
29
- hash: 113
30
28
  segments:
31
29
  - 1
32
30
  - 4
@@ -44,11 +42,23 @@ extensions: []
44
42
  extra_rdoc_files:
45
43
  - COPYING
46
44
  - README.rdoc
45
+ - lib/rightstuff/client.rb
46
+ - lib/rightstuff/array_instance.rb
47
+ - lib/rightstuff/server.rb
48
+ - lib/rightstuff/base.rb
49
+ - lib/rightstuff/server_array.rb
50
+ - lib/rightstuff/credentials.rb
47
51
  - lib/rightstuff.rb
48
52
  files:
49
53
  - COPYING
50
54
  - Rakefile
51
55
  - README.rdoc
56
+ - lib/rightstuff/client.rb
57
+ - lib/rightstuff/array_instance.rb
58
+ - lib/rightstuff/server.rb
59
+ - lib/rightstuff/base.rb
60
+ - lib/rightstuff/server_array.rb
61
+ - lib/rightstuff/credentials.rb
52
62
  - lib/rightstuff.rb
53
63
  has_rdoc: true
54
64
  homepage: http://github.com/joeyates/rightstuff
@@ -67,7 +77,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
67
77
  requirements:
68
78
  - - ">="
69
79
  - !ruby/object:Gem::Version
70
- hash: 3
71
80
  segments:
72
81
  - 0
73
82
  version: "0"
@@ -76,7 +85,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
76
85
  requirements:
77
86
  - - ">="
78
87
  - !ruby/object:Gem::Version
79
- hash: 3
80
88
  segments:
81
89
  - 0
82
90
  version: "0"