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.
Files changed (110) hide show
  1. data/.gitignore +4 -0
  2. data/.travis.yml +3 -1
  3. data/AUTHORS +4 -3
  4. data/Gemfile +9 -0
  5. data/Gemfile.lock +64 -21
  6. data/README.md +19 -14
  7. data/Rakefile +12 -8
  8. data/Test Results - discovery_interface.html +862 -0
  9. data/bin/occi +333 -83
  10. data/examples/dsl_example.rb +6 -6
  11. data/examples/x509auth_example.rb +6 -6
  12. data/features/common/step_definitions/common_steps.rb +32 -0
  13. data/features/occi/core/create/create.feature +17 -0
  14. data/features/occi/core/create/step_definitions/create_steps.rb +0 -0
  15. data/features/occi/core/delete/delete.feature +14 -0
  16. data/features/occi/core/delete/step_definitions/delete_steps.rb +0 -0
  17. data/features/occi/core/discovery_interface/discovery_interface.feature +35 -0
  18. data/features/occi/core/discovery_interface/step_definitions/discovery_interface_steps.rb +19 -0
  19. data/features/occi/core/miscellaneous/miscellaneous.feature +14 -0
  20. data/features/occi/core/miscellaneous/step_definitions/miscellaneous_steps.rb +0 -0
  21. data/features/occi/core/read/read.feature +14 -0
  22. data/features/occi/core/read/step_definitions/read_steps.rb +0 -0
  23. data/features/occi/core/update/step_definitions/update_steps.rb +0 -0
  24. data/features/occi/core/update/update.feature +14 -0
  25. data/features/occi/infrastructure/create/create.feature +14 -0
  26. data/features/occi/infrastructure/create/step_definitions/create_steps.rb +0 -0
  27. data/features/support/env.rb +4 -0
  28. data/lib/occi.rb +29 -3
  29. data/lib/occi/api/client/client_amqp.rb +756 -0
  30. data/lib/occi/api/client/client_http.rb +922 -0
  31. data/lib/occi/api/client/http/httparty_fix.rb +53 -0
  32. data/lib/occi/api/client/http/net_http_fix.rb +46 -0
  33. data/lib/occi/api/dsl.rb +77 -73
  34. data/lib/occi/bin/helpers.rb +91 -0
  35. data/lib/occi/bin/occi_opts.rb +251 -0
  36. data/lib/occi/bin/resource_output_factory.rb +90 -0
  37. data/lib/occi/bin/templates/compute.erb +15 -0
  38. data/lib/occi/bin/templates/network.erb +11 -0
  39. data/lib/occi/bin/templates/os_tpl.erb +9 -0
  40. data/lib/occi/bin/templates/resource_tpl.erb +9 -0
  41. data/lib/occi/bin/templates/storage.erb +10 -0
  42. data/lib/occi/collection.rb +122 -25
  43. data/lib/occi/core.rb +18 -9
  44. data/lib/occi/core/action.rb +20 -4
  45. data/lib/occi/core/action_instance.rb +24 -0
  46. data/lib/occi/core/actions.rb +22 -0
  47. data/lib/occi/core/attribute_properties.rb +33 -84
  48. data/lib/occi/core/attributes.rb +32 -14
  49. data/lib/occi/core/categories.rb +46 -0
  50. data/lib/occi/core/category.rb +94 -20
  51. data/lib/occi/core/entities.rb +50 -0
  52. data/lib/occi/core/entity.rb +130 -89
  53. data/lib/occi/core/kind.rb +28 -35
  54. data/lib/occi/core/kinds.rb +22 -0
  55. data/lib/occi/core/link.rb +43 -40
  56. data/lib/occi/core/links.rb +34 -0
  57. data/lib/occi/core/mixin.rb +28 -23
  58. data/lib/occi/core/mixins.rb +22 -0
  59. data/lib/occi/core/related.rb +20 -0
  60. data/lib/occi/core/resource.rb +40 -40
  61. data/lib/occi/core/resources.rb +14 -0
  62. data/lib/occi/infrastructure.rb +27 -0
  63. data/lib/occi/infrastructure/compute.rb +159 -0
  64. data/lib/occi/infrastructure/network.rb +131 -0
  65. data/lib/occi/infrastructure/network/ipnetwork.rb +34 -0
  66. data/lib/occi/infrastructure/networkinterface.rb +124 -0
  67. data/lib/occi/infrastructure/networkinterface/ipnetworkinterface.rb +34 -0
  68. data/lib/occi/infrastructure/os_tpl.rb +19 -0
  69. data/lib/occi/infrastructure/resource_tpl.rb +19 -0
  70. data/lib/occi/infrastructure/storage.rb +96 -0
  71. data/lib/occi/infrastructure/storagelink.rb +73 -0
  72. data/lib/occi/log.rb +6 -2
  73. data/lib/occi/model.rb +38 -70
  74. data/lib/occi/parser.rb +108 -88
  75. data/lib/occi/version.rb +2 -2
  76. data/lib/occiantlr/OCCIANTLR.g +6 -5
  77. data/lib/occiantlr/OCCIANTLRLexer.rb +52 -52
  78. data/lib/occiantlr/OCCIANTLRParser.rb +678 -569
  79. data/lib/occiantlr/README.md +1 -1
  80. data/occi.gemspec +2 -1
  81. data/spec/cassettes/client_http_text_plain.yml +1066 -0
  82. data/spec/occi/api/client/client_amqp_spec.rb +148 -0
  83. data/spec/occi/api/client/client_http_0.5_spec.rb +292 -0
  84. data/spec/occi/api/client/client_http_spec.rb +259 -0
  85. data/spec/occi/api/dsl_spec.rb +0 -0
  86. data/spec/occi/collection_spec.rb +23 -10
  87. data/spec/occi/core/categories_spec.rb +30 -0
  88. data/spec/occi/core/category_spec.rb +41 -0
  89. data/spec/occi/core/entity_spec.rb +52 -0
  90. data/spec/occi/core/resource_spec.rb +21 -0
  91. data/spec/occi/infrastructure/compute_spec.rb +32 -0
  92. data/spec/occi/log_spec.rb +10 -10
  93. data/spec/occi/model_spec.rb +24 -24
  94. data/spec/occi/parser_spec.rb +89 -39
  95. data/spec/occi/test.json +22 -58
  96. data/spec/occiantlr/parser_spec.rb +5 -7
  97. data/spec/spec_helper.rb +13 -3
  98. metadata +116 -19
  99. data/etc/model/infrastructure/compute.json +0 -108
  100. data/etc/model/infrastructure/ipnetwork.json +0 -40
  101. data/etc/model/infrastructure/ipnetworkinterface.json +0 -40
  102. data/etc/model/infrastructure/network.json +0 -55
  103. data/etc/model/infrastructure/networkinterface.json +0 -38
  104. data/etc/model/infrastructure/os_template.json +0 -9
  105. data/etc/model/infrastructure/resource_template.json +0 -9
  106. data/etc/model/infrastructure/storage.json +0 -72
  107. data/etc/model/infrastructure/storagelink.json +0 -38
  108. data/lib/occi/api/client.rb +0 -596
  109. data/lib/occi/client/occiopts.rb +0 -146
  110. data/spec/occi/client_spec.rb +0 -12
