lorj 1.0.5 → 1.0.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|