rubineti 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/.rvmrc +1 -0
  2. data/Gemfile +13 -0
  3. data/Gemfile.lock +33 -0
  4. data/LICENSE +4 -0
  5. data/README.md +44 -0
  6. data/Rakefile +22 -0
  7. data/VERSION +1 -0
  8. data/lib/ganeti.rb +6 -0
  9. data/lib/rubineti/compute/cluster.rb +74 -0
  10. data/lib/rubineti/compute/instances.rb +245 -0
  11. data/lib/rubineti/compute/jobs.rb +42 -0
  12. data/lib/rubineti/compute/node.rb +140 -0
  13. data/lib/rubineti/compute.rb +125 -0
  14. data/lib/rubineti.rb +2 -0
  15. data/rubineti.gemspec +106 -0
  16. data/test/fixtures/cassettes/cluster_info.yml +96 -0
  17. data/test/fixtures/cassettes/cluster_oses.yml +32 -0
  18. data/test/fixtures/cassettes/cluster_redistribute_config.yml +32 -0
  19. data/test/fixtures/cassettes/cluster_version.yml +30 -0
  20. data/test/fixtures/cassettes/instance_create.yml +32 -0
  21. data/test/fixtures/cassettes/instance_delete.yml +30 -0
  22. data/test/fixtures/cassettes/instance_info.yml +30 -0
  23. data/test/fixtures/cassettes/instance_list.yml +93 -0
  24. data/test/fixtures/cassettes/instance_reboot.yml +32 -0
  25. data/test/fixtures/cassettes/instance_reinstall.yml +32 -0
  26. data/test/fixtures/cassettes/instance_shutdown.yml +32 -0
  27. data/test/fixtures/cassettes/instance_startup.yml +32 -0
  28. data/test/fixtures/cassettes/instances.yml +95 -0
  29. data/test/fixtures/cassettes/job_list.yml +135 -0
  30. data/test/fixtures/cassettes/jobs.yml +35 -0
  31. data/test/fixtures/cassettes/node_list.yml +55 -0
  32. data/test/fixtures/cassettes/node_role_list.yml +30 -0
  33. data/test/fixtures/cassettes/nodes.yml +39 -0
  34. data/test/lib/rubineti/compute/test_cluster.rb +71 -0
  35. data/test/lib/rubineti/compute/test_instances.rb +202 -0
  36. data/test/lib/rubineti/compute/test_jobs.rb +41 -0
  37. data/test/lib/rubineti/compute/test_node.rb +77 -0
  38. data/test/lib/rubineti/test_compute.rb +92 -0
  39. data/test/support.rb +35 -0
  40. metadata +225 -0