@@ -1,99 +1,48 @@
1
1
  require 'hashie/mash'
2
2
 
3
- module OCCI
3
+ module Occi
4
4
  module Core
5
5
  class AttributeProperties < Hashie::Mash
6
6
 
7
- # @param [Hashie::Mash] attributes
7
+ # @param [Hash] properties
8
8
  # @param [Hash] default
9
- def initialize(attributes = nil, default = nil)
10
- if [:Type, :Required, :Mutable, :Pattern, :Default, :Minimum, :Maximum, :Description].any? { |k| attributes.key?(k.capitalize) }
11
- attributes[:Type] ||= "string"
12
- attributes[:Required] ||= false
13
- attributes[:Mutable] ||= false
14
- attributes[:Pattern] ||= ".*"
15
- end if attributes
16
- super(attributes, default)
9
+ def initialize(properties=nil,default=nil)
10
+ properties ||= {}
11
+ properties[:type] ||= 'string'
12
+ properties[:required] ||= false
13
+ properties[:mutable] ||= false
14
+ properties[:pattern] ||= '.*'
15
+ super properties, default
17
16
  end
18
17
 
19
- # @return [Array] list of full attribute names
20
- def combine
21
- array = []
22
- self.each_key do |key|
23
- if self[key].key?('Type') || self[key].key?('type')
24
- array << key
25
- else
26
- attribute = self[key]
27
- attribute.combine.each { |attr| array << key + '.' + attr }
18
+ # @param [Hash] properties
19
+ # @return [Occi::Core::Attributes] parsed Attribute Properties
20
+ def self.parse(properties)
21
+ properties ||= Hashie::Mash.new
22
+ if [:Type, :Required, :Mutable, :Default, :Description, :Pattern, :type, :required, :mutable, :default, :description, :pattern].any? { |k| properties.key?(k) and not properties[k].kind_of? Hash }
23
+ properties[:type] ||= properties[:Type] ||= "string"
24
+ properties[:required] ||= properties[:Required] ||= false
25
+ properties[:mutable] ||= properties[:Mutable] ||= false
26
+ properties[:default] = properties[:Default] if properties[:Default]
27
+ properties[:description] = properties[:Description] if properties[:Description]
28
+ properties[:pattern] ||= properties[:Pattern] ||= ".*"
29
+ properties.delete :Type
30
+ properties.delete :Required
31
+ properties.delete :Mutable
32
+ properties.delete :Default
33
+ properties.delete :Description
34
+ properties.delete :Pattern
35
+ return self.new properties
36
+ else
37
+ attributes = Occi::Core::Attributes.new
38
+ properties.each_key do |key|
39
+ attributes[key] = self.parse properties[key]
28
40
  end
