occi 2.4.0 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +11 -7
- data/etc/model/infrastructure/compute.json +4 -11
- data/etc/model/infrastructure/ipnetwork.json +3 -6
- data/etc/model/infrastructure/ipnetworkinterface.json +3 -6
- data/etc/model/infrastructure/network.json +1 -2
- data/etc/model/infrastructure/networkinterface.json +2 -4
- data/etc/model/infrastructure/storage.json +2 -5
- data/examples/x509auth_example.rb +42 -0
- data/lib/occi/client.rb +270 -167
- data/lib/occi/collection.rb +12 -7
- data/lib/occi/core/action.rb +1 -0
- data/lib/occi/core/attribute_properties.rb +10 -3
- data/lib/occi/core/attributes.rb +10 -2
- data/lib/occi/core/category.rb +7 -0
- data/lib/occi/core/entity.rb +32 -12
- data/lib/occi/core/kind.rb +3 -0
- data/lib/occi/core/link.rb +24 -5
- data/lib/occi/core/mixin.rb +3 -0
- data/lib/occi/core/resource.rb +20 -15
- data/lib/occi/log.rb +7 -5
- data/lib/occi/model.rb +9 -5
- data/lib/occi/parser.rb +28 -2
- data/lib/occi/version.rb +1 -1
- metadata +4 -3
data/README.md
CHANGED
@@ -85,8 +85,8 @@ Before the parser may be used, the available categories have to be registered in
|
|
85
85
|
|
86
86
|
For categories already specified by the OCCI WG a method exists in the OCCI Model class to register them:
|
87
87
|
|
88
|
-
OCCI::Model.
|
89
|
-
|
88
|
+
model = OCCI::Model.new
|
89
|
+
model.register_infrastructure
|
90
90
|
|
91
91
|
Further categories can either be registered from files which include OCCI collections in JSON formator or from parsed
|
92
92
|
JSON objects (e.g. from the query interface of an OCCI service endpoint).
|
@@ -103,7 +103,7 @@ OCCI messages can be parsed to an OCCI collection for example like
|
|
103
103
|
|
104
104
|
media_type = text/plain
|
105
105
|
body = %Q|Category: compute; scheme="http://schemas.ogf.org/occi/infrastructure#"; class="kind"|
|
106
|
-
collection=OCCI::Parser.parse(media_type,body)
|
106
|
+
collection=OCCI::Parser.parse(media_type, body)
|
107
107
|
|
108
108
|
### Parsing OVF / OVA files
|
109
109
|
|
@@ -136,6 +136,10 @@ The OCCI gem includes all OCCI Core classes necessary to handly arbitrary OCCI o
|
|
136
136
|
Changelog
|
137
137
|
---------
|
138
138
|
|
139
|
+
### Version 2.4
|
140
|
+
|
141
|
+
* Changed OCCI attribute properties from lowercase to first letter uppercase (e.g. type -> Type, default -> Default, ...)
|
142
|
+
|
139
143
|
### Version 2.3
|
140
144
|
|
141
145
|
* OCCI objects are now initialized with a list of attributes instead of a hash. Thus it is easier to check which
|
@@ -145,19 +149,19 @@ future versions of rOCCI.
|
|
145
149
|
|
146
150
|
### Version 2.2
|
147
151
|
|
148
|
-
OCCI Client added. The client simplifies the execution of OCCI commands and provides shortcuts for often used steps.
|
152
|
+
* OCCI Client added. The client simplifies the execution of OCCI commands and provides shortcuts for often used steps.
|
149
153
|
|
150
154
|
### Version 2.1
|
151
155
|
|
152
|
-
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.
|
156
|
+
* 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.
|
153
157
|
|
154
158
|
### Version 2.0
|
155
159
|
|
156
|
-
Starting with version 2.0 Florian Feldhaus and Piotr Kasprzak took over the development of the OCCI gem. The codebase was taken from the rOCCI framework and improved to be bundled as a standalone gem.
|
160
|
+
* Starting with version 2.0 Florian Feldhaus and Piotr Kasprzak took over the development of the OCCI gem. The codebase was taken from the rOCCI framework and improved to be bundled as a standalone gem.
|
157
161
|
|
158
162
|
### Version 1.X
|
159
163
|
|
160
|
-
Version 1.X of the OCCI gem has been developed by retr0h and served as a simple way to access the first OpenNebula OCCI implementation.
|
164
|
+
* Version 1.X of the OCCI gem has been developed by retr0h and served as a simple way to access the first OpenNebula OCCI implementation.
|
161
165
|
|
162
166
|
Development
|
163
167
|
-----------
|
@@ -14,15 +14,12 @@
|
|
14
14
|
"Mutable":true,
|
15
15
|
"Required":false,
|
16
16
|
"Type":"string",
|
17
|
-
"Pattern":"x86|x64"
|
18
|
-
"Default":"x86"
|
17
|
+
"Pattern":"x86|x64"
|
19
18
|
},
|
20
19
|
"cores":{
|
21
20
|
"Mutable":true,
|
22
21
|
"Required":false,
|
23
|
-
"Type":"number"
|
24
|
-
"Minimum":1,
|
25
|
-
"Maximum":32767
|
22
|
+
"Type":"number"
|
26
23
|
},
|
27
24
|
"hostname":{
|
28
25
|
"Mutable":true,
|
@@ -33,16 +30,12 @@
|
|
33
30
|
"speed":{
|
34
31
|
"Mutable":true,
|
35
32
|
"Required":false,
|
36
|
-
"Type":"number"
|
37
|
-
"Minimum":0,
|
38
|
-
"Maximum":32767
|
33
|
+
"Type":"number"
|
39
34
|
},
|
40
35
|
"memory":{
|
41
36
|
"Mutable":true,
|
42
37
|
"Required":false,
|
43
|
-
"Type":"number"
|
44
|
-
"Minimum":0,
|
45
|
-
"Maximum":32767
|
38
|
+
"Type":"number"
|
46
39
|
},
|
47
40
|
"state":{
|
48
41
|
"Mutable":false,
|
@@ -11,22 +11,19 @@
|
|
11
11
|
"Mutable":true,
|
12
12
|
"Required":false,
|
13
13
|
"Type":"string",
|
14
|
-
"Pattern":"(^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*(\\/(\\d|\\d\\d|1[0-1]\\d|12[0-8]))$)|(^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/(\\d|[1-2]\\d|3[0-2]))$)"
|
15
|
-
"Default":"10.0.0.0/8"
|
14
|
+
"Pattern":"(^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*(\\/(\\d|\\d\\d|1[0-1]\\d|12[0-8]))$)|(^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/(\\d|[1-2]\\d|3[0-2]))$)"
|
16
15
|
},
|
17
16
|
"gateway":{
|
18
17
|
"Mutable":true,
|
19
18
|
"Required":false,
|
20
19
|
"Type":"string",
|
21
|
-
"Pattern":"(^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*)"
|
22
|
-
"Default":"10.0.0.1"
|
20
|
+
"Pattern":"(^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*)"
|
23
21
|
},
|
24
22
|
"allocation":{
|
25
23
|
"Mutable":true,
|
26
24
|
"Required":false,
|
27
25
|
"Type":"string",
|
28
|
-
"Pattern":"dynamic|static"
|
29
|
-
"Default":"dynamic"
|
26
|
+
"Pattern":"dynamic|static"
|
30
27
|
},
|
31
28
|
"state":{
|
32
29
|
"Mutable":false,
|
@@ -11,22 +11,19 @@
|
|
11
11
|
"Mutable":true,
|
12
12
|
"Required":false,
|
13
13
|
"Type":"string",
|
14
|
-
"Pattern":"(^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*)"
|
15
|
-
"Default":"10.0.0.0/8"
|
14
|
+
"Pattern":"(^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*)"
|
16
15
|
},
|
17
16
|
"gateway":{
|
18
17
|
"Mutable":true,
|
19
18
|
"Required":false,
|
20
19
|
"Type":"string",
|
21
|
-
"Pattern":"(^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*)"
|
22
|
-
"Default":"10.0.0.1"
|
20
|
+
"Pattern":"(^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*)"
|
23
21
|
},
|
24
22
|
"allocation":{
|
25
23
|
"Mutable":true,
|
26
24
|
"Required":false,
|
27
25
|
"Type":"string",
|
28
|
-
"Pattern":"dynamic|static"
|
29
|
-
"Default":"dynamic"
|
26
|
+
"Pattern":"dynamic|static"
|
30
27
|
},
|
31
28
|
"state":{
|
32
29
|
"Mutable":false,
|
@@ -14,15 +14,13 @@
|
|
14
14
|
"Mutable":true,
|
15
15
|
"Required":false,
|
16
16
|
"Type":"string",
|
17
|
-
"Pattern":".*"
|
18
|
-
"Default":"eth0"
|
17
|
+
"Pattern":".*"
|
19
18
|
},
|
20
19
|
"mac":{
|
21
20
|
"Mutable":true,
|
22
21
|
"Required":false,
|
23
22
|
"Type":"string",
|
24
|
-
"Pattern":"^([0-
|
25
|
-
"Default":"00:16:3e:00:00:00"
|
23
|
+
"Pattern":"^([0-9a-fA-F]{2}[:-]){5}([0-9a-fA-F]{2})$"
|
26
24
|
},
|
27
25
|
"state":{
|
28
26
|
"Mutable":false,
|
@@ -13,9 +13,7 @@
|
|
13
13
|
"size":{
|
14
14
|
"Mutable":true,
|
15
15
|
"Required":false,
|
16
|
-
"Type":"number"
|
17
|
-
"Minimum":0,
|
18
|
-
"Maximum":32767
|
16
|
+
"Type":"number"
|
19
17
|
},
|
20
18
|
"state":{
|
21
19
|
"Mutable":false,
|
@@ -66,8 +64,7 @@
|
|
66
64
|
"size":{
|
67
65
|
"Mutable":true,
|
68
66
|
"Required":false,
|
69
|
-
"Type":"number"
|
70
|
-
"Default":"suspend"
|
67
|
+
"Type":"number"
|
71
68
|
}
|
72
69
|
}
|
73
70
|
}
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'occi'
|
3
|
+
require 'pp'
|
4
|
+
|
5
|
+
USER_CERT = ENV['HOME'] + '/.globus/usercert.pem'
|
6
|
+
USER_CERT_PASSPWORD = 'mypassphrase'
|
7
|
+
CA_PATH = '/etc/grid-security/certificates'
|
8
|
+
|
9
|
+
client = OCCI::Client.new('https://localhost:3300',
|
10
|
+
{ :type => "x509",
|
11
|
+
:user_cert => USER_CERT,
|
12
|
+
:user_cert_password => USER_CERT_PASSWORD,
|
13
|
+
:ca_path => CA_PATH })
|
14
|
+
|
15
|
+
puts "\n\nPrinting all resources"
|
16
|
+
pp client.get resources
|
17
|
+
|
18
|
+
puts "\n\nPrinting storage resources"
|
19
|
+
pp client.get storage
|
20
|
+
|
21
|
+
puts "\n\nPrinting network resources"
|
22
|
+
pp client.get network
|
23
|
+
|
24
|
+
puts "\n\nPrinting compute resources"
|
25
|
+
pp client.get compute
|
26
|
+
|
27
|
+
puts "\n\nPrinting locations of all resources"
|
28
|
+
pp client.list resources
|
29
|
+
|
30
|
+
puts "\n\nPrinting locations of storage resources"
|
31
|
+
pp client.list storage
|
32
|
+
|
33
|
+
puts "\n\nPrinting locations of compute resources"
|
34
|
+
pp client.list compute
|
35
|
+
|
36
|
+
puts "\n\nPrinting locations of network resources"
|
37
|
+
pp client.list network
|
38
|
+
|
39
|
+
puts "\n\nCreate compute resources"
|
40
|
+
cmpt = OCCI::Core::Resource.new compute
|
41
|
+
cmpt_loc = client.create cmpt
|
42
|
+
pp "Location of new compute resource: #{cmpt_loc}"
|
data/lib/occi/client.rb
CHANGED
@@ -1,203 +1,306 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'httparty'
|
3
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
|
+
|
4
20
|
module OCCI
|
5
21
|
class Client
|
6
22
|
include HTTParty
|
7
|
-
|
8
|
-
headers 'Accept' => 'application/occi+json'
|
23
|
+
headers 'Accept' => 'application/occi+json,text/plain;q=0.5'
|
9
24
|
|
10
25
|
attr_reader :endpoint
|
11
26
|
attr_reader :model
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
def get_resources_list
|
43
|
-
self.class.get(@endpoint, :headers => { 'Accept' => 'text/uri-list' }).split("\n").compact
|
44
|
-
end
|
45
|
-
|
46
|
-
def post_resource(attributes, kind, mixins, resources_to_link)
|
47
|
-
resource = OCCI::Core::Resource.new(kind.type_identifier)
|
48
|
-
mixins = mixins.collect { |mixin| mixin.type_identifiers } unless mixins.first.kind_of? String
|
49
|
-
resource.mixins = mixins
|
50
|
-
attributes = OCCI::Core::Attributes.split(attributes) unless attributes.kind_of? OCCI::Core::Attributes
|
51
|
-
resource.attributes = attributes
|
52
|
-
resource.links = []
|
53
|
-
resources_to_link.each do |res|
|
54
|
-
kind = 'http://schemas.ogf.org/occi/infrastructure#storagelink' if @model.get_by_id(res.kind).related_to? 'http://schemas.ogf.org/occi/infrastructure#storage'
|
55
|
-
kind = 'http://schemas.ogf.org/occi/infrastructure#networkinterface' if @model.get_by_id(res.kind).related_to? 'http://schemas.ogf.org/occi/infrastructure#network'
|
56
|
-
link = OCCI::Link.new(kind)
|
57
|
-
link.titlte "Link to #{res.title}"
|
58
|
-
link.target = res.location
|
59
|
-
resource.links << link
|
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]}]!"
|
60
56
|
end
|
61
|
-
resource.check
|
62
|
-
collection = OCCI::Collection.new(:resources => [resource])
|
63
|
-
self.class.post(@endpoint + kind.location, { :body => collection.to_json, :headers => { 'Content-Type' => 'application/occi+json', 'Accept' => 'text/uri-list' }, :format => 'text/plain' }).body
|
64
|
-
end
|
65
|
-
|
66
|
-
def delete_resources
|
67
|
-
self.class.delete(@endpoint)
|
68
|
-
end
|
69
|
-
|
70
|
-
def trigger_action(url)
|
71
|
-
self.class.post(url)
|
72
|
-
end
|
73
|
-
|
74
|
-
def trigger_action_on_resources(resources, action)
|
75
|
-
end
|
76
|
-
|
77
|
-
|
78
|
-
def get_compute_list
|
79
|
-
self.class.get(@endpoint + @compute.location, { :headers => { 'Accept' => 'text/uri-list' }, :format => 'text/plain' }).split("\n").compact
|
80
|
-
end
|
81
|
-
|
82
|
-
def get_compute_resources
|
83
|
-
self.class.get(endpoint + @compute.location)
|
84
|
-
end
|
85
|
-
|
86
|
-
def post_compute_resource(attributes=OCCI::Core::Attributes.new, os = nil, size = nil, mixins=[], resources_to_link=[])
|
87
|
-
mixins << os if os
|
88
|
-
mixins << size if size
|
89
|
-
post_resource(attributes, @compute, mixins, resources_to_link)
|
90
|
-
end
|
91
|
-
|
92
|
-
def delete_compute_resource(id)
|
93
|
-
self.class.delete(@endpoint + @compute.location + id)
|
94
|
-
end
|
95
|
-
|
96
|
-
def delete_compute_resources
|
97
|
-
self.class.delete(@endpoint + @compute.location)
|
98
|
-
end
|
99
57
|
|
100
|
-
|
101
|
-
|
58
|
+
raise 'endpoint not a valid URI' if (endpoint =~ URI::ABS_URI).nil?
|
59
|
+
@endpoint = endpoint.chomp('/') + '/'
|
60
|
+
refresh_model
|
61
|
+
select_media_type
|
102
62
|
end
|
103
63
|
|
104
|
-
|
105
|
-
|
64
|
+
# @return [OCCI::Model]
|
65
|
+
def refresh_model
|
66
|
+
model = get '/-/'
|
67
|
+
@model = OCCI::Model.new(model)
|
106
68
|
end
|
107
69
|
|
108
|
-
|
109
|
-
|
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)
|
110
77
|
end
|
111
78
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
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' }
|
118
87
|
end
|
119
88
|
|
120
|
-
|
121
|
-
|
122
|
-
|
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
|
+
self.class.get(path, :headers => { "Accept" => 'text/uri-list' }).split("\n").compact
|
146
|
+
end
|
147
|
+
|
148
|
+
# @param [OCCI::Core::Entity] entity
|
149
|
+
# @return [URI] location of the entity
|
150
|
+
def create(entity)
|
151
|
+
raise "#{entity} not an entity" unless entity.kind_of? OCCI::Core::Entity
|
152
|
+
entity.check(model)
|
153
|
+
kind = @model.get_by_id(entity.kind)
|
154
|
+
raise "no kind found for #{entity}" unless kind
|
155
|
+
location = @model.get_by_id(entity.kind).location
|
156
|
+
collection = OCCI::Collection.new
|
157
|
+
collection.resources << entity if entity.kind_of? OCCI::Core::Resource
|
158
|
+
collection.links << entity if entity.kind_of? OCCI::Core::Link
|
159
|
+
post location, collection
|
160
|
+
end
|
161
|
+
|
162
|
+
# @param [String] path
|
163
|
+
# @param [OCCI::Collection] filter
|
164
|
+
# @return [OCCI::Collection]
|
165
|
+
def get(path='', filter=nil)
|
166
|
+
path = path.split('#').last + '/' if path.start_with? 'http://'
|
167
|
+
path = path.reverse.chomp('/').reverse
|
168
|
+
response = if filter
|
169
|
+
categories = filter.categories.collect { |category| category.to_text }.join(',')
|
170
|
+
attributes = filter.entities.collect { |entity| entity.attributes.combine.collect { |k, v| k + '=' + v } }.join(',')
|
171
|
+
self.class.get(@endpoint + path,
|
172
|
+
:headers => { 'Accept' => 'application/occi+json,text/plain;q=0.5',
|
173
|
+
'Content-Type' => 'text/occi',
|
174
|
+
'Category' => categories,
|
175
|
+
'X-OCCI-Attributes' => attributes })
|
176
|
+
else
|
177
|
+
self.class.get(@endpoint + path)
|
178
|
+
end
|
179
|
+
|
180
|
+
response_message response
|
181
|
+
|
182
|
+
kind = @model.get_by_location path if @model
|
183
|
+
kind ? entity_type = kind.entity_type : entity_type = nil
|
184
|
+
_, collection = OCCI::Parser.parse(response.content_type, response.body, path.include?('/-/'), entity_type)
|
185
|
+
collection
|
186
|
+
end
|
187
|
+
|
188
|
+
# @param [String] path
|
189
|
+
# @param [OCCI::Collection] collection
|
190
|
+
# @return [URI] if an entity has been created its location is returned
|
191
|
+
def post(path, collection)
|
192
|
+
path = path.reverse.chomp('/').reverse
|
193
|
+
response = if @media_type == 'application/occi+json'
|
194
|
+
self.class.post(@endpoint + path,
|
195
|
+
:body => collection.to_json,
|
196
|
+
:headers => { 'Accept' => 'text/uri-list', 'Content-Type' => 'application/occi+json' })
|
197
|
+
else
|
198
|
+
self.class.post(@endpoint + path,
|
199
|
+
:body => collection.to_text,
|
200
|
+
:headers => { 'Accept' => 'text/uri-list', 'Content-Type' => 'text/plain' })
|
201
|
+
end
|
123
202
|
|
124
|
-
|
125
|
-
self.class.delete(@endpoint + @network.location + id)
|
126
|
-
end
|
203
|
+
response_message response
|
127
204
|
|
128
|
-
|
129
|
-
self.class.delete(@endpoint + @network.location)
|
205
|
+
URI.parse(response.body)
|
130
206
|
end
|
131
207
|
|
132
|
-
|
133
|
-
|
134
|
-
|
208
|
+
# @param [String] path
|
209
|
+
# @param [OCCI::Collection] collection
|
210
|
+
# @return [OCCI::Collection]
|
211
|
+
def put(path, collection)
|
212
|
+
path = path.reverse.chomp('/').reverse
|
213
|
+
response = if @media_type == 'application/occi+json'
|
214
|
+
self.class.post(@endpoint + path, :body => collection.to_json, :headers => { 'Accept' => 'application/occi+json,text/plain;q=0.5', 'Content-Type' => 'application/occi+json' })
|
215
|
+
else
|
216
|
+
self.class.post(@endpoint + path, { :body => collection.to_text, :headers => { 'Accept' => 'application/occi+json,text/plain;q=0.5', 'Content-Type' => 'text/plain' } })
|
217
|
+
end
|
135
218
|
|
136
|
-
|
137
|
-
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' }
|
138
|
-
end
|
219
|
+
response_message response
|
139
220
|
|
140
|
-
|
141
|
-
|
142
|
-
[categories].flatten.each do |category|
|
143
|
-
category = @model.get_by_id(category) if category.kind_of? String
|
144
|
-
attributes.merge! category.attributes.combine_with_defaults
|
145
|
-
end
|
146
|
-
attributes
|
221
|
+
_, collection = OCCI::Parser.parse(response.content_type, response.body)
|
222
|
+
collection
|
147
223
|
end
|
148
224
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
225
|
+
# @param [String] path
|
226
|
+
# @param [OCCI::Collection] collection
|
227
|
+
# @return [true,false]
|
228
|
+
def delete(path, collection=nil)
|
229
|
+
path = path.reverse.chomp('/').reverse
|
230
|
+
response = self.class.delete(@endpoint + path)
|
231
|
+
response_message response
|
232
|
+
false unless response.code.between? 200, 300
|
156
233
|
end
|
157
234
|
|
158
235
|
private
|
159
236
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
237
|
+
# @return [String]
|
238
|
+
def select_media_type
|
239
|
+
media_types = self.class.head(@endpoint).headers['accept']
|
240
|
+
OCCI::Log.debug("Available media types: #{media_types}")
|
241
|
+
@media_type = case media_types
|
242
|
+
when /application\/occi\+json/
|
243
|
+
'application/occi+json'
|
244
|
+
else
|
245
|
+
'text/plain'
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
# @param [Integer] code
|
250
|
+
# @return [String] HTTP status reason
|
251
|
+
def reason_phrase(code)
|
252
|
+
hash = {
|
253
|
+
"100" => "Continue",
|
254
|
+
"101" => "Switching Protocols",
|
255
|
+
"200" => "OK",
|
256
|
+
"201" => "Created",
|
257
|
+
"202" => "Accepted",
|
258
|
+
"203" => "Non-Authoritative Information",
|
259
|
+
"204" => "No Content",
|
260
|
+
"205" => "Reset Content",
|
261
|
+
"206" => "Partial Content",
|
262
|
+
"300" => "Multiple Choices",
|
263
|
+
"301" => "Moved Permanently",
|
264
|
+
"302" => "Found",
|
265
|
+
"303" => "See Other",
|
266
|
+
"304" => "Not Modified",
|
267
|
+
"305" => "Use Proxy",
|
268
|
+
"307" => "Temporary Redirect",
|
269
|
+
"400" => "Bad Request",
|
270
|
+
"401" => "Unauthorized",
|
271
|
+
"402" => "Payment Required",
|
272
|
+
"403" => "Forbidden",
|
273
|
+
"404" => "Not Found",
|
274
|
+
"405" => "Method Not Allowed",
|
275
|
+
"406" => "Not Acceptable",
|
276
|
+
"407" => "Proxy Authentication Required",
|
277
|
+
"408" => "Request Time-out",
|
278
|
+
"409" => "Conflict",
|
279
|
+
"410" => "Gone",
|
280
|
+
"411" => "Length Required",
|
281
|
+
"412" => "Precondition Failed",
|
282
|
+
"413" => "Request Entity Too Large",
|
283
|
+
"414" => "Request-URI Too Large",
|
284
|
+
"415" => "Unsupported Media Type",
|
285
|
+
"416" => "Requested range not satisfiable",
|
286
|
+
"417" => "Expectation Failed",
|
287
|
+
"500" => "Internal Server Error",
|
288
|
+
"501" => "Not Implemented",
|
289
|
+
"502" => "Bad Gateway",
|
290
|
+
"503" => "Service Unavailable",
|
291
|
+
"504" => "Gateway Time-out",
|
292
|
+
"505" => "HTTP Version not supported"
|
293
|
+
}
|
294
|
+
hash[code.to_s]
|
295
|
+
end
|
296
|
+
|
297
|
+
# @param [HTTParty::Response] response
|
298
|
+
def response_message(response)
|
299
|
+
if defined?(IRB)
|
300
|
+
puts 'HTTP Response status: ' + response.code.to_s + ' ' + reason_phrase(response.code)
|
301
|
+
raise response.request.http_method.to_s + ' failed ' unless response.code.between? 200, 300
|
176
302
|
end
|
177
303
|
end
|
178
304
|
|
179
|
-
def post(path, collection)
|
180
|
-
accept = self.class.head(path).headers['accept']
|
181
|
-
if accept.include? 'application/occi+json'
|
182
|
-
self.class.post(path, :body => collection.to_json)
|
183
|
-
else
|
184
|
-
self.class.post(path, { :body => collection.to_text, :headers => { 'Accept' => 'text/plain', 'Content-Type' => 'text/plain' } })
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
def put(path, collection)
|
189
|
-
accept = self.class.head(path).headers['accept']
|
190
|
-
if accept.include? 'application/occi+json'
|
191
|
-
self.class.put(path, :body => collection.to_json)
|
192
|
-
else
|
193
|
-
self.class.put(path, { :body => collection.to_text, :headers => { 'Accept' => 'text/plain', 'Content-Type' => 'text/plain' } })
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
def delete(path, collection)
|
198
|
-
accept = self.class.head(path).headers['accept']
|
199
|
-
self.class.delete(path)
|
200
|
-
end
|
201
|
-
|
202
305
|
end
|
203
306
|
end
|