forj 1.0.1 → 1.0.2
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.
- checksums.yaml +4 -4
- data/.gitignore +7 -0
- data/.gitreview +4 -0
- data/Gemfile +21 -19
- data/Gemfile.lock +71 -0
- data/bin/forj +126 -83
- data/forj.gemspec +64 -0
- data/{lib → forj}/defaults.yaml +23 -1
- data/lib/appinit.rb +5 -5
- data/lib/build_tmpl/build-env.py +293 -0
- data/lib/cloud_test.rb +121 -0
- data/lib/forj-settings.rb +52 -39
- data/lib/forj/ForjCli.rb +11 -10
- data/lib/forj/ForjCore.rb +8 -6
- data/lib/forj/process/ForjProcess.rb +345 -82
- data/lib/ssh.rb +81 -20
- metadata +110 -80
- data/lib/compute.rb +0 -36
- data/lib/connection.rb +0 -144
- data/lib/down.rb +0 -60
- data/lib/forj-account.rb +0 -294
- data/lib/forj-config.rb +0 -522
- data/lib/helpers.rb +0 -56
- data/lib/lib-forj/lib/core/core.rb +0 -1740
- data/lib/lib-forj/lib/core/definition.rb +0 -441
- data/lib/lib-forj/lib/core/definition_internal.rb +0 -306
- data/lib/lib-forj/lib/core_process/CloudProcess.rb +0 -334
- data/lib/lib-forj/lib/core_process/global_process.rb +0 -406
- data/lib/lib-forj/lib/core_process/network_process.rb +0 -603
- data/lib/lib-forj/lib/lib-forj.rb +0 -37
- data/lib/lib-forj/lib/providers/hpcloud/Hpcloud.rb +0 -419
- data/lib/lib-forj/lib/providers/hpcloud/compute.rb +0 -108
- data/lib/lib-forj/lib/providers/hpcloud/network.rb +0 -117
- data/lib/lib-forj/lib/providers/hpcloud/security_groups.rb +0 -67
- data/lib/lib-forj/lib/providers/templates/compute.rb +0 -42
- data/lib/lib-forj/lib/providers/templates/core.rb +0 -61
- data/lib/lib-forj/lib/providers/templates/network.rb +0 -33
- data/lib/log.rb +0 -162
- data/lib/network.rb +0 -365
- data/lib/repositories.rb +0 -222
- data/lib/security.rb +0 -207
- data/lib/ssh.sh +0 -185
- data/spec/connection_spec.rb +0 -52
- data/spec/forj-config_spec.rb +0 -237
- data/spec/repositories_spec.rb +0 -50
@@ -1,441 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: UTF-8
|
3
|
-
|
4
|
-
# (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
|
5
|
-
#
|
6
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
-
# you may not use this file except in compliance with the License.
|
8
|
-
# You may obtain a copy of the License at
|
9
|
-
#
|
10
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#
|
12
|
-
# Unless required by applicable law or agreed to in writing, software
|
13
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
-
# See the License for the specific language governing permissions and
|
16
|
-
# limitations under the License.
|
17
|
-
|
18
|
-
|
19
|
-
class BaseDefinition
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
###################################################
|
24
|
-
# Class management Section
|
25
|
-
###################################################
|
26
|
-
|
27
|
-
# Meta Object declaration structure
|
28
|
-
# <Object>
|
29
|
-
# :query_mapping List of keypath mapped.
|
30
|
-
# <keypath> = <keypath mapped>
|
31
|
-
# :lambdas:
|
32
|
-
# :create_e: function to call at 'Create' task
|
33
|
-
# :delete_e: function to call at 'Delete' task
|
34
|
-
# :update_e: function to call at 'Update' task
|
35
|
-
# :get_e: function to call at 'Get' task
|
36
|
-
# :query_e: function to call at 'Query' task
|
37
|
-
# :value_mapping: Define list of Object's key values mapping.
|
38
|
-
# <keypath> key value mapping lists
|
39
|
-
# <value> = <map> Define the value mapping.
|
40
|
-
# :returns
|
41
|
-
# <keypath> key value to extract from controller object.
|
42
|
-
# :params: Defines CloudData (:data) or CloudObj (:CloudObj) needs by the <Object>
|
43
|
-
# :keys: Contains keys in a tree of hash.
|
44
|
-
# <keypath>: String. One element (string with : and /) of :list defining the key
|
45
|
-
# :type: :data or :CloudObj
|
46
|
-
# :for: Array of events which requires the data or CloudObj to work.
|
47
|
-
# :mapping: To automatically create a provider hash data mapped (hdata).
|
48
|
-
# :required: True if this parameter is required.
|
49
|
-
# :extract_from: Array. Build the keypath value from another hParams value.
|
50
|
-
# Ex: This example will extract :id from :security_groups object
|
51
|
-
# :extract_from => [:security_groups, :id]
|
52
|
-
#
|
53
|
-
@@meta_obj = {}
|
54
|
-
|
55
|
-
# meta data are defined in defaults.yaml and loaded in ForjDefault class definition
|
56
|
-
# Cloud provider can redefine ForjData defaults and add some extra parameters.
|
57
|
-
# To get Application defaults, read defaults.yaml, under :sections:
|
58
|
-
@@meta_data = {}
|
59
|
-
# <Section>:
|
60
|
-
# <Data>: Required. Symbol/String. default: nil
|
61
|
-
# => Data name. This symbol must be unique, across sections.
|
62
|
-
# :desc: Required. String. default: nil
|
63
|
-
# => Description
|
64
|
-
# :readonly: Optional. true/false. Default: false
|
65
|
-
# => oForjConfig.set() will fail if readonly is true.
|
66
|
-
# Can be set, only thanks to oForjConfig.setup()
|
67
|
-
# or using private oForjConfig._set()
|
68
|
-
# :account_exclusive: Optional. true/false. Default: false
|
69
|
-
# => Only oConfig.account_get/set() can handle the value
|
70
|
-
# oConfig.set/get cannot.
|
71
|
-
# :account: Optional. default: False
|
72
|
-
# => setup will configure the account with this <Data>
|
73
|
-
# :depends_on:
|
74
|
-
# => Identify :data type required to be set before the current one.
|
75
|
-
# :validate: Regular expression to validate end user input during setup.
|
76
|
-
# :value_mapping: list of values to map as defined by the controller
|
77
|
-
# :controller: mapping for get controller value from process values
|
78
|
-
# <value> : <map> value map equivalence. See data_value_mapping function
|
79
|
-
# :process: mapping for get process value from controller values
|
80
|
-
# <value> : <map> value map equivalence. See data_value_mapping function
|
81
|
-
# :defaut: Default value
|
82
|
-
# :list_values: Defines a list of valid values for the current data.
|
83
|
-
# :query_type :controller_call to execute a function defined in the controller object.
|
84
|
-
# :process_call to execute a function defined in the process object.
|
85
|
-
# :values to get list of values from :values.
|
86
|
-
# :object Object to load before calling the function. Only :query_type = :*_call
|
87
|
-
# :query_call Symbol. function name to call. Only :query_type = :*_call
|
88
|
-
# function must return an Array.
|
89
|
-
# :query_params Hash. Controler function parameters. Only :query_type = :*_call
|
90
|
-
# :validate :list_strict. valid only if value is one of those listed.
|
91
|
-
# :values:
|
92
|
-
# to retrieve from.
|
93
|
-
# otherwise define simply a list of possible values.
|
94
|
-
|
95
|
-
# The Generic Process can pre-define some data and value (function predefine_data)
|
96
|
-
# The Generic Process (and external framework call) only knows about Generic data.
|
97
|
-
# information used
|
98
|
-
#
|
99
|
-
@@meta_predefined_values = {}
|
100
|
-
|
101
|
-
# <Data>: Data name
|
102
|
-
# :values: List of possible values
|
103
|
-
# <Value>: Value Name attached to the data
|
104
|
-
# options: Options
|
105
|
-
# :desc: Description of that predefine value.
|
106
|
-
|
107
|
-
@@Context = {
|
108
|
-
:oCurrentObj => nil, # Defines the Current Object to manipulate
|
109
|
-
:needs_optional => nil, # set optional to true for any next needs declaration
|
110
|
-
:ClassProcess => nil # Current Process Class declaration
|
111
|
-
}
|
112
|
-
|
113
|
-
# Available functions for:
|
114
|
-
# - BaseDefinition class declaration
|
115
|
-
# - Controler (derived from BaseDefinition) class declaration
|
116
|
-
|
117
|
-
def self.current_process (cProcessClass)
|
118
|
-
@@Context[:ClassProcess] = cProcessClass
|
119
|
-
end
|
120
|
-
|
121
|
-
def self.obj_needs_optional
|
122
|
-
@@Context[:needs_optional] = true
|
123
|
-
end
|
124
|
-
|
125
|
-
def self.obj_needs_requires
|
126
|
-
@@Context[:needs_optional] = false
|
127
|
-
end
|
128
|
-
|
129
|
-
def self.process_default(hOptions)
|
130
|
-
aSupportedOptions = [:use_controller]
|
131
|
-
unless hOptions.nil?
|
132
|
-
hOptions.each_key { | key |
|
133
|
-
case key
|
134
|
-
when :use_controller
|
135
|
-
value = rhGet(hOptions, :use_controller)
|
136
|
-
next unless value.is_a?(TrueClass) or value.is_a?(FalseClass)
|
137
|
-
rhSet(@@Context, hOptions[key], :options, key)
|
138
|
-
else
|
139
|
-
raise ForjError.new, "Unknown default process options '%s'. Supported are '%s'" % [key, aSupportedOptions.join(',')]
|
140
|
-
end
|
141
|
-
}
|
142
|
-
end
|
143
|
-
|
144
|
-
end
|
145
|
-
|
146
|
-
# Defines Object and connect to functions events
|
147
|
-
def self.define_obj(sCloudObj, hParam = nil)
|
148
|
-
return nil if not sCloudObj
|
149
|
-
return nil if not [String, Symbol].include?(sCloudObj.class)
|
150
|
-
|
151
|
-
aCaller = caller
|
152
|
-
aCaller.pop
|
153
|
-
|
154
|
-
sCloudObj = sCloudObj.to_sym if sCloudObj.class == String
|
155
|
-
@@Context[:oCurrentObj] = sCloudObj
|
156
|
-
@@Context[:needs_optional] = false
|
157
|
-
@@Context[:needs_setup] = false
|
158
|
-
bController = rhGet(@@Context, :options, :use_controller)
|
159
|
-
bController = true if bController.nil?
|
160
|
-
|
161
|
-
if not [Hash].include?(hParam.class)
|
162
|
-
if rhExist?(@@meta_obj, sCloudObj) != 1
|
163
|
-
raise ForjError.new(), "New undefined object '%s' requires at least one handler. Ex: define_obj :%s, :create_e => myhandler " % [sCloudObj, sCloudObj]
|
164
|
-
end
|
165
|
-
hParam = {}
|
166
|
-
end
|
167
|
-
|
168
|
-
oCloudObj = rhGet(@@meta_obj, sCloudObj)
|
169
|
-
if not oCloudObj
|
170
|
-
oCloudObj = {
|
171
|
-
:lambdas => {:create_e => nil, :delete_e => nil, :update_e => nil, :get_e => nil, :query_e => nil, :get_attr_e => nil},
|
172
|
-
:params => {},
|
173
|
-
:options => {:controller => bController },
|
174
|
-
:query_mapping => { ":id" => ":id", ":name" => ":name"},
|
175
|
-
:returns => {":id" => ":id", ":name" => ":name"}
|
176
|
-
}
|
177
|
-
msg = nil
|
178
|
-
else
|
179
|
-
msg = ""
|
180
|
-
end
|
181
|
-
|
182
|
-
sObjectName = "'%s.%s'" % [self.class, sCloudObj]
|
183
|
-
|
184
|
-
# Checking hParam data
|
185
|
-
if not rhGet(hParam, :nohandler)
|
186
|
-
hParam.each_key do | key |
|
187
|
-
raise ForjError.new(), "'%s' parameter is invalid. Use '%s'" % [key, oCloudObj[:lambdas].keys.join(', ')], aCaller if rhExist?(oCloudObj, :lambdas, key)!= 2
|
188
|
-
end
|
189
|
-
msg = "%-28s object declared." % [sObjectName] if not msg
|
190
|
-
else
|
191
|
-
msg = "%-28s meta object declared." % [sObjectName] if not msg
|
192
|
-
end
|
193
|
-
ForjLib.debug(2, msg) if msg != ""
|
194
|
-
|
195
|
-
# Setting procs
|
196
|
-
rhGet(oCloudObj, :lambdas).each_key { |key|
|
197
|
-
next if not hParam.key?(key)
|
198
|
-
|
199
|
-
if not @@Context[:ClassProcess].instance_methods.include?(hParam[key])
|
200
|
-
raise ForjError.new(), "'%s' parameter requires a valid instance method '%s' in the process '%s'." % [key, hParam[key], @@Context[:ClassProcess]], aCaller
|
201
|
-
end
|
202
|
-
if hParam[key] == :default
|
203
|
-
# By default, we use the event name as default function to call.
|
204
|
-
# Those function are predefined in ForjController
|
205
|
-
# The Provider needs to derive from ForjController and redefine those functions.
|
206
|
-
oCloudObj[:lambdas][key] = key
|
207
|
-
else
|
208
|
-
# If needed, ForjProviver redefined can contains some additionnal functions
|
209
|
-
# to call.
|
210
|
-
oCloudObj[:lambdas][key] = hParam[key]
|
211
|
-
end
|
212
|
-
}
|
213
|
-
rhSet(@@meta_obj, oCloudObj, sCloudObj)
|
214
|
-
end
|
215
|
-
|
216
|
-
def self.def_query_attribute(key)
|
217
|
-
self.query_mapping(key, key)
|
218
|
-
end
|
219
|
-
|
220
|
-
def self.query_mapping(key, map)
|
221
|
-
return nil if not [String, Symbol].include?(key.class)
|
222
|
-
return nil if not [NilClass, Symbol, String].include?(map.class)
|
223
|
-
|
224
|
-
aCaller = caller
|
225
|
-
aCaller.pop
|
226
|
-
|
227
|
-
raise ForjError.new(), "%s: No Object defined. Missing define_obj?" % [ self.class], aCaller if @@Context[:oCurrentObj].nil?
|
228
|
-
|
229
|
-
sCloudObj = @@Context[:oCurrentObj]
|
230
|
-
oKeyPath = KeyPath.new(key)
|
231
|
-
oMapPath = KeyPath.new(map)
|
232
|
-
|
233
|
-
@@Context[:oCurrentKey] = oKeyPath
|
234
|
-
|
235
|
-
rhSet(@@meta_obj, oMapPath.sFullPath, sCloudObj, :query_mapping, oKeyPath.sFullPath)
|
236
|
-
end
|
237
|
-
|
238
|
-
# Available functions exclusively for Controler (derived from BaseDefinition) class declaration
|
239
|
-
|
240
|
-
# Following functions are related to Object Attributes
|
241
|
-
# ----------------------------------------------------
|
242
|
-
|
243
|
-
# Defines Object CloudData/CloudObj dependency
|
244
|
-
def self.obj_needs(sType, sParam, hParams = {})
|
245
|
-
return nil if not [String, Symbol].include?(sType.class)
|
246
|
-
return nil if not [String, Symbol, Array].include?(sParam.class)
|
247
|
-
|
248
|
-
hParams = {} if not hParams
|
249
|
-
|
250
|
-
hParams[:required] = not(@@Context[:needs_optional]) if rhExist?(hParams, :required) != 1
|
251
|
-
|
252
|
-
aCaller = caller
|
253
|
-
aCaller.pop
|
254
|
-
|
255
|
-
raise ForjError.new(), "%s: No Object defined. Missing define_obj?" % [ self.class], aCaller if @@Context[:oCurrentObj].nil?
|
256
|
-
|
257
|
-
sCloudObj = @@Context[:oCurrentObj]
|
258
|
-
|
259
|
-
aForEvents = rhGet(@@meta_obj, sCloudObj, :lambdas).keys
|
260
|
-
hParams = hParams.merge({ :for => aForEvents}) if not hParams.key?(:for)
|
261
|
-
sType = sType.to_sym if sType.class == String
|
262
|
-
|
263
|
-
|
264
|
-
raise ForjError.new(), "%s: '%s' not declared. Missing define_obj(%s)?" % [ self.class, sCloudObj, sCloudObj], aCaller if rhExist?(@@meta_obj, sCloudObj) != 1
|
265
|
-
|
266
|
-
oObjTopParam = rhGet(@@meta_obj, sCloudObj, :params)
|
267
|
-
if not oObjTopParam.key?(:keys)
|
268
|
-
# Initialize top structure
|
269
|
-
|
270
|
-
oObjTopParam.merge!({ :keys => {} })
|
271
|
-
end
|
272
|
-
|
273
|
-
oKeyPath = KeyPath.new(sParam)
|
274
|
-
sKeyAccess = oKeyPath.sFullPath
|
275
|
-
|
276
|
-
@@Context[:oCurrentKey] = oKeyPath
|
277
|
-
|
278
|
-
oCloudObjParam = rhGet(oObjTopParam, :keys, sKeyAccess)
|
279
|
-
if oCloudObjParam.nil?
|
280
|
-
sMsgAction = "New"
|
281
|
-
oObjTopParam[:keys][sKeyAccess] = {}
|
282
|
-
oCloudObjParam = oObjTopParam[:keys][sKeyAccess]
|
283
|
-
else
|
284
|
-
sMsgAction = "Upd"
|
285
|
-
end
|
286
|
-
sObjectName = "'%s.%s'" % [self.class, sCloudObj]
|
287
|
-
case sType
|
288
|
-
when :data
|
289
|
-
if ForjDefault.meta_exist?(sParam)
|
290
|
-
ForjLib.debug(2, "%-28s: %s predefined config '%s'." % [sObjectName, sMsgAction, sParam])
|
291
|
-
else
|
292
|
-
ForjLib.debug(2, "%-28s: %s runtime config '%s'." % [sObjectName, sMsgAction, sParam])
|
293
|
-
end
|
294
|
-
oCloudObjParam.merge!( hParams.merge({:type => sType}) ) # Merge from predefined params, but ensure type is never updated.
|
295
|
-
when :CloudObject
|
296
|
-
raise ForjError.new(), "%s: '%s' not declared. Missing define_obj(%s)?" % [self.class, sParam, sParam], aCaller if not @@meta_obj.key?(sParam)
|
297
|
-
oCloudObjParam.merge!( hParams.merge({:type => sType}) ) # Merge from predefined params, but ensure type is never updated.
|
298
|
-
else
|
299
|
-
raise ForjError.new(), "%s: Object parameter type '%s' unknown." % [ self.class, sType ], aCaller
|
300
|
-
end
|
301
|
-
end
|
302
|
-
|
303
|
-
def self.attr_value_mapping(value, map)
|
304
|
-
return nil if not [String, Symbol].include?(value.class)
|
305
|
-
return nil if not [NilClass, Symbol, String].include?(map.class)
|
306
|
-
|
307
|
-
aCaller = caller
|
308
|
-
aCaller.pop
|
309
|
-
|
310
|
-
sCloudObj = @@Context[:oCurrentObj]
|
311
|
-
raise ForjError.new, "attr_value_mapping: mapping '%s' needs object context definition. You need to call define_obj to get the context." % value if sCloudObj.nil?
|
312
|
-
|
313
|
-
oKeypath = @@Context[:oCurrentKey]
|
314
|
-
raise ForjError.new, "attr_value_mapping: mapping '%s' needs object data context definition. You need to call define_obj, then obj_needs to get the context." % value if oKeypath.nil?
|
315
|
-
|
316
|
-
keypath = oKeypath.sFullPath
|
317
|
-
ForjLib.debug(2, "%s-%s: Value mapping definition '%s' => '%s'" % [sCloudObj, oKeypath.to_s, value, map])
|
318
|
-
rhSet(@@meta_obj, map, sCloudObj, :value_mapping, keypath, value)
|
319
|
-
end
|
320
|
-
|
321
|
-
|
322
|
-
def self.def_attribute(key, options = nil)
|
323
|
-
self.get_attr_mapping(key, options)
|
324
|
-
#~ self.def_query_attribute(key) unless options and options.key?(:not_queriable) and options[:not_queriable]== true
|
325
|
-
end
|
326
|
-
|
327
|
-
# Function used by the controler to define mapping.
|
328
|
-
# By default, any attributes are queriable as well. No need to call
|
329
|
-
# query_mapping
|
330
|
-
def self.get_attr_mapping(key, map = nil, options = nil)
|
331
|
-
return nil if not [String, Symbol].include?(key.class)
|
332
|
-
return nil if not [NilClass, Symbol, String, Array].include?(map.class)
|
333
|
-
|
334
|
-
aCaller = caller
|
335
|
-
aCaller.pop
|
336
|
-
|
337
|
-
raise ForjError.new(), "%s: No Object defined. Missing define_obj?" % [ self.class], aCaller if @@Context[:oCurrentObj].nil?
|
338
|
-
|
339
|
-
sCloudObj = @@Context[:oCurrentObj]
|
340
|
-
oKeyPath = KeyPath.new(key)
|
341
|
-
oMapPath = oKeyPath
|
342
|
-
oMapPath = KeyPath.new(map) unless map.nil?
|
343
|
-
|
344
|
-
rhSet(@@meta_obj, oMapPath.sFullPath, sCloudObj, :returns, oKeyPath.sFullPath)
|
345
|
-
@@Context[:oCurrentKey] = oKeyPath
|
346
|
-
if oMapPath == oKeyPath
|
347
|
-
ForjLib::debug(4, "%s: Defining object attribute '%s'" % [sCloudObj, oKeyPath.sFullPath])
|
348
|
-
else
|
349
|
-
ForjLib::debug(4, "%s: Defining object attribute mapping '%s' => '%s'" % [sCloudObj, oKeyPath.sFullPath, oMapPath.sFullPath])
|
350
|
-
end
|
351
|
-
|
352
|
-
self.query_mapping(key, map) unless options and options.key?(:not_queriable) and options[:not_queriable]== true
|
353
|
-
end
|
354
|
-
|
355
|
-
def self.undefine_attribute(key)
|
356
|
-
return nil if not [String, Symbol].include?(key.class)
|
357
|
-
|
358
|
-
aCaller = caller
|
359
|
-
aCaller.pop
|
360
|
-
|
361
|
-
raise ForjError.new(), "%s: No Object defined. Missing define_obj?" % [ self.class], aCaller if @@Context[:oCurrentObj].nil?
|
362
|
-
|
363
|
-
sCloudObj = @@Context[:oCurrentObj]
|
364
|
-
oKeyPath = KeyPath.new(key)
|
365
|
-
|
366
|
-
rhSet(@@meta_obj, nil, sCloudObj, :returns, oKeyPath.sFullPath)
|
367
|
-
@@Context[:oCurrentKey] = oKeyPath
|
368
|
-
ForjLib::debug(4, "%s: Undefining attribute mapping '%s'" % [sCloudObj, oKeyPath.sFullPath])
|
369
|
-
|
370
|
-
self.query_mapping(key, nil)
|
371
|
-
end
|
372
|
-
|
373
|
-
# Defines/update CloudData parameters
|
374
|
-
def self.define_data(sData, hMeta)
|
375
|
-
return nil if not sData or not hMeta
|
376
|
-
return nil if not [String, Symbol].include?(sData.class)
|
377
|
-
return nil if hMeta.class != Hash
|
378
|
-
|
379
|
-
aCaller = caller
|
380
|
-
aCaller.pop
|
381
|
-
|
382
|
-
sData = sData.to_sym if sData.class == String
|
383
|
-
raise ForjError.new(), "%s: Config data '%s' unknown" % [self.class, sData], aCaller if not ForjDefault.meta_exist?(sData)
|
384
|
-
|
385
|
-
@@Context[:oCurrentData] = sData
|
386
|
-
|
387
|
-
section = ForjDefault.get_meta_section(sData)
|
388
|
-
section = :runtime if section.nil?
|
389
|
-
|
390
|
-
if rhExist?(@@meta_data, section, sData) == 2
|
391
|
-
rhGet(@@meta_data, section, sData).merge!(hMeta)
|
392
|
-
else
|
393
|
-
rhSet(@@meta_data, hMeta, section, sData)
|
394
|
-
end
|
395
|
-
|
396
|
-
end
|
397
|
-
|
398
|
-
def self.data_value_mapping(value, map)
|
399
|
-
return nil if not [String, Symbol].include?(value.class)
|
400
|
-
return nil if not [NilClass, Symbol, String].include?(map.class)
|
401
|
-
|
402
|
-
aCaller = caller
|
403
|
-
aCaller.pop
|
404
|
-
sData = @@Context[:oCurrentData]
|
405
|
-
raise ForjError.new, "Config data context not set. at least, you need to call define_data before." if sData.nil?
|
406
|
-
|
407
|
-
section = ForjDefault.get_meta_section(sData)
|
408
|
-
section = :runtime if section.nil?
|
409
|
-
|
410
|
-
ForjLib.debug(2, "%s/%s: Define config data value mapping: '%s' => '%s'" % [section, sData, value, map])
|
411
|
-
rhSet(@@meta_data, map, section, sData, :value_mapping, :controller, value)
|
412
|
-
rhSet(@@meta_data, value, section, sData, :value_mapping, :process, map)
|
413
|
-
end
|
414
|
-
|
415
|
-
def self.provides(aObjType)
|
416
|
-
@aObjType = aObjType
|
417
|
-
end
|
418
|
-
|
419
|
-
def self.defined?(objType)
|
420
|
-
@aObjType.include?(objType)
|
421
|
-
end
|
422
|
-
|
423
|
-
# Internal BaseDefinition function
|
424
|
-
|
425
|
-
def self.predefine_data_value(data, hOptions)
|
426
|
-
return nil if self.class != BaseDefinition # Refuse to run if not a BaseDefinition call
|
427
|
-
return nil if not [String, Symbol].include?(value.class)
|
428
|
-
return nil if not [NilClass, Symbol, String].include?(map.class)
|
429
|
-
|
430
|
-
aCaller = caller
|
431
|
-
aCaller.pop
|
432
|
-
|
433
|
-
oKeyPath = @@Context[:oCurrentKey]
|
434
|
-
|
435
|
-
value = {data => {:options => hOptions} }
|
436
|
-
|
437
|
-
rhSet(@@predefine_data_value, value, oKeyPath.sFullPath, :values)
|
438
|
-
end
|
439
|
-
|
440
|
-
|
441
|
-
end
|
@@ -1,306 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: UTF-8
|
3
|
-
|
4
|
-
# (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
|
5
|
-
#
|
6
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
-
# you may not use this file except in compliance with the License.
|
8
|
-
# You may obtain a copy of the License at
|
9
|
-
#
|
10
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#
|
12
|
-
# Unless required by applicable law or agreed to in writing, software
|
13
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
-
# See the License for the specific language governing permissions and
|
16
|
-
# limitations under the License.
|
17
|
-
|
18
|
-
|
19
|
-
class BaseDefinition
|
20
|
-
|
21
|
-
private
|
22
|
-
# ------------------------------------------------------
|
23
|
-
# Class Definition internal function.
|
24
|
-
# ------------------------------------------------------
|
25
|
-
|
26
|
-
def _ask_encrypted(sDesc, sDefault)
|
27
|
-
# Checking key file used to encrypt/decrypt passwords
|
28
|
-
key_file = File.join($FORJ_CREDS_PATH, '.key')
|
29
|
-
if not File.exists?(key_file)
|
30
|
-
# Need to create a random key.
|
31
|
-
entr = {
|
32
|
-
:key => rand(36**10).to_s(36),
|
33
|
-
:salt => Time.now.to_i.to_s,
|
34
|
-
:iv => Base64::strict_encode64(OpenSSL::Cipher::Cipher.new('aes-256-cbc').random_iv)
|
35
|
-
}
|
36
|
-
|
37
|
-
ForjLib.debug(2, "Writing '%s' key file" % key_file)
|
38
|
-
File.open(key_file, 'w') do |out|
|
39
|
-
out.write(Base64::encode64(entr.to_yaml))
|
40
|
-
end
|
41
|
-
else
|
42
|
-
ForjLib.debug(2, "Loading '%s' key file" % key_file)
|
43
|
-
encoded_key = IO.read(key_file)
|
44
|
-
entr = YAML.load(Base64::decode64(encoded_key))
|
45
|
-
end
|
46
|
-
|
47
|
-
enc_value = sDefault
|
48
|
-
|
49
|
-
if not enc_value.nil?
|
50
|
-
begin
|
51
|
-
value_hidden = '*' * Encryptor.decrypt(
|
52
|
-
:value => Base64::strict_decode64(enc_value),
|
53
|
-
:key => entr[:key],
|
54
|
-
:iv => Base64::strict_decode64(entr[:iv]),
|
55
|
-
:salt => entr[:salt]
|
56
|
-
).length
|
57
|
-
rescue => e
|
58
|
-
Logging.error("Unable to decrypt your %s. You will need to re-enter it." % sDesc)
|
59
|
-
enc_value = ""
|
60
|
-
else
|
61
|
-
value_hidden="[%s]" % value_hidden
|
62
|
-
Logging.message("%s is already set. If you want to keep it, just press Enter" % [sDesc])
|
63
|
-
end
|
64
|
-
else
|
65
|
-
value_hidden = ""
|
66
|
-
end
|
67
|
-
|
68
|
-
value_free = ""
|
69
|
-
while value_free == ""
|
70
|
-
# ask for encrypted data.
|
71
|
-
value_free = ask("Enter %s: [%s]" % [sDesc, value_hidden]) do |q|
|
72
|
-
q.echo = '*'
|
73
|
-
end
|
74
|
-
if value_free == "" and enc_value
|
75
|
-
value_free = Encryptor.decrypt(
|
76
|
-
:value => Base64::strict_decode64(enc_value),
|
77
|
-
:key => entr[:key],
|
78
|
-
:iv => Base64::strict_decode64(entr[:iv]),
|
79
|
-
:salt => entr[:salt]
|
80
|
-
)
|
81
|
-
else
|
82
|
-
Logging.message("%s cannot be empty." % sDesc) if value_free == ""
|
83
|
-
end
|
84
|
-
end
|
85
|
-
enc_value = Base64::strict_encode64(
|
86
|
-
Encryptor.encrypt(
|
87
|
-
:value => value_free,
|
88
|
-
:key => entr[:key],
|
89
|
-
:iv => Base64::strict_decode64(entr[:iv]),
|
90
|
-
:salt => entr[:salt]
|
91
|
-
)
|
92
|
-
)
|
93
|
-
end
|
94
|
-
|
95
|
-
def _ask(sDesc, sDefault, rValidate, bEncrypted, bRequired)
|
96
|
-
if bEncrypted
|
97
|
-
value = _ask_encrypted(sDesc, sDefault)
|
98
|
-
if bRequired and value == ""
|
99
|
-
say "%sThis information is required!%s" % [ANSI.bold, ANSI.clear]
|
100
|
-
while value == ""
|
101
|
-
value = _ask_encrypted(sDesc, sDefault)
|
102
|
-
end
|
103
|
-
end
|
104
|
-
else
|
105
|
-
value = ask('Enter %s:' % [sDesc]) do |q|
|
106
|
-
q.default = sDefault unless sDefault.nil?
|
107
|
-
q.validate = rValidate unless rValidate.nil?
|
108
|
-
end
|
109
|
-
if bRequired and value == ""
|
110
|
-
say "%sThis information is required!%s" % [ANSI.bold, ANSI.clear]
|
111
|
-
while value == ""
|
112
|
-
value = ask('Enter %s:[%s]' % [sDesc, sDefault]) do |q|
|
113
|
-
q.default = sDefault unless sDefault.nil?
|
114
|
-
q.validate = rValidate unless rValidate.nil?
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
119
|
-
value.to_s
|
120
|
-
end
|
121
|
-
|
122
|
-
# return Object data meta data.
|
123
|
-
def _get_meta_data(sKey)
|
124
|
-
|
125
|
-
hMetaDefault = ForjDefault.get_meta(sKey)
|
126
|
-
return nil if hMetaDefault.nil?
|
127
|
-
hMetaDefault = hMetaDefault.clone
|
128
|
-
|
129
|
-
sSection = ForjDefault.get_meta_section(sKey)
|
130
|
-
return hMetaDefault if sSection.nil?
|
131
|
-
hMeta = rhGet(@@meta_data, sSection, sKey)
|
132
|
-
return hMetaDefault if hMeta.nil?
|
133
|
-
|
134
|
-
hMetaDefault.merge!(hMeta)
|
135
|
-
end
|
136
|
-
|
137
|
-
def _return_map(sCloudObj, oControlerObject)
|
138
|
-
return nil if oControlerObject.nil?
|
139
|
-
|
140
|
-
attr_value = {}
|
141
|
-
|
142
|
-
pProc = rhGet(@@meta_obj, sCloudObj, :lambdas, :get_attr_e)
|
143
|
-
bController = rhGet(@@meta_obj, sCloudObj, :options, :controller)
|
144
|
-
return nil if not pProc and not bController
|
145
|
-
|
146
|
-
hMap = rhGet(@@meta_obj, sCloudObj, :returns)
|
147
|
-
hMap.each { |key, map|
|
148
|
-
oKeyPath = KeyPath.new(key)
|
149
|
-
oMapPath = KeyPath.new(map)
|
150
|
-
next if not map
|
151
|
-
if pProc
|
152
|
-
ForjLib::debug(4, "Calling process function '%s' to retrieve/map Controller object '%s' data " % [pProc, sCloudObj])
|
153
|
-
controller_attr_value = @oForjProcess.method(pProc).call(sCloudObj, oControlerObject)
|
154
|
-
else
|
155
|
-
ForjLib::debug(4, "Calling controller function 'get_attr' to retrieve/map Controller object '%s' data " % [sCloudObj])
|
156
|
-
controller_attr_value = @oProvider.get_attr(oControlerObject, oMapPath.aTree) if bController
|
157
|
-
end
|
158
|
-
|
159
|
-
hValueMapping = rhGet(@@meta_obj, sCloudObj, :value_mapping, oKeyPath.sFullPath)
|
160
|
-
if hValueMapping and not controller_attr_value.nil?
|
161
|
-
hValueMapping.each { | map_key, map_value |
|
162
|
-
if controller_attr_value == map_value
|
163
|
-
rhSet(attr_value, map_key ,oKeyPath.aTree)
|
164
|
-
ForjLib::debug(5, "Object '%s' value mapped '%s': '%s' => '%s'" % [sCloudObj, oKeyPath.aTree, controller_attr_value, map_value])
|
165
|
-
break
|
166
|
-
end
|
167
|
-
}
|
168
|
-
raise ForjError.new(), "'%s.%s': No controller value mapping for '%s'." % [sCloudObj, oKeyPath.sKey, controller_attr_value] if attr_value.nil?
|
169
|
-
else
|
170
|
-
ForjLib::debug(5, "Object '%s' value '%s' extracted: '%s'" % [sCloudObj, oKeyPath.aTree, controller_attr_value])
|
171
|
-
rhSet(attr_value, controller_attr_value ,oKeyPath.aTree)
|
172
|
-
end
|
173
|
-
}
|
174
|
-
attr_value
|
175
|
-
end
|
176
|
-
|
177
|
-
def _build_data(sCloudObj, oParam, oKeyPath, hParams, bController = false)
|
178
|
-
|
179
|
-
sKey = oKeyPath.sKey
|
180
|
-
sDefault = rhGet(hParams, :default_value)
|
181
|
-
if rhExist?(hParams, :extract_from) == 1
|
182
|
-
value = oParam[hParams[:extract_from]]
|
183
|
-
end
|
184
|
-
value = @oForjConfig.get(sKey, sDefault) if not value
|
185
|
-
|
186
|
-
if bController
|
187
|
-
hValueMapping = rhGet(@@meta_obj, sCloudObj, :value_mapping, oKeyPath.sFullPath)
|
188
|
-
|
189
|
-
# Mapping from Object/data definition
|
190
|
-
if hValueMapping
|
191
|
-
raise ForjError.new(), "'%s.%s': No value mapping for '%s'" % [sCloudObj, sKey, value] if rhExist?(hValueMapping, value) != 1
|
192
|
-
value = hValueMapping[value]
|
193
|
-
# Will be moved to the setup section or while setting it for a controller attached account.
|
194
|
-
#~ else
|
195
|
-
#~ # Or mapping from Config/data definition
|
196
|
-
#~ section = ForjDefault.get_meta_section(sKey)
|
197
|
-
#~ section = :runtime if section.nil?
|
198
|
-
#~ hValueMapping = rhGet(@@meta_data, section, sKey, :value_mapping)
|
199
|
-
#~ if hValueMapping
|
200
|
-
#~ raise ForjError.new(), "'%s.%s': No Config value mapping for '%s'" % [section, sKey, value] if rhExist?(hValueMapping, value) != 1
|
201
|
-
#~ value = hValueMapping[value]
|
202
|
-
#~ end
|
203
|
-
end
|
204
|
-
if rhExist?(hParams, :mapping) == 1
|
205
|
-
# NOTE: if mapping is set, the definition subtree
|
206
|
-
# is ignored.
|
207
|
-
# if key map to mykey
|
208
|
-
# [:section1][subsect][key] = value
|
209
|
-
# oParam => [:hdata][mykey] = value
|
210
|
-
# not oParam => [:hdata][:section1][subsect][mykey] = value
|
211
|
-
rhSet(oParam[:hdata], value, rhGet(hParams, :mapping))
|
212
|
-
end
|
213
|
-
end
|
214
|
-
oParam[oKeyPath.aTree] = value
|
215
|
-
end
|
216
|
-
|
217
|
-
def _get_object_params(sCloudObj, sEventType, fname, bController = false)
|
218
|
-
|
219
|
-
oParams = ObjectData.new(not(bController)) # hdata is built for controller. ie, ObjectData is NOT internal.
|
220
|
-
|
221
|
-
hTopParams= rhGet(@@meta_obj,sCloudObj, :params)
|
222
|
-
hkeyPaths = rhGet(hTopParams, :keys)
|
223
|
-
raise ForjError.new(), "'%s' Object data needs not set. Forgot obj_needs?" % [sCloudObj] if hkeyPaths.nil?
|
224
|
-
|
225
|
-
hkeyPaths.each { | sKeypath, hParams|
|
226
|
-
next if not hParams[:for].include?(sEventType)
|
227
|
-
oKeyPath = KeyPath.new(sKeypath)
|
228
|
-
sKey = oKeyPath.sKey
|
229
|
-
case hParams[:type]
|
230
|
-
when :data
|
231
|
-
_build_data(sCloudObj, oParams, oKeyPath, hParams, bController)
|
232
|
-
when :CloudObject
|
233
|
-
#~ if hParams[:required] and rhExist?(@CloudData, sKey, :object) != 2
|
234
|
-
if hParams[:required] and @ObjectData.type?(sKey) != :DataObject
|
235
|
-
raise ForjError.new(), "Object '%s/%s' is not defined. '%s' requirement failed." % [ self.class, sKey, fname]
|
236
|
-
end
|
237
|
-
if @ObjectData.exist?(sKey)
|
238
|
-
oParams.add(@ObjectData[sKey, :ObjectData])
|
239
|
-
else
|
240
|
-
ForjLib::debug(2, "The optional '%s' was not loaded" % sKey)
|
241
|
-
end
|
242
|
-
else
|
243
|
-
raise ForjError.new(), "Undefined ObjectData '%s'." % [ hParams[:type]]
|
244
|
-
end
|
245
|
-
}
|
246
|
-
oParams
|
247
|
-
end
|
248
|
-
|
249
|
-
def _get_controller_map_value(keypath, sProcessValue)
|
250
|
-
section = ForjDefault.get_meta_section(sData)
|
251
|
-
section = :runtime if section.nil?
|
252
|
-
oKeypath = KeyPath.new(keypath)
|
253
|
-
sKeyPath = oKeypath.sKeyPath
|
254
|
-
return nil if rhExist?(@@meta_data, section, sKeyPath, :controller, sProcessValue) != 4
|
255
|
-
rhGet(@@meta_data, section, sKeyPath, :controller, sProcessValue)
|
256
|
-
end
|
257
|
-
|
258
|
-
def _get_process_map_value(keypath, sControllerValue)
|
259
|
-
section = ForjDefault.get_meta_section(sData)
|
260
|
-
section = :runtime if section.nil?
|
261
|
-
oKeypath = KeyPath.new(keypath)
|
262
|
-
sKeyPath = oKeypath.sKeyPath
|
263
|
-
return nil if rhExist?(@@meta_data, section, sKeyPath, :process, sControllerValue) != 4
|
264
|
-
rhGet(@@meta_data, section, sKeyPath, :process, sControllerValue)
|
265
|
-
end
|
266
|
-
|
267
|
-
def _check_required(sCloudObj, sEventType, fname)
|
268
|
-
aCaller = caller
|
269
|
-
aCaller.pop
|
270
|
-
|
271
|
-
oObjMissing=[]
|
272
|
-
|
273
|
-
hTopParams= rhGet(@@meta_obj,sCloudObj, :params)
|
274
|
-
hkeyPaths = rhGet(hTopParams, :keys)
|
275
|
-
raise ForjError.new(), "'%s' Object data needs not set. Forgot obj_needs?" % [sCloudObj] if hkeyPaths.nil?
|
276
|
-
|
277
|
-
hkeyPaths.each { | sKeypath, hParams|
|
278
|
-
next if not hParams[:for].include?(sEventType)
|
279
|
-
oKeyPath = KeyPath.new(sKeypath)
|
280
|
-
|
281
|
-
sKey = oKeyPath.sKey
|
282
|
-
case hParams[:type]
|
283
|
-
when :data
|
284
|
-
sDefault = rhGet(hParams, :default_value)
|
285
|
-
if hParams[:required]
|
286
|
-
if hParams.key?(:extract_from)
|
287
|
-
if not @ObjectData.exist?(hParams[:extract_from])
|
288
|
-
raise ForjError.new(), "key '%s' was not extracted from '%s'. '%s' requirement failed." % [ sKey, hParams[:extract_from], fname], aCaller
|
289
|
-
end
|
290
|
-
elsif @oForjConfig.get(sKey, sDefault).nil?
|
291
|
-
sSection = ForjDefault.get_meta_section(sKey)
|
292
|
-
sSection = 'runtime' if not sSection
|
293
|
-
raise ForjError.new(), "key '%s/%s' is not set. '%s' requirement failed." % [ sSection, sKey, fname], aCaller
|
294
|
-
end
|
295
|
-
end
|
296
|
-
when :CloudObject
|
297
|
-
#~ if hParams[:required] and rhExist?(@CloudData, sKey, :object) != 2
|
298
|
-
if hParams[:required] and @ObjectData.type?(sKey) != :DataObject
|
299
|
-
oObjMissing << sKey
|
300
|
-
end
|
301
|
-
end
|
302
|
-
}
|
303
|
-
return oObjMissing
|
304
|
-
end
|
305
|
-
|
306
|
-
end
|