29
- end
30
- array
31
- end
32
-
33
-
34
- # @return [Hash] key value pairs of attribute names with their defaults set
35
- def combine_with_defaults
36
- hash = { }
37
- self.each_key do |key|
38
- if self[key].include?('Type') || self[key].include?('type')
39
- hash[key] = self[key]['Default']
40
- else
41
- self[key].combine_with_defaults.each { |k, v| hash[key + '.' + k] = v }
42
- end
43
- end
44
- hash
45
- end
46
-
47
- def convert_value(val, duping=false) #:nodoc:
48
- case val
49
- when self.class
50
- val.dup
51
- when ::Hash
52
- val = val.dup if duping
53
- self.class.subkey_class.new(val)
54
- when Array
55
- val.collect { |e| convert_value(e) }
56
- else
57
- val
58
- end
59
- end
60
-
61
- # Overrides method of hashie mash to check if one of the attribute properties has been set
62
- def method_missing(method_name, *args, &blk)
63
- return self.[](method_name, &blk) if key?(method_name)
64
- match = method_name.to_s.match(/(.*?)([?=!]?)$/)
65
- case match[2]
66
- when "="
67
- key = match[1]
68
- self[key] = args.first
69
- if %w|Type Required Mutable Pattern Default Minimum Maximum Description|.any? { |k| key.to_s.capitalize == k }
70
- self["Type"] = "string" unless key?("Type") || key?("type")
71
- self["Required"] = false unless key?("Required") || key?("required")
72
- self["Mutable"] = false unless key?("Mutable") || key?("mutable")
73
- self["Pattern"] = ".*" unless key?("Pattern") || key?("pattern")
74
- end
75
- when "?"
76
- !!self[match[1]]
77
- when "!"
78
- initializing_reader(match[1])
79
- else
80
- default(method_name, *args, &blk)
81
- end
82
- end
83
-
84
- # Sets an attribute in the Mash. Key will be converted to
85
- # a string before it is set, and Hashes will be converted
86
- # into Mashes for nesting purposes.
87
- def []=(key, value) #:nodoc:
88
- regular_writer(convert_key(key), convert_value(value))
89
- if %w|Type Required Mutable Pattern Default Minimum Maximum Description|.any? { |k| key.to_s.capitalize == k }
90
- self["Type"] = "string" unless key?("Type") || key?("type")
91
- self["Required"] = false unless key?("Required") || key?("required")
92
- self["Mutable"] = false unless key?("Mutable") || key?("mutable")
93
- self["Pattern"] = ".*" unless key?("Pattern") || key?("pattern")
41
+ return attributes
94
42
  end
