forj 0.0.48 → 1.0.0

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/forj-account.rb CHANGED
@@ -16,22 +16,6 @@
16
16
  # limitations under the License.
17
17
 
18
18
  require 'rubygems'
19
- require 'highline/import'
20
-
21
- require 'yaml_parse.rb'
22
- include YamlParse
23
- require 'helpers.rb'
24
- include Helpers
25
-
26
- require 'encryptor' # gem install encryptor
27
- require 'base64'
28
-
29
- # TODO: To move to a specific module driven by providers.
30
- require 'hpcloud/version'
31
- require 'hpcloud/config'
32
- require 'hpcloud/accounts'
33
- require 'hpcloud/connection'
34
- include HP::Cloud
35
19
 
36
20
  class ForjAccounts
37
21
  # Class to query FORJ Accounts list.
@@ -262,7 +246,7 @@ class ForjAccount
262
246
  @hAccountData = {:account => {:name => sAccountName, :provider => @oConfig.get(:provider_name)}}
263
247
  end
264
248
 
265
- def ac_load(sAccountName = @sAccountName, bHPCloudLoad = true)
249
+ def ac_load(sAccountName = @sAccountName)
266
250
  # Load Account Information
267
251
 
268
252
  if sAccountName != @sAccountName
@@ -275,7 +259,7 @@ class ForjAccount
275
259
  sProvider = @oConfig.get(:provider, 'hpcloud')
276
260
  rhSet(@hAccountData, @sAccountName, :account, :name) if rhExist?(@hAccountData, :account, :name) != 2
277
261
  rhSet(@hAccountData, sProvider, :account, :provider) if rhExist?(@hAccountData, :account, :provider) != 2
278
- provider_load() if bHPCloudLoad
262
+
279
263
  if rhKeyToSymbol?(@hAccountData, 2)
280
264
  @hAccountData = rhKeyToSymbol(@hAccountData, 2)
281
265
  self.ac_save()
@@ -286,7 +270,7 @@ class ForjAccount
286
270
  end
287
271
 
288
272
  def dump()
289
- { :forj_account => @hAccountData, :hpc_account => provider_load() }
273
+ { :forj_account => @hAccountData }
290
274
  end
291
275
 
292
276
  def ac_save()
@@ -299,367 +283,6 @@ class ForjAccount
299
283
  end
300
284
  end
301
285
 
