occi 2.5.3 → 2.5.4

Sign up to get free protection for your applications and to get access to all the features.
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