95
43
  end
96
44
 
45
+ # @return [String] json representation
97
46
  def inspect
98
47
  JSON.pretty_generate(JSON.parse(to_json))
99
48
  end
@@ -1,14 +1,14 @@
1
1
  require 'hashie/mash'
2
2
 
3
- module OCCI
3
+ module Occi
4
4
  module Core
5
5
  class Attributes < Hashie::Mash
6
6
 
7
- # @return [Array] key value pair of full attribute names with their corresponding values
8
- def combine
7
+ # @return [Array] key value pair of full attribute names with their corresponding values
8
+ def combine
9
9
  hash = { }
10
10
  self.each_key do |key|
11
- if self[key].kind_of? OCCI::Core::Attributes
11
+ if self[key].kind_of? Occi::Core::Attributes
12
12
  self[key].combine.each_pair { |k, v| hash[key + '.' + k] = v }
13
13
  else
14
14
  hash[key] = self[key]
@@ -17,12 +17,34 @@ module OCCI
17
17
  hash
18
18
  end
19
19
 
20
- # @param [Hash] attributes key value pair of full attribute names with their corresponding values
21
- # @return [OCCI::Core::Attributes]
22
- def self.split(attributes)
20
+ def convert_value(val, duping=false) #:nodoc:
21
+ case val
22
+ when self.class
23
+ val.dup
24
+ when Hashie::Mash
25
+ val = val.dup if duping
26
+ val
27
+ when ::Hash
28
+ val = val.dup if duping
29
+ self.class.subkey_class.new.merge(val)
30
+ when Array
31
+ val.collect { |e| convert_value(e) }
32
+ else
33
+ val
34
+ end
35
+ end
36
+
37
+ # @return [String] json representation
38
+ def inspect
39
+ JSON.pretty_generate(JSON.parse(to_json))
40
+ end
41
+
42
+ # @param [Hash] attributes key value pair of full attribute names with their corresponding values
43
+ # @return [Occi::Core::Attributes]
44
+ def self.split(attributes)
23
45
  attribute = Attributes.new
24
- attributes.each do |name,value|
25
- puts name
46
+ attributes.each do |name, value|
47
+ Occi::Log.debug "Attribute named #{name}"
26
48
  key, _, rest = name.partition('.')
27
49
  if rest.empty?
28
50
  attribute[key] = value
@@ -35,9 +57,5 @@ module OCCI
35
57
 
36
58
  end
37
59
 
38
- def inspect
39
- JSON.pretty_generate(JSON.parse(to_json))
40
- end
41
-
42
60
  end
