occi 2.5.3 → 2.5.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/occi.gemspec CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |gem|
11
11
  gem.email = ["florian.feldhaus@gwdg.de", "piotr.kasprzak@gwdg.de"]
12
12
  gem.description = %q{OCCI is a collection of classes to simplify the implementation of the Open Cloud Computing API in Ruby}
13
13
  gem.summary = %q{OCCI toolkit}
14
- gem.homepage = 'https://github.com/gwdg/occi'
14
+ gem.homepage = 'https://github.com/gwdg/rOCCI'
15
15
 
16
16
  gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
17
  gem.files = `git ls-files`.split("\n")
@@ -25,6 +25,7 @@ Gem::Specification.new do |gem|
25
25
  gem.add_dependency 'nokogiri'
26
26
  gem.add_dependency 'activesupport'
27
27
  gem.add_dependency 'httparty'
28
+ gem.add_dependency 'i18n'
28
29
 
29
30
  gem.required_ruby_version = ">= 1.8.7"
30
31
  end
@@ -8,22 +8,22 @@ module OCCI
8
8
  describe Parser do
9
9
  describe "#Category" do
10
10
  it "is parsed successful" do
11
- ATTRIBUTE = { :mutable => true, :required => false, :type => "string" }
11
+ ATTRIBUTE = { :Mutable => true, :Required => false, :Type => "string" }
12
12
  term = 'entity'
13
13
  scheme = 'http://schemas.ogf.org/occi/core#'
14
14
  class_type = 'kind'
15
15
  title = 'Storage Resource How\'s your quotes escaping?\"'
16
- rel = 'http://schemas.ogf.org/occi/core#resource'
16
+ rel = ['http://schemas.ogf.org/occi/core#resource#']
17
17
  location = '/storage/'
18
18
  attributes = Hashie::Mash.new
19
- attributes.occi!.storage!.size = ATTRIBUTE
19
+ attributes.occi!.storage!.size = { :Mutable => false, :Required => false, :Type => "string" }
20
20
  attributes.occi!.storage!.state = ATTRIBUTE
21
- attributes_string = 'occi.storage.size occi.storage.state'
21
+ attributes_string = 'occi.storage.size{immutable} occi.storage.state'
22
22
  actions = Array.new
23
23
  actions << 'http://schemas.ogf.org/occi/infrastructure/storage/action#resize'
24
24
  actions << 'http://schemas.ogf.org/occi/infrastructure/storage/action#online'
25
25
 
