forj 0.0.39 → 0.0.40

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/lib/repositories.rb CHANGED
@@ -159,7 +159,7 @@ module Repositories
159
159
  end
160
160
  end
161
161
  rescue => e
162
- Logging.fatal(1, "Unable to open the build environment file to migrate it\n%s" % e.backtrace.join('\n'))
162
+ Logging.fatal(1, "Unable to open the build environment file to migrate it", e)
163
163
  end
164
164
  oConfig.ExtraSet(:forj_accounts, sAccountName, :dns, yDns)
165
165
  oConfig.ExtraSave(File.join($FORJ_ACCOUNTS_PATH, sAccountName), :forj_accounts, sAccountName)
data/lib/security.rb CHANGED
@@ -54,6 +54,7 @@ module SecurityGroup
54
54
  if not oSSLError.ErrorDetected(e.message,e.backtrace)
55
55
  retry
56
56
  end
57
+ Logging.fatal(1, "Unable to get list of security groups.", e)
57
58
  end
58
59
  case sgroups.length()
59
60
  when 0
@@ -137,42 +138,70 @@ module SecurityGroup
137
138
  rule
138
139
  end
139
140
 
140
- def hpc_import_key(oConfig, account)
141
-
142
- key_name = oConfig.get('keypair_name')
143
- key_path = oConfig.get('keypair_path')
144
-
145
- mObj = key_path.match(/^(.*)(\.pem)?$/)
146
-
147
- key_path = mObj[1]
148
-
149
- Logging.fatal(1, "'keypair_path' undefined. check your config.yaml file.") if not key_path
150
- Logging.fatal(1, "'keypair_name' undefined. check your config.yaml file.") if not key_name
151
-
152
- pubkey_path = key_path + '.pub'
153
- Logging.fatal(1, "keypair '%s' are missing. Please call 'forj setup %s' to create the missing key pair required." % [pubkey_path, account]) if not File.exists?(pubkey_path)
154
- if not File.exists?(File.join($HPC_KEYPAIRS, key_name + '.pub'))
155
- Logging.info("Importing your forj public key '%s' to hpcloud." % pubkey_path)
156
- command = 'hpcloud keypairs:import %s %s -a %s' % [key_name, pubkey_path, account]
141
+ def keypair_detect(keypair_name, key_fullpath)
142
+ # Build key data information structure.
143
+ # Take care of priv with or without .pem and pubkey with pub.
144
+
145
+ key_basename = File.basename(key_fullpath)
146
+ key_path = File.expand_path(File.dirname(key_fullpath))
147
+
148
+ mObj = key_basename.match(/^(.*?)(\.pem|\.pub)?$/)
149
+ key_basename = mObj[1]
150
+
151
+ private_key_ext = nil
152
+ private_key_ext = "" if File.exists?(File.join(key_path, key_basename))
153
+ private_key_ext = '.pem' if File.exists?(File.join(key_path, key_basename + '.pem'))
154
+ if private_key_ext
155
+ private_key_exist = true
156
+ private_key_name = key_basename + private_key_ext
157
+ else
158
+ private_key_exist = false
159
+ private_key_name = key_basename
160
+ end
161
+
162
+ public_key_exist = File.exists?(File.join(key_path, key_basename + '.pub'))
163
+ public_key_name = key_basename + '.pub'
164
+
165
+
166
+ result = {:keypair_name => keypair_name,
167
+ :keypair_path => key_path, :key_basename => key_basename,
168
+ :private_key_name => private_key_name, :private_key_exist? => private_key_exist,
169
+ :public_key_name => public_key_name, :public_key_exist? => public_key_exist,
170
+ }
171
+ end
172
+
173
+ def hpc_import_key(oForjAccount)
174
+
175
+ keys = keypair_detect(oForjAccount.get(:credentials, 'keypair_name'), oForjAccount.get(:credentials, 'keypair_path'))
176
+ account = oForjAccount.get(:account, :name)
177
+
178
+ Logging.fatal(1, "'keypair_path' undefined. check your config.yaml file.") if not keys[:keypair_path]
179
+ Logging.fatal(1, "'keypair_name' undefined. check your config.yaml file.") if not keys[:keypair_name]
180
+ Logging.fatal(1, "keypair '%s' are missing. Please call 'forj setup %s' to create the missing key pair required." % [keys[:keypair_name], account]) if not keys[:public_key_exist?]
181
+
182
+ public_key_path = File.join(keys[:keypair_path], keys[:public_key_name])
183
+ private_key_path = File.join(keys[:keypair_path], keys[:private_key_name])
184
+
185
+ if not File.exists?(File.join($HPC_KEYPAIRS, keys[:keypair_name] + '.pub'))
186
+ Logging.info("Importing your forj public key '%s' to hpcloud." % keys[:public_key_name])
187
+ command = 'hpcloud keypairs:import %s %s -a %s' % [keys[:keypair_name], public_key_path , account]
157
188
  Logging.debug("Executing command '%s'" % command)
