occi 2.5.19 → 3.0.0.beta.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/.travis.yml +3 -1
- data/AUTHORS +4 -3
- data/Gemfile +9 -0
- data/Gemfile.lock +64 -21
- data/README.md +19 -14
- data/Rakefile +12 -8
- data/Test Results - discovery_interface.html +862 -0
- data/bin/occi +333 -83
- data/examples/dsl_example.rb +6 -6
- data/examples/x509auth_example.rb +6 -6
- data/features/common/step_definitions/common_steps.rb +32 -0
- data/features/occi/core/create/create.feature +17 -0
- data/features/occi/core/create/step_definitions/create_steps.rb +0 -0
- data/features/occi/core/delete/delete.feature +14 -0
- data/features/occi/core/delete/step_definitions/delete_steps.rb +0 -0
- data/features/occi/core/discovery_interface/discovery_interface.feature +35 -0
- data/features/occi/core/discovery_interface/step_definitions/discovery_interface_steps.rb +19 -0
- data/features/occi/core/miscellaneous/miscellaneous.feature +14 -0
- data/features/occi/core/miscellaneous/step_definitions/miscellaneous_steps.rb +0 -0
- data/features/occi/core/read/read.feature +14 -0
- data/features/occi/core/read/step_definitions/read_steps.rb +0 -0
- data/features/occi/core/update/step_definitions/update_steps.rb +0 -0
- data/features/occi/core/update/update.feature +14 -0
- data/features/occi/infrastructure/create/create.feature +14 -0
- data/features/occi/infrastructure/create/step_definitions/create_steps.rb +0 -0
- data/features/support/env.rb +4 -0
- data/lib/occi.rb +29 -3
- data/lib/occi/api/client/client_amqp.rb +756 -0
- data/lib/occi/api/client/client_http.rb +922 -0
- data/lib/occi/api/client/http/httparty_fix.rb +53 -0
- data/lib/occi/api/client/http/net_http_fix.rb +46 -0
- data/lib/occi/api/dsl.rb +77 -73
- data/lib/occi/bin/helpers.rb +91 -0
- data/lib/occi/bin/occi_opts.rb +251 -0
- data/lib/occi/bin/resource_output_factory.rb +90 -0
- data/lib/occi/bin/templates/compute.erb +15 -0
- data/lib/occi/bin/templates/network.erb +11 -0
- data/lib/occi/bin/templates/os_tpl.erb +9 -0
- data/lib/occi/bin/templates/resource_tpl.erb +9 -0
- data/lib/occi/bin/templates/storage.erb +10 -0
- data/lib/occi/collection.rb +122 -25
- data/lib/occi/core.rb +18 -9
- data/lib/occi/core/action.rb +20 -4
- data/lib/occi/core/action_instance.rb +24 -0
- data/lib/occi/core/actions.rb +22 -0
- data/lib/occi/core/attribute_properties.rb +33 -84
- data/lib/occi/core/attributes.rb +32 -14
- data/lib/occi/core/categories.rb +46 -0
- data/lib/occi/core/category.rb +94 -20
- data/lib/occi/core/entities.rb +50 -0
- data/lib/occi/core/entity.rb +130 -89
- data/lib/occi/core/kind.rb +28 -35
- data/lib/occi/core/kinds.rb +22 -0
- data/lib/occi/core/link.rb +43 -40
- data/lib/occi/core/links.rb +34 -0
- data/lib/occi/core/mixin.rb +28 -23
- data/lib/occi/core/mixins.rb +22 -0
- data/lib/occi/core/related.rb +20 -0
- data/lib/occi/core/resource.rb +40 -40
- data/lib/occi/core/resources.rb +14 -0
- data/lib/occi/infrastructure.rb +27 -0
- data/lib/occi/infrastructure/compute.rb +159 -0
- data/lib/occi/infrastructure/network.rb +131 -0
- data/lib/occi/infrastructure/network/ipnetwork.rb +34 -0
- data/lib/occi/infrastructure/networkinterface.rb +124 -0
- data/lib/occi/infrastructure/networkinterface/ipnetworkinterface.rb +34 -0
- data/lib/occi/infrastructure/os_tpl.rb +19 -0
- data/lib/occi/infrastructure/resource_tpl.rb +19 -0
- data/lib/occi/infrastructure/storage.rb +96 -0
- data/lib/occi/infrastructure/storagelink.rb +73 -0
- data/lib/occi/log.rb +6 -2
- data/lib/occi/model.rb +38 -70
- data/lib/occi/parser.rb +108 -88
- data/lib/occi/version.rb +2 -2
- data/lib/occiantlr/OCCIANTLR.g +6 -5
- data/lib/occiantlr/OCCIANTLRLexer.rb +52 -52
- data/lib/occiantlr/OCCIANTLRParser.rb +678 -569
- data/lib/occiantlr/README.md +1 -1
- data/occi.gemspec +2 -1
- data/spec/cassettes/client_http_text_plain.yml +1066 -0
- data/spec/occi/api/client/client_amqp_spec.rb +148 -0
- data/spec/occi/api/client/client_http_0.5_spec.rb +292 -0
- data/spec/occi/api/client/client_http_spec.rb +259 -0
- data/spec/occi/api/dsl_spec.rb +0 -0
- data/spec/occi/collection_spec.rb +23 -10
- data/spec/occi/core/categories_spec.rb +30 -0
- data/spec/occi/core/category_spec.rb +41 -0
- data/spec/occi/core/entity_spec.rb +52 -0
- data/spec/occi/core/resource_spec.rb +21 -0
- data/spec/occi/infrastructure/compute_spec.rb +32 -0
- data/spec/occi/log_spec.rb +10 -10
- data/spec/occi/model_spec.rb +24 -24
- data/spec/occi/parser_spec.rb +89 -39
- data/spec/occi/test.json +22 -58
- data/spec/occiantlr/parser_spec.rb +5 -7
- data/spec/spec_helper.rb +13 -3
- metadata +116 -19
- data/etc/model/infrastructure/compute.json +0 -108
- data/etc/model/infrastructure/ipnetwork.json +0 -40
- data/etc/model/infrastructure/ipnetworkinterface.json +0 -40
- data/etc/model/infrastructure/network.json +0 -55
- data/etc/model/infrastructure/networkinterface.json +0 -38
- data/etc/model/infrastructure/os_template.json +0 -9
- data/etc/model/infrastructure/resource_template.json +0 -9
- data/etc/model/infrastructure/storage.json +0 -72
- data/etc/model/infrastructure/storagelink.json +0 -38
- data/lib/occi/api/client.rb +0 -596
- data/lib/occi/client/occiopts.rb +0 -146
- data/spec/occi/client_spec.rb +0 -12
@@ -0,0 +1,73 @@
|
|
1
|
+
module Occi
|
2
|
+
module Infrastructure
|
3
|
+
class Storagelink < Occi::Core::Link
|
4
|
+
|
5
|
+
class Online < Occi::Core::Action
|
6
|
+
def initialize(scheme='http://schemas.ogf.org/occi/infrastructure/storagelink/action#',
|
7
|
+
term='online',
|
8
|
+
title='activate storagelink')
|
9
|
+
super
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Offline < Occi::Core::Action
|
14
|
+
def initialize(scheme='http://schemas.ogf.org/occi/infrastructure/storagelink/action#',
|
15
|
+
term='offline',
|
16
|
+
title='deactivate storagelink')
|
17
|
+
super
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.actions
|
22
|
+
Occi::Core::Actions.new << Online.new << Offline.new
|
23
|
+
end
|
24
|
+
|
25
|
+
begin
|
26
|
+
@kind = Occi::Core::Kind.new('http://schemas.ogf.org/occi/infrastructure#', 'storagelink')
|
27
|
+
|
28
|
+
@kind.title = "storage link"
|
29
|
+
|
30
|
+
@kind.related << Occi::Core::Link.kind
|
31
|
+
|
32
|
+
@kind.attributes.occi!.storagelink!.deviceid = Occi::Core::AttributeProperties.new(
|
33
|
+
{ :mutable => true })
|
34
|
+
|
35
|
+
@kind.attributes.occi!.storagelink!.mountpoint = Occi::Core::AttributeProperties.new(
|
36
|
+
{ :mutable => true })
|
37
|
+
|
38
|
+
@kind.attributes.occi!.storagelink!.state = Occi::Core::AttributeProperties.new(
|
39
|
+
{ :pattern => 'active|inactive|error',
|
40
|
+
:default => 'inactive' })
|
41
|
+
|
42
|
+
@kind.location = '/storagelink/'
|
43
|
+
|
44
|
+
@kind.actions = self.actions
|
45
|
+
end
|
46
|
+
|
47
|
+
def deviceid
|
48
|
+
@attributes.occi.storagelink.deviceid if @attributes.occi.storagelink if @attributes.occi
|
49
|
+
end
|
50
|
+
|
51
|
+
def deviceid=(deviceid)
|
52
|
+
@attributes.occi!.storagelink!.deviceid = deviceid
|
53
|
+
end
|
54
|
+
|
55
|
+
def mountpoint
|
56
|
+
@attributes.occi.storagelink.mountpoint if @attributes.occi.storagelink if @attributes.occi
|
57
|
+
end
|
58
|
+
|
59
|
+
def mountpoint=(mountpoint)
|
60
|
+
@attributes.occi!.storagelink!.mountpoint = mountpoint
|
61
|
+
end
|
62
|
+
|
63
|
+
def state
|
64
|
+
@attributes.occi.storagelink.state if @attributes.occi.storagelink if @attributes.occi
|
65
|
+
end
|
66
|
+
|
67
|
+
def state=(state)
|
68
|
+
@attributes.occi!.storagelink!.state = state
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/occi/log.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'logger'
|
2
2
|
|
3
|
-
module
|
3
|
+
module Occi
|
4
4
|
class Log
|
5
5
|
|
6
6
|
include ::Logger::Severity
|
@@ -19,10 +19,14 @@ module OCCI
|
|
19
19
|
|
20
20
|
# subscribe to log messages and send to logger
|
21
21
|
@log_subscriber = ActiveSupport::Notifications.subscribe("log") do |name, start, finish, id, payload|
|
22
|
-
@logger.log(payload[:level], payload[:message])
|
22
|
+
@logger.log(payload[:level], payload[:message]) if @logger
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
+
def close
|
27
|
+
ActiveSupport::Notifications.unsubscribe(@log_subscriber)
|
28
|
+
end
|
29
|
+
|
26
30
|
# @param [Logger::Severity] severity
|
27
31
|
def level=(severity)
|
28
32
|
@logger.level = severity
|
data/lib/occi/model.rb
CHANGED
@@ -1,31 +1,29 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Occi
|
2
|
+
class Model < Occi::Collection
|
3
3
|
|
4
|
-
|
5
|
-
class Model
|
6
|
-
attr_accessor :categories
|
7
|
-
attr_accessor :locations
|
8
|
-
|
9
|
-
# @param [OCCI::Core::Collection] collection
|
4
|
+
# @param [Occi::Core::Collection] collection
|
10
5
|
def initialize(collection=nil)
|
11
|
-
|
12
|
-
@locations = { }
|
6
|
+
super(nil, nil) # model must be empty for model class
|
13
7
|
register_core
|
14
|
-
register_collection collection if collection.kind_of?
|
8
|
+
register_collection collection if collection.kind_of? Occi::Collection
|
9
|
+
end
|
10
|
+
|
11
|
+
def model=(model)
|
12
|
+
# will not assign a model inside a model
|
15
13
|
end
|
16
14
|
|
17
|
-
# register
|
15
|
+
# register Occi Core categories enitity, resource and link
|
18
16
|
def register_core
|
19
|
-
|
20
|
-
register
|
21
|
-
register
|
22
|
-
register
|
17
|
+
Occi::Log.info "### Registering OCCI Core categories enitity, resource and link ###"
|
18
|
+
register Occi::Core::Entity.kind
|
19
|
+
register Occi::Core::Resource.kind
|
20
|
+
register Occi::Core::Link.kind
|
23
21
|
end
|
24
22
|
|
25
|
-
# register
|
23
|
+
# register Occi Infrastructure categories
|
26
24
|
def register_infrastructure
|
27
|
-
|
28
|
-
|
25
|
+
Occi::Log.info "### Registering OCCI Infrastructure categories ###"
|
26
|
+
Occi::Infrastructure.categories.each { |category| register category }
|
29
27
|
end
|
30
28
|
|
31
29
|
# register OCCI categories from files
|
@@ -34,9 +32,9 @@ module OCCI
|
|
34
32
|
# recursively searched for files with the extension .json .
|
35
33
|
# @param [Sting] scheme_base_url base location for provider specific extensions of the OCCI model
|
36
34
|
def register_files(path, scheme_base_url='http://localhost')
|
37
|
-
|
35
|
+
Occi::Log.info "### Initializing OCCI Model from #{path} ###"
|
38
36
|
Dir.glob(path + '/**/*.json').each do |file|
|
39
|
-
collection =
|
37
|
+
collection = Occi::Collection.new(JSON.parse(File.read(file)))
|
40
38
|
# add location of service provider to scheme if it has a relative location
|
41
39
|
collection.kinds.collect { |kind| kind.scheme = scheme_base_url + kind.scheme if kind.scheme.start_with? '/' } if collection.kinds
|
42
40
|
collection.mixins.collect { |mixin| mixin.scheme = scheme_base_url + mixin.scheme if mixin.scheme.start_with? '/' } if collection.mixins
|
@@ -47,71 +45,41 @@ module OCCI
|
|
47
45
|
|
48
46
|
# register OCCI categories from OCCI collection
|
49
47
|
def register_collection(collection)
|
50
|
-
collection.
|
48
|
+
collection.kinds.each { |kind| kind.model = self }
|
49
|
+
collection.mixins.each { |mixin| mixin.model = self }
|
50
|
+
collection.actions.each { |action| action.model = self }
|
51
|
+
merge! collection
|
51
52
|
end
|
52
53
|
|
53
54
|
# clear all entities from all categories
|
54
55
|
def reset()
|
55
|
-
|
56
|
+
categories.each { |category| category.entities = [] if category.respond_to? :entities }
|
56
57
|
end
|
57
58
|
|
58
|
-
# @param [
|
59
|
+
# @param [Occi::Core::Category] category
|
59
60
|
def register(category)
|
60
|
-
|
61
|
-
@categories[category.type_identifier] = category
|
62
|
-
@locations[category.location] = category.type_identifier unless category.kind_of? OCCI::Core::Action
|
61
|
+
Occi::Log.debug "### Registering category #{category}"
|
63
62
|
# add model to category as back reference
|
64
63
|
category.model = self
|
64
|
+
@kinds << category unless get_by_id(category.to_s) if category.class.ancestors.include? Occi::Core::Kind
|
65
|
+
@mixins << category unless get_by_id(category.to_s) if category.class.ancestors.include? Occi::Core::Mixin
|
66
|
+
@actions << category unless get_by_id(category.to_s) if category.class.ancestors.include? Occi::Core::Action
|
65
67
|
end
|
66
68
|
|
67
|
-
# @param [
|
69
|
+
# @param [Occi::Core::Category] category
|
68
70
|
def unregister(category)
|
69
|
-
|
70
|
-
@
|
71
|
-
@
|
72
|
-
|
73
|
-
|
74
|
-
# Returns the category corresponding to a given type identifier
|
75
|
-
#
|
76
|
-
# @param [URI] id type identifier of a category
|
77
|
-
# @return [OCCI::Core::Category]
|
78
|
-
def get_by_id(id)
|
79
|
-
@categories.fetch(id) { OCCI::Log.debug("Category with id #{id} not found"); nil }
|
80
|
-
end
|
81
|
-
|
82
|
-
# Returns the category corresponding to a given location
|
83
|
-
#
|
84
|
-
# @param [URI] location
|
85
|
-
# @return [OCCI::Core::Category]
|
86
|
-
def get_by_location(location)
|
87
|
-
id = @locations.fetch(location) { OCCI::Log.debug("Category with location #{location} not found"); nil }
|
88
|
-
get_by_id id
|
71
|
+
Occi::Log.debug "### Unregistering category #{category.type_identifier}"
|
72
|
+
@kinds.delete category
|
73
|
+
@mixins.delete category
|
74
|
+
@actions.delete category
|
89
75
|
end
|
90
76
|
|
91
77
|
# Return all categories from model. If filter is present, return only the categories specified by filter
|
92
78
|
#
|
93
|
-
# @param [
|
94
|
-
# @return [
|
95
|
-
def get(filter =
|
96
|
-
|
97
|
-
if filter.empty?
|
98
|
-
@categories.each_value do |category|
|
99
|
-
collection.kinds << category if category.kind_of? OCCI::Core::Kind
|
100
|
-
collection.mixins << category if category.kind_of? OCCI::Core::Mixin
|
101
|
-
collection.actions << category if category.kind_of? OCCI::Core::Action
|
102
|
-
end
|
103
|
-
else
|
104
|
-
categories = filter.categories
|
105
|
-
OCCI::Log.debug("### Filtering categories #{categories.collect { |c| c.type_identifier }.inspect}")
|
106
|
-
while categories.any? do
|
107
|
-
category = categories.pop
|
108
|
-
categories.concat @categories.each_value.select { |cat| cat.related_to?(category.type_identifier) }
|
109
|
-
collection.kinds << get_by_id(category.type_identifier) if category.kind_of? OCCI::Core::Kind
|
110
|
-
collection.mixins << get_by_id(category.type_identifier) if category.kind_of? OCCI::Core::Mixin
|
111
|
-
collection.actions << get_by_id(category.type_identifier) if category.kind_of? OCCI::Core::Action
|
112
|
-
end
|
113
|
-
end
|
114
|
-
collection
|
79
|
+
# @param [Occi::Collection] filter
|
80
|
+
# @return [Occi::Collection] collection
|
81
|
+
def get(filter = nil)
|
82
|
+
filter ? intersect(filter) : self
|
115
83
|
end
|
116
84
|
|
117
85
|
end
|
data/lib/occi/parser.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module Occi
|
2
2
|
class Parser
|
3
3
|
|
4
4
|
# Declaring Class constants for OVF XML namespaces (defined in OVF specification ver.1.1)
|
@@ -12,24 +12,25 @@ module OCCI
|
|
12
12
|
# @param [String] media_type the media type of the OCCI message
|
13
13
|
# @param [String] body the body of the OCCI message
|
14
14
|
# @param [true, false] category for text/plain and text/occi media types information e.g. from the HTTP request location is needed to determine if the OCCI message includes a category or an entity
|
15
|
-
# @param [
|
15
|
+
# @param [Occi::Core::Resource,Occi::Core::Link] entity_type entity type to use for parsing of text plain entities
|
16
16
|
# @param [Hash] header optional header of the OCCI message
|
17
|
-
# @return [
|
18
|
-
def self.parse(media_type, body, category=false, entity_type=
|
19
|
-
|
20
|
-
collection =
|
17
|
+
# @return [Occi::Collection] list consisting of an array of locations and the OCCI object collection
|
18
|
+
def self.parse(media_type, body, category=false, entity_type=Occi::Core::Resource, header={ })
|
19
|
+
Occi::Log.debug '### Parsing request data to OCCI Collection ###'
|
20
|
+
collection = Occi::Collection.new
|
21
21
|
|
22
|
-
|
23
|
-
|
22
|
+
# remove trailing HTTP_ prefix if present
|
23
|
+
header = Hash[header.map {|k, v| [k.gsub('HTTP_','').upcase, v] }]
|
24
|
+
|
25
|
+
category ? collection = self.header_categories(header) : collection = self.header_entity(header, entity_type)
|
24
26
|
|
25
27
|
case media_type
|
26
28
|
when 'text/uri-list'
|
27
|
-
|
29
|
+
nil
|
28
30
|
when 'text/occi'
|
29
31
|
nil
|
30
32
|
when 'text/plain', nil
|
31
|
-
|
32
|
-
category ? collection = self.text_categories(body) : collection = self.text_entity(body, entity_type) if locations.empty? && collection.empty?
|
33
|
+
category ? collection = self.text_categories(body) : collection = self.text_entity(body, entity_type) if collection.empty?
|
33
34
|
when 'application/occi+json', 'application/json'
|
34
35
|
collection = self.json(body)
|
35
36
|
when 'application/occi+xml', 'application/xml'
|
@@ -41,7 +42,20 @@ module OCCI
|
|
41
42
|
else
|
42
43
|
raise "Content Type not supported"
|
43
44
|
end
|
44
|
-
|
45
|
+
collection
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.locations(media_type, body, header)
|
49
|
+
locations = self.header_locations(header)
|
50
|
+
case media_type
|
51
|
+
when 'text/uri-list'
|
52
|
+
body.each_line { |line| locations << URI.parse(line.chomp) }
|
53
|
+
when 'text/plain', nil
|
54
|
+
locations.concat self.text_locations(body)
|
55
|
+
else
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
locations
|
45
59
|
end
|
46
60
|
|
47
61
|
private
|
@@ -49,33 +63,33 @@ module OCCI
|
|
49
63
|
# @param [Hash] header
|
50
64
|
# @return [Array] list of URIs
|
51
65
|
def self.header_locations(header)
|
52
|
-
x_occi_location_strings = header['
|
66
|
+
x_occi_location_strings = header['X_OCCI_LOCATION'].to_s.split(',')
|
53
67
|
x_occi_location_strings.collect { |loc| OCCIANTLR::Parser.new('X-OCCI-Location: ' + loc).x_occi_location }
|
54
68
|
end
|
55
69
|
|
56
70
|
# @param [Hash] header
|
57
|
-
# @return [
|
71
|
+
# @return [Occi::Collection]
|
58
72
|
def self.header_categories(header)
|
59
|
-
collection =
|
60
|
-
category_strings = header['
|
73
|
+
collection = Occi::Collection.new
|
74
|
+
category_strings = header['CATEGORY'].to_s.split(',')
|
61
75
|
category_strings.each do |cat|
|
62
76
|
category = OCCIANTLR::Parser.new('Category: ' + cat).category
|
63
|
-
collection.kinds.
|
64
|
-
collection.mixins.
|
65
|
-
collection.actions.
|
77
|
+
collection.kinds.merge category.kinds.collect { |kind| Occi::Core::Kind.new(kind.scheme, kind.term, kind.title, kind.attributes, kind.related, kind.actions) }
|
78
|
+
collection.mixins.merge category.mixins.collect { |mixin| Occi::Core::Mixin.new(mixin.scheme, mixin.term, mixin.title, mixin.attributes, mixin.related, mixin.actions) }
|
79
|
+
collection.actions.merge category.actions.collect { |action| Occi::Core::Action.new(action.scheme, action.term, action.title, action.attributes) }
|
66
80
|
end
|
67
81
|
collection
|
68
82
|
end
|
69
83
|
|
70
84
|
# @param [Hash] header
|
71
85
|
# @param [Class] entity_type
|
72
|
-
# @return [
|
86
|
+
# @return [Occi::Collection]
|
73
87
|
def self.header_entity(header, entity_type)
|
74
|
-
collection =
|
88
|
+
collection = Occi::Collection.new
|
75
89
|
entity = Hashie::Mash.new
|
76
|
-
category_strings = header['
|
90
|
+
category_strings = header['CATEGORY'].to_s.split(',')
|
77
91
|
return collection if category_strings.empty?
|
78
|
-
attribute_strings = header['
|
92
|
+
attribute_strings = header['X_OCCI_ATTRIBUTE'].to_s.split(',')
|
79
93
|
categories = Hashie::Mash.new({ :kinds => [], :mixins => [], :actions => [] })
|
80
94
|
category_strings.each do |category|
|
81
95
|
cat = OCCIANTLR::Parser.new('Category: ' + category).category
|
@@ -88,16 +102,16 @@ module OCCI
|
|
88
102
|
entity.kind = categories.kinds.first.scheme + categories.kinds.first.term
|
89
103
|
entity.mixins = categories.mixins.collect { |mixin| mixin.scheme + mixin.term } if categories.mixins.any?
|
90
104
|
attribute_strings.each { |attr| entity.attributes!.merge!(OCCIANTLR::Parser.new('X-OCCI-Attribute: ' + attr).x_occi_attribute) }
|
91
|
-
if entity_type ==
|
105
|
+
if entity_type == Occi::Core::Link
|
92
106
|
entity.target = link.attributes!.occi!.core!.target
|
93
107
|
entity.source = link.attributes!.occi!.core!.source
|
94
108
|
cats = entity.categories.split(' ')
|
95
109
|
kind = cats.reverse!.pop
|
96
110
|
mixins = cats.categories
|
97
|
-
collection.links <<
|
98
|
-
elsif entity_type ==
|
111
|
+
collection.links << Occi::Core::Link.new(kind, mixins, entity.attributes)
|
112
|
+
elsif entity_type == Occi::Core::Resource
|
99
113
|
entity.links = []
|
100
|
-
link_strings = header['
|
114
|
+
link_strings = header['LINK'].to_s.split(',')
|
101
115
|
link_strings.each do |link_string|
|
102
116
|
link = OCCIANTLR::Parser.new('Link: ' + link_string).link
|
103
117
|
if link.rel.include? 'action#'
|
@@ -105,15 +119,14 @@ module OCCI
|
|
105
119
|
else
|
106
120
|
link.attributes!.occi!.core!.target = link.target
|
107
121
|
|
108
|
-
link.
|
109
|
-
|
110
|
-
|
111
|
-
mixins = cats
|
122
|
+
link.categories = (link.categories.presence || %w'http://schemas.ogf.org/occi/core#link')
|
123
|
+
kind = link.categories.reverse!.pop
|
124
|
+
mixins = link.categories
|
112
125
|
|
113
|
-
entity.links <<
|
126
|
+
entity.links << Occi::Core::Link.new(kind, mixins, link.attributes, link.actions, link.rel, link.target, link.source)
|
114
127
|
end
|
115
128
|
end
|
116
|
-
collection.resources <<
|
129
|
+
collection.resources << Occi::Core::Resource.new(entity.kind, entity.mixins, entity.attributes, entity.actions, entity.links)
|
117
130
|
end
|
118
131
|
collection
|
119
132
|
end
|
@@ -125,28 +138,27 @@ module OCCI
|
|
125
138
|
end
|
126
139
|
|
127
140
|
# @param [String] text
|
128
|
-
# @return [
|
141
|
+
# @return [Occi::Collection]
|
129
142
|
def self.text_categories(text)
|
130
|
-
collection =
|
143
|
+
collection = Occi::Collection.new
|
131
144
|
text.each_line do |line|
|
132
145
|
category = OCCIANTLR::Parser.new(line.chomp).category
|
133
146
|
next if category.nil?
|
134
|
-
collection.kinds.
|
135
|
-
collection.mixins.
|
136
|
-
collection.actions.
|
147
|
+
collection.kinds.merge category.kinds.collect { |kind| Occi::Core::Kind.new(kind.scheme, kind.term, kind.title, kind.attributes, kind.related, kind.actions) }
|
148
|
+
collection.mixins.merge category.mixins.collect { |mixin| Occi::Core::Mixin.new(mixin.scheme, mixin.term, mixin.title, mixin.attributes, mixin.related, mixin.actions) }
|
149
|
+
collection.actions.merge category.actions.collect { |action| Occi::Core::Action.new(action.scheme, action.term, action.title, action.attributes) }
|
137
150
|
end
|
138
151
|
collection
|
139
152
|
end
|
140
153
|
|
141
154
|
# @param [String] text
|
142
155
|
# @param [Class] entity_type
|
143
|
-
# @return [
|
156
|
+
# @return [Occi::Collection]
|
144
157
|
def self.text_entity(text, entity_type)
|
145
|
-
collection
|
146
|
-
entity
|
147
|
-
links
|
148
|
-
|
149
|
-
categories = Hashie::Mash.new({ :kinds => [], :mixins => [], :actions => [] })
|
158
|
+
collection = Occi::Collection.new
|
159
|
+
entity = Hashie::Mash.new
|
160
|
+
links = []
|
161
|
+
categories = Hashie::Mash.new({ :kinds => [], :mixins => [], :actions => [] })
|
150
162
|
text.each_line do |line|
|
151
163
|
if line.include? 'Category'
|
152
164
|
cat = (OCCIANTLR::Parser.new(line.chomp).category)
|
@@ -159,49 +171,48 @@ module OCCI
|
|
159
171
|
end
|
160
172
|
entity.kind = categories.kinds.first.scheme + categories.kinds.first.term if categories.kinds.first
|
161
173
|
entity.mixins = categories.mixins.collect { |mixin| mixin.scheme + mixin.term } if categories.mixins
|
162
|
-
if entity_type ==
|
174
|
+
if entity_type == Occi::Core::Link
|
163
175
|
entity.target = links.first.attributes!.occi!.core!.target
|
164
176
|
entity.source = links.first.attributes!.occi!.core!.source
|
165
177
|
cats = entity.categories.split(' ')
|
166
178
|
kind = cats.reverse!.pop
|
167
|
-
mixins = cats
|
168
|
-
|
169
|
-
|
170
|
-
|
179
|
+
mixins = cats
|
180
|
+
collection.links << Occi::Core::Link.new(kind, mixins, entity.attributes)
|
181
|
+
elsif entity_type == Occi::Core::Resource
|
182
|
+
entity.links = []
|
171
183
|
links.each do |link|
|
172
184
|
if link.rel.include? 'action#'
|
173
185
|
entity.actions = [link.rel] + entity.actions.to_a
|
174
186
|
else
|
175
187
|
link.attributes!.occi!.core!.target = link.target
|
176
|
-
link.category ||= 'http://schemas.ogf.org/occi/core#link'
|
177
|
-
cats = link.category.split(' ')
|
178
|
-
kind = cats.reverse!.pop
|
179
|
-
mixins = cats
|
180
188
|
|
181
|
-
link =
|
182
|
-
|
189
|
+
link.categories = (link.categories.presence || %w'http://schemas.ogf.org/occi/core#link')
|
190
|
+
cats = link.categories
|
191
|
+
kind = link.categories.reverse!.pop
|
192
|
+
mixins = link.categories
|
193
|
+
|
194
|
+
link = Occi::Core::Link.new(kind, mixins, link.attributes, link.actions, link.rel, link.target, link.source)
|
183
195
|
entity.links << link
|
184
196
|
end
|
185
197
|
end
|
186
|
-
collection.resources <<
|
198
|
+
collection.resources << Occi::Core::Resource.new(entity.kind, entity.mixins, entity.attributes, entity.actions, entity.links)
|
187
199
|
end unless entity.kind.nil?
|
188
200
|
collection
|
189
201
|
end
|
190
202
|
|
191
203
|
# @param [String] json
|
192
|
-
# @return [
|
204
|
+
# @return [Occi::Collection]
|
193
205
|
def self.json(json)
|
194
|
-
collection =
|
195
|
-
hash
|
196
|
-
collection.kinds.
|
197
|
-
collection.mixins.
|
198
|
-
collection.actions.
|
199
|
-
collection.resources.
|
200
|
-
collection.links.
|
201
|
-
|
202
|
-
if collection.resources.size == 1
|
206
|
+
collection = Occi::Collection.new
|
207
|
+
hash = Hashie::Mash.new(JSON.parse(json))
|
208
|
+
collection.kinds.merge hash.kinds.collect { |kind| Occi::Core::Kind.new(kind.scheme, kind.term, kind.title, kind.attributes, kind.related, kind.actions) } if hash.kinds
|
209
|
+
collection.mixins.merge hash.mixins.collect { |mixin| Occi::Core::Mixin.new(mixin.scheme, mixin.term, mixin.title, mixin.attributes, mixin.related, mixin.actions) } if hash.mixins
|
210
|
+
collection.actions.merge hash.actions.collect { |action| Occi::Core::Action.new(action.scheme, action.term, action.title, action.attributes) } if hash.actions
|
211
|
+
collection.resources.merge hash.resources.collect { |resource| Occi::Core::Resource.new(resource.kind, resource.mixins, resource.attributes, resource.actions, resource.links) } if hash.resources
|
212
|
+
collection.links.merge hash.links.collect { |link| Occi::Core::Link.new(link.kind, link.mixins, link.attributes) } if hash.links
|
213
|
+
|
214
|
+
if collection.resources.size == 1 & collection.links.size > 0
|
203
215
|
if collection.resources.first.links.empty?
|
204
|
-
collection.links.each { |link| link.source = collection.resources.first }
|
205
216
|
collection.resources.first.links = collection.links
|
206
217
|
end
|
207
218
|
end
|
@@ -218,14 +229,15 @@ module OCCI
|
|
218
229
|
end
|
219
230
|
|
220
231
|
# @param [String] xml
|
221
|
-
# @return [
|
232
|
+
# @return [Occi::Collection]
|
222
233
|
def self.xml(xml)
|
223
|
-
collection =
|
234
|
+
collection = Occi::Collection.new
|
224
235
|
hash = Hashie::Mash.new(Hash.from_xml(Nokogiri::XML(xml)))
|
225
|
-
collection.kinds.
|
226
|
-
collection.mixins.
|
227
|
-
collection.
|
228
|
-
collection.
|
236
|
+
collection.kinds.merge hash.kinds.collect { |kind| Occi::Core::Kind.new(kind.scheme, kind.term, kind.title, kind.attributes, kind.related, kind.actions) } if hash.kinds
|
237
|
+
collection.mixins.merge hash.mixins.collect { |mixin| Occi::Core::Mixin.new(mixin.scheme, mixin.term, mixin.title, mixin.attributes, mixin.related, mixin.actions) } if hash.mixins
|
238
|
+
collection.actions.merge hash.actions.collect { |action| Occi::Core::Action.new(action.scheme, action.term, action.title, action.attributes) } if hash.actions
|
239
|
+
collection.resources.merge hash.resources.collect { |resource| Occi::Core::Resource.new(resource.kind, resource.mixins, resource.attributes, resource.actions, resource.links) } if hash.resources
|
240
|
+
collection.links.merge hash.links.collect { |link| Occi::Core::Link.new(link.kind, link.mixins, link.attributes) } if hash.links
|
229
241
|
collection
|
230
242
|
end
|
231
243
|
|
@@ -239,7 +251,7 @@ module OCCI
|
|
239
251
|
|
240
252
|
|
241
253
|
def self.calculate_capacity_gb(capacity)
|
242
|
-
capacity_gb = capacity/(2**30)
|
254
|
+
capacity_gb = capacity.to_f/(2**30)
|
243
255
|
capacity_gb
|
244
256
|
end
|
245
257
|
|
@@ -256,7 +268,7 @@ module OCCI
|
|
256
268
|
###############End of Helper methods for OVF Parsing ##################################################################
|
257
269
|
|
258
270
|
# @param [String] ova
|
259
|
-
# @return [
|
271
|
+
# @return [Occi::Collection]
|
260
272
|
def self.ova(ova)
|
261
273
|
tar = Gem::Package::TarReader.new(StringIO.new(ova))
|
262
274
|
ovf = mf = cert = nil
|
@@ -274,7 +286,7 @@ module OCCI
|
|
274
286
|
File.read(mf).each_line do |line|
|
275
287
|
name = line.scan(/SHA1\(([^\)]*)\)= (.*)/).flatten.first
|
276
288
|
sha1 = line.scan(/SHA1\(([^\)]*)\)= (.*)/).flatten.last
|
277
|
-
|
289
|
+
Occi::Log.debug "SHA1 hash #{Digest::SHA1.hexdigest(files[name])}"
|
278
290
|
raise "SHA1 mismatch for file #{name}" if Digest::SHA1.hexdigest(File.read(files[name])) != sha1
|
279
291
|
end if mf
|
280
292
|
|
@@ -286,7 +298,7 @@ module OCCI
|
|
286
298
|
# @param [String] ovf
|
287
299
|
# @param [Hash] files key value pairs of file names and paths to the file
|
288
300
|
def self.ovf(ovf, files={ })
|
289
|
-
collection =
|
301
|
+
collection = Occi::Collection.new
|
290
302
|
doc = Nokogiri::XML(ovf)
|
291
303
|
references = { }
|
292
304
|
|
@@ -304,9 +316,9 @@ module OCCI
|
|
304
316
|
end
|
305
317
|
|
306
318
|
doc.xpath('envelope:Envelope/envelope:DiskSection/envelope:Disk', 'envelope' => "#{Parser::OVF}").each do |disk|
|
307
|
-
storage =
|
319
|
+
storage = Occi::Core::Resource.new('http://schemas.ogf.org/occi/infrastructure#storage')
|
308
320
|
if disk.attributes['fileRef']
|
309
|
-
storagelink
|
321
|
+
storagelink = Occi::Core::Link.new("http://schemas.ogf.org/occi/infrastructure#storagelink")
|
310
322
|
storagelink.attributes.occi!.core!.title = disk.attributes['fileRef'].to_s
|
311
323
|
storagelink.attributes.occi!.core!.target = references[disk.attributes['fileRef'].to_s]
|
312
324
|
storage.attributes.occi!.core!.title = disk.attributes['diskId'].to_s
|
@@ -326,7 +338,7 @@ module OCCI
|
|
326
338
|
capacity = self.calculate_capacity_bytes(disk.attributes['capacity'].to_s, alloc_unit_bytes)
|
327
339
|
end
|
328
340
|
capacity_gb = self.calculate_capacity_gb(capacity)
|
329
|
-
|
341
|
+
Occi::Log.debug('capacity in gb ' + capacity_gb.to_s)
|
330
342
|
storage.attributes.occi!.storage!.size = capacity_gb.to_s if capacity_gb
|
331
343
|
storage.attributes.occi!.core!.title = disk.attributes['diskId'].to_s if disk.attributes['diskId']
|
332
344
|
end
|
@@ -334,14 +346,14 @@ module OCCI
|
|
334
346
|
end
|
335
347
|
|
336
348
|
doc.xpath('envelope:Envelope/envelope:NetworkSection/envelope:Network', 'envelope' => "#{Parser::OVF}").each do |nw|
|
337
|
-
network =
|
349
|
+
network = Occi::Core::Resource.new('http://schemas.ogf.org/occi/infrastructure#network')
|
338
350
|
network.attributes.occi!.core!.title = nw.attributes['name'].to_s
|
339
351
|
collection.resources << network
|
340
352
|
end
|
341
353
|
|
342
354
|
# Iteration through all the virtual hardware sections,and a sub-iteration on each Item defined in the Virtual Hardware section
|
343
355
|
doc.xpath('envelope:Envelope/envelope:VirtualSystem', 'envelope' => "#{Parser::OVF}").each do |virtsys|
|
344
|
-
compute =
|
356
|
+
compute = Occi::Core::Resource.new('http://schemas.ogf.org/occi/infrastructure#compute')
|
345
357
|
|
346
358
|
doc.xpath('envelope:Envelope/envelope:VirtualSystem/envelope:VirtualHardwareSection', 'envelope' => "#{Parser::OVF}").each do |virthwsec|
|
347
359
|
compute.attributes.occi!.core!.summary = virthwsec.xpath("item:Info/text()", 'item' => "#{Parser::RASD}").to_s
|
@@ -351,27 +363,35 @@ module OCCI
|
|
351
363
|
case resType.to_s
|
352
364
|
# 4 is the ResourceType for memory in the CIM_ResourceAllocationSettingData
|
353
365
|
when "4" then
|
354
|
-
|
366
|
+
Occi::Log.debug('calculating memory in gb ')
|
367
|
+
alloc_units = resource_alloc.xpath("item:AllocationUnits/text()", 'item' => "#{Parser::RASD}").to_s
|
368
|
+
Occi::Log.debug('allocated units in ovf file: ' + alloc_units)
|
369
|
+
alloc_unit_bytes = self.alloc_units_bytes(alloc_units)
|
370
|
+
capacity = self.calculate_capacity_bytes(resource_alloc.xpath("item:VirtualQuantity/text()", 'item' => "#{Parser::RASD}").to_s, alloc_unit_bytes)
|
371
|
+
capacity_gb = self.calculate_capacity_gb(capacity)
|
372
|
+
Occi::Log.debug('virtual quantity of memory configured in gb: ' + capacity_gb.to_s)
|
373
|
+
compute.attributes.occi!.compute!.memory = capacity_gb
|
374
|
+
# compute.attributes.occi!.compute!.memory = resource_alloc.xpath("item:VirtualQuantity/text()", 'item' => "#{Parser::RASD}").to_s.to_i
|
355
375
|
# 3 is the ResourceType for processor in the CIM_ResourceAllocationSettingData
|
356
376
|
when "3" then
|
357
377
|
compute.attributes.occi!.compute!.cores = resource_alloc.xpath("item:VirtualQuantity/text()", 'item' => "#{Parser::RASD}").to_s.to_i
|
358
378
|
when "10" then
|
359
|
-
networkinterface =
|
379
|
+
networkinterface = Occi::Core::Link.new('http://schemas.ogf.org/occi/infrastructure#networkinterface')
|
360
380
|
networkinterface.attributes.occi!.core!.title = resource_alloc.xpath("item:ElementName/text()", 'item' => "#{Parser::RASD}").to_s
|
361
381
|
id = resource_alloc.xpath("item:Connection/text()", 'item' => "#{Parser::RASD}").to_s
|
362
382
|
network = collection.resources.select { |resource| resource.attributes.occi!.core!.title == id }.first
|
363
383
|
raise "Network with id #{id} not found" unless network
|
364
|
-
networkinterface.attributes.occi!.core!.target = network
|
384
|
+
networkinterface.attributes.occi!.core!.target = network
|
365
385
|
when "17" then
|
366
|
-
storagelink =
|
386
|
+
storagelink = Occi::Core::Link.new("http://schemas.ogf.org/occi/infrastructure#storagelink")
|
367
387
|
storagelink.attributes.occi!.core!.title = resource_alloc.xpath("item:ElementName/text()", 'item' => "#{Parser::RASD}").to_s
|
368
388
|
# extract the mountpoint
|
369
389
|
host_resource = resource_alloc.xpath("item:HostResource/text()", 'item' => "#{Parser::RASD}").to_s
|
370
390
|
if host_resource.start_with? 'ovf:/disk/'
|
371
|
-
id
|
391
|
+
id = host_resource.gsub('ovf:/disk/', '')
|
372
392
|
storage = collection.resources.select { |resource| resource.attributes.occi!.core!.title == id }.first
|
373
393
|
raise "Disk with id #{id} not found" unless storage
|
374
|
-
storagelink.attributes.occi!.core!.target = storage
|
394
|
+
storagelink.attributes.occi!.core!.target = storage
|
375
395
|
elsif host_resource.start_with? 'ovf:/file/'
|
376
396
|
id = host_resource.gsub('ovf:/file/', '')
|
377
397
|
storagelink.attributes.occi!.core!.target = references[id]
|