occi-api 4.0.0.alpha.1
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/.gitignore +15 -0
- data/.rspec +1 -0
- data/.travis.yml +43 -0
- data/.yardopts +1 -0
- data/AUTHORS +9 -0
- data/Gemfile +16 -0
- data/LICENSE +13 -0
- data/README.md +344 -0
- data/Rakefile +37 -0
- data/examples/dsl_example.rb +167 -0
- data/examples/x509auth_example.rb +161 -0
- data/ext/mkrf_conf.rb +34 -0
- data/features/cassettes/Create_an_OCCI_Resource/_http_http___141_5_99_69__text_plain_201_.yml +288 -0
- data/features/cassettes/Delete_an_OCCI_Resource/_http_http___141_5_99_69__text_plain_201_.yml +288 -0
- data/features/cassettes/Discovery_Interface/Retrieving_all_OCCI_Categories_supported_by_the_OCCI_Server/_http_http___141_5_99_69__application_json_200_.yml +333 -0
- data/features/cassettes/Discovery_Interface/Retrieving_all_OCCI_Categories_supported_by_the_OCCI_Server/_http_http___141_5_99_69__text_plain_200_.yml +529 -0
- data/features/cassettes/Discovery_Interface/Retrieving_all_OCCI_Categories_supported_by_the_OCCI_Server/_http_http___141_5_99_69__text_plain_200_action_.yml +288 -0
- data/features/cassettes/Miscellaneous_operation_on_an_OCCI_Resource/_http_http___141_5_99_69__text_plain_201_.yml +288 -0
- data/features/cassettes/Read_an_OCCI_Resource/_http_http___141_5_99_69__text_plain_201_.yml +288 -0
- data/features/cassettes/Update_an_OCCI_Resource/_http_http___141_5_99_69__text_plain_201_.yml +288 -0
- data/features/common/step_definitions/common_steps.rb +32 -0
- data/features/occi/core/create/create.feature +18 -0
- data/features/occi/core/create/step_definitions/create_steps.rb +0 -0
- data/features/occi/core/delete/delete.feature +18 -0
- data/features/occi/core/delete/step_definitions/delete_steps.rb +0 -0
- data/features/occi/core/discovery_interface/discovery_interface.feature +37 -0
- data/features/occi/core/discovery_interface/step_definitions/discovery_interface_steps.rb +19 -0
- data/features/occi/core/miscellaneous/miscellaneous.feature +18 -0
- data/features/occi/core/miscellaneous/step_definitions/miscellaneous_steps.rb +0 -0
- data/features/occi/core/read/read.feature +18 -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 +18 -0
- data/features/occi/infrastructure/create/create.feature +18 -0
- data/features/occi/infrastructure/create/step_definitions/create_steps.rb +0 -0
- data/features/support/env.rb +16 -0
- data/lib/occi/api/client/client_amqp.rb +766 -0
- data/lib/occi/api/client/client_base.rb +689 -0
- data/lib/occi/api/client/client_http.rb +541 -0
- data/lib/occi/api/client/errors/authn_error.rb +7 -0
- data/lib/occi/api/client/errors.rb +1 -0
- data/lib/occi/api/client/http/authn_plugins/base.rb +27 -0
- data/lib/occi/api/client/http/authn_plugins/basic.rb +22 -0
- data/lib/occi/api/client/http/authn_plugins/digest.rb +22 -0
- data/lib/occi/api/client/http/authn_plugins/dummy.rb +13 -0
- data/lib/occi/api/client/http/authn_plugins/keystone.rb +61 -0
- data/lib/occi/api/client/http/authn_plugins/x509.rb +46 -0
- data/lib/occi/api/client/http/authn_plugins.rb +6 -0
- data/lib/occi/api/client/http/authn_utils.rb +87 -0
- data/lib/occi/api/client/http/httparty_fix.rb +53 -0
- data/lib/occi/api/client/http/net_http_fix.rb +21 -0
- data/lib/occi/api/dsl.rb +146 -0
- data/lib/occi/api/version.rb +5 -0
- data/lib/occi-api.rb +14 -0
- data/occi-api.gemspec +38 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/creates_a_new_compute_resource.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/creates_a_new_network_resource.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/creates_a_new_storage_resource.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/deletes_a_compute_resource.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/deletes_a_network_resource.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/deletes_a_storage_resource.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/deploys_an_instance_based_on_OVF_OVA_file.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/describes_compute_resources.yml +368 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/describes_network_resources.yml +370 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/describes_storage_resources.yml +430 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/establishes_connection.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/finds_and_describes_scoped_os_tpl_mixin.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/finds_and_describes_scoped_resource_tpl_mixin.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/finds_and_describes_unscoped_mixin.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/instantiates_a_compute_resource_using_type_identifier.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/instantiates_a_compute_resource_using_type_name.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/instantiates_a_network_resource_using_type_identifier.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/instantiates_a_network_resource_using_type_name.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/instantiates_a_storage_resource_using_type_identifier.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/instantiates_a_storage_resource_using_type_name.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/lists_all_available_entity_type_identifiers.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/lists_all_available_entity_types.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/lists_all_available_link_type_identifiers.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/lists_all_available_link_types.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/lists_all_available_mixin_type_identifiers.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/lists_all_available_mixin_types.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/lists_all_available_mixins.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/lists_all_available_resource_type_identifiers.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/lists_all_available_resource_types.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/lists_compute_resources.yml +308 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/lists_network_resources.yml +308 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/lists_os_tpl_mixins.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/lists_resource_tpl_mixins.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/lists_storage_resources.yml +310 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/refreshes_its_model.yml +485 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/triggers_an_action_on_a_compute_resource.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/triggers_an_action_on_a_network_resource.yml +266 -0
- data/spec/cassettes/Occi_Api_Client_ClientHttp/using_media_type_text_plain/triggers_an_action_on_a_storage_resource.yml +266 -0
- data/spec/occi/api/client/client_amqp_spec.rb +158 -0
- data/spec/occi/api/client/client_http_spec.rb +292 -0
- data/spec/occi/api/client/http/authn_utils_spec.rb +55 -0
- data/spec/occi/api/client/http/httparty_fix_spec.rb +0 -0
- data/spec/occi/api/client/http/net_http_fix_spec.rb +0 -0
- data/spec/occi/api/client/http/rocci-cred-cert.pem +3 -0
- data/spec/occi/api/client/http/rocci-cred-key-jruby.pem +3 -0
- data/spec/occi/api/client/http/rocci-cred-key.pem +3 -0
- data/spec/occi/api/client/http/rocci-cred.p12 +0 -0
- data/spec/occi/api/dsl_spec.rb +21 -0
- data/spec/spec_helper.rb +38 -0
- metadata +379 -0
|
@@ -0,0 +1,689 @@
|
|
|
1
|
+
module Occi
|
|
2
|
+
module Api
|
|
3
|
+
module Client
|
|
4
|
+
|
|
5
|
+
class ClientBase
|
|
6
|
+
|
|
7
|
+
# a few attributes which should be visible outside the client
|
|
8
|
+
attr_reader :endpoint
|
|
9
|
+
attr_reader :auth_options
|
|
10
|
+
attr_reader :media_type
|
|
11
|
+
attr_reader :connected
|
|
12
|
+
attr_reader :model
|
|
13
|
+
attr_reader :logger
|
|
14
|
+
attr_reader :last_response
|
|
15
|
+
attr_reader :options
|
|
16
|
+
|
|
17
|
+
def initialize(options = {})
|
|
18
|
+
defaults = {
|
|
19
|
+
:endpoint => "http://localhost:3300/",
|
|
20
|
+
:auth => {:type => "none"},
|
|
21
|
+
:log => {:out => STDERR, :level => Occi::Log::WARN, :logger => nil},
|
|
22
|
+
:auto_connect => true,
|
|
23
|
+
:media_type => nil
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
options = options.marshal_dump if options.is_a? OpenStruct
|
|
27
|
+
@options = defaults.merge options
|
|
28
|
+
|
|
29
|
+
# set Occi::Log
|
|
30
|
+
set_logger @options[:log]
|
|
31
|
+
|
|
32
|
+
# check the validity and canonize the endpoint URI
|
|
33
|
+
set_endpoint @options[:endpoint]
|
|
34
|
+
|
|
35
|
+
# pass auth options
|
|
36
|
+
set_auth @options[:auth]
|
|
37
|
+
|
|
38
|
+
# verify authN before attempting actual
|
|
39
|
+
# message exchange with the server; this
|
|
40
|
+
# is necessary because of OCCI-OS and its
|
|
41
|
+
# redirect to OS Keystone
|
|
42
|
+
preauthenticate
|
|
43
|
+
|
|
44
|
+
# set accepted media types
|
|
45
|
+
set_media_type @options[:media_type]
|
|
46
|
+
|
|
47
|
+
@connected = false
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Issues necessary connecting operations on connection-oriented
|
|
51
|
+
# clients. Stateless clients (such as ClientHttp) should use
|
|
52
|
+
# the auto_connect option during instantiation.
|
|
53
|
+
#
|
|
54
|
+
# @example
|
|
55
|
+
# client.connect # => true
|
|
56
|
+
#
|
|
57
|
+
# @param [Boolean] force re-connect on already connected client
|
|
58
|
+
# @return [Boolean] true on successful connect
|
|
59
|
+
def connect(force = false)
|
|
60
|
+
raise "Client already connected!" if @connected && !force
|
|
61
|
+
@connected = true
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
##############################################################################
|
|
65
|
+
######## STUBS START
|
|
66
|
+
##############################################################################
|
|
67
|
+
|
|
68
|
+
# Retrieves available resources represented by resource locations (URIs).
|
|
69
|
+
# If no type identifier is specified, all available resource are listed.
|
|
70
|
+
# Type identifier can be specified in its shortened format (e.g. "compute",
|
|
71
|
+
# "storage", "network").
|
|
72
|
+
#
|
|
73
|
+
# @example
|
|
74
|
+
# client.list
|
|
75
|
+
# # => [ "http://localhost:3300/compute/jh425jhj3h413-7dj29d7djd9e3-djh2jh4j4j",
|
|
76
|
+
# # "http://localhost:3300/network/kh425jhj3h413-7dj29d7djd9e3-djh2jh4j4j",
|
|
77
|
+
# # "http://localhost:3300/storage/lh425jhj3h413-7dj29d7djd9e3-djh2jh4j4j" ]
|
|
78
|
+
# client.list "compute"
|
|
79
|
+
# # => [ "http://localhost:3300/compute/jh425jhj3h413-7dj29d7djd9e3-djh2jh4j4j" ]
|
|
80
|
+
# client.list "http://schemas.ogf.org/occi/infrastructure#compute"
|
|
81
|
+
# # => [ "http://localhost:3300/compute/jh425jhj3h413-7dj29d7djd9e3-djh2jh4j4j" ]
|
|
82
|
+
#
|
|
83
|
+
# @param [String] resource type identifier or just type name
|
|
84
|
+
# @return [Array<String>] list of links
|
|
85
|
+
def list(resource_type_identifier=nil); end
|
|
86
|
+
|
|
87
|
+
# Retrieves descriptions for available resources specified by a type
|
|
88
|
+
# identifier or resource location. If no type identifier or location
|
|
89
|
+
# is specified, all available resources in all available resource types
|
|
90
|
+
# will be described.
|
|
91
|
+
#
|
|
92
|
+
# @example
|
|
93
|
+
# client.describe
|
|
94
|
+
# # => [#<Occi::Collection>, #<Occi::Collection>, #<Occi::Collection>]
|
|
95
|
+
# client.describe "compute"
|
|
96
|
+
# # => [#<Occi::Collection>, #<Occi::Collection>, #<Occi::Collection>]
|
|
97
|
+
# client.describe "http://schemas.ogf.org/occi/infrastructure#compute"
|
|
98
|
+
# # => [#<Occi::Collection>, #<Occi::Collection>, #<Occi::Collection>]
|
|
99
|
+
# client.describe "http://localhost:3300/compute/j5hk1234jk2524-2j3j2k34jjh234-adfaf1234"
|
|
100
|
+
# # => [#<Occi::Collection>]
|
|
101
|
+
#
|
|
102
|
+
# @param [String] resource type identifier, type name or resource location
|
|
103
|
+
# @return [Array<Occi::Collection>] list of resource descriptions
|
|
104
|
+
def describe(resource_type_identifier=nil); end
|
|
105
|
+
|
|
106
|
+
# Creates a new resource on the server. Resource must be provided
|
|
107
|
+
# as an instance of Occi::Core::Entity, e.g. instantiated using
|
|
108
|
+
# the get_resource method.
|
|
109
|
+
#
|
|
110
|
+
# @example
|
|
111
|
+
# res = client.get_resource "compute"
|
|
112
|
+
#
|
|
113
|
+
# res.title = "MyComputeResource1"
|
|
114
|
+
# res.mixins << client.find_mixin('small', "resource_tpl")
|
|
115
|
+
# res.mixins << client.find_mixin('debian6', "os_tpl")
|
|
116
|
+
#
|
|
117
|
+
# client.create res # => "http://localhost:3300/compute/df7698...f987fa"
|
|
118
|
+
#
|
|
119
|
+
# @param [Occi::Core::Entity] resource to be created on the server
|
|
120
|
+
# @return [String] URI of the new resource
|
|
121
|
+
def create(entity); end
|
|
122
|
+
|
|
123
|
+
# Deploys a compute resource based on an OVF/OVA descriptor available
|
|
124
|
+
# on a local file system.
|
|
125
|
+
#
|
|
126
|
+
# @example
|
|
127
|
+
# client.deploy "~/MyVMs/rOcciVM.ovf" # => "http://localhost:3300/compute/343423...42njhdafa"
|
|
128
|
+
#
|
|
129
|
+
# @param [String] location of an OVF/OVA file
|
|
130
|
+
# @return [String] URI of the new resource
|
|
131
|
+
def deploy(location); end
|
|
132
|
+
|
|
133
|
+
# Deploys a compute resource based on an OVF descriptor available
|
|
134
|
+
# directly as a String.
|
|
135
|
+
#
|
|
136
|
+
# @example
|
|
137
|
+
# client.deploy_ovf "OVF DESCRIPTOR HERE" # => "http://localhost:3300/compute/343423...42njhdafa"
|
|
138
|
+
#
|
|
139
|
+
# @param [String] OVF descriptor (e.g., already read from a file or generated)
|
|
140
|
+
# @return [String] URI of the new resource
|
|
141
|
+
def deploy_ovf(descriptor); end
|
|
142
|
+
|
|
143
|
+
# Deploys a compute resource based on an OVA descriptor available
|
|
144
|
+
# directly as a String.
|
|
145
|
+
#
|
|
146
|
+
# @example
|
|
147
|
+
# client.deploy_ova "OVA DESCRIPTOR HERE" # => "http://localhost:3300/compute/343423...42njhdafa"
|
|
148
|
+
#
|
|
149
|
+
# @param [String] OVA descriptor (e.g., already read from a file or generated)
|
|
150
|
+
# @return [String] URI of the new resource
|
|
151
|
+
def deploy_ova(descriptor); end
|
|
152
|
+
|
|
153
|
+
# Deletes a resource or all resource of a certain resource type
|
|
154
|
+
# from the server.
|
|
155
|
+
#
|
|
156
|
+
# @example
|
|
157
|
+
# client.delete "compute" # => true
|
|
158
|
+
# client.delete "http://schemas.ogf.org/occi/infrastructure#compute" # => true
|
|
159
|
+
# client.delete "http://localhost:3300/compute/245j42594...98s9df8s9f" # => true
|
|
160
|
+
#
|
|
161
|
+
# @param [String] resource type identifier, type name or location
|
|
162
|
+
# @return [Boolean] status
|
|
163
|
+
def delete(resource_type_identifier); end
|
|
164
|
+
|
|
165
|
+
# Triggers given action on a specific resource.
|
|
166
|
+
#
|
|
167
|
+
# @example
|
|
168
|
+
# TODO: add examples
|
|
169
|
+
#
|
|
170
|
+
# @param [String] resource location
|
|
171
|
+
# @param [String] type of action
|
|
172
|
+
# @return [String] resource location
|
|
173
|
+
def trigger(resource_type_identifier, action); end
|
|
174
|
+
|
|
175
|
+
# Refreshes the Occi::Model used inside the client. Useful for
|
|
176
|
+
# updating the model without creating a new instance or
|
|
177
|
+
# reconnecting. Saves a lot of time in an interactive mode.
|
|
178
|
+
#
|
|
179
|
+
# @example
|
|
180
|
+
# client.refresh
|
|
181
|
+
def refresh; end
|
|
182
|
+
|
|
183
|
+
##############################################################################
|
|
184
|
+
######## STUBS END
|
|
185
|
+
##############################################################################
|
|
186
|
+
|
|
187
|
+
# Creates a new resource instance, resource should be specified
|
|
188
|
+
# by its name or identifier.
|
|
189
|
+
#
|
|
190
|
+
# @example
|
|
191
|
+
# client.get_resource "compute" # => Occi::Core::Resource
|
|
192
|
+
# client.get_resource "storage" # => Occi::Core::Resource
|
|
193
|
+
# client.get_resource "http://schemas.ogf.org/occi/infrastructure#network"
|
|
194
|
+
# # => Occi::Core::Resource
|
|
195
|
+
#
|
|
196
|
+
# @param [String] resource name or resource identifier
|
|
197
|
+
# @return [Occi::Core::Resource] new resource instance
|
|
198
|
+
def get_resource(resource_type)
|
|
199
|
+
|
|
200
|
+
Occi::Log.debug("Instantiating #{resource_type} ...")
|
|
201
|
+
|
|
202
|
+
type_id = nil
|
|
203
|
+
if @model.get_by_id resource_type
|
|
204
|
+
# we got a resource type identifier
|
|
205
|
+
type_id = resource_type
|
|
206
|
+
else
|
|
207
|
+
# we got a resource type name
|
|
208
|
+
type_ids = @model.kinds.select { |kind| kind.term == resource_type }
|
|
209
|
+
type_id = type_ids.first.type_identifier if type_ids.any?
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
raise "Unknown resource type! [#{resource_type}]" unless type_id
|
|
213
|
+
|
|
214
|
+
Occi::Core::Resource.new type_id
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# Retrieves all entity type identifiers related to a given type identifier
|
|
218
|
+
#
|
|
219
|
+
# @example
|
|
220
|
+
# client.get_entity_type_identifiers_related_to 'network'
|
|
221
|
+
# # => [ "http://schemas.ogf.org/occi/infrastructure#network",
|
|
222
|
+
# # "http://schemas.ogf.org/occi/infrastructure#ipnetwork" ]
|
|
223
|
+
#
|
|
224
|
+
# @param [String] type_identifier
|
|
225
|
+
# @return [Array<String>] list of available entity type identifiers related to
|
|
226
|
+
# given type identifier in a human-readable format
|
|
227
|
+
def get_entity_types_related_to(type_identifier)
|
|
228
|
+
Occi::Log.debug("Getting entity type identifiers related to #{type_identifier}")
|
|
229
|
+
collection = @model.get type_identifier
|
|
230
|
+
collection.kinds.collect { |kind| kind.type_identifier }
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
# Retrieves all available entity types.
|
|
234
|
+
#
|
|
235
|
+
# @example
|
|
236
|
+
# client.get_entity_types # => [ "entity", "resource", "link" ]
|
|
237
|
+
#
|
|
238
|
+
# @return [Array<String>] list of available entity types in a human-readable format
|
|
239
|
+
def get_entity_types
|
|
240
|
+
Occi::Log.debug("Getting entity types ...")
|
|
241
|
+
@model.kinds.collect { |kind| kind.term }
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
# Retrieves all available entity type identifiers.
|
|
245
|
+
#
|
|
246
|
+
# @example
|
|
247
|
+
# client.get_entity_type_identifiers
|
|
248
|
+
# # => [ "http://schemas.ogf.org/occi/core#entity",
|
|
249
|
+
# # "http://schemas.ogf.org/occi/core#resource",
|
|
250
|
+
# # "http://schemas.ogf.org/occi/core#link" ]
|
|
251
|
+
#
|
|
252
|
+
# @return [Array<String>] list of available entity types in a OCCI ID format
|
|
253
|
+
def get_entity_type_identifiers
|
|
254
|
+
get_entity_types_related_to Occi::Core::Entity.kind.type_identifier
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
# Retrieves all available resource types.
|
|
258
|
+
#
|
|
259
|
+
# @example
|
|
260
|
+
# client.get_resource_types # => [ "compute", "storage", "network" ]
|
|
261
|
+
#
|
|
262
|
+
# @return [Array<String>] list of available resource types in a human-readable format
|
|
263
|
+
def get_resource_types
|
|
264
|
+
Occi::Log.debug("Getting resource types ...")
|
|
265
|
+
collection = @model.get Occi::Core::Resource.kind
|
|
266
|
+
collection.kinds.collect { |kind| kind.term }
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
# Retrieves all available resource type identifiers.
|
|
270
|
+
#
|
|
271
|
+
# @example
|
|
272
|
+
# client.get_resource_type_identifiers
|
|
273
|
+
# # => [ "http://schemas.ogf.org/occi/infrastructure#compute",
|
|
274
|
+
# # "http://schemas.ogf.org/occi/infrastructure#storage",
|
|
275
|
+
# # "http://schemas.ogf.org/occi/infrastructure#network" ]
|
|
276
|
+
#
|
|
277
|
+
# @return [Array<String>] list of available resource types in a Occi ID format
|
|
278
|
+
def get_resource_type_identifiers
|
|
279
|
+
get_entity_types_related_to Occi::Core::Resource.kind.type_identifier
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
# Retrieves all available link types.
|
|
283
|
+
#
|
|
284
|
+
# @example
|
|
285
|
+
# client.get_link_types # => [ "storagelink", "networkinterface" ]
|
|
286
|
+
#
|
|
287
|
+
# @return [Array<String>] list of available link types in a human-readable format
|
|
288
|
+
def get_link_types
|
|
289
|
+
Occi::Log.debug("Getting link types ...")
|
|
290
|
+
collection = @model.get Occi::Core::Link.kind
|
|
291
|
+
collection.kinds.collect { |kind| kind.term }
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
# Retrieves all available link type identifiers.
|
|
295
|
+
#
|
|
296
|
+
# @example
|
|
297
|
+
# client.get_link_type_identifiers
|
|
298
|
+
# # => [ "http://schemas.ogf.org/occi/infrastructure#storagelink",
|
|
299
|
+
# # "http://schemas.ogf.org/occi/infrastructure#networkinterface" ]
|
|
300
|
+
#
|
|
301
|
+
# @return [Array<String>] list of available link types in a OCCI ID format
|
|
302
|
+
def get_link_type_identifiers
|
|
303
|
+
get_entity_types_related_to Occi::Core::Link.kind.type_identifier
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
# Looks up a mixin using its name and, optionally, a type as well.
|
|
307
|
+
# Will return mixin's full location (a link) or a description.
|
|
308
|
+
#
|
|
309
|
+
# @example
|
|
310
|
+
# client.find_mixin "debian6"
|
|
311
|
+
# # => "http://my.occi.service/occi/infrastructure/os_tpl#debian6"
|
|
312
|
+
# client.find_mixin "debian6", "os_tpl", true
|
|
313
|
+
# # => #<Occi::Collection>
|
|
314
|
+
# client.find_mixin "large", "resource_tpl"
|
|
315
|
+
# # => "http://my.occi.service/occi/infrastructure/resource_tpl#large"
|
|
316
|
+
# client.find_mixin "debian6", "resource_tpl" # => nil
|
|
317
|
+
#
|
|
318
|
+
# @param [String] name of the mixin
|
|
319
|
+
# @param [String] type of the mixin
|
|
320
|
+
# @param [Boolean] should we describe the mixin or return its link?
|
|
321
|
+
# @return [String, Occi::Collection, nil] link, mixin description or nothing found
|
|
322
|
+
def find_mixin(name, type = nil, describe = false)
|
|
323
|
+
|
|
324
|
+
Occi::Log.debug("Looking for mixin #{name} + #{type} + #{describe}")
|
|
325
|
+
|
|
326
|
+
# is type valid?
|
|
327
|
+
raise "Unknown mixin type! [#{type}]" if type && !@mixins.has_key?(type.to_sym)
|
|
328
|
+
|
|
329
|
+
# TODO: extend this code to support multiple matches and regex filters
|
|
330
|
+
# should we look for links or descriptions?
|
|
331
|
+
if describe
|
|
332
|
+
# we are looking for descriptions
|
|
333
|
+
find_mixin_describe name, type
|
|
334
|
+
else
|
|
335
|
+
# we are looking for links
|
|
336
|
+
find_mixin_list name, type
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
# Looks up a mixin using its name and, optionally, a type as well.
|
|
341
|
+
# Will return mixin's full description.
|
|
342
|
+
#
|
|
343
|
+
# @example
|
|
344
|
+
# client.find_mixin "debian6"
|
|
345
|
+
# # => #<Occi::Collection>
|
|
346
|
+
# client.find_mixin "debian6", "os_tpl"
|
|
347
|
+
# # => #<Occi::Collection>
|
|
348
|
+
# client.find_mixin "large", "resource_tpl"
|
|
349
|
+
# # => #<Occi::Collection>
|
|
350
|
+
# client.find_mixin "debian6", "resource_tpl" # => nil
|
|
351
|
+
#
|
|
352
|
+
# @param [String] name of the mixin
|
|
353
|
+
# @param [String] type of the mixin
|
|
354
|
+
# @return [Occi::Collection, nil] mixin description or nothing found
|
|
355
|
+
def find_mixin_describe(name, type = nil)
|
|
356
|
+
found_ary = []
|
|
357
|
+
|
|
358
|
+
if type
|
|
359
|
+
# get the first match from either os_tpls or resource_tpls
|
|
360
|
+
case type
|
|
361
|
+
when "os_tpl"
|
|
362
|
+
found_ary = get_os_templates.select { |mixin| mixin.term == name }
|
|
363
|
+
when "resource_tpl"
|
|
364
|
+
found_ary = get_resource_templates.select { |template| template.term == name }
|
|
365
|
+
else
|
|
366
|
+
# TODO: should raise an Error?
|
|
367
|
+
end
|
|
368
|
+
else
|
|
369
|
+
# try in os_tpls first
|
|
370
|
+
found_ary = get_os_templates.select { |os| os.term == name }
|
|
371
|
+
|
|
372
|
+
# then try in resource_tpls
|
|
373
|
+
|
|
374
|
+
found_ary = get_resource_templates.select {
|
|
375
|
+
|template| template.term == name
|
|
376
|
+
} unless found_ary.any?
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
found_ary.any? ? found_ary.first : nil
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
# Looks up a mixin using its name and, optionally, a type as well.
|
|
383
|
+
# Will return mixin's full location.
|
|
384
|
+
#
|
|
385
|
+
# @example
|
|
386
|
+
# client.find_mixin "debian6"
|
|
387
|
+
# # => "http://my.occi.service/occi/infrastructure/os_tpl#debian6"
|
|
388
|
+
# client.find_mixin "debian6", "os_tpl"
|
|
389
|
+
# # => "http://my.occi.service/occi/infrastructure/os_tpl#debian6"
|
|
390
|
+
# client.find_mixin "large", "resource_tpl"
|
|
391
|
+
# # => "http://my.occi.service/occi/infrastructure/resource_tpl#large"
|
|
392
|
+
# client.find_mixin "debian6", "resource_tpl" # => nil
|
|
393
|
+
#
|
|
394
|
+
# @param [String] name of the mixin
|
|
395
|
+
# @param [String] type of the mixin
|
|
396
|
+
# @return [String, nil] link or nothing found
|
|
397
|
+
def find_mixin_list(name, type = nil)
|
|
398
|
+
# prefix mixin name with '#' to simplify the search
|
|
399
|
+
mxns = []
|
|
400
|
+
name_rev = "##{name}".reverse
|
|
401
|
+
|
|
402
|
+
if type
|
|
403
|
+
# return the first match with the selected type
|
|
404
|
+
mxns = @mixins[type.to_sym].select {
|
|
405
|
+
|mixin| mixin.to_s.reverse.start_with? name_rev
|
|
406
|
+
}
|
|
407
|
+
else
|
|
408
|
+
# there is no type preference, return first global match
|
|
409
|
+
mxns = @mixins.flatten(2).select {
|
|
410
|
+
|mixin| mixin.to_s.reverse.start_with? name_rev
|
|
411
|
+
}
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
mxns.any? ? mxns.first : nil
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
# Retrieves available mixins of a specified type or all available
|
|
418
|
+
# mixins if the type wasn't specified. Mixins are returned in the
|
|
419
|
+
# form of mixin identifiers.
|
|
420
|
+
#
|
|
421
|
+
# @example
|
|
422
|
+
# client.get_mixins
|
|
423
|
+
# # => ["http://my.occi.service/occi/infrastructure/os_tpl#debian6",
|
|
424
|
+
# # "http://my.occi.service/occi/infrastructure/resource_tpl#small"]
|
|
425
|
+
# client.get_mixins "os_tpl"
|
|
426
|
+
# # => ["http://my.occi.service/occi/infrastructure/os_tpl#debian6"]
|
|
427
|
+
# client.get_mixins "resource_tpl"
|
|
428
|
+
# # => ["http://my.occi.service/occi/infrastructure/resource_tpl#small"]
|
|
429
|
+
#
|
|
430
|
+
# @param [String] type of mixins
|
|
431
|
+
# @return [Array<String>] list of available mixins
|
|
432
|
+
def get_mixins(type = nil)
|
|
433
|
+
if type
|
|
434
|
+
# is type valid?
|
|
435
|
+
raise "Unknown mixin type! #{type}" unless @mixins.has_key? type.to_sym
|
|
436
|
+
|
|
437
|
+
# return mixin of the selected type
|
|
438
|
+
@mixins[type.to_sym]
|
|
439
|
+
else
|
|
440
|
+
# we did not get a type, return all mixins
|
|
441
|
+
mixins = []
|
|
442
|
+
|
|
443
|
+
# flatten the hash and remove its keys
|
|
444
|
+
get_mixin_types.each do |ltype|
|
|
445
|
+
mixins.concat @mixins[ltype.to_sym]
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
mixins
|
|
449
|
+
end
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
# Retrieves available mixin types. Mixin types are presented
|
|
453
|
+
# in a shortened format (i.e. not as type identifiers).
|
|
454
|
+
#
|
|
455
|
+
# @example
|
|
456
|
+
# client.get_mixin_types # => [ "os_tpl", "resource_tpl" ]
|
|
457
|
+
#
|
|
458
|
+
# @return [Array<String>] list of available mixin types
|
|
459
|
+
def get_mixin_types
|
|
460
|
+
@mixins.keys.map { |k| k.to_s }
|
|
461
|
+
end
|
|
462
|
+
|
|
463
|
+
# Retrieves available mixin type identifiers.
|
|
464
|
+
#
|
|
465
|
+
# @example
|
|
466
|
+
# client.get_mixin_type_identifiers
|
|
467
|
+
# # => ['http://schemas.ogf.org/occi/infrastructure#os_tpl',
|
|
468
|
+
# # 'http://schemas.ogf.org/occi/infrastructure#resource_tpl']
|
|
469
|
+
#
|
|
470
|
+
# @return [Array<String>] list of available mixin type identifiers
|
|
471
|
+
def get_mixin_type_identifiers
|
|
472
|
+
identifiers = []
|
|
473
|
+
|
|
474
|
+
get_mixin_types.each do |mixin_type|
|
|
475
|
+
identifiers << 'http://schemas.ogf.org/occi/infrastructure#' + mixin_type
|
|
476
|
+
end
|
|
477
|
+
|
|
478
|
+
identifiers
|
|
479
|
+
end
|
|
480
|
+
|
|
481
|
+
# Retrieves available os_tpls from the model.
|
|
482
|
+
#
|
|
483
|
+
# @example
|
|
484
|
+
# get_os_templates # => #<Occi::Collection>
|
|
485
|
+
#
|
|
486
|
+
# @return [Occi::Collection] collection containing all registered OS templates
|
|
487
|
+
def get_os_templates
|
|
488
|
+
@model.get.mixins.select { |mixin| mixin.related.select { |rel| rel.end_with? 'os_tpl' }.any? }
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
# Retrieves available resource_tpls from the model.
|
|
492
|
+
#
|
|
493
|
+
# @example
|
|
494
|
+
# get_resource_templates # => #<Occi::Collection>
|
|
495
|
+
#
|
|
496
|
+
# @return [Occi::Collection] collection containing all registered resource templates
|
|
497
|
+
def get_resource_templates
|
|
498
|
+
@model.get.mixins.select { |mixin| mixin.related.select { |rel| rel.end_with? 'resource_tpl' }.any? }
|
|
499
|
+
end
|
|
500
|
+
|
|
501
|
+
# Creates a link of a specified kind and binds it to the given resource.
|
|
502
|
+
#
|
|
503
|
+
# @example
|
|
504
|
+
# link_kind = 'http://schemas.ogf.org/occi/infrastructure#storagelink'
|
|
505
|
+
# compute = client.get_resource "compute"
|
|
506
|
+
# storage_location = "http://localhost:3300/storage/321df21adfad-f3adfa5f4adf-a3d54ffadffe"
|
|
507
|
+
# linked_resource_kind = 'http://schemas.ogf.org/occi/infrastructure#storage'
|
|
508
|
+
#
|
|
509
|
+
# link link_kind, compute, storage_location, linked_resource_kind
|
|
510
|
+
#
|
|
511
|
+
# @param [String] link type identifier (link kind)
|
|
512
|
+
# @param [Occi::Core::Resource] resource to link to
|
|
513
|
+
# @param [URI, String] resource to be linked
|
|
514
|
+
# @param [String] type identifier of the linked resource
|
|
515
|
+
# @param [Occi::Core::Attributes] link attributes
|
|
516
|
+
# @param [Array<String>] link mixins
|
|
517
|
+
# @return [Occi::Core::Link] link instance
|
|
518
|
+
def link(kind, source, target_location, target_kind, attributes=Occi::Core::Attributes.new, mixins=[])
|
|
519
|
+
link = Occi::Core::Link.new(kind)
|
|
520
|
+
link.mixins = mixins
|
|
521
|
+
link.attributes = attributes
|
|
522
|
+
link.target = (target_location.kind_of? URI::Generic) ? target_location.path : target_location.to_s
|
|
523
|
+
link.rel = target_kind
|
|
524
|
+
|
|
525
|
+
link.check @model
|
|
526
|
+
source.links << link
|
|
527
|
+
|
|
528
|
+
link
|
|
529
|
+
end
|
|
530
|
+
|
|
531
|
+
# Returns the path for a given resource type identifier
|
|
532
|
+
#
|
|
533
|
+
# @example
|
|
534
|
+
# path_for_resource_type "http://schemas.ogf.org/occi/infrastructure#compute"
|
|
535
|
+
# # => "/compute/"
|
|
536
|
+
# path_for_resource_type "http://localhost:3300/compute/35ad4f45gsf-gsfg524s6gsfg-sfgsf4gsfg"
|
|
537
|
+
# # => "/compute/35ad4f45gsf-gsfg524s6gsfg-sfgsf4gsfg"
|
|
538
|
+
#
|
|
539
|
+
# @param [String] resource type identifier
|
|
540
|
+
# @return [String]
|
|
541
|
+
def path_for_resource_type(resource_type_identifier)
|
|
542
|
+
return "/" if resource_type_identifier.nil? || resource_type_identifier == "/"
|
|
543
|
+
|
|
544
|
+
kinds = @model.kinds.select { |kind| kind.term == resource_type_identifier }
|
|
545
|
+
if kinds.any?
|
|
546
|
+
#we got an type identifier
|
|
547
|
+
path = "/" + kinds.first.type_identifier.split('#').last + "/"
|
|
548
|
+
elsif resource_type_identifier.start_with?(@endpoint) || resource_type_identifier.start_with?('/')
|
|
549
|
+
#we got an resource link
|
|
550
|
+
path = sanitize_resource_link(resource_type_identifier)
|
|
551
|
+
else
|
|
552
|
+
raise "Unknown resource identifier! #{resource_type_identifier}"
|
|
553
|
+
end
|
|
554
|
+
end
|
|
555
|
+
|
|
556
|
+
# Extracts the resource path from a resource link. It will remove the leading @endpoint
|
|
557
|
+
# and replace it with a slash.
|
|
558
|
+
#
|
|
559
|
+
# @example
|
|
560
|
+
# sanitize_resource_link "http://localhost:3300/compute/35ad4f45gsf-gsfg524s6gsfg-sfgsf4gsfg"
|
|
561
|
+
# # => "/compute/35ad4f45gsf-gsfg524s6gsfg-sfgsf4gsfg"
|
|
562
|
+
# sanitize_resource_link "/compute/35ad4f45gsf-gsfg524s6gsfg-sfgsf4gsfg"
|
|
563
|
+
# # => "/compute/35ad4f45gsf-gsfg524s6gsfg-sfgsf4gsfg"
|
|
564
|
+
#
|
|
565
|
+
# @param [String] string containing the full resource link
|
|
566
|
+
# @return [String] extracted path, with a leading slash
|
|
567
|
+
def sanitize_resource_link(resource_link)
|
|
568
|
+
# everything starting with '/' is considered to be a resource path
|
|
569
|
+
return resource_link if resource_link.start_with? '/'
|
|
570
|
+
|
|
571
|
+
raise "Resource link #{resource_link} is not valid!" unless resource_link.start_with? @endpoint
|
|
572
|
+
|
|
573
|
+
resource_link.gsub @endpoint, '/'
|
|
574
|
+
end
|
|
575
|
+
|
|
576
|
+
protected
|
|
577
|
+
|
|
578
|
+
# Sets auth method and appropriate httparty attributes. Supported auth methods
|
|
579
|
+
# are: ["basic", "digest", "x509", "none"]
|
|
580
|
+
#
|
|
581
|
+
# @example
|
|
582
|
+
# set_auth { :type => "none" }
|
|
583
|
+
# set_auth { :type => "basic", :username => "123", :password => "321" }
|
|
584
|
+
# set_auth { :type => "digest", :username => "123", :password => "321" }
|
|
585
|
+
# set_auth { :type => "x509", :user_cert => "~/cert.pem",
|
|
586
|
+
# :user_cert_password => "321", :ca_path => nil }
|
|
587
|
+
#
|
|
588
|
+
# @param [Hash] authentication options
|
|
589
|
+
# @param [Boolean] allow fallback-only options
|
|
590
|
+
def set_auth(auth_options, fallback = false); end
|
|
591
|
+
|
|
592
|
+
# Attempts to establish a preliminary connection with the server
|
|
593
|
+
# to verify provided credentials and perform fallback authN
|
|
594
|
+
# if necessary. Has to be invoked after set_auth
|
|
595
|
+
def preauthenticate; end
|
|
596
|
+
|
|
597
|
+
# Sets media type. Will choose either application/occi+json or text/plain
|
|
598
|
+
# based on the formats supported by the server.
|
|
599
|
+
#
|
|
600
|
+
# @example
|
|
601
|
+
# set_media_type # => 'application/occi+json'
|
|
602
|
+
#
|
|
603
|
+
# @return [String] chosen media type
|
|
604
|
+
def set_media_type(force_type = nil); end
|
|
605
|
+
|
|
606
|
+
# Sets the logger and log levels. This allows users to pass existing logger
|
|
607
|
+
# instances to the rOCCI client.
|
|
608
|
+
#
|
|
609
|
+
# @example
|
|
610
|
+
# set_logger { :out => STDERR, :level => Occi::Log::WARN, :logger => nil }
|
|
611
|
+
#
|
|
612
|
+
# @param [Hash] logger options
|
|
613
|
+
def set_logger(log_options)
|
|
614
|
+
if log_options[:logger].nil? || (not log_options[:logger].kind_of? Occi::Log)
|
|
615
|
+
@logger = Occi::Log.new(log_options[:out])
|
|
616
|
+
@logger.level = log_options[:level]
|
|
617
|
+
end
|
|
618
|
+
end
|
|
619
|
+
|
|
620
|
+
# Checks whether the given endpoint URI is valid and adds a trailing
|
|
621
|
+
# slash if necessary.
|
|
622
|
+
#
|
|
623
|
+
# @example
|
|
624
|
+
# set_endpoint "http://localhost:3300" # => "http://localhost:3300/"
|
|
625
|
+
#
|
|
626
|
+
# @param [String] endpoint URI in a non-canonical string
|
|
627
|
+
# @return [String] canonical endpoint URI in a string, with a trailing slash
|
|
628
|
+
def set_endpoint(endpoint)
|
|
629
|
+
raise 'Endpoint not a valid URI' if (endpoint =~ URI::ABS_URI).nil?
|
|
630
|
+
@endpoint = endpoint.chomp('/') + '/'
|
|
631
|
+
end
|
|
632
|
+
|
|
633
|
+
# Creates an Occi::Model from data retrieved from the server.
|
|
634
|
+
#
|
|
635
|
+
# @example
|
|
636
|
+
# model = get('/-/')
|
|
637
|
+
# set_model model # => #<Occi::Model>
|
|
638
|
+
#
|
|
639
|
+
# @param [Occi::Collection] parsed representation of server's model
|
|
640
|
+
# @return [Occi::Model] Model instance
|
|
641
|
+
def set_model(model)
|
|
642
|
+
# build model
|
|
643
|
+
@model = Occi::Model.new(model)
|
|
644
|
+
|
|
645
|
+
@mixins = {
|
|
646
|
+
:os_tpl => get_os_tpl_mixins_ary,
|
|
647
|
+
:resource_tpl => get_res_tpl_mixins_ary
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
@model
|
|
651
|
+
end
|
|
652
|
+
|
|
653
|
+
#
|
|
654
|
+
#
|
|
655
|
+
#
|
|
656
|
+
def get_os_tpl_mixins_ary
|
|
657
|
+
os_tpls = []
|
|
658
|
+
|
|
659
|
+
get_os_templates.each do |os_tpl|
|
|
660
|
+
unless os_tpl.nil? || os_tpl.type_identifier.nil?
|
|
661
|
+
tid = os_tpl.type_identifier.strip
|
|
662
|
+
os_tpls << tid unless tid.empty?
|
|
663
|
+
end
|
|
664
|
+
end
|
|
665
|
+
|
|
666
|
+
os_tpls
|
|
667
|
+
end
|
|
668
|
+
|
|
669
|
+
#
|
|
670
|
+
#
|
|
671
|
+
#
|
|
672
|
+
def get_res_tpl_mixins_ary
|
|
673
|
+
res_tpls = []
|
|
674
|
+
|
|
675
|
+
get_resource_templates.each do |res_tpl|
|
|
676
|
+
unless res_tpl.nil? || res_tpl.type_identifier.nil?
|
|
677
|
+
tid = res_tpl.type_identifier.strip
|
|
678
|
+
res_tpls << tid unless tid.empty?
|
|
679
|
+
end
|
|
680
|
+
end
|
|
681
|
+
|
|
682
|
+
res_tpls
|
|
683
|
+
end
|
|
684
|
+
|
|
685
|
+
end
|
|
686
|
+
|
|
687
|
+
end
|
|
688
|
+
end
|
|
689
|
+
end
|