occi 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm ruby-1.9.2-p0@occi
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source "http://rubygems.org"
2
+
3
+ #gem "hugs", "~> 2.1.0"
4
+ gem "hugs", :path => "~/git/hugs"
5
+ gem "multipart-post", "~> 1.0.1"
6
+ gem "nokogiri", "~> 1.4.4"
7
+
8
+ group :development do
9
+ gem "rake"
10
+ gem "jeweler", "~> 1.5.1"
11
+ gem "webmock", "~> 1.6.1"
12
+ gem "vcr", "~> 1.4.0"
13
+ gem "minitest", "~> 2.0.0"
14
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,41 @@
1
+ PATH
2
+ remote: ~/git/hugs
3
+ specs:
4
+ hugs (2.0.0)
5
+ net-http-persistent (~> 1.4.1)
6
+ nokogiri (~> 1.4.4)
7
+ yajl-ruby (~> 0.7.8)
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ addressable (2.2.2)
13
+ crack (0.1.8)
14
+ git (1.2.5)
15
+ jeweler (1.5.1)
16
+ bundler (~> 1.0.0)
17
+ git (>= 1.2.5)
18
+ rake
19
+ minitest (2.0.0)
20
+ multipart-post (1.0.1)
21
+ net-http-persistent (1.4.1)
22
+ nokogiri (1.4.4)
23
+ rake (0.8.7)
24
+ vcr (1.4.0)
25
+ webmock (1.6.1)
26
+ addressable (>= 2.2.2)
27
+ crack (>= 0.1.7)
28
+ yajl-ruby (0.7.8)
29
+
30
+ PLATFORMS
31
+ ruby
32
+
33
+ DEPENDENCIES
34
+ hugs!
35
+ jeweler (~> 1.5.1)
36
+ minitest (~> 2.0.0)
37
+ multipart-post (~> 1.0.1)
38
+ nokogiri (~> 1.4.4)
39
+ rake
40
+ vcr (~> 1.4.0)
41
+ webmock (~> 1.6.1)
data/LICENSE ADDED
@@ -0,0 +1,4 @@
1
+ "THE BEER-WARE LICENSE" (Revision 42):
2
+ <john@dewey.ws> wrote this file. As long as you retain this notice you
3
+ can do whatever you want with this stuff. If we meet some day, and you think
4
+ this stuff is worth it, you can buy me a beer in return John-B Dewey Jr.
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # OCCI
2
+
3
+ [Ruby](http://www.ruby-lang.org/) bindings to [OpenNebula's](http://opennebula.org) [Open Cloud Computing Interface (OCCI)](http://www.opennebula.org/documentation:rel2.0:occidd).
4
+
5
+ ## Usage
6
+
7
+ ### Bundler
8
+
9
+ gem "occi"
10
+
11
+ ### Examples
12
+
13
+ See the examples section in the [wiki](http://github.com/retr0h/occi/wiki).
14
+
15
+ ## Testing
16
+
17
+ MiniTest will run the tests in a random order. When rebuilding the fixtures, the entity
18
+ tests depend on the pool tests having already been run. Since the fixtures change infrequently,
19
+ this should be acceptable.
20
+
21
+ $ export ONE_USER=$user
22
+ $ export ONE_PASSWORD=$password
23
+
24
+ $ bundle exec rake
25
+
26
+ ## TODO
27
+
28
+ * Should we raise when we do not have expected HTTP code or body?
data/Rakefile ADDED
@@ -0,0 +1,25 @@
1
+ require "rubygems"
2
+ require "rake"
3
+
4
+ begin
5
+ require "jeweler"
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "occi"
8
+ gem.summary = %Q{Ruby bindings to Open Cloud Computing Interface (OCCI).}
9
+ gem.email = "john@dewey.ws"
10
+ gem.homepage = "http://github.com/retr0h/occi"
11
+ gem.authors = ["retr0h"]
12
+ end
13
+ Jeweler::GemcutterTasks.new
14
+ rescue LoadError
15
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
16
+ end
17
+
18
+ require "rake/testtask"
19
+ Rake::TestTask.new(:test) do |test|
20
+ test.libs << "lib" << "test"
21
+ test.pattern = "test/**/test_*.rb"
22
+ test.verbose = true
23
+ end
24
+
25
+ task :default => :test
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
data/lib/occi.rb ADDED
@@ -0,0 +1 @@
1
+ require "occi/client"
@@ -0,0 +1,35 @@
1
+ require "hugs"
2
+ require "digest/sha1"
3
+
4
+ module Occi
5
+ class Client
6
+ ##
7
+ # Include endpoints.
8
+
9
+ %w(pool entity).each do |mixin|
10
+ require "occi/#{mixin}"
11
+ include eval "Occi::#{mixin.capitalize}"
12
+ end
13
+
14
+ ##
15
+ # Required:
16
+ # +user+: A String containing the username for use in HTTP Basic auth.
17
+ # +password+: A String containing the password for use in HTTP Basic auth.
18
+ # +host+: A String with the host to connect.
19
+
20
+ def initialize options
21
+ @connection = Hugs.new(
22
+ :user => options[:user],
23
+ :password => Digest::SHA1.hexdigest(options[:password]),
24
+ :host => options[:host],
25
+ :scheme => options[:scheme] || "http",
26
+ :port => options[:port] || 4567,
27
+ :type => options[:type] || :xml,
28
+ )
29
+ end
30
+
31
+ def request
32
+ @connection
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,63 @@
1
+ module Occi
2
+ module Entity
3
+ Gets = %w(
4
+ compute
5
+ network
6
+ storage
7
+ ).map { |v| "#{v}_get" }.freeze
8
+
9
+ Deletes = %w(
10
+ compute
11
+ network
12
+ storage
13
+ ).map { |v| "#{v}_delete" }.freeze
14
+
15
+ Puts = %w(
16
+ compute
17
+ ).map { |v| "#{v}_put" }.freeze
18
+
19
+ ##
20
+ # The _get methods:
21
+ # Returns the representation of the Compute resource identified by +compute_id+.
22
+ # 200 OK: An XML representation of the pool in the http body.
23
+ #
24
+ # The _delete methods:
25
+ # Deletes the Compute resource identified by +compute_id+.
26
+ # 204 No Content : The Compute has been successfully deleted.
27
+ #
28
+ # The _put methods:
29
+ # Update request for a Compute identified by +compute_id+.
30
+ # 202 Accepted : The update request is being process, polling required to confirm update.
31
+
32
+ (Gets + Deletes + Puts).each do |method|
33
+ define_method method do |*args|
34
+ id = args[0]
35
+ params = args[1] || {}
36
+ path, verb = method.split("_")
37
+
38
+ request.send verb, "/#{path}/#{id}", params
39
+ end
40
+ end
41
+
42
+ ##
43
+ # :method: compute_get
44
+
45
+ ##
46
+ # :method: compute_delete
47
+
48
+ ##
49
+ # :method: compute_put
50
+
51
+ ##
52
+ # :method: network_get
53
+
54
+ ##
55
+ # :method: network_delete
56
+
57
+ ##
58
+ # :method: storage_get
59
+
60
+ ##
61
+ # :method: storage_delete
62
+ end
63
+ end
data/lib/occi/pool.rb ADDED
@@ -0,0 +1,52 @@
1
+ module Occi
2
+ module Pool
3
+ Gets = %w(
4
+ computes
5
+ networks
6
+ storages
7
+ ).map { |v| "#{v}_get" }.freeze
8
+
9
+ Posts = %w(
10
+ computes
11
+ networks
12
+ storages
13
+ ).map { |v| "#{v}_post" }.freeze
14
+
15
+ ##
16
+ # The _get methods:
17
+ # Returns the contents of the pool.
18
+ # 200 OK: An XML representation of the pool in the http body.
19
+ #
20
+ # The _post methods:
21
+ # Request for the creation of an ER. An XML representation of a
22
+ # VM without the ID element should be passed in the http body.
23
+ # 201 Created: An XML representation of a ER of type COMPUTE with the ID.
24
+
25
+ (Gets + Posts).each do |method|
26
+ define_method method do |*args|
27
+ params = args[0] || {}
28
+ path, verb = method.split("_")
29
+
30
+ request.send verb, "/#{path.sub(%r{s$}, '')}", params
31
+ end
32
+ end
33
+
34
+ ##
35
+ # :method: computes_get
36
+
37
+ ##
38
+ # :method: computes_post
39
+
40
+ ##
41
+ # :method: networks_get
42
+
43
+ ##
44
+ # :method: networks_post
45
+
46
+ ##
47
+ # :method: storages_get
48
+
49
+ ##
50
+ # :method: storages_post
51
+ end
52
+ end
@@ -0,0 +1,22 @@
1
+ ---
2
+ - !ruby/struct:VCR::HTTPInteraction
3
+ request: !ruby/struct:VCR::Request
4
+ method: :delete
5
+ uri: http://oneadmin:a9464e3228ae563be6207bbf50437a219550f48b@one.example.com:4567/compute/135
6
+ body:
7
+ headers:
8
+ accept:
9
+ - application/xml
10
+ connection:
11
+ - keep-alive
12
+ keep-alive:
13
+ - 30
14
+ response: !ruby/struct:VCR::Response
15
+ status: !ruby/struct:VCR::ResponseStatus
16
+ code: 204
17
+ message: No Content
18
+ headers:
19
+ server:
20
+ - thin 1.2.7 codename No Hup
21
+ body:
22
+ http_version: "1.1"
@@ -0,0 +1,109 @@
1
+ ---
2
+ - !ruby/struct:VCR::HTTPInteraction
3
+ request: !ruby/struct:VCR::Request
4
+ method: :get
5
+ uri: http://oneadmin:a9464e3228ae563be6207bbf50437a219550f48b@one.example.com:4567/compute/130
6
+ body:
7
+ headers:
8
+ accept:
9
+ - application/xml
10
+ connection:
11
+ - keep-alive
12
+ keep-alive:
13
+ - 30
14
+ response: !ruby/struct:VCR::Response
15
+ status: !ruby/struct:VCR::ResponseStatus
16
+ code: 200
17
+ message: OK
18
+ headers:
19
+ content-type:
20
+ - text/html;charset=utf-8
21
+ content-length:
22
+ - "714"
23
+ connection:
24
+ - keep-alive
25
+ server:
26
+ - thin 1.2.7 codename No Hup
27
+ body: <COMPUTE href="http://cm-01.cloud.int.ev1.atti.com:4567/compute/130"><ID>130</ID><NAME>Test Framework</NAME><INSTANCE_TYPE>small</INSTANCE_TYPE><STATE>ACTIVE</STATE><DISK><STORAGE href="http://cm-01.cloud.int.ev1.atti.com:4567/storage/11" name="Centos 5.4 x86_64"/><TYPE>DISK</TYPE><TARGET>hda</TARGET></DISK><NIC><NETWORK href="http://cm-01.cloud.int.ev1.atti.com:4567/network/14" name="10.3.172.0"/><IP>10.3.172.23</IP><MAC>02:00:0a:03:ac:17</MAC></NIC><CONTEXT><FILES>/opt/tpkg/opennebula-2.0/../var/opennebula-2.0/templates/context/init.sh</FILES><GATEWAY>10.3.172.1</GATEWAY><HOSTNAME>02:00:0a:03:ac:17</HOSTNAME><IP_PUBLIC>10.3.172.23</IP_PUBLIC><NETMASK>/23</NETMASK><TARGET>hdc</TARGET></CONTEXT></COMPUTE>
28
+ http_version: "1.1"
29
+ - !ruby/struct:VCR::HTTPInteraction
30
+ request: !ruby/struct:VCR::Request
31
+ method: :get
32
+ uri: http://oneadmin:a9464e3228ae563be6207bbf50437a219550f48b@one.example.com:4567/compute/131
33
+ body:
34
+ headers:
35
+ accept:
36
+ - application/xml
37
+ connection:
38
+ - keep-alive
39
+ keep-alive:
40
+ - 30
41
+ response: !ruby/struct:VCR::Response
42
+ status: !ruby/struct:VCR::ResponseStatus
43
+ code: 200
44
+ message: OK
45
+ headers:
46
+ content-type:
47
+ - text/html;charset=utf-8
48
+ content-length:
49
+ - "715"
50
+ connection:
51
+ - keep-alive
52
+ server:
53
+ - thin 1.2.7 codename No Hup
54
+ body: <COMPUTE href="http://cm-01.cloud.int.ev1.atti.com:4567/compute/131"><ID>131</ID><NAME>Test Framework</NAME><INSTANCE_TYPE>small</INSTANCE_TYPE><STATE>PENDING</STATE><DISK><STORAGE href="http://cm-01.cloud.int.ev1.atti.com:4567/storage/11" name="Centos 5.4 x86_64"/><TYPE>DISK</TYPE><TARGET>hda</TARGET></DISK><NIC><NETWORK href="http://cm-01.cloud.int.ev1.atti.com:4567/network/14" name="10.3.172.0"/><IP>10.3.172.24</IP><MAC>02:00:0a:03:ac:18</MAC></NIC><CONTEXT><FILES>/opt/tpkg/opennebula-2.0/../var/opennebula-2.0/templates/context/init.sh</FILES><GATEWAY>10.3.172.1</GATEWAY><HOSTNAME>02:00:0a:03:ac:18</HOSTNAME><IP_PUBLIC>10.3.172.24</IP_PUBLIC><NETMASK>/23</NETMASK><TARGET>hdc</TARGET></CONTEXT></COMPUTE>
55
+ http_version: "1.1"
56
+ - !ruby/struct:VCR::HTTPInteraction
57
+ request: !ruby/struct:VCR::Request
58
+ method: :get
59
+ uri: http://oneadmin:a9464e3228ae563be6207bbf50437a219550f48b@one.example.com:4567/compute/1
60
+ body:
61
+ headers:
62
+ accept:
63
+ - application/xml
64
+ connection:
65
+ - keep-alive
66
+ keep-alive:
67
+ - 30
68
+ response: !ruby/struct:VCR::Response
69
+ status: !ruby/struct:VCR::ResponseStatus
70
+ code: 200
71
+ message: OK
72
+ headers:
73
+ content-type:
74
+ - text/html;charset=utf-8
75
+ content-length:
76
+ - "136"
77
+ connection:
78
+ - keep-alive
79
+ server:
80
+ - thin 1.2.7 codename No Hup
81
+ body: <COMPUTE href="http://cm-01.cloud.int.ev1.atti.com:4567/compute/1"><ID>1</ID><NAME>Centos 5.4 x86_64</NAME><STATE>DONE</STATE></COMPUTE>
82
+ http_version: "1.1"
83
+ - !ruby/struct:VCR::HTTPInteraction
84
+ request: !ruby/struct:VCR::Request
85
+ method: :get
86
+ uri: http://oneadmin:a9464e3228ae563be6207bbf50437a219550f48b@one.example.com:4567/compute/135
87
+ body:
88
+ headers:
89
+ accept:
90
+ - application/xml
91
+ connection:
92
+ - keep-alive
93
+ keep-alive:
94
+ - 30
95
+ response: !ruby/struct:VCR::Response
96
+ status: !ruby/struct:VCR::ResponseStatus
97
+ code: 200
98
+ message: OK
99
+ headers:
100
+ content-type:
101
+ - text/html;charset=utf-8
102
+ content-length:
103
+ - "714"
104
+ connection:
105
+ - keep-alive
106
+ server:
107
+ - thin 1.2.7 codename No Hup
108
+ body: <COMPUTE href="http://cm-01.cloud.int.ev1.atti.com:4567/compute/135"><ID>135</ID><NAME>Test Framework</NAME><INSTANCE_TYPE>small</INSTANCE_TYPE><STATE>ACTIVE</STATE><DISK><STORAGE href="http://cm-01.cloud.int.ev1.atti.com:4567/storage/11" name="Centos 5.4 x86_64"/><TYPE>DISK</TYPE><TARGET>hda</TARGET></DISK><NIC><NETWORK href="http://cm-01.cloud.int.ev1.atti.com:4567/network/14" name="10.3.172.0"/><IP>10.3.172.25</IP><MAC>02:00:0a:03:ac:19</MAC></NIC><CONTEXT><FILES>/opt/tpkg/opennebula-2.0/../var/opennebula-2.0/templates/context/init.sh</FILES><GATEWAY>10.3.172.1</GATEWAY><HOSTNAME>02:00:0a:03:ac:19</HOSTNAME><IP_PUBLIC>10.3.172.25</IP_PUBLIC><NETMASK>/23</NETMASK><TARGET>hdc</TARGET></CONTEXT></COMPUTE>
109
+ http_version: "1.1"
@@ -0,0 +1,35 @@
1
+ ---
2
+ - !ruby/struct:VCR::HTTPInteraction
3
+ request: !ruby/struct:VCR::Request
4
+ method: :put
5
+ uri: http://oneadmin:a9464e3228ae563be6207bbf50437a219550f48b@one.example.com:4567/compute/134
6
+ body: |
7
+ <?xml version="1.0"?>
8
+ <COMPUTE>
9
+ <STATE>shutdown</STATE>
10
+ </COMPUTE>
11
+
12
+ headers:
13
+ accept:
14
+ - application/xml
15
+ content-type:
16
+ - application/xml
17
+ connection:
18
+ - keep-alive
19
+ keep-alive:
20
+ - 30
21
+ response: !ruby/struct:VCR::Response
22
+ status: !ruby/struct:VCR::ResponseStatus
23
+ code: 202
24
+ message: Accepted
25
+ headers:
26
+ content-type:
27
+ - text/html;charset=utf-8
28
+ content-length:
29
+ - "809"
30
+ connection:
31
+ - keep-alive
32
+ server:
33
+ - thin 1.2.7 codename No Hup
34
+ body: <COMPUTE href="http://cm-01.cloud.int.ev1.atti.com:4567/compute/134"><ID>134</ID><NAME>Centos-5-4_x86_64-Kevin</NAME><STATE>ACTIVE</STATE><DISK><STORAGE href="http://cm-01.cloud.int.ev1.atti.com:4567/storage/22" name="Centos 5.4 x86_64 Kevin"/><TYPE>DISK</TYPE><TARGET>hda</TARGET></DISK><DISK><STORAGE href="http://cm-01.cloud.int.ev1.atti.com:4567/storage/" name=""/><TYPE>swap</TYPE><TARGET>hdd</TARGET></DISK><NIC><NETWORK href="http://cm-01.cloud.int.ev1.atti.com:4567/network/15" name="10.3.174.0"/><IP>10.3.174.10</IP><MAC>02:00:0a:03:ae:0a</MAC></NIC><CONTEXT><FILES>/opt/tpkg/var/opennebula-2.0/templates/context/init.sh</FILES><GATEWAY>10.3.174.1</GATEWAY><HOSTNAME>02:00:0a:03:ae:0a</HOSTNAME><IP_PUBLIC>10.3.174.10</IP_PUBLIC><NETMASK>/23</NETMASK><NS></NS><TARGET>hdc</TARGET></CONTEXT></COMPUTE>
35
+ http_version: "1.1"