lorj 1.0.5 → 1.0.6
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/README.md +13 -0
- data/lib/core/core_setup_ask.rb +34 -3
- data/lib/core/core_setup_encrypt.rb +4 -4
- data/lib/lorj/version.rb +1 -1
- data/lib/providers/openstack/openstack.rb +99 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 913a046318c32edd50058f113100fed25d93075d
|
4
|
+
data.tar.gz: 58fb06cb60adfc5b01682f9c966d23dc82b29ae6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c5839c30daa322cf69478379d1dc5282eded2fdb34e6d1f0de7a37d8674e25bddc5e850a386467e0573eed6fc56b11a83868d9289441897c763a518d44ec9901
|
7
|
+
data.tar.gz: 8128e5644c561b4fd66456e917cfe5cc3a3c51da5c52b581b352adaa3da8f0714a69a745ec37e982c58bbebccaf849c9399526b4c0a30afbe8764143a77f7020
|
data/README.md
CHANGED
@@ -33,6 +33,19 @@ clouds providers.
|
|
33
33
|
Currently, forj cli has implemented *hpcloud* and *openstack* providers, using
|
34
34
|
*fog*. Docker controller is under development.
|
35
35
|
|
36
|
+
### embedded process/controllers
|
37
|
+
|
38
|
+
Currently, lorj embed a Cloud process and 3 providers (controllers: hpcloud/openstack/mock)
|
39
|
+
|
40
|
+
The cloud process is used by [forj cli|http://www.rubydoc.info/gems/forj] - the DevOps forge builder,
|
41
|
+
to execute cloud task transparently against hpcloud or openstack.
|
42
|
+
|
43
|
+
To support a new cloud provider, you need to write your own cloud controller.
|
44
|
+
Look in [lib/providers] to clone an existing one and update to use your own cloud.
|
45
|
+
|
46
|
+
TODO: Move process and controller to new gem libraries.
|
47
|
+
TODO: write up cloud controller documentation for contributors.
|
48
|
+
|
36
49
|
## Getting started
|
37
50
|
|
38
51
|
As playing by example is better than a long discussion, let's start playing with a simple example.
|
data/lib/core/core_setup_ask.rb
CHANGED
@@ -117,14 +117,31 @@ module Lorj
|
|
117
117
|
result
|
118
118
|
end
|
119
119
|
|
120
|
+
# rubocop: disable Metrics/CyclomaticComplexity
|
121
|
+
# rubocop: disable Metrics/PerceivedComplexity
|
122
|
+
|
120
123
|
# Internal setup function to ask to the end user from a list.
|
121
124
|
#
|
122
125
|
# * *Args* :
|
123
126
|
# - +data+ : Data to ask.
|
124
127
|
# - +list_options+: list and validation options
|
128
|
+
# - +:validate+ : Can be :list_strict to restrict possible value to only
|
129
|
+
# those listed.
|
125
130
|
# - +desc+ : Data description
|
126
131
|
# - +options+ : Used when user have to enter a string instead of
|
127
132
|
# selecting from a list.
|
133
|
+
# - +:default_value+ : predfined default value.
|
134
|
+
#
|
135
|
+
# if data model defines :default_value. => choose it
|
136
|
+
# In this last case, the :default_value is interpreted by ERB.
|
137
|
+
# ERB context contains:
|
138
|
+
# - config : data config layer.
|
139
|
+
#
|
140
|
+
# Ex: So you can set :default_value like:
|
141
|
+
#
|
142
|
+
# :default_value: "~/.ssh/<%= config[:keypair_name] %>-id_rsa"
|
143
|
+
# This may assume that keypair_name is setup before abd would need:
|
144
|
+
# - :after: <datas>
|
128
145
|
#
|
129
146
|
# * *Returns*:
|
130
147
|
# - value : value entered by the end user.
|
@@ -138,6 +155,18 @@ module Lorj
|
|
138
155
|
options[:default_value])
|
139
156
|
|
140
157
|
list = result[:list]
|
158
|
+
default = options[:default_value]
|
159
|
+
default = result[:default_value] unless result[:default_value].nil?
|
160
|
+
|
161
|
+
begin
|
162
|
+
default = erb(default)
|
163
|
+
rescue => e
|
164
|
+
PrcLib.warning("ERB error with :%s/:default_value '%s'.\n%s",
|
165
|
+
data, result[:default_value], e.message)
|
166
|
+
else
|
167
|
+
default = nil if default == ''
|
168
|
+
options[:default_value] = default
|
169
|
+
end
|
141
170
|
|
142
171
|
is_strict_list = (list_options[:validate] == :list_strict)
|
143
172
|
|
@@ -155,11 +184,12 @@ module Lorj
|
|
155
184
|
value = _setup_choose_data_from_list(data, desc, list, options)
|
156
185
|
|
157
186
|
if !is_strict_list && value == 'Not in this list'
|
158
|
-
value = _setup_ask_data_from_keyboard(desc, data, options
|
159
|
-
result[:default_value])
|
187
|
+
value = _setup_ask_data_from_keyboard(desc, data, options)
|
160
188
|
end
|
161
189
|
value
|
162
190
|
end
|
191
|
+
# rubocop: enable Metrics/CyclomaticComplexity
|
192
|
+
# rubocop: enable Metrics/PerceivedComplexity
|
163
193
|
|
164
194
|
# Internal setup function to present the list to the user and ask to choose.
|
165
195
|
#
|
@@ -194,8 +224,9 @@ module Lorj
|
|
194
224
|
# - +desc+ : Data description
|
195
225
|
# - +data+ : Data to ask.
|
196
226
|
# - +options+: list and validation options
|
197
|
-
# - :ask_function: Replace the _ask default call by a process function
|
227
|
+
# - :ask_function : Replace the _ask default call by a process function
|
198
228
|
# This function should return a string or nil, if no value.
|
229
|
+
# - :default_value: Predefined default value.
|
199
230
|
# - +default+: Default value.
|
200
231
|
#
|
201
232
|
# setup will present a default value. This value can come from several
|
@@ -84,9 +84,9 @@ module Lorj
|
|
84
84
|
value_hidden = ''
|
85
85
|
begin
|
86
86
|
value_hidden = '*' * _get_encrypted_value(enc_value, entr).length
|
87
|
-
rescue
|
88
|
-
PrcLib.error('Unable to decrypt your %s. You will need to re-enter it.'
|
89
|
-
sDesc)
|
87
|
+
rescue => e
|
88
|
+
PrcLib.error('Unable to decrypt your %s. You will need to re-enter it.'\
|
89
|
+
'\n%s', sDesc, e.message)
|
90
90
|
else
|
91
91
|
PrcLib.message("'%s' is already set. If you want to keep it,"\
|
92
92
|
' just press Enter', sDesc)
|
@@ -137,7 +137,7 @@ module Lorj
|
|
137
137
|
def _ask_encrypted(sDesc, default)
|
138
138
|
entr = _get_encrypt_key
|
139
139
|
|
140
|
-
enc_value = default
|
140
|
+
enc_value = default unless default == ''
|
141
141
|
|
142
142
|
value_hidden = _get_encrypted_value_hidden(sDesc, default, entr)
|
143
143
|
|
data/lib/lorj/version.rb
CHANGED
@@ -35,7 +35,8 @@ class Openstack
|
|
35
35
|
# Define Data used by service
|
36
36
|
|
37
37
|
obj_needs :data, :account_id, :mapping => :openstack_username
|
38
|
-
obj_needs :data, :account_key, :mapping => :openstack_api_key
|
38
|
+
obj_needs :data, :account_key, :mapping => :openstack_api_key,
|
39
|
+
:decrypt => true
|
39
40
|
obj_needs :data, :auth_uri, :mapping => :openstack_auth_uri
|
40
41
|
obj_needs :data, :tenant, :mapping => :openstack_tenant
|
41
42
|
obj_needs :data, ':excon_opts/:connect_timeout', :default_value => 30
|
@@ -139,7 +140,15 @@ class Openstack
|
|
139
140
|
'API, then download the Openstack RC file. The Region name is '\
|
140
141
|
'set as OS_REGION_NAME.'\
|
141
142
|
"\nIf there is no region shown, you can ignore it.",
|
142
|
-
:desc => 'Openstack Compute Region (Ex: RegionOne)'
|
143
|
+
:desc => 'Openstack Compute Region (Ex: RegionOne)',
|
144
|
+
:depends_on => [:account_id, :account_key, :auth_uri, :tenant],
|
145
|
+
:list_values => {
|
146
|
+
:query_type => :controller_call,
|
147
|
+
:object => :services,
|
148
|
+
:query_call => :get_services,
|
149
|
+
:query_params => { :list_services => [:Compute, :compute] },
|
150
|
+
:validate => :list_strict
|
151
|
+
}
|
143
152
|
)
|
144
153
|
|
145
154
|
define_data(:network,
|
@@ -152,7 +161,15 @@ class Openstack
|
|
152
161
|
"\nYou can also get it from Project-Compute-Access & Security-"\
|
153
162
|
'API, then download the Openstack RC file. The Region name is '\
|
154
163
|
'set as OS_REGION_NAME.'\
|
155
|
-
"\nIf there is no region shown, you can ignore it."
|
164
|
+
"\nIf there is no region shown, you can ignore it.",
|
165
|
+
:depends_on => [:account_id, :account_key, :auth_uri, :tenant],
|
166
|
+
:list_values => {
|
167
|
+
:query_type => :controller_call,
|
168
|
+
:object => :services,
|
169
|
+
:query_call => :get_services,
|
170
|
+
:query_params => { :list_services => [:Networking, :network] },
|
171
|
+
:validate => :list_strict
|
172
|
+
}
|
156
173
|
)
|
157
174
|
|
158
175
|
define_obj :server
|
@@ -308,3 +325,82 @@ class OpenstackController
|
|
308
325
|
controller_error "==>Unable to map '%s'. %s", key, e.message
|
309
326
|
end
|
310
327
|
end
|
328
|
+
|
329
|
+
# Following class describe how FORJ should handle Openstack Cloud objects.
|
330
|
+
class OpenstackController
|
331
|
+
# This function requires to return an Array of values or nil.
|
332
|
+
def get_services(sObjectType, oParams)
|
333
|
+
case sObjectType
|
334
|
+
when :services
|
335
|
+
# oParams[sObjectType] will provide the controller object.
|
336
|
+
# This one can be interpreted only by controller code,
|
337
|
+
# except if controller declares how to map with this object.
|
338
|
+
# Processes can deal only process mapped data.
|
339
|
+
# Currently there is no services process function. No need to map.
|
340
|
+
services = oParams[:services]
|
341
|
+
if !oParams[:list_services].is_a?(Array)
|
342
|
+
service_to_find = [oParams[:list_services]]
|
343
|
+
else
|
344
|
+
service_to_find = oParams[:list_services]
|
345
|
+
end
|
346
|
+
# Search for service. Ex: Can be :Networking or network. I currently do
|
347
|
+
# not know why...
|
348
|
+
search_services = services.rh_get(:service_catalog)
|
349
|
+
service = nil
|
350
|
+
service_to_find.each do |sServiceElem|
|
351
|
+
if search_services.key?(sServiceElem)
|
352
|
+
service = sServiceElem
|
353
|
+
break
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
controller_error 'Unable to find services %s',
|
358
|
+
service_to_find if service.nil?
|
359
|
+
result = services.rh_get(:service_catalog, service).keys
|
360
|
+
result.delete('name')
|
361
|
+
result.each_index do |iIndex|
|
362
|
+
result[iIndex] = result[iIndex].to_s if result[iIndex].is_a?(Symbol)
|
363
|
+
end
|
364
|
+
return result
|
365
|
+
else
|
366
|
+
controller_error "'%s' is not a valid object for 'get_services'",
|
367
|
+
sObjectType
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
def format_retrieve_result(retrieve_result)
|
372
|
+
{
|
373
|
+
:auth_token => retrieve_result['access']['token']['id'],
|
374
|
+
:expires => retrieve_result['access']['token']['expires'],
|
375
|
+
:service_catalog =>
|
376
|
+
get_service_catalog(retrieve_result['access']['serviceCatalog']),
|
377
|
+
:endpoint_url => nil,
|
378
|
+
:cdn_endpoint_url => nil
|
379
|
+
}
|
380
|
+
end
|
381
|
+
|
382
|
+
def get_service_catalog(body)
|
383
|
+
fail 'Unable to parse service catalog.' unless body
|
384
|
+
service_catalog = {}
|
385
|
+
body.each do |s|
|
386
|
+
type = s['type']
|
387
|
+
next if type.nil?
|
388
|
+
type = type.to_sym
|
389
|
+
next if s['endpoints'].nil?
|
390
|
+
service_catalog[type] = {}
|
391
|
+
service_catalog[type]['name'] = s['name']
|
392
|
+
service_catalog = parse_service_catalog_endpoint(s, type, service_catalog)
|
393
|
+
end
|
394
|
+
service_catalog
|
395
|
+
end
|
396
|
+
|
397
|
+
def parse_service_catalog_endpoint(s, type, service_catalog)
|
398
|
+
s['endpoints'].each do |ep|
|
399
|
+
next if ep['region'].nil?
|
400
|
+
next if ep['publicURL'].nil?
|
401
|
+
next if ep['publicURL'].empty?
|
402
|
+
service_catalog[type][ep['region'].to_sym] = ep['publicURL']
|
403
|
+
end
|
404
|
+
service_catalog
|
405
|
+
end
|
406
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lorj
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- forj team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|