158
189
  Kernel.system(command)
159
190
  else
160
- Logging.info("Using '%s' as public key." % pubkey_path)
191
+ Logging.info("Using '%s' as public key." % public_key_path)
161
192
  end
162
- private_key = nil
163
- private_key = key_path if File.exists?(key_path)
164
- private_key = key_path + '.pem' if File.exists?(key_path + '.pem')
165
- if not File.exists?(File.join($HPC_KEYPAIRS, key_name + '.pem'))
166
- if private_key
167
- Logging.info("Importing your forj private key '%s' to hpcloud." % private_key)
168
- command = 'hpcloud keypairs:private:add %s %s' % [key_name, private_key]
193
+
194
+ if not File.exists?(File.join($HPC_KEYPAIRS, keys[:keypair_name] + '.pem'))
195
+ if keys[:private_key_exist?]
196
+ Logging.info("Importing your forj private key '%s' to hpcloud." % private_key_path)
197
+ command = 'hpcloud keypairs:private:add %s %s' % [keys[:keypair_name], private_key_path]
169
198
  Logging.debug("Executing command '%s'" % command)
170
199
  Kernel.system(command)
171
200
  else
172
201
  Logging.warning('Unable to find the private key. This will be required to access with ssh to Maestro and any blueprint boxes.')
173
202
  end
174
203
  else
175
- Logging.info("Using '%s' as private key." % key_path)
204
+ Logging.info("Using '%s' as private key." % private_key_path)
176
205
  end
177
206
  end
178
207
  end
data/lib/setup.rb CHANGED
@@ -16,312 +16,28 @@
16
16
  # limitations under the License.
17
17
 
18
18
  require 'rubygems'
19
- require 'require_relative'
20
- require 'highline/import'
21
19
 
22
- require_relative 'yaml_parse.rb'
23
- include YamlParse
24
- require_relative 'helpers.rb'
25
- include Helpers
26
-
27
- require 'encryptor' # gem install encryptor
28
- require 'base64'
29
-
30
- # TODO: To move to a specific module driven by providers.
31
- require 'hpcloud/version'
32
- require 'hpcloud/config'
33
- require 'hpcloud/accounts'
34
- require 'hpcloud/connection'
35
- include HP::Cloud
36
20
 
37
21
  #
38
22
  # Setup module call the hpcloud functions
39
23
  #
40
24
  module Setup
41
- def setup(oConfig, options )
25
+ def setup(oConfig)
42
26
 
43
27
  # TODO: Provide a way to re-edit all or partially elements set up by this function.
44
28
  begin
45
- Logging.fatal(1, 'No provider specified.') if not oConfig.exist?('provider')
46
-
47
- sProvider = oConfig.get('provider')
48
- sAccountName = sProvider # By default, the account name uses the same provider name.
49
- sAccountName = options[:account_name] if options[:account_name]
50
-
51
- if sProvider != 'hpcloud'
52
- Logging.fatal(1, "forj setup support only hpcloud. '%s' is currently not supported." % sProvider)
53
- end
29
+ oForjAccount = ForjAccount.new(oConfig)
54
30
 