@@ -0,0 +1,202 @@
1
+ require "support"
2
+
3
+ describe Rubineti::Compute do
4
+ describe Rubineti::Instances do
5
+
6
+ describe "#instance_activate_disks" do
7
+ it "is not implemented" do
8
+ out, err = capture_io { Connection.instance_activate_disks(:invalid_instance_name) }
9
+
10
+ err.must_match Not_Implemented_Matcher
11
+ end
12
+ end
13
+
14
+ describe "#instance_create" do
15
+ it "returns a job_id" do
16
+ params = {
17
+ :__version__ => Ganeti::Version,
18
+ :name => "compute1",
19
+ :pnode => "node1",
20
+ :snode => "node2",
21
+ :disk_template => "drbd8",
22
+ :disks => [4096],
23
+ :beparams => { :vcpus => 1, :memory => 512 },
24
+ :os => "debootstrap+default"
25
+ }
26
+
27
+ VCR.use_cassette "instance_create" do
28
+ response = Connection.instance_create :body => params, :query => "dry-run=1"
29
+
30
+ response.must_match Job_Matcher
31
+ end
32
+ end
33
+ end
34
+
35
+ describe "#instance_deactivate_disks" do
36
+ it "is not implemented" do
37
+ out, err = capture_io { Connection.instance_deactivate_disks :invalid_instance_name }
38
+
39
+ err.must_match Not_Implemented_Matcher
40
+ end
41
+ end
42
+
43
+ describe "#instance_delete" do
44
+ it "returns a job_id" do
45
+ VCR.use_cassette "instance_delete" do
46
+ response = Connection.instance_delete :invalid_instance_name, :query => "dry-run=1"
47
+
48
+ response.must_match Job_Matcher
49
+ end
50
+ end
51
+ end
52
+
53
+ describe "#instance_export" do
54
+ it "is not implemented" do
55
+ out, err = capture_io { Connection.instance_export :invalid_instance_name }
56
+
57
+ err.must_match Not_Implemented_Matcher
58
+ end
59
+ end
60
+
61
+ describe "#instance_info" do
62
+ it "returns a job_id" do
63
+ instance_name = cassette_for("instances").first["name"]
64
+
65
+ VCR.use_cassette "instance_info" do
66
+ response = Connection.instance_info instance_name
67
+
68
+ response.must_match Job_Matcher
69
+ end
70
+ end
71
+ end
72
+
73
+ describe "#instance_list" do
74
+ it "returns a Hash" do
75
+ instance_name = cassette_for("instances").first["name"]
76
+
77
+ VCR.use_cassette "instance_list" do
78
+ response = Connection.instance_list instance_name
79
+
80
+ response.must_be_kind_of Hash
81
+ end
82
+ end
83
+ end
84
+
85
+ describe "#instance_migrate" do
86
+ it "is not implemented" do
87
+ out, err = capture_io { Connection.instance_migrate :invalid_instance_name }
88
+
89
+ err.must_match Not_Implemented_Matcher
90
+ end
91
+ end
92
+
93
+ describe "#instance_modify" do
94
+ it "is not implemented" do
95
+ out, err = capture_io { Connection.instance_modify :invalid_instance_name }
96
+
97
+ err.must_match Not_Implemented_Matcher
98
+ end
99
+ end
100
+
101
+ describe "#instance_prepare_export" do
102
+ it "is not implemented" do
103
+ out, err = capture_io { Connection.instance_prepare_export :invalid_instance_name }
104
+
105
+ err.must_match Not_Implemented_Matcher
106
+ end
107
+ end
108
+
109
+ describe "#instance_reboot" do
110
+ it "returns a job_id" do
111
+ VCR.use_cassette "instance_reboot" do
112
+ response = Connection.instance_reboot :invalid_instance_name, :query => "dry-run=1"
113
+
114
+ response.must_match Job_Matcher
115
+ end
116
+ end
117
+ end
118
+
119
+ describe "#instance_reinstall" do
120
+ it "returns a job_id" do
121
+ instance_name = cassette_for("instances").first["name"]
122
+ params = {
123
+ :os => "debootstrap+default"
124
+ }
125
+
126
+ VCR.use_cassette "instance_reinstall" do
127
+ response = Connection.instance_reinstall instance_name, :body => params
128
+
129
+ response.must_match Job_Matcher
130
+ end
131
+ end
132
+ end
133
+
134
+ describe "#instance_rename" do
135
+ it "is not implemented" do
136
+ lambda { Connection.instance_rename :invalid_instance_name }.must_output(nil, nil).must_equal true
137
+ end
138
+ end
139
+
140
+ describe "#instance_replace_disks" do
141
+ it "is not implemented" do
142
+ out, err = capture_io { Connection.instance_replace_disks :invalid_instance_name }
143
+
144
+ err.must_match Not_Implemented_Matcher
145
+ end
146
+ end
147
+
148
+ describe "#instance_shutdown" do
149
+ it "returns a job_id" do
150
+ VCR.use_cassette "instance_shutdown" do
151
+ response = Connection.instance_shutdown :invalid_instance_name, :query => "dry-run=1"
152
+
153
+ response.must_match Job_Matcher
154
+ end
155
+ end
156
+ end
157
+
158
+ describe "#instances_list" do
159
+ it "returns an Array of Hashes" do
160
+ VCR.use_cassette "instances" do
161
+ response = Connection.instances_list :query => "bulk=1"
162
+
163
+ response.size.must_equal 1
164
+ end
165
+ end
166
+ end
167
+
168
+ describe "#instance_startup" do
169
+ it "returns a job_id" do
170
+ VCR.use_cassette "instance_startup" do
171
+ response = Connection.instance_startup :invalid_instance_name, :query => "dry-run=1"
172
+
173
+ response.must_match Job_Matcher
174
+ end
175
+ end
176
+ end
177
+
178
+ describe "#instance_tag_create" do
179
+ it "is not implemented" do
180
+ out, err = capture_io { Connection.instance_tag_create :invalid_instance_name }
181
+
182
+ err.must_match Not_Implemented_Matcher
183
+ end
184
+ end
185
+
186
+ describe "#instance_tag_delete" do
187
+ it "is not implemented" do
188
+ out, err = capture_io { Connection.instance_tag_delete :invalid_instance_name }
189
+
190
+ err.must_match Not_Implemented_Matcher
191
+ end
192
+ end
193
+
194
+ describe "#instance_tag_list" do
195
+ it "is not implemented" do
196
+ out, err = capture_io { Connection.instance_tag_list :invalid_instance_name }
197
+
198
+ err.must_match Not_Implemented_Matcher
199
+ end
200
+ end
201
+ end
202
+ end
@@ -0,0 +1,41 @@
1
+ require "support"
2
+
3
+ describe Rubineti::Compute do
4
+ describe Rubineti::Jobs do
5
+ describe "#jobs_list" do
6
+ it "returns an Array" do
7
+ VCR.use_cassette "jobs" do
8
+ Connection.jobs_list.size.must_equal 1
9
+ end
10
+ end
11
+ end
12
+
13
+ describe "#job_list" do
14
+ it "returns a Hash" do
15
+ job_id = cassette_for("jobs").first["id"]
16
+
17
+ VCR.use_cassette "job_list" do
18
+ response = Connection.job_list job_id
19
+
20
+ response.must_be_kind_of Hash
21
+ end
22
+ end
23
+ end
24
+
25
+ describe "#job_delete" do
26
+ it "is not implemented" do
27
+ out, err = capture_io { Connection.job_delete :invalid_job_id }
28
+
29
+ err.must_match Not_Implemented_Matcher
30
+ end
31
+ end
32
+
33
+ describe "#job_wait" do
34
+ it "is not implemented" do
35
+ out, err = capture_io { Connection.job_wait :invalid_job_id }
36
+
37
+ err.must_match Not_Implemented_Matcher
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,77 @@
1
+ require "support"
2
+
3
+ describe Rubineti::Compute do
4
+ describe Rubineti::Node do
5
+ describe "#node_evacuate" do
6
+ it "is not implemented" do
7
+ out, err = capture_io { Connection.node_evacuate :invalid_node_name }
8
+
9
+ err.must_match Not_Implemented_Matcher
10
+ end
11
+ end
12
+
13
+ describe "#node_list" do
14
+ it "returns Hash" do
15
+ node_name = cassette_for("nodes").first["id"]
16
+
17
+ VCR.use_cassette "node_list" do
18
+ response = Connection.node_list node_name
19
+
20
+ response.must_be_kind_of Hash
21
+ end
22
+ end
23
+ end
24
+
25
+ describe "#node_migrate" do
26
+ it "is not implemented" do
27
+ out, err = capture_io { Connection.node_migrate :invalid_node_name }
28
+
29
+ err.must_match Not_Implemented_Matcher
30
+ end
31
+ end
32
+
33
+ describe "#node_role_create" do
34
+ it "is not implemented" do
35
+ out, err = capture_io { Connection.node_role_create :invalid_node_name }
36
+
37
+ err.must_match Not_Implemented_Matcher
38
+ end
39
+ end
40
+
41
+ describe "#node_role_list" do
42
+ it "returns a role" do
43
+ node_name = cassette_for("nodes").first["id"]
44
+
45
+ VCR.use_cassette "node_role_list" do
46
+ response = Connection.node_role_list node_name
47
+
48
+ response.must_equal "master"
49
+ end
50
+ end
51
+ end
52
+
53
+ describe "#nodes_list" do
54
+ it "returns an Array of Hashes" do
55
+ VCR.use_cassette "nodes" do
56
+ Connection.nodes_list.size.must_equal 2
57
+ end
58
+ end
59
+ end
60
+
61
+ describe "#node_storage_list" do
62
+ it "is not implemented" do
63
+ out, err = capture_io { Connection.node_storage_list :invalid_node_name }
64
+
65
+ err.must_match Not_Implemented_Matcher
66
+ end
67
+ end
68
+
69
+ describe "#node_storage_modify" do
70
+ it "is not implemented" do
71
+ out, err = capture_io { Connection.node_storage_modify :invalid_node_name }
72
+
73
+ err.must_match Not_Implemented_Matcher
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,92 @@
1
+ require "support"
2
+
3
+ describe Rubineti::Compute do
4
+ before do
5
+ @user = "fake"
6
+ @password = "credentials"
7
+ @valid_params = {
8
+ :host => "ganeti.primary",
9
+ :user => @user,
10
+ :password => @password
11
+ }
12
+ end
13
+
14
+ describe "#initialize" do
15
+ #it "requires params" do
16
+ # @valid_params.keys.each do |param|
17
+ # lambda { Rubineti::Compute.new @valid_params.reject { |k,v| k == param } }.must_raise StandardError
18
+ # end
19
+ #end
20
+ end
21
+
22
+ describe "#response_for" do
23
+ before do
24
+ @instance = Rubineti::Compute.new @valid_params
25
+ @http = mock(:request => mock(:body => :body))
26
+ @request = Net::HTTP::Get
27
+
28
+ Net::HTTP::Persistent.stubs :new => @http
29
+ end
30
+
31
+ it "generates a path" do
32
+ @instance.send :response_for, @request, "/", {}
33
+
34
+ @instance.instance_variable_get(:@request).path.must_equal "/"
35
+ end
36
+
37
+ it "generates a path when a valid :query exists" do
38
+ @instance.send :response_for, @request, "/", :query => "foo=bar"
39
+
40
+ @instance.instance_variable_get(:@request).path.must_equal "/?foo=bar"
41
+ end
42
+
43
+ it "generates a path when a nil :query exists" do
44
+ @instance.send :response_for, @request, "/", :query => nil
45
+
46
+ @instance.instance_variable_get(:@request).path.must_equal "/"
47
+ end
48
+
49
+ it "sets the body as JSON when a valid :body exists" do
50
+ @instance.send :response_for, @request, "/", :body => {:foo => :bar}
51
+
52
+ @instance.instance_variable_get(:@request).body.must_equal '{"foo":"bar"}'
53
+ end
54
+
55
+ it "doesn't set the body when an invalid :body exists" do
56
+ @instance.send :response_for, @request, "/", :body => nil
57
+
58
+ @instance.instance_variable_get(:@request).body.must_be_nil
59
+ end
60
+
61
+ describe "headers" do
62
+ it "has authentication" do
63
+ @instance.send :response_for, @request, "/", {}
64
+
65
+ @instance.instance_variable_get(:@request).get_fields("authorization").join.
66
+ must_match %r{Basic #{Base64.encode64("#{@user}:#{@password}").delete("\r\n")}}
67
+ end
68
+
69
+ [Net::HTTP::Post, Net::HTTP::Put].each do |clazz|
70
+ it "has content-type and accept for '#{clazz}'" do
71
+ @instance.send :response_for, clazz, "/", {}
72
+
73
+ @instance.instance_variable_get(:@request).get_fields("content-type").join.
74
+ must_match Json_Headers_Matcher
75
+ @instance.instance_variable_get(:@request).get_fields("accept").join.
76
+ must_match Json_Headers_Matcher
77
+ end
78
+ end
79
+
80
+ [Net::HTTP::Get, Net::HTTP::Delete].each do |clazz|
81
+ it "has accept for '#{clazz}'" do
82
+ @instance.send :response_for, clazz, "/", {}
83
+
84
+ @instance.instance_variable_get(:@request).get_fields("accept").join.
85
+ must_match Json_Headers_Matcher
86
+ @instance.instance_variable_get(:@request).get_fields("content-type").
87
+ must_be_nil
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
data/test/support.rb ADDED
@@ -0,0 +1,35 @@
1
+ Bundler.setup :default, :test
2
+
3
+ require "minitest/spec"
4
+ require "mocha"
5
+
6
+ Dir[File.join "./lib", "**", "*.rb"].each { |f| require f }
7
+
8
+ class MiniTest::Unit::TestCase
9
+ Connection = Rubineti::Compute.new(
10
+ :host => "ganeti.primary",
11
+ :user => "fake",
12
+ :password => "credentials"
13
+ )
14
+ Job_Matcher = %r{^\d{4}$}
15
+ Json_Headers_Matcher = %r{#{Rubineti::Compute::Headers[:json]}}
16
+ Not_Implemented_Matcher = %r{^WARNING: [A-Z][a-z]+#[a-z]+_[a-z_]+ not implemented.$}
17
+
18
+ require "yajl"
19
+ def cassette_for cassette
20
+ c = VCR::Cassette.new(cassette).send :recorded_interactions
21
+
22
+ Yajl::Parser.parse c.first.response.body
23
+ end
24
+ end
25
+
26
+ require "vcr"
27
+ require "webmock"
28
+ WebMock.disable_net_connect! :allow => "ganeti.primary"
29
+ VCR.config do |c|
30
+ c.stub_with :webmock
31
+ c.cassette_library_dir = "test/fixtures/cassettes"
32
+ c.default_cassette_options = { :record => :new_episodes }
33
+ end
34
+
35
+ MiniTest::Unit.autorun
metadata ADDED
@@ -0,0 +1,225 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rubineti
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 0
8
+ - 2
9
+ version: 1.0.2
10
+ platform: ruby
11
+ authors:
12
+ - retr0h
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-11-29 00:00:00 -08:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: yajl-ruby
22
+ requirement: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ - 7
30
+ - 8
31
+ version: 0.7.8
32
+ type: :runtime
33
+ prerelease: false
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: net-http-persistent
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ~>
41
+ - !ruby/object:Gem::Version
42
+ segments:
43
+ - 1
44
+ - 4
45
+ - 1
46
+ version: 1.4.1
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: rake
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ segments:
58
+ - 0
59
+ version: "0"
60
+ type: :development
61
+ prerelease: false
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: jeweler
65
+ requirement: &id004 !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ~>
69
+ - !ruby/object:Gem::Version
70
+ segments:
71
+ - 1
72
+ - 5
73
+ - 1
74
+ version: 1.5.1
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: *id004
78
+ - !ruby/object:Gem::Dependency
79
+ name: vcr
80
+ requirement: &id005 !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ segments:
86
+ - 1
87
+ - 3
88
+ - 3
89
+ version: 1.3.3
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: *id005
93
+ - !ruby/object:Gem::Dependency
94
+ name: webmock
95
+ requirement: &id006 !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ~>
99
+ - !ruby/object:Gem::Version
100
+ segments:
101
+ - 1
102
+ - 6
103
+ - 1
104
+ version: 1.6.1
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: *id006
108
+ - !ruby/object:Gem::Dependency
109
+ name: minitest
110
+ requirement: &id007 !ruby/object:Gem::Requirement
111
+ none: false
112
+ requirements:
113
+ - - ~>
114
+ - !ruby/object:Gem::Version
115
+ segments:
116
+ - 2
117
+ - 0
118
+ - 0
119
+ version: 2.0.0
120
+ type: :development
121
+ prerelease: false
122
+ version_requirements: *id007
123
+ - !ruby/object:Gem::Dependency
124
+ name: mocha
125
+ requirement: &id008 !ruby/object:Gem::Requirement
126
+ none: false
127
+ requirements:
128
+ - - ~>
129
+ - !ruby/object:Gem::Version
130
+ segments:
131
+ - 0
132
+ - 9
133
+ - 10
134
+ version: 0.9.10
135
+ type: :development
136
+ prerelease: false
137
+ version_requirements: *id008
138
+ description:
139
+ email: john@dewey.ws
140
+ executables: []
141
+
142
+ extensions: []
143
+
144
+ extra_rdoc_files:
145
+ - LICENSE
146
+ - README.md
147
+ files:
148
+ - .rvmrc
149
+ - Gemfile
150
+ - Gemfile.lock
151
+ - LICENSE
152
+ - README.md
153
+ - Rakefile
154
+ - VERSION
155
+ - lib/ganeti.rb
156
+ - lib/rubineti.rb
157
+ - lib/rubineti/compute.rb
158
+ - lib/rubineti/compute/cluster.rb
159
+ - lib/rubineti/compute/instances.rb
160
+ - lib/rubineti/compute/jobs.rb
161
+ - lib/rubineti/compute/node.rb
162
+ - rubineti.gemspec
163
+ - test/fixtures/cassettes/cluster_info.yml
164
+ - test/fixtures/cassettes/cluster_oses.yml
165
+ - test/fixtures/cassettes/cluster_redistribute_config.yml
166
+ - test/fixtures/cassettes/cluster_version.yml
167
+ - test/fixtures/cassettes/instance_create.yml
168
+ - test/fixtures/cassettes/instance_delete.yml
169
+ - test/fixtures/cassettes/instance_info.yml
170
+ - test/fixtures/cassettes/instance_list.yml
171
+ - test/fixtures/cassettes/instance_reboot.yml
172
+ - test/fixtures/cassettes/instance_reinstall.yml
173
+ - test/fixtures/cassettes/instance_shutdown.yml
174
+ - test/fixtures/cassettes/instance_startup.yml
175
+ - test/fixtures/cassettes/instances.yml
176
+ - test/fixtures/cassettes/job_list.yml
177
+ - test/fixtures/cassettes/jobs.yml
178
+ - test/fixtures/cassettes/node_list.yml
179
+ - test/fixtures/cassettes/node_role_list.yml
180
+ - test/fixtures/cassettes/nodes.yml
181
+ - test/lib/rubineti/compute/test_cluster.rb
182
+ - test/lib/rubineti/compute/test_instances.rb
183
+ - test/lib/rubineti/compute/test_jobs.rb
184
+ - test/lib/rubineti/compute/test_node.rb
185
+ - test/lib/rubineti/test_compute.rb
186
+ - test/support.rb
187
+ has_rdoc: true
188
+ homepage: http://github.com/retr0h/rubineti
189
+ licenses: []
190
+
191
+ post_install_message:
192
+ rdoc_options: []
193
+
194
+ require_paths:
195
+ - lib
196
+ required_ruby_version: !ruby/object:Gem::Requirement
197
+ none: false
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ segments:
202
+ - 0
203
+ version: "0"
204
+ required_rubygems_version: !ruby/object:Gem::Requirement
205
+ none: false
206
+ requirements:
207
+ - - ">="
208
+ - !ruby/object:Gem::Version
209
+ segments:
210
+ - 0
211
+ version: "0"
212
+ requirements: []
213
+
214
+ rubyforge_project:
215
+ rubygems_version: 1.3.7
216
+ signing_key:
217
+ specification_version: 3
218
+ summary: Ruby bindings to Ganeti's v2 Remote API.
219
+ test_files:
220
+ - test/lib/rubineti/compute/test_cluster.rb
221
+ - test/lib/rubineti/compute/test_instances.rb
222
+ - test/lib/rubineti/compute/test_jobs.rb
223
+ - test/lib/rubineti/compute/test_node.rb
224
+ - test/lib/rubineti/test_compute.rb
225
+ - test/support.rb