occi 2.1.2 → 2.2.0
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/Gemfile +1 -0
- data/Gemfile.lock +5 -0
- data/README.md +45 -0
- data/lib/occi/client.rb +167 -0
- data/lib/occi/collection.rb +9 -0
- data/lib/occi/core/attribute_properties.rb +16 -4
- data/lib/occi/core/attributes.rb +15 -1
- data/lib/occi/parser.rb +5 -4
- data/lib/occi/version.rb +1 -1
- data/lib/occi.rb +1 -0
- metadata +3 -2
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -8,9 +8,13 @@ GEM
|
|
8
8
|
builder (3.0.0)
|
9
9
|
diff-lcs (1.1.3)
|
10
10
|
hashie (1.2.0)
|
11
|
+
httparty (0.8.1)
|
12
|
+
multi_json
|
13
|
+
multi_xml
|
11
14
|
i18n (0.6.0)
|
12
15
|
json (1.6.6)
|
13
16
|
multi_json (1.3.5)
|
17
|
+
multi_xml (0.4.2)
|
14
18
|
nokogiri (1.5.3)
|
15
19
|
rake (0.9.2.2)
|
16
20
|
rspec (2.10.0)
|
@@ -40,6 +44,7 @@ DEPENDENCIES
|
|
40
44
|
antlr3
|
41
45
|
builder
|
42
46
|
hashie
|
47
|
+
httparty
|
43
48
|
json
|
44
49
|
nokogiri
|
45
50
|
rake
|
data/README.md
CHANGED
@@ -37,6 +37,47 @@ Usage
|
|
37
37
|
First require the gem
|
38
38
|
require 'occi'
|
39
39
|
|
40
|
+
### Client
|
41
|
+
|
42
|
+
The OCCI gem includes a Client to simplify the usage of an OCCI endpoint.
|
43
|
+
|
44
|
+
To connect to an OCCI endpoint/server (e.g. running at http://localhost:3000/ ) use
|
45
|
+
|
46
|
+
client = OCCI::Client.new('http://localhost:3000')
|
47
|
+
|
48
|
+
All available categories are automatically registered to the OCCI model during client initialization. You can get them via
|
49
|
+
|
50
|
+
OCCI::Model.get
|
51
|
+
|
52
|
+
To get all resources (as a list of OCCI::Resources) currently managed by the endpoint use
|
53
|
+
|
54
|
+
client.get_resources
|
55
|
+
|
56
|
+
To get only compute, storage or network resources use get_compute_resources, ...
|
57
|
+
|
58
|
+
To get the location of all resources use
|
59
|
+
|
60
|
+
client.get_resource_list
|
61
|
+
|
62
|
+
Analogue for compute, storage, network via get_compute_list, ...
|
63
|
+
|
64
|
+
To get a list of all OS / resource templates use
|
65
|
+
|
66
|
+
client.get_os_templates
|
67
|
+
client.get_resource_templates
|
68
|
+
|
69
|
+
To get all attributes with their default values for a given category use
|
70
|
+
|
71
|
+
client.get_attributes(client.compute)
|
72
|
+
|
73
|
+
To create a new compute resource use
|
74
|
+
|
75
|
+
os = client.get_os_templates.select { |template| template.term.include? 'my_os' }
|
76
|
+
size = client.get_resource_templates.select { |template| template.term.include? 'large' }
|
77
|
+
attributes = client.get_attributes([client.compute,os,size])
|
78
|
+
attributes['occi.core.title'] = "My VM"
|
79
|
+
client.post_compute(attributes,os,size)
|
80
|
+
|
40
81
|
### Logging
|
41
82
|
|
42
83
|
The OCCI gem includes its own logging mechanism using a message queue. By default, no one is listening to that queue.
|
@@ -84,6 +125,10 @@ The OCCI gem includes all OCCI Core classes necessary to handly arbitrary OCCI o
|
|
84
125
|
Changelog
|
85
126
|
---------
|
86
127
|
|
128
|
+
### Version 2.2
|
129
|
+
|
130
|
+
OCCI Client added. The client simplifies the execution of OCCI commands and provides shortcuts for often used steps.
|
131
|
+
|
87
132
|
### Version 2.1
|
88
133
|
|
89
134
|
Several improvements to the gem structure and code documentation. First rSpec test were added. Readme has been extended to include instructions how the gem can be used.
|
data/lib/occi/client.rb
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'httparty'
|
3
|
+
|
4
|
+
module OCCI
|
5
|
+
class Client
|
6
|
+
include HTTParty
|
7
|
+
format :json
|
8
|
+
headers 'Accept' => 'application/occi+json'
|
9
|
+
|
10
|
+
attr_reader :endpoint
|
11
|
+
|
12
|
+
attr_reader :compute
|
13
|
+
attr_reader :storage
|
14
|
+
attr_reader :network
|
15
|
+
|
16
|
+
def initialize(endpoint)
|
17
|
+
@endpoint = endpoint
|
18
|
+
collection = OCCI::Collection.new(get_model)
|
19
|
+
OCCI::Model.register_collection(collection)
|
20
|
+
@compute = OCCI::Model.get_by_id('http://schemas.ogf.org/occi/infrastructure#compute')
|
21
|
+
@storage = OCCI::Model.get_by_id('http://schemas.ogf.org/occi/infrastructure#storage')
|
22
|
+
@network = OCCI::Model.get_by_id('http://schemas.ogf.org/occi/infrastructure#network')
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_model
|
26
|
+
self.class.get(endpoint + '/-/')
|
27
|
+
end
|
28
|
+
|
29
|
+
def post_mixin
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
def post_resources_to_mixin
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
def delete_resources_from_mixin
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
def delete_mixin
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
def get_resources
|
46
|
+
OCCI::Collection.new(self.class.get(endpoint)).resources
|
47
|
+
end
|
48
|
+
|
49
|
+
def get_resources_list
|
50
|
+
self.class.get(@endpoint, :headers => { 'Accept' => 'text/uri-list' }).split("\n").compact
|
51
|
+
end
|
52
|
+
|
53
|
+
def post_resource(attributes, kind, mixins, resources_to_link)
|
54
|
+
resource = OCCI::Core::Resource.new
|
55
|
+
resource.kind = kind.type_identifier
|
56
|
+
mixins = mixins.collect { |mixin| mixin.type_identifiers } unless mixins.first.kind_of? String
|
57
|
+
resource.mixins = mixins
|
58
|
+
attributes = OCCI::Core::Attributes.split(attributes) unless attributes.kind_of? OCCI::Core::Attributes
|
59
|
+
resource.attributes = attributes
|
60
|
+
resource.links = []
|
61
|
+
resources_to_link.each do |res|
|
62
|
+
link = OCCI::Link.new
|
63
|
+
link.kind = 'http://schemas.ogf.org/occi/infrastructure#storagelink' if OCCI::Model.get_by_id(res.kind).related_to? 'http://schemas.ogf.org/occi/infrastructure#storage'
|
64
|
+
link.kind = 'http://schemas.ogf.org/occi/infrastructure#networkinterface' if OCCI::Model.get_by_id(res.kind).related_to? 'http://schemas.ogf.org/occi/infrastructure#network'
|
65
|
+
link.titlte "Link to #{res.title}"
|
66
|
+
link.target = res.location
|
67
|
+
resource.links << link
|
68
|
+
end
|
69
|
+
resource.check
|
70
|
+
collection = OCCI::Collection.new(:resources => [resource])
|
71
|
+
self.class.post(@endpoint + kind.location, { :body => collection.to_json, :headers => { 'Content-Type' => 'application/occi+json', 'Accept' => 'text/uri-list' }, :format => 'text/plain' }).to_s
|
72
|
+
end
|
73
|
+
|
74
|
+
def delete_resources
|
75
|
+
self.class.delete(@endpoint)
|
76
|
+
end
|
77
|
+
|
78
|
+
def trigger_action(url)
|
79
|
+
self.class.post(url)
|
80
|
+
end
|
81
|
+
|
82
|
+
def trigger_action_on_resources(resources, action)
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
def get_compute_list
|
87
|
+
self.class.get(@endpoint + @compute.location, {:headers => { 'Accept' => 'text/uri-list' }, :format => 'text/plain'}).split("\n").compact
|
88
|
+
end
|
89
|
+
|
90
|
+
def get_compute_resources
|
91
|
+
self.class.get(endpoint + @compute.location)
|
92
|
+
end
|
93
|
+
|
94
|
+
def post_compute_resource(attributes=OCCI::Core::Attributes.new, os = nil, size = nil, mixins=[], resources_to_link=[])
|
95
|
+
mixins << os if os
|
96
|
+
mixins << size if size
|
97
|
+
post_resource(attributes, @compute, mixins, resources_to_link)
|
98
|
+
end
|
99
|
+
|
100
|
+
def delete_compute_resource(id)
|
101
|
+
self.class.delete(@endpoint + @compute.location + id)
|
102
|
+
end
|
103
|
+
|
104
|
+
def delete_compute_resources
|
105
|
+
self.class.delete(@endpoint + @compute.location)
|
106
|
+
end
|
107
|
+
|
108
|
+
def get_storage_resources
|
109
|
+
self.class.get(@endpoint + @storage.location)
|
110
|
+
end
|
111
|
+
|
112
|
+
def post_storage_resource(attributes=OCCI::Core::Attributes.new, mixins=[], resources_to_link=[])
|
113
|
+
post_resource(attributes, @storage, mixins, resources_to_link)
|
114
|
+
end
|
115
|
+
|
116
|
+
def delete_storage_resource(id)
|
117
|
+
self.class.delete(@endpoint + @storage.location + id)
|
118
|
+
end
|
119
|
+
|
120
|
+
def delete_storage_resources
|
121
|
+
self.class.delete @endpoint + (@storage.location)
|
122
|
+
end
|
123
|
+
|
124
|
+
def get_network_resources
|
125
|
+
self.class.get(@endpoint + @network)
|
126
|
+
end
|
127
|
+
|
128
|
+
def post_network_resource(attributes=OCCI::Core::Attributes.new, mixins=[], resources_to_link=[])
|
129
|
+
post_resource(attributes, @network, mixins, resources_to_link)
|
130
|
+
end
|
131
|
+
|
132
|
+
def delete_network_resource(id)
|
133
|
+
self.class.delete(@endpoint + @network.location + id)
|
134
|
+
end
|
135
|
+
|
136
|
+
def delete_network_resources
|
137
|
+
self.class.delete(@endpoint + @network.location)
|
138
|
+
end
|
139
|
+
|
140
|
+
def get_os_templates
|
141
|
+
OCCI::Collection.new(self.class.get(@endpoint + '/-/', :headers => { 'Accept' => 'application/occi+json', 'Content-Type' => 'text/occi', 'Category' => 'os_tpl;scheme="http://schemas.ogf.org/occi/infrastructure#";class="mixin"' })).mixins.select { |mixin| mixin.term != 'os_tpl' }
|
142
|
+
end
|
143
|
+
|
144
|
+
def get_resource_templates
|
145
|
+
OCCI::Collection.new(self.class.get(@endpoint + '/-/', :headers => { 'Accept' => 'application/occi+json', 'Content-Type' => 'text/occi', 'Category' => 'resource_tpl;scheme="http://schemas.ogf.org/occi/infrastructure#";class="mixin"' })).mixins.select { |mixin| mixin.term != 'resource_tpl' }
|
146
|
+
end
|
147
|
+
|
148
|
+
def get_attributes(categories)
|
149
|
+
attributes = Hashie::Mash.new
|
150
|
+
[categories].flatten.each do |category|
|
151
|
+
category = OCCI::Model.get_by_id(category) if category.kind_of? String
|
152
|
+
attributes.merge! category.attributes.combine_with_defaults
|
153
|
+
end
|
154
|
+
attributes
|
155
|
+
end
|
156
|
+
|
157
|
+
def get_attribute_definitions(categories)
|
158
|
+
definitions = OCCI::Core::AttributeProperties.new
|
159
|
+
[categories].flatten.each do |category|
|
160
|
+
category = OCCI::Model.get_by_id(category) if category.kind_of? String
|
161
|
+
definitions.merge! category.attributes
|
162
|
+
end
|
163
|
+
definitions
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
167
|
+
end
|
data/lib/occi/collection.rb
CHANGED
@@ -34,5 +34,14 @@ module OCCI
|
|
34
34
|
def entities
|
35
35
|
@resources + @links
|
36
36
|
end
|
37
|
+
|
38
|
+
def empty?
|
39
|
+
@kinds.empty? && @mixins.empty? && @actions.empty? && @resources.empty? && @links.empty?
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_json(options = { })
|
43
|
+
{ :kinds => @kinds, :mixins => @mixins, :actions => @actions, :resources => @resources, :links => @links }.to_json
|
44
|
+
end
|
45
|
+
|
37
46
|
end
|
38
47
|
end
|
@@ -6,10 +6,10 @@ module OCCI
|
|
6
6
|
|
7
7
|
def initialize(attributes = nil, default = nil)
|
8
8
|
if attributes[:type] || attributes.required || attributes.mutable || attributes.pattern || attributes.minimum || attributes.maximum || attributes.description
|
9
|
-
attributes[:type]
|
9
|
+
attributes[:type] ||= "string"
|
10
10
|
attributes.required ||= false
|
11
|
-
attributes.mutable
|
12
|
-
attributes.pattern
|
11
|
+
attributes.mutable ||= false
|
12
|
+
attributes.pattern ||= ".*"
|
13
13
|
end unless attributes.nil?
|
14
14
|
super(attributes, default)
|
15
15
|
end
|
@@ -18,7 +18,7 @@ module OCCI
|
|
18
18
|
array = []
|
19
19
|
self.each_key do |key|
|
20
20
|
if self[key].include? 'type'
|
21
|
-
array << key
|
21
|
+
array << key
|
22
22
|
else
|
23
23
|
self[key].combine.each { |attr| array << key + '.' + attr }
|
24
24
|
end
|
@@ -26,6 +26,18 @@ module OCCI
|
|
26
26
|
return array
|
27
27
|
end
|
28
28
|
|
29
|
+
def combine_with_defaults
|
30
|
+
hash = {}
|
31
|
+
self.each_key do |key|
|
32
|
+
if self[key].include? 'type'
|
33
|
+
hash[key] = self[key]['default']
|
34
|
+
else
|
35
|
+
self[key].combine_with_defaults.each { |k,v| hash[key + '.' + k] = v }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
return hash
|
39
|
+
end
|
40
|
+
|
29
41
|
end
|
30
42
|
end
|
31
43
|
end
|
data/lib/occi/core/attributes.rb
CHANGED
@@ -5,7 +5,7 @@ module OCCI
|
|
5
5
|
class Attributes < Hashie::Mash
|
6
6
|
|
7
7
|
def combine
|
8
|
-
hash = {}
|
8
|
+
hash = { }
|
9
9
|
self.each_key do |key|
|
10
10
|
if self[key].kind_of? Hashie::Mash
|
11
11
|
self[key].combine.each_pair { |k, v| hash[key + '.' + k] = v }
|
@@ -16,6 +16,20 @@ module OCCI
|
|
16
16
|
return hash
|
17
17
|
end
|
18
18
|
|
19
|
+
def self.split(attributes)
|
20
|
+
attribute = Attributes.new
|
21
|
+
attributes.each do |name,value|
|
22
|
+
puts name
|
23
|
+
key, dot, rest = name.partition('.')
|
24
|
+
if rest.empty?
|
25
|
+
attribute[key] = value
|
26
|
+
else
|
27
|
+
attribute.merge! Attributes.new(key => self.split(rest => value))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
return attribute
|
31
|
+
end
|
32
|
+
|
19
33
|
end
|
20
34
|
end
|
21
35
|
end
|
data/lib/occi/parser.rb
CHANGED
@@ -44,15 +44,16 @@ module OCCI
|
|
44
44
|
OCCI::Log.debug('### Parsing request data to OCCI data structure ###')
|
45
45
|
collection = OCCI::Collection.new
|
46
46
|
|
47
|
+
locations = self.header_locations(header)
|
48
|
+
category ? collection = self.header_categories(header) : collection = self.header_entity(header) if locations.empty?
|
49
|
+
|
47
50
|
case media_type
|
48
51
|
when 'text/occi'
|
49
|
-
locations = self.header_locations(header)
|
50
|
-
category ? collection = self.header_categories(header) : collection = self.header_entity(header) if locations.empty?
|
51
52
|
when 'text/uri-list'
|
52
53
|
body.each_line { |line| locations << URI.parse(line) }
|
53
54
|
when 'text/plain', nil
|
54
|
-
locations
|
55
|
-
category ? collection = self.text_categories(body) : collection = self.text_entity(body) if locations.empty?
|
55
|
+
locations << self.text_locations(body)
|
56
|
+
category ? collection = self.text_categories(body) : collection = self.text_entity(body) if locations.empty? && collection.empty?
|
56
57
|
when 'application/occi+json', 'application/json'
|
57
58
|
collection = self.json(body)
|
58
59
|
when 'application/occi+xml', 'application/xml'
|
data/lib/occi/version.rb
CHANGED
data/lib/occi.rb
CHANGED
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.
|
4
|
+
version: 2.2.0
|
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-06-
|
13
|
+
date: 2012-06-14 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: json
|
@@ -138,6 +138,7 @@ files:
|
|
138
138
|
- etc/model/infrastructure/storage.json
|
139
139
|
- etc/model/infrastructure/storagelink.json
|
140
140
|
- lib/occi.rb
|
141
|
+
- lib/occi/client.rb
|
141
142
|
- lib/occi/collection.rb
|
142
143
|
- lib/occi/core/action.rb
|
143
144
|
- lib/occi/core/attribute_properties.rb
|