55
- # setting up provider account - Required, while calling external provider tool, like hpcloud.
56
- setup_provider_account(oConfig, sAccountName)
31
+ oForjAccount.ac_load()
32
+ # TODO: Provide a way to update partially some account data.
33
+ oForjAccount.setup() # any kind of setup, ask from users.
57
34
 
58
- # Implementation of simple credential encoding for build.sh/maestro
59
- save_maestro_creds(oConfig, sAccountName)
35
+ oForjAccount.ac_save()
60
36
 
61
- # DNS Setting for Gardener
62
- setup_dns(oConfig, sAccountName)
63
-
64
- # Check/create keypair
65
- keypair_setup(oConfig)
66
-
67
- # Checking cloud connection
68
- Logging.message("Checking cloud connection")
69
- oFC=ForjConnection.new(oConfig)
70
-
71
- Logging.message("Setup '%s' done. Thank you." % sAccountName)
72
-
73
37
  rescue RuntimeError => e
74
38
  Logging.fatal(1,e.message)
75
39
  rescue => e
76
- Logging.fatal(1,"%s\n%s" % [e.message,e.backtrace.join("\n")])
40
+ Logging.fatal(1,"Unable to run setup" , e)
77
41
  end
78
42
  end
79
43
  end
80
-
81
- def setup_tenant_name(oConfig, sAccountName)
82
- # Maestro uses fog/openstack to connect to the cloud. It needs Tenant name instead of tenant ID.
83
- # Getting it from Compute connection and set it
84
-
85
- oSSLError=SSLErrorMgt.new # Retry object
86
- Logging.debug("Getting tenants from hpcloud cli libraries")
87
- begin
88
- tenants = Connection.instance.tenants(sAccountName)
89
- rescue => e
90
- if not oSSLError.ErrorDetected(e.message,e.backtrace)
91
- retry
92
- end
93
- Logging.fatal(1, 'Network: Unable to connect.')
94
- end
95
- tenant_id = rhGet(oConfig.ExtraGet(:hpc_accounts, sAccountName, :credentials), :tenant_id)
96
- tenant_name = nil
97
- tenants.each { |elem| tenant_name = elem['name'] if elem['id'] == tenant_id }
98
- if tenant_name
99
- Logging.debug("Tenant ID '%s': '%s' found." % [tenant_id, tenant_name])
100
- hCompute = { :tenant_name => tenant_name }
101
- oConfig.ExtraSet(:forj_accounts, sAccountName, :compute, hCompute)
102
- else
103
- Logging.error("Unable to find the tenant Name for '%s' ID." % tenant_id)
104
- end
105
- oConfig.set('tenants', tenants)
106
- end
107
-
108
- def setup_provider_account(oConfig, sAccountName)
109
- # TODO: Support of multiple providers thanks to fog.
110
- # TODO: Replace this code by our own forj account setup, inspired/derived from hpcloud account::setup
111
-
112
- # delegate the initial configuration to hpcloud (unix_cli)
113
- if File.exists?(File.join($HPC_ACCOUNTS, 'hp')) and not File.exists?(File.join($HPC_ACCOUNTS, sAccountName)) and sAccountName != 'hp'
114
- Logging.info("hpcloud: Copying 'hp' account setup to '%s'" % sAccountName)
115
- Kernel.system('hpcloud account:copy hp %s' % [sAccountName])
116
- end
117
-
118
- Logging.info("Configuring hpcloud account '%s'" % [sAccountName] )
119
- command = 'hpcloud account:setup %s' % [sAccountName]
120
- Logging.debug("Executing : '%s'" % command)
121
- case Kernel.system(command)
122
- when false
123
- Logging.fatal(1, "Unable to setup your hpcloud account")
124
- when nil
125
- Logging.fatal(1, "Unable to execute 'hpcloud' cli. Please check hpcloud installation.")
126
- end
127
-
128
- if not oConfig.yConfig['default'].has_key?('account')
129
- oConfig.LocalSet('account',sAccountName)
130
- oConfig.SaveConfig
131
- end
132
-
133
- # Loading HPCloud account setting in Config.
134
- hpc_account_file = File.join($HPC_ACCOUNTS, sAccountName)
135
-
136
- # Maestro compute use openstack. It requires meta tenant_name (not ID). Need to query HPC to get the Project Name from the ID.
137
- oConfig.ExtraLoad(hpc_account_file, :hpc_accounts, sAccountName)
138
-
139
- setup_tenant_name(oConfig, sAccountName)
140
- end
141
-
142
- def setup_dns(oConfig, sAccountName)
143
- sAsk = "Optionally, you can ask Maestro to manage a Domain name. It requires your DNS cloud service to be enabled.\nDo you want to configure it?"
144
- if agree(sAsk)
145
- # Get HPCloud account definition
146
- yHPC = oConfig.ExtraGet(:hpc_accounts, sAccountName)
147
-
148
- # Get Forj account definition
149
- yDNS = oConfig.ExtraGet(:forj_accounts, sAccountName, :dns)
150
- yDNS = {} if not yDNS
151
-
152
- # Getting tenants
153
- tenants = oConfig.get('tenants')
154
-
155
- # Question about DNS Tenant ID
156
- # In HPCloud : credentials/tenant_id
157
- aDNS_TenantIDs = []
158
- sDNS_TenantIDs = rhGet(yDNS, :tenant_id)
159
- sDNS_TenantIDs = rhGet(yHPC, :credentials, :tenant_id) if not sDNS_TenantIDs and rhExist?(yHPC, :credentials, :tenant_id) > 0
160
-
161
- Logging.message("Following are the list of know project attached to your credentials:")
162
- tenants.each do | elem |
163
- aDNS_TenantIDs.push(elem['id'])
164
- if sDNS_TenantIDs and elem['id'] == sDNS_TenantIDs
165
- Logging.message("%s - %s" % [ANSI.bold+elem['id']+ANSI.reset, elem['name']])
166
- else
167
- Logging.message("%s - %s" % [elem['id'], elem['name']])
168
- end
169
- end
170
-
171
- sOption = ' [%s]' % aDNS_TenantIDs.join(', ') if aDNS_TenantIDs.length() == 2
172
- sDNS_TenantID = ask('Enter DNS Tenant ID:%s' % sOption) do |q|
173
- q.default = sDNS_TenantIDs
174
- q.validate = /[\w\d]+/
175
- end
176
- yDNS[:tenant_id] = sDNS_TenantID.to_s
177
-
178
- # Question about DNS Service
179
- # In HPCloud : regions/dns
180
- if sDNS_TenantID == rhGet(yHPC, :credentials, :tenant_id)
181
- sDNS_Service = rhGet(yHPC, :regions, :dns)
182
- else
183
- aDNS_Services = []
184
- aDNS_Services.push(rhGet(yDNS, :service)) if rhExist?(yDNS, :service) > 0
185
-
186
- sDNS_Service = ask("Enter DNS Service for the Tenant ID '%s' (ex: region-a.geo-1): " % sDNS_TenantID) do |q|
187
- q.validate = /[\w.-]+/
188
- end
189
- end
190
- yDNS[:service] = sDNS_Service.to_s
191
-
192
- else
193
- yDNS = {} # Any information about DNS setting is removed.
194
- Logging.message("Maestro won't manage any Domain.")
195
- end
196
- # Question about Domain name
197
- previousDomainName = rhGet(yDNS, :domain_name) if rhExist?(yDNS, :domain_name) > 0
198
-
199
- sDNS_DomainName = ask('Enter Domain name (puppet requirement) (ex: dev.forj.io):') do |q|
200
- q.default = previousDomainName if previousDomainName
201
- q.validate = /[\w._]+/
202
- end
203
- yDNS[:domain_name] = sDNS_DomainName.to_s
204
-
205
- oConfig.ExtraSet(:forj_accounts, sAccountName, :dns, yDNS)
206
- forjAccountFile = File.join($FORJ_ACCOUNTS_PATH, sAccountName)
207
- oConfig.ExtraSave(forjAccountFile, :forj_accounts, sAccountName)
208
- end
209
-
210
- def ensure_forj_dirs_exists()
211
- # Function to create FORJ paths if missing.
212
-
213
- # Defining Global variables
214
- $FORJ_DATA_PATH = File.expand_path(File.join('~', '.forj'))
215
- $FORJ_ACCOUNTS_PATH = File.join($FORJ_DATA_PATH, 'accounts')
216
- $FORJ_KEYPAIRS_PATH = File.join($FORJ_DATA_PATH, 'keypairs')
217
- $FORJ_CREDS_PATH = File.expand_path(File.join('~', '.cache', 'forj'))
218
-
219
- # TODO: To move to an hpcloud object.
220
- $HPC_KEYPAIRS = File.expand_path(File.join('~', '.hpcloud', 'keypairs'))
221
- $HPC_ACCOUNTS = File.expand_path(File.join('~', '.hpcloud', 'accounts'))
222
-
223
- Helpers.ensure_dir_exists($FORJ_DATA_PATH)
224
- Helpers.ensure_dir_exists($FORJ_ACCOUNTS_PATH)
225
- Helpers.ensure_dir_exists($FORJ_KEYPAIRS_PATH)
226
- Helpers.ensure_dir_exists($FORJ_CREDS_PATH)
227
- end
228
-
229
- def keypair_setup(oConfig)
230
-
231
- key_path = oConfig.get('keypair_path')
232
-
233
- Logging.info("Configuring forj keypair '%s'" % [key_path] )
234
-
235
- if not File.exists?(key_path)
236
- # Need to create a key. ask if we need so.
237
- real_key_path = File.expand_path(ask("If your ssh keypair doesn't exist, forj will ask ssh-keygen to create one for you.\nPrivate key file path:") do |q|
238
- q.validate = /\w+/
239
- q.default = key_path
240
- end)
241
- if not File.exists?(real_key_path)
242
- Helpers.ensure_dir_exists(File.dirname(real_key_path))
243
- command = 'ssh-keygen -t rsa -f %s' % real_key_path
244
- Logging.debug("Executing '%s'" % command)
245
- system(command)
246
- end
247
- if not File.exists?(real_key_path)
248
- Logging.fatal(1, "'%s' not found. Unable to add your keypair to hpcloud. Create it yourself and provide it with -p option. Then retry." % [real_key_path])
249
- else
250
- if real_key_path != key_path and not oConfig.LocalDefaultExist?('keypair_path')
251
- Logging.debug("Saving forj keypair '%s' as default." % [real_key_path] )
252
- oConfig.LocalSet('keypair_path', real_key_path)
253
- oConfig.SaveConfig()
254
- end
255
- end
256
- end
257
- end
258
-
259
-
260
- def save_maestro_creds(oConfig, sAccountName)
261
- # Check required global data
262
- if not $FORJ_CREDS_PATH
263
- Logging.fatal(1, "Internal error: '$FORJ_CREDS_PATH' missing.")
264
- end
265
- if not Helpers.dir_exists?($FORJ_CREDS_PATH)
266
- Logging.fatal(1, "Internal error: '%s' doesn't exist." % $FORJ_CREDS_PATH)
267
- end
268
-
269
- Logging.info("Completing hpcloud account '%s' information." % [sAccountName] )
270
-
271
- forjAccountFile = File.join($FORJ_ACCOUNTS_PATH, sAccountName)
272
- oConfig.ExtraLoad(forjAccountFile, :forj_accounts, sAccountName)
273
-
274
- forj_user = rhGet(oConfig.ExtraGet(:forj_accounts, sAccountName, :credentials), :os_user)
275
-
276
- hpcloud_os_user = ask('Enter hpcloud username: ') do |q|
277
- q.validate = /\w+/
278
- q.default = forj_user if forj_user
279
- end
280
-
281
- hpcloud_os_key = ask("Enter hpcloud password for '%s': " % hpcloud_os_user) do |q|
282
- q.echo = '*'
283
- q.validate = /.+/
284
- end
285
-
286
- # Checking key file used to encrypt/decrypt passwords
287
- key_file = File.join($FORJ_CREDS_PATH, '.key')
288
- if not File.exists?(key_file)
289
- # Need to create a random key.
290
- entr = { :key => rand(36**10).to_s(36), :salt => Time.now.to_i.to_s, :iv => OpenSSL::Cipher::Cipher.new('aes-256-cbc').random_iv}
291
-
292
- Logging.debug("Writing '%s' key file" % key_file)
293
- File.open(key_file, 'w') do |out|
294
- out.write(Base64::encode64(entr.to_yaml))
295
- end
296
- else
297
- Logging.debug("Loading '%s' key file" % key_file)
298
- encoded_key = IO.read(key_file)
299
- entr = YAML.load(Base64::decode64(encoded_key))
300
- end
301
- enc_hpcloud_os_key = Base64::strict_encode64(Encryptor.encrypt(:value => hpcloud_os_key, :key => entr[:key], :iv => entr[:iv], :salt => entr[:salt]))
302
-
303
- cloud_fog = File.join($FORJ_CREDS_PATH, sAccountName+'.g64')
304
-
305
- # Security fix: Remove old temp file with clear password.
306
- old_file = '%s/master.forj-13.5' % [$FORJ_CREDS_PATH]
307
- File.delete(old_file) if File.exists?(old_file)
308
- old_file = '%s/creds' % [$FORJ_CREDS_PATH]
309
- File.delete(old_file) if File.exists?(old_file)
310
-
311
- hpc_creds = oConfig.ExtraGet(:hpc_accounts, sAccountName, :credentials)
312
-
313
- forj_creds = { :os_user => hpcloud_os_user.to_s,
314
- :os_enckey => enc_hpcloud_os_key
315
- }
316
- oConfig.ExtraSet(:forj_accounts, sAccountName, :credentials, forj_creds)
317
- oConfig.ExtraSave(forjAccountFile, :forj_accounts, sAccountName)
318
-
319
- IO.popen('gzip -c | base64 -w0 > %s' % [cloud_fog], 'r+') {|pipe|
320
- pipe.puts('HPCLOUD_OS_USER=%s' % [hpcloud_os_user] )
321
- pipe.puts('HPCLOUD_OS_KEY=%s' % [hpcloud_os_key] )
322
- pipe.puts('DNS_KEY=%s' % [hpc_creds[:account_id]] )
323
- pipe.puts('DNS_SECRET=%s' % [hpc_creds[:secret_key]])
324
- pipe.close_write
325
- }
326
- Logging.info("'%s' written." % cloud_fog)
327
- end
@@ -28,12 +28,16 @@ $LOAD_PATH << './lib'
28
28
 
29
29
  require 'forj-config.rb' # Load class ForjConfig
30
30
  require 'log.rb' # Load default loggers
31
+ require 'connection.rb' # Load class ForjConnection
32
+ require 'forj-account.rb'
33
+
34
+ # Initialize forj paths
35
+ ensure_forj_dirs_exists()
31
36
 
32
37
  include Logging
33
38
 
34
39
  $FORJ_LOGGER=ForjLog.new('forj-rspec.log', Logger::FATAL)
35
40
 
36
- require 'connection.rb' # Load class ForjConnection
37
41
 
38
42
  describe 'Module: forj-connection' do
39
43