43
- end
61
+ end
@@ -0,0 +1,46 @@
1
+ module Occi
2
+ module Core
3
+ class Categories < Set
4
+
5
+ attr_accessor :model
6
+
7
+ def initialize(categories=[])
8
+ categories.collect! { |category| convert category } if categories
9
+ super categories
10
+ end
11
+
12
+ def <<(category)
13
+ super convert category
14
+ end
15
+
16
+ def join(separator)
17
+ self.to_a.join(separator)
18
+ end
19
+
20
+ # @param [Occi::Model] model
21
+ # @return [Occi::Model]
22
+ def model=(model)
23
+ @model = model
24
+ collect! { |category| model.get_by_id category.to_s or category }
25
+ end
26
+
27
+ # @param [Hash] options
28
+ # @return [Hashie::Mash] json representation
29
+ def as_json(options={ })
30
+ self.to_a.as_json
31
+ end
32
+
33
+ # @return [String] json representation
34
+ def inspect
35
+ JSON.pretty_generate(JSON.parse(to_json))
36
+ end
37
+
38
+ private
39
+
40
+ def convert(category)
41
+ (@model.get_by_id category if @model if category.kind_of? String) or category
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -1,22 +1,76 @@
1
- require 'active_support/json'
2
- require 'active_support/inflector'
3
- require 'hashie/mash'
4
-
5
- module OCCI
1
+ module Occi
6
2
  module Core
7
3
  class Category
8
4
 
9
- attr_accessor :model, :scheme, :term, :title, :attributes
5
+ attr_accessor :scheme, :term, :title, :attributes, :model
6
+
7
+ def self.categories
8
+ self.mixins + self.actions << self.kind
9
+ end
10
10
 
11
11
  # @param [String ] scheme
12
12
  # @param [String] term
13
13
  # @param [String] title
14
- # @param [OCCI::Core::AttributeProperties] attributes
15
- def initialize(scheme, term, title=nil, attributes=nil)
14
+ # @param [Hash] attributes
15
+ def initialize(scheme='http://schemas.ogf.org/occi/core#',
16
+ term='category',
17
+ title=nil,
18
+ attributes=Occi::Core::Attributes.new)
16
19
  @scheme = scheme
17
20
  @term = term
18
21
  @title = title
19
- @attributes = OCCI::Core::AttributeProperties.new(attributes)
22
+ @attributes = Occi::Core::AttributeProperties.parse attributes
23
+ end
24
+
25
+ # @param [String] scheme
26
+ # @param [String] term
27
+ # @param [Array] related
28
+ # @return [Class] ruby class with scheme as namespace, term as name and related kind as super class
29
+ def self.get_class(scheme, term, related=['http://schemas.ogf.org/occi/core#entity'])
30
+ related = related.to_a.flatten
31
+ scheme += '#' unless scheme.end_with? '#'
32
+
33
+ if related.first.to_s == 'http://schemas.ogf.org/occi/core#entity' or related.first.nil?
34
+ parent = Occi::Core::Entity
35
+ elsif related.first.kind_of? Occi::Core::Category
36
+ parent = related.first.class
37
+ else
38
+ related_scheme, related_term = related.first.to_s.split '#'
39
+ parent = self.get_class related_scheme, related_term
40
+ end
41
+
42
+ uri = URI.parse(scheme)
43
+
44
+ namespace = if uri.host == 'schemas.ogf.org'
45
+ uri.path.reverse.chomp('/').reverse.split('/')
46
+ else
47
+ uri.host.split('.').reverse + uri.path.reverse.chomp('/').reverse.split('/')
48
+ end
49
+
50
+ namespace = namespace.inject(Object) do |mod, name|
51
+ if mod.constants.collect { |sym| sym.to_s }.include? name.classify
52
+ mod.const_get name.classify
53
+ else
54
+ mod.const_set name.classify, Module.new
55
+ end
56
+ end
57
+
58
+ if namespace.const_defined? term.classify
59
+ klass = namespace.const_get term.classify
60
+ unless klass.ancestors.include? Occi::Core::Entity or klass.ancestors.include? Occi::Core::Category
61
+ raise "OCCI Kind with type identifier #{scheme + term} could not be created as the corresponding class #{klass.to_s} already exists and is not derived from Occi::Core::Entity"
62
+ end
63
+ else
64
+ klass = namespace.const_set term.classify, Class.new(parent)
65
+ klass.kind = Occi::Core::Kind.new scheme, term, nil, { }, related unless parent.ancestors.include? Occi::Core::Category
66
+ end
67
+
68
+ klass
69
+ end
70
+
71
+ # @param [Occi::Model] model
72
+ def model=(model)
73
+ @related.model=model if @related
20
74
  end