302
- def setup()
303
- # Full setup to make it work.
304
-
305
- # setting up provider account - Required, while calling external provider tool, like hpcloud.
306
- self.setup_provider_account()
307
-
308
- # Implementation of simple credential encoding for build.sh/maestro
309
- self.setup_maestro_creds()
310
-
311
- # DNS Setting for Gardener
312
- self.setup_dns()
313
-
314
- # Check/create keypair
315
- self.keypair_setup()
316
-
317
- # Checking cloud connection
318
- Logging.message("Checking cloud connection")
319
- ForjConnection.new(self)
320
-
321
- Logging.message("Setup '%s' done. Thank you." % @sAccountName)
322
- end
323
-
324
- def setup_provider_account()
325
- # TODO: Support of multiple providers thanks to fog.
326
- # TODO: Replace this code by our own forj account setup, inspired/derived from hpcloud account::setup
327
-
328
- # delegate the initial configuration to hpcloud (unix_cli)
329
- if File.exists?(File.join($HPC_ACCOUNTS, 'hp')) and not File.exists?(File.join($HPC_ACCOUNTS, @sAccountName)) and @sAccountName != 'hp'
330
- Logging.info("hpcloud: Copying 'hp' account setup to '%s'" % @sAccountName)
331
- Kernel.system('hpcloud account:copy hp %s' % [@sAccountName])
332
- end
333
-
334
- Logging.info("Configuring hpcloud account '%s'" % [@sAccountName] )
335
- command = 'hpcloud account:setup %s' % [@sAccountName]
336
- Logging.debug("Executing : '%s'" % command)
337
- case Kernel.system(command)
338
- when false
339
- Logging.fatal(1, "Unable to setup your '%s' account" % [@sAccountName])
340
- when nil
341
- Logging.fatal(1, "Unable to execute 'hpcloud' cli. Please check hpcloud installation.")
342
- end
343
-
344
- provider_load() # To ensure latest provider data are loaded
345
-
346
- setup_tenant_name()
347
- end
348
-
349
- def provider_load()
350
- # TODO: Should be provider agnostic
351
- # Loading HPCloud account setting in Config.
352
- hpc_account_file = File.join($HPC_ACCOUNTS, @sAccountName)
353
-
354
- # Maestro compute use openstack. It requires meta tenant_name (not ID). Need to query HPC to get the Project Name from the ID.
355
- @oConfig.ExtraLoad(hpc_account_file, :hpc_accounts, @sAccountName)
356
- end
357
-
358
- # Maestro uses fog/openstack to connect to the cloud. It needs Tenant name instead of tenant ID.
359
- # Getting it from Compute connection and set it
360
- def setup_tenant_name()
361
- oSSLError=SSLErrorMgt.new # Retry object
362
- Logging.debug("Getting tenants from hpcloud cli libraries")
363
- begin
364
- tenants = Connection.instance.tenants(@sAccountName)
365
- rescue => e
366
- if not oSSLError.ErrorDetected(e.message,e.backtrace)
367
- retry
368
- end
369
- Logging.fatal(1, 'Network: Unable to connect.')
370
- end
371
- tenant_id = rhGet(@oConfig.ExtraGet(:hpc_accounts, @sAccountName, :credentials), :tenant_id)
372
- tenant_name = nil
373
- tenants.each { |elem| tenant_name = elem['name'] if elem['id'] == tenant_id }
374
- if tenant_name
375
- Logging.debug("Tenant ID '%s': '%s' found." % [tenant_id, tenant_name])
376
- hCompute = { :tenant_name => tenant_name }
377
- rhSet(@hAccountData, hCompute, :maestro)
378
- else
379
- Logging.error("Unable to find the tenant Name for '%s' ID." % tenant_id)
380
- end
381
- @oConfig.set('tenants', tenants)
382
- end
383
-
384
- # Setting up DNS information
385
- def setup_dns()
386
- # Get HPCloud account definition
387
- yHPC = @oConfig.ExtraGet(:hpc_accounts, @sAccountName)
388
- # Get Forj account definition
389
- yDNS = rhGet(@hAccountData, :dns)
390
- yDNS = {} if not yDNS
391
-
392
- sAsk = "Optionally, you can ask Maestro to use/manage a domain name on your cloud. It requires your DNS cloud service to be enabled.\nDo you want to configure it?"
393
- if agree(sAsk)
394
- # Getting tenants
395
- tenants = @oConfig.get(:tenants)
396
-
397
- # Question about DNS Tenant ID
398
- # In HPCloud : credentials/tenant_id
399
- aDNS_TenantIDs = []
400
- sDNS_TenantIDs = rhGet(yDNS, :tenant_id)
401
- sDNS_TenantIDs = rhGet(yHPC, :credentials, :tenant_id) if not sDNS_TenantIDs and rhExist?(yHPC, :credentials, :tenant_id) > 0
402
-
403
- Logging.message("Following are the list of know project attached to your credentials:")
404
- tenants.each do | elem |
405
- aDNS_TenantIDs.push(elem['id'])
406
- if sDNS_TenantIDs and elem['id'] == sDNS_TenantIDs
407
- Logging.message("%s - %s" % [ANSI.bold+elem['id']+ANSI.reset, elem['name']])
408
- else
409
- Logging.message("%s - %s" % [elem['id'], elem['name']])
410
- end
411
- end
412
-
413
- sOption = ' [%s]' % aDNS_TenantIDs.join(', ') if aDNS_TenantIDs.length() == 2
414
- sDNS_TenantID = ask('Enter DNS Tenant ID:%s' % sOption) do |q|
415
- q.default = sDNS_TenantIDs
416
- q.validate = /[\w\d]+/
417
- end
418
- yDNS[:tenant_id] = sDNS_TenantID.to_s
419
-
420
- # Question about DNS Service
421
- # In HPCloud : regions/dns
422
- if sDNS_TenantID == rhGet(yHPC, :credentials, :tenant_id)
423
- sDNS_Service = rhGet(yHPC, :regions, :dns)
424
- else
425
- aDNS_Services = []
426
- aDNS_Services.push(rhGet(yDNS, :service)) if rhExist?(yDNS, :service) > 0
427
-
428
- sDNS_Service = ask("Enter DNS Service for the Tenant ID '%s' (ex: region-a.geo-1): " % sDNS_TenantID) do |q|
429
- q.validate = /[\w.-]+/
430
- end
431
- end
432
- yDNS[:service] = sDNS_Service.to_s
433
-
434
- else
435
- yDNS.delete(:service)
436
- yDNS.delete(:tenant_id)
437
- Logging.message("Maestro won't manage any Domain with '%s' provider." % [ rhGet(@hAccountData, [:account, :provider])])
438
- end
439
- # Question about Domain name
440
- previousDomainName = rhGet(yDNS, :domain_name) if rhExist?(yDNS, :domain_name) > 0
441
-
442
- sDNS_DomainName = ask('Enter Domain name to add to hostnames (puppet requirement) (ex: dev.forj.io):') do |q|
443
- q.default = previousDomainName if previousDomainName
444
- q.validate = /[\w._]+/
445
- end
446
- yDNS[:domain_name] = sDNS_DomainName.to_s
447
-
448
- # Attaching to the account.
449
- rhSet(@hAccountData, yDNS, :dns)
450
- end
451
-
452
- # manage keypair attached to a FORJ account.
453
- def keypair_setup()
454
-
455
- # Getting Account keypair information
456
- yCreds = rhGet(@hAccountData, :credentials)
457
- key_name = @oConfig.get(:keypair_name, yCreds )
458
- orig_key_path = File.expand_path(@oConfig.get(:keypair_path, yCreds))
459
-
460
- Logging.warning("'keypair_path' is missing at least from defaults.yaml. To fix it, set it in your configuration file ~/.forj/config.yaml under default section") if not orig_key_path
461
-
462
- key_name = ask ("Please provide the keypair name used by default on this account:") do | q |
463
- q.default = key_name
464
- q.validate = /.*+/
465
- end
466
- key_name = key_name.to_s
467
-
468
- key_path = nil
469
- while not key_path
470
- key_path = ask ("Please provide the SSH private key path used by default on this account:") do | q |
471
- q.default = orig_key_path
472
- q.validate = /.*+/
473
- end
474
- keys_entered = keypair_detect(key_name, key_path)
475
- if not keys_entered[:private_key_exist? ] and not keys_entered[:public_key_exist? ]
476
- if agree("The key you entered was not found. Do you want to create this one?")
477
- base_dir = keys_entered[:keypair_path]
478
- if not File.directory?(base_dir)
479
- if agree("'%s' doesn't exist. Do you want to create it?" % base_dir)
480
- AppInit.ensure_dir_exists(base_dir)
481
- end
482
- end
483
- else
484
- key_path = nil
485
- end
486
- end
487
- end
488
- keys_imported = nil
489
- keys_imported = keypair_detect(key_name, @oConfig.LocalGet(key_name, :imported_keys)) if @oConfig.LocalExist?(key_name, :imported_keys)
490
-
491
- if keys_imported and keys_imported[:key_basename] != keys_entered[:key_basename] and $FORJ_KEYPAIRS_PATH != keys_entered[:keypair_path]
492
- Logging.warning("The private key '%s' was imported from a different private key file '%s'.\nTo not overwrite it, we recommend you to choose a different keypair name." % [key_name, sImportedKey])
493
- key_name = nil
494
- end
495
-
496
-
497
- keys = keypair_detect(key_name, key_path)
498
-
499
- Logging.info("Configuring forj keypair '%s'" % [ keys[:keypair_name] ] )
500
-
501
-
502
- private_key_file = File.join(keys[:keypair_path], keys[:private_key_name])
503
- public_key_file = File.join(keys[:keypair_path], keys[:public_key_name])
504
-
505
-
506
- # Creation sequences
507
- if not keys[:private_key_exist? ]
508
- # Need to create a key. ask if we need so.
509
- Logging.message("The private key file attached to keypair named '%s' is not found. forj will propose to create one for you. Please review the proposed private key file name and path.\nYou can press Enter to accept the default value." % keys[:keypair_name])
510
- real_key_path = File.expand_path(ask("Private key file path:") do |q|
511
- q.validate = /\w+/
512
- q.default = private_key_file
513
- end)
514
- if not File.exists?(real_key_path)
515
- AppInit.ensure_dir_exists(File.dirname(real_key_path))
516
- command = 'ssh-keygen -t rsa -f %s' % real_key_path
517
- Logging.debug("Executing '%s'" % command)
518
- system(command)
519
- end
520
- if not File.exists?(real_key_path)
521
- 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])
522
- else
523
- if real_key_path != key_path and not @oConfig.LocalDefaultExist?('keypair_path')
524
- Logging.debug("Saving forj keypair '%s' as default." % [real_key_path] )
525
- @oConfig.LocalSet('keypair_path', real_key_path)
526
- @oConfig.SaveConfig()
527
- end
528
- end
529
- end
530
-
531
- if not keys[:public_key_exist? ]
532
- Logging.message("Your public key '%s' was not found. Getting it from the private one. It may require your passphrase." % [public_key_file])
533
- command = 'ssh-keygen -y -f %s > %s' % [private_key_file,public_key_file ]
534
- Logging.debug("Executing '%s'" % command)
535
- system(command)
536
- end
537
-
538
- forj_private_key_file = File.join($FORJ_KEYPAIRS_PATH, key_name )
539
- forj_public_key_file = File.join($FORJ_KEYPAIRS_PATH, key_name + ".pub")
540
-
541
- # Saving sequences
542
- if keys[:keypair_path] != $FORJ_KEYPAIRS_PATH
543
- if not File.exists?(forj_private_key_file)
544
- Logging.info("Importing key pair to FORJ keypairs list.")
545
- FileUtils.copy(private_key_file, forj_private_key_file)
546
- FileUtils.copy(public_key_file, forj_public_key_file)
547
- # Attaching this keypair to the account
548
- rhSet(@hAccountData, key_name, :credentials, 'keypair_name')
549
- rhSet(@hAccountData, forj_private_key_file, :credentials, 'keypair_path')
550
- @oConfig.LocalSet(key_name.to_s, private_key_file, :imported_keys)
551
- @oConfig.SaveConfig()
552
- end
553
- end
554
- end
555
-
556
- def setup_maestro_creds()
557
- # Check required global data
558
- if not $FORJ_CREDS_PATH
559
- Logging.fatal(1, "Internal error: '$FORJ_CREDS_PATH' missing.")
560
- end
561
- if not Helpers.dir_exists?($FORJ_CREDS_PATH)
562
- Logging.fatal(1, "Internal error: '%s' doesn't exist." % $FORJ_CREDS_PATH)
563
- end
564
-
565
- Logging.info("Completing hpcloud account '%s' information." % [@sAccountName] )
566
-
567
- forj_user = rhGet(@hAccountData, :credentials, :os_user)
568
- enc_hpcloud_os_key = rhGet(@hAccountData, :credentials, :os_enckey)
569
-
570
- hpcloud_os_user = ask('Enter hpcloud username: ') do |q|
571
- q.validate = /\w+/
572
- q.default = forj_user if forj_user
573
- end
574
-
575
- # Checking key file used to encrypt/decrypt passwords
576
- key_file = File.join($FORJ_CREDS_PATH, '.key')
577
- if not File.exists?(key_file)
578
- # Need to create a random key.
579
- entr = {
580
- :key => rand(36**10).to_s(36),
581
- :salt => Time.now.to_i.to_s,
582
- :iv => Base64::strict_encode64(OpenSSL::Cipher::Cipher.new('aes-256-cbc').random_iv)
583
- }
584
-
585
- Logging.debug("Writing '%s' key file" % key_file)
586
- File.open(key_file, 'w') do |out|
587
- out.write(Base64::encode64(entr.to_yaml))
588
- end
589
- else
590
- Logging.debug("Loading '%s' key file" % key_file)
591
- encoded_key = IO.read(key_file)
592
- entr = YAML.load(Base64::decode64(encoded_key))
593
- end
594
-
595
- if enc_hpcloud_os_key
596
- begin
597
- hpcloud_os_key_hidden = '*' * Encryptor.decrypt(
598
- :value => Base64::strict_decode64(enc_hpcloud_os_key),
599
- :key => entr[:key],
600
- :iv => Base64::strict_decode64(entr[:iv]),
601
- :salt => entr[:salt]
602
- ).length
603
- rescue => e
604
- Logging.error("Unable to decrypt your password. You will need to re-enter it.")
605
- enc_hpcloud_os_key = ""
606
- else
607
- hpcloud_os_key_hidden="[%s]" % hpcloud_os_key_hidden
608
- Logging.message("A password is already set for '%s'. If you want to keep it, just press Enter" % [hpcloud_os_user])
609
- end
610
- else
611
- hpcloud_os_key_hidden = ""
612
- end
613
-
614
- hpcloud_os_key = ""
615
- while hpcloud_os_key == ""
616
- # ask for password.
617
- hpcloud_os_key = ask("Enter hpcloud password for '%s': %s" % [hpcloud_os_user, hpcloud_os_key_hidden]) do |q|
618
- q.echo = '*'
619
- end
620
- if hpcloud_os_key == "" and enc_hpcloud_os_key
621
- hpcloud_os_key = Encryptor.decrypt(
622
- :value => Base64::strict_decode64(enc_hpcloud_os_key),
623
- :key => entr[:key],
624
- :iv => Base64::strict_decode64(entr[:iv]),
625
- :salt => entr[:salt]
626
- )
627
- else
628
- Logging.message("The password cannot be empty.") if hpcloud_os_key == ""
629
- end
630
- end
631
- enc_hpcloud_os_key = Base64::strict_encode64(
632
- Encryptor.encrypt(
633
- :value => hpcloud_os_key,
634
- :key => entr[:key],
635
- :iv => Base64::strict_decode64(entr[:iv]),
636
- :salt => entr[:salt]
637
- )
638
- )
639
-
640
- cloud_fog = File.join($FORJ_CREDS_PATH, @sAccountName+'.g64')
641
-
642
- # Security fix: Remove old temp file with clear password.
643
- old_file = '%s/master.forj-13.5' % [$FORJ_CREDS_PATH]
644
- File.delete(old_file) if File.exists?(old_file)
645
- old_file = '%s/creds' % [$FORJ_CREDS_PATH]
646
- File.delete(old_file) if File.exists?(old_file)
647
-
648
- provider_load() if not @oConfig.ExtraExist?(:hpc_accounts, @sAccountName)
649
- hpc_creds = @oConfig.ExtraGet(:hpc_accounts, @sAccountName, :credentials)
650
-
651
- rhSet(@hAccountData, hpcloud_os_user.to_s, :credentials, :os_user)
652
- rhSet(@hAccountData, enc_hpcloud_os_key, :credentials, :os_enckey)
653
-
654
- IO.popen('gzip -c | base64 -w0 > %s' % [cloud_fog], 'r+') {|pipe|
655
- pipe.puts('HPCLOUD_OS_USER=%s' % [hpcloud_os_user] )
656
- pipe.puts('HPCLOUD_OS_KEY=%s' % [hpcloud_os_key] )
657
- pipe.puts('DNS_KEY=%s' % [hpc_creds[:account_id]] )
658
- pipe.puts('DNS_SECRET=%s' % [hpc_creds[:secret_key]])
659
- pipe.close_write
660
- }
661
- Logging.info("'%s' written." % cloud_fog)
662
- end
663
286
  # private functions
664
287
  private
665
288
  def _set(section, key, value)
data/lib/forj-config.rb CHANGED
@@ -64,18 +64,18 @@ def rhSet(yVal, value, *p)
64
64
  p=p.flatten
65
65
  if p.length() == 1
66
66
  if not yVal.nil?
67
- if value
67
+ if not value.nil?
68
68
  yVal[p[0]] = value
69
69
  else
70
70
  yVal.delete(p[0])
71
71
  end
72
72
  return yVal
73
73
  end
74
- if value
75
- ret = { p[0] => value }
76
- else
77
- ret = {}
78
- end
74
+ #~ if value
75
+ ret = { p[0] => value }
76
+ #~ else
77
+ #~ ret = {}
78
+ #~ end
79
79
  return ret
80
80
  end
81
81
  if not yVal.nil?