26
- category_string = %Q{Category: #{term}; scheme="#{scheme}"; class="#{class_type}"; title="#{title}"; rel="#{rel}"; location="#{location}"; attributes="#{attributes_string}"; actions="#{actions.join(' ')}"}
26
+ category_string = %Q{Category: #{term}; scheme="#{scheme}"; class="#{class_type}"; title="#{title}"; rel="#{rel.first}"; location="#{location}"; attributes="#{attributes_string}"; actions="#{actions.join(' ')}"}
27
27
 
28
28
  category = OCCIANTLR::Parser.new(category_string).category
29
29
  kind = category[:kinds].first
@@ -42,19 +42,19 @@ module OCCI
42
42
  target = '/network/123'
43
43
  rel = 'http://schemas.ogf.org/occi/infrastructure#network'
44
44
  self_location = '/link/networkinterface/456'
45
- category = 'http://schemas.ogf.org/occi/infrastructure#networkinterface'
45
+ kind = 'http://schemas.ogf.org/occi/infrastructure#networkinterface'
46
46
  attributes = Hashie::Mash.new
47
47
  attributes.occi!.networkinterface!.interface = '"eth0"'
48
48
  attributes.occi!.networkinterface!.mac = '"00:11:22:33:44:55"'
49
49
  attributes.occi!.networkinterface!.state = '"active"'
50
50
  attributes_string = %Q{occi.networkinterface.interface="eth0";occi.networkinterface.mac="00:11:22:33:44:55";occi.networkinterface.state="active"}
51
- link_string = %Q{Link: <#{target}>; rel="#{rel}"; self="#{self_location}"; category="#{category}"; #{attributes_string}}
51
+ link_string = %Q{Link: <#{target}>; rel="#{rel}"; self="#{self_location}"; category="#{kind}"; #{attributes_string}}
52
52
 
53
53
  link = OCCIANTLR::Parser.new(link_string).link
54
54
  link[:target].should == target
55
55
  link[:rel].should == rel
56
56
  link[:self].should == self_location
57
- link[:category].should == category
57
+ link[:kind].should == kind
58
58
  link[:attributes].should == attributes
59
59
  end
60
60
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: occi
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.3
4
+ version: 2.5.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-08-21 00:00:00.000000000 Z
13
+ date: 2012-09-10 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: json
@@ -124,12 +124,29 @@ dependencies:
124
124
  - - ! '>='
125
125
  - !ruby/object:Gem::Version
126
126
  version: '0'
127
+ - !ruby/object:Gem::Dependency
128
+ name: i18n
129
+ requirement: !ruby/object:Gem::Requirement
130
+ none: false
131
+ requirements:
132
+ - - ! '>='
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ type: :runtime
136
+ prerelease: false
137
+ version_requirements: !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ! '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
127
143
  description: OCCI is a collection of classes to simplify the implementation of the
128
144
  Open Cloud Computing API in Ruby
129
145
  email:
130
146
  - florian.feldhaus@gwdg.de
131
147
  - piotr.kasprzak@gwdg.de
132
- executables: []
148
+ executables:
149
+ - occi
133
150
  extensions: []
134
151
  extra_rdoc_files: []
135
152
  files:
@@ -143,6 +160,7 @@ files:
143
160
  - LICENSE
144
161
  - README.md
145
162
  - Rakefile
163
+ - bin/occi
146
164
  - etc/model/infrastructure/compute.json
147
165
  - etc/model/infrastructure/ipnetwork.json
148
166
  - etc/model/infrastructure/ipnetworkinterface.json
@@ -152,10 +170,13 @@ files:
152
170
  - etc/model/infrastructure/resource_template.json
153
171
  - etc/model/infrastructure/storage.json
154
172
  - etc/model/infrastructure/storagelink.json
173
+ - examples/dsl_example.rb
155
174
  - examples/x509auth_example.rb
156
175
  - lib/occi.rb
157
- - lib/occi/client.rb
176
+ - lib/occi/api/client.rb
177
+ - lib/occi/api/dsl.rb
158
178
  - lib/occi/collection.rb
179
+ - lib/occi/core.rb
159
180
  - lib/occi/core/action.rb
160
181
  - lib/occi/core/attribute_properties.rb
161
182
  - lib/occi/core/attributes.rb
@@ -186,7 +207,7 @@ files:
186
207
  - spec/occi/test.ovf
187
208
  - spec/occiantlr/parser_spec.rb
188
209
  - spec/spec_helper.rb
189
- homepage: https://github.com/gwdg/occi
210
+ homepage: https://github.com/gwdg/rOCCI
190
211
  licenses: []
191
212
  post_install_message:
192
213
  rdoc_options: []
data/lib/occi/client.rb DELETED
@@ -1,308 +0,0 @@
1
- require 'rubygems'
2
- require 'httparty'
3
-
4
- def compute
5
- 'http://schemas.ogf.org/occi/infrastructure#compute'
6
- end
7
-
8
- def storage
9
- 'http://schemas.ogf.org/occi/infrastructure#storage'
10
- end
11
-
12
- def network
13
- 'http://schemas.ogf.org/occi/infrastructure#network'
14
- end
15
-
16
- def resources
17
- '/'
18
- end
19
-
20
- module OCCI
21
- class Client
22
- include HTTParty
23
- headers 'Accept' => 'application/occi+json,text/plain;q=0.5'
24
-
25
- attr_reader :endpoint
26
- attr_reader :model
27
- attr_reader :auth_options
28
-
29
- # @param [String] endpoint URI of the OCCI endpoint to connect to
30
- # @param [Hash] authorization hash containing authorization information
31
- # @param [IO,String] log_dev The log device. This is a filename (String) or IO object (typically +STDOUT+#, +STDERR+, or an open file).
32
- def initialize(endpoint, auth_options = { }, log_dev=STDOUT)
33
- OCCI::Log.new(log_dev)
34
-
35
- @auth_options = auth_options || { :type => "none" }
36
- case @auth_options[:type]
37
- when "basic"
38
- # set up basic auth
39
- raise ArgumentError, "Missing required options 'username' and 'password' for basic auth!" unless @auth_options[:username] and @auth_options[:password]
40
- self.class.basic_auth @auth_options[:username], @auth_options[:password]
41
- when "digest"
42
- # set up digest auth
43
- raise ArgumentError, "Missing required options 'username' and 'password' for digest auth!" unless @auth_options[:username] and @auth_options[:password]
44
- self.class.digest_auth @auth_options[:username], @auth_options[:password]
45
- when "x509"
46
- # set up pem and optionally pem_password and ssl_ca_path
47
- raise ArgumentError, "Missing required option 'user_cert' for x509 auth!" unless @auth_options[:user_cert]
48
- raise ArgumentError, "The file specified in 'user_cert' does not exist!" unless File.exists? @auth_options[:user_cert]
49
-
50
- self.class.pem File.read(@auth_options[:user_cert]), @auth_options[:user_cert_password]
51
- self.class.ssl_ca_path @auth_options[:ca_path] unless @auth_options[:ca_path].nil? or @auth_options[:ca_path].empty?
52
- when "none", nil
53
- # do nothing
54
- else
55
- raise ArgumentError, "Unknown AUTH method [#{@auth_options[:type]}]!"
56
- end
57
-
58
- raise 'endpoint not a valid URI' if (endpoint =~ URI::ABS_URI).nil?
59
- @endpoint = endpoint.chomp('/') + '/'
60
- refresh_model
61
- select_media_type
62
- end
63
-
64
- # @return [OCCI::Model]
65
- def refresh_model
66
- model = get '/-/'
67
- @model = OCCI::Model.new(model)
68
- end
69
-
70
- # trigger action on resource location
71
- # @param [OCCI::Core::Action] action
72
- # @param [String,URI::Generic] location
73
- def trigger(action, location)
74
- collection = OCCI::Collection.new
75
- collection.actions << action
76
- post(location, collection)
77
- end
78
-
79
- # @return [OCCI::Collection] collection including all registered OS templates
80
- def get_os_templates
81
- filter = OCCI::Collection.new
82
- # use the os_tpl mixin as filter for the request
83
- filter.mixins = @model.get.mixins.select { |mixin| mixin.term == 'os_tpl' }
84
- collection = get '/-/', filter
85
- # remove os_tpl mixin from the mixins as it does not represent a template itself
86
- collection.mixins.select { |mixin| mixin.term != 'os_tpl' }
87
- end
88
-
89
- # @return [OCCI::Collection] collection including all registered resource templates
90
- def get_resource_templates
91
- filter = OCCI::Collection.new
92
- # use the resource_tpl mixin as filter for the request
93
- filter.mixins = @model.get.mixins.select { |mixin| mixin.term == 'resource_tpl' }
94
- collection = get '/-/', filter
95
- # remove os_tpl mixin from the mixins as it does not represent a template itself
96
- collection.mixins.select { |mixin| mixin.term != 'resource_tpl' }
97
- end
98
-
99
- # @param [OCCI::Core::Resource] compute
100
- # @param [URI,String] storage_location
101
- # @param [OCCI::Core::Attributes] attributes
102
- # @param [Array] mixins
103
- # @return [OCCI::Core::Link]
104
- def storagelink(compute, storage_location, attributes=OCCI::Core::Attributes.new, mixins=[])
105
- kind = 'http://schemas.ogf.org/occi/infrastructure#storagelink'
106
- storage_kind = 'http://schemas.ogf.org/occi/infrastructure#storage'
107
- storagelink = link(kind, compute, storage_location, storage_kind, attributes, mixins)
108
- storagelink
109
- end
110
-
111
- # @param [OCCI::Core::Resource] compute
112
- # @param [URI,String] network_location
113
- # @param [OCCI::Core::Attributes] attributes
114
- # @param [Array] mixins
115
- # @return [OCCI::Core::Link]
116
- def networkinterface(compute, network_location, attributes=OCCI::Core::Attributes.new, mixins=[])
117
- kind = 'http://schemas.ogf.org/occi/infrastructure#networkinterface'
118
- network_kind = 'http://schemas.ogf.org/occi/infrastructure#network'
119
- networkinterface = link(kind, compute, network_location, network_kind, attributes, mixins)
120
- networkinterface
121
- end
122
-
123
- # @param [String] kind
124
- # @param [OCCI::Core::Resource] source
125
- # @param [URI,String] target_location
126
- # @param [String] target_kind
127
- # @param [OCCI::Core::Attributes] attributes
128
- # @param [Array] mixins
129
- # @return [OCCI::Core::Link]
130
- def link(kind, source, target_location, target_kind, attributes=OCCI::Core::Attributes.new, mixins=[])
131
- link = OCCI::Core::Link.new(kind)
132
- link.mixins = mixins
133
- link.attributes = attributes
134
- link.target = (target_location.kind_of? URI::Generic) ? target_location.path : target_location.to_s
135
- link.rel = target_kind
136
- jj link
137
- link.check @model
138
- source.links << link
139
- link
140
- end
141
-
142
- # @param [String] path
143
- # @return [Array] list of URIs
144
- def list(path='')
145
- path = path.split('#').last + '/' if path.start_with? 'http://'
146
- path = path.reverse.chomp('/').reverse
147
- self.class.get(@endpoint + path, :headers => { "Accept" => 'text/uri-list' }).body.split("\n").compact
148
- end
149
-
150
- # @param [OCCI::Core::Entity] entity
151
- # @return [URI] location of the entity
152
- def create(entity)
153
- raise "#{entity} not an entity" unless entity.kind_of? OCCI::Core::Entity
154
- entity.check(model)
155
- kind = @model.get_by_id(entity.kind)
156
- raise "no kind found for #{entity}" unless kind
157
- location = @model.get_by_id(entity.kind).location
158
- collection = OCCI::Collection.new
159
- collection.resources << entity if entity.kind_of? OCCI::Core::Resource
160
- collection.links << entity if entity.kind_of? OCCI::Core::Link
161
- post location, collection
162
- end
163
-
164
- # @param [String] path
165
- # @param [OCCI::Collection] filter
166
- # @return [OCCI::Collection]
167
- def get(path='', filter=nil)
168
- path = path.split('#').last + '/' if path.start_with? 'http://'
169
- path = path.reverse.chomp('/').reverse
170
- response = if filter
171
- categories = filter.categories.collect { |category| category.to_text }.join(',')
172
- attributes = filter.entities.collect { |entity| entity.attributes.combine.collect { |k, v| k + '=' + v } }.join(',')
173
- self.class.get(@endpoint + path,
174
- :headers => { 'Accept' => 'application/occi+json,text/plain;q=0.5',
175
- 'Content-Type' => 'text/occi',
176
- 'Category' => categories,
177
- 'X-OCCI-Attributes' => attributes })
178
- else
179
- self.class.get(@endpoint + path)
180
- end
181
-
182
- response_message response
183
-
184
- kind = @model.get_by_location path if @model
185
- kind ? entity_type = kind.entity_type : entity_type = nil
186
- _, collection = OCCI::Parser.parse(response.content_type, response.body, path.include?('/-/'), entity_type)
187
- collection
188
- end
189
-
190
- # @param [String] path
191
- # @param [OCCI::Collection] collection
192
- # @return [URI] if an entity has been created its location is returned
193
- def post(path, collection)
194
- path = path.reverse.chomp('/').reverse
195
- response = if @media_type == 'application/occi+json'
196
- self.class.post(@endpoint + path,
197
- :body => collection.to_json,
198
- :headers => { 'Accept' => 'text/uri-list', 'Content-Type' => 'application/occi+json' })
199
- else
200
- self.class.post(@endpoint + path,
201
- :body => collection.to_text,
202
- :headers => { 'Accept' => 'text/uri-list', 'Content-Type' => 'text/plain' })
203
- end
204
-
205
- response_message response
206
-
207
- URI.parse(response.body)
208
- end
209
-
210
- # @param [String] path
211
- # @param [OCCI::Collection] collection
212
- # @return [OCCI::Collection]
213
- def put(path, collection)
214
- path = path.reverse.chomp('/').reverse
215
- response = if @media_type == 'application/occi+json'
216
- self.class.post(@endpoint + path, :body => collection.to_json, :headers => { 'Accept' => 'application/occi+json,text/plain;q=0.5', 'Content-Type' => 'application/occi+json' })
217
- else
218
- self.class.post(@endpoint + path, { :body => collection.to_text, :headers => { 'Accept' => 'application/occi+json,text/plain;q=0.5', 'Content-Type' => 'text/plain' } })
219
- end
220
-
221
- response_message response
222
-
223
- _, collection = OCCI::Parser.parse(response.content_type, response.body)
224
- collection
225
- end
226
-
227
- # @param [String] path
228
- # @param [OCCI::Collection] collection
229
- # @return [true,false]
230
- def delete(path, collection=nil)
231
- path = path.reverse.chomp('/').reverse
232
- response = self.class.delete(@endpoint + path)
233
- response_message response
234
- false unless response.code.between? 200, 300
235
- end
236
-
237
- private
238
-
239
- # @return [String]
240
- def select_media_type
241
- media_types = self.class.head(@endpoint).headers['accept']
242
- OCCI::Log.debug("Available media types: #{media_types}")
243
- @media_type = case media_types
244
- when /application\/occi\+json/
245
- 'application/occi+json'
246
- else
247
- 'text/plain'
248
- end
249
- end
250
-
251
- # @param [Integer] code
252
- # @return [String] HTTP status reason
253
- def reason_phrase(code)
254
- hash = {
255
- "100" => "Continue",
256
- "101" => "Switching Protocols",
257
- "200" => "OK",
258
- "201" => "Created",
259
- "202" => "Accepted",
260
- "203" => "Non-Authoritative Information",
261
- "204" => "No Content",
262
- "205" => "Reset Content",
263
- "206" => "Partial Content",
264
- "300" => "Multiple Choices",
265
- "301" => "Moved Permanently",
266
- "302" => "Found",
267
- "303" => "See Other",
268
- "304" => "Not Modified",
269
- "305" => "Use Proxy",
270
- "307" => "Temporary Redirect",
271
- "400" => "Bad Request",
272
- "401" => "Unauthorized",
273
- "402" => "Payment Required",
274
- "403" => "Forbidden",
275
- "404" => "Not Found",
276
- "405" => "Method Not Allowed",
277
- "406" => "Not Acceptable",
278
- "407" => "Proxy Authentication Required",
279
- "408" => "Request Time-out",
280
- "409" => "Conflict",
281
- "410" => "Gone",
282
- "411" => "Length Required",
283
- "412" => "Precondition Failed",
284
- "413" => "Request Entity Too Large",
285
- "414" => "Request-URI Too Large",
286
- "415" => "Unsupported Media Type",
287
- "416" => "Requested range not satisfiable",
288
- "417" => "Expectation Failed",
289
- "500" => "Internal Server Error",
290
- "501" => "Not Implemented",
291
- "502" => "Bad Gateway",
292
- "503" => "Service Unavailable",
293
- "504" => "Gateway Time-out",
294
- "505" => "HTTP Version not supported"
295
- }
296
- hash[code.to_s]
297
- end
298
-
299
- # @param [HTTParty::Response] response
300
- def response_message(response)
301
- if defined?(IRB)
302
- puts 'HTTP Response status: ' + response.code.to_s + ' ' + reason_phrase(response.code)
303
- raise response.request.http_method.to_s + ' failed ' unless response.code.between? 200, 300
304
- end
305
- end
306
-
307
- end
308
- end