21
75
 
22
76
  # @return [String] Type identifier of the category
@@ -25,12 +79,12 @@ module OCCI
25
79
  end
26
80
 
27
81
  # check if category is related to another category
28
- # @param [String] category_id Type identifier of a related category
82
+ # @param [String, Category] category Related Category or its type identifier
29
83
  # @return [true,false] true if category is related to category_id else false
30
- def related_to?(category_id)
31
- self.related.each do |rel_id|
32
- return true if rel_id == category_id || @model.get_by_id(rel_id).related_to?(category_id)
33
- end if self.class.method_defined? 'related'
84
+ def related_to?(category)
85
+ self.related.each do |cat|
86
+ return true if cat.to_s == category.to_s
87
+ end if @related
34
88
  false
35
89
  end
36
90
 
@@ -45,22 +99,42 @@ module OCCI
45
99
  category
46
100
  end
47
101
 
102
+ # @return [String] short text representation of the category
103
+ def to_string_short
104
+ @term + ';scheme=' + @scheme.inspect + ';class=' + self.class.name.demodulize.downcase.inspect
105
+ end
106
+
107
+ # @return [String] full text representation of the category
108
+ def to_string
109
+ string = self.to_string_short
110
+ string << ';title=' + @title.inspect if @title
111
+ string
112
+ end
113
+
48
114
  # @return [String] text representation
49
115
  def to_text
50
- text = @term + ';scheme=' + @scheme.inspect + ';class=' + self.class.name.demodulize.downcase.inspect
51
- text << ';title=' + @title.inspect if @title
52
- text
116
+ 'Category: ' + self.to_string
53
117
  end
54
118
 
119
+ # @return [Hash] hash containing the HTTP headers of the text/occi rendering
55
120
  def to_header
56
- header = Hashie::Mash.new
57
- header[:Category] = self.to_text
121
+ { :Category => self.to_string }
58
122
  end
59
123
 
124
+ # @return [String] json representation
60
125
  def inspect
61
126
  JSON.pretty_generate(JSON.parse(to_json))
62
127
  end
63
128
 
129
+ # @return [NilClass] category itself does not have a location
130
+ def location
131
+ nil # not implemented
132
+ end
133
+
134
+ def to_s
135
+ self.type_identifier
136
+ end
137
+
64
138
  end
65
139
  end
66
- end
140
+ end
@@ -0,0 +1,50 @@
1
+ module Occi
2
+ module Core
3
+ class Entities < Set
4
+
5
+ attr_accessor :model
6
+
7
+ def initialize(entities=[])
8
+ entities.to_a.each { |entity| entity.model = @model } if @model
9
+ super entities
10
+ end
11
+
12
+ def join(separator)
13
+ self.to_a.join(separator)
14
+ end
15
+
16
+ def model=(model)
17
+ @model = model
18
+ each { |entity| entity.model=model }
19
+ end
20
+
21
+ def check
22
+ each { |entity| entity.check }
23
+ end
24
+
25
+ def create(*args)
26
+ entity = Occi::Core::Entity.new(*args)
27
+ entity.model = @model if @model
28
+ self << entity
29
+ entity
30
+ end
31
+
32
+ def <<(entity)
33
+ entity.model = @model if @model
34
+ super entity
35
+ end
36
+
37
+ # @param [Hash] options
38
+ # @return [Hashie::Mash] json representation
39
+ def as_json(options={ })
40
+ self.to_a.as_json
41
+ end
42
+
43
+ # @return [String] json representation
44
+ def inspect
45
+ JSON.pretty_generate(JSON.parse(to_json))
46
+ end
47
+
48
+ end
49
+ end
50
+ end