forj 1.0.7 → 1.0.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 70f1b264464790bfae435e9dcfb4fda06d646bc7
4
- data.tar.gz: 1e54b8faf466d33cb3147b38a26473a2fd368319
3
+ metadata.gz: 8ae496ebb4a7235af6bb457cb453a6756d2a0642
4
+ data.tar.gz: f2b320eb7ea1a74f9333c1225c9fa6ded4ea4c11
5
5
  SHA512:
6
- metadata.gz: b539bf62bd365a93000a0b5abf5883f4328d624fa5577f621add143fbaadfa309bc881b86f2984a91a6062aaef048ef8190d7895dd16f677e3ec391a3d9e1c2e
7
- data.tar.gz: a42889ff7406624e986c36c59c13b9bb683509e129cfbc8ef8be42407bd6f267f75d3a6475390a38dfa5542bd556b0a5e2083841ae01169c0940be8bdaa32d7e
6
+ metadata.gz: 104dfb17330577fd62ad5495f4fa919fdf552f0ceac21891192e34b8ca7c059d2b65dbfc274aac89ae604e6a80ab8af73c07662e0ff2b4103c40e5da6a43ae5c
7
+ data.tar.gz: 95c65f260efee949a181a5549c5883309eaec1158b76939d85db356e74e4ce6ece8d3ec7a144db66710b6168e8d5a08ccb395785de5408089e66d360a89e90aa
data/bin/forj CHANGED
@@ -387,6 +387,7 @@ Several data will be requested like:
387
387
  o_cloud = Forj::CloudConnection.connect(account)
388
388
  o_cloud.setup(:forge, sAccountName)
389
389
  o_cloud.config.ac_save
390
+ PrcLib.high_level_msg("\nAccount %s '%s' saved.\n", sProvider, sAccountName)
390
391
  end
391
392
  end
392
393
 
data/forj/defaults.yaml CHANGED
@@ -128,15 +128,21 @@
128
128
  :account: true
129
129
  :ask_step: 2
130
130
  :after: :keypair_name
131
+ :pre_step_function: :forj_cloud_keypair_coherent?
131
132
  :post_step_function: :forj_setup_keypairs_files
132
133
  :keypair_path:
133
- :desc: "Forj internal copy of private and public key pair files "
134
+ :desc: "Contains the full path to the :keypair_base."
135
+ :default_value: "<%= Forj.keypairs_path %>"
136
+ :keypair_base:
137
+ :desc: "Contains the key file base name without .pem/.pub."
134
138
  :keypair_name:
135
139
  :desc: "keypair name defined in your cloud to access your server. By default we named it 'forj'. If it doesn't exist, it will be created."
136
140
  :required: true
137
141
  :default_value: "forj"
138
142
  :account: true
139
143
  :ask_step: 2
144
+ :pre_step_function: :update_keypair_config
145
+ :post_step_function: :forj_check_cloud_keypair
140
146
  :auth_uri:
141
147
  :desc: "Generic service auth url"
142
148
  :account_exclusive: true
data/forj.gemspec CHANGED
@@ -19,8 +19,8 @@ Gem::Specification.new do |s|
19
19
  s.name = 'forj'
20
20
  s.homepage = 'https://www.forj.io'
21
21
 
22
- s.version = '1.0.7'
23
- s.date = '2015-03-23'
22
+ s.version = '1.0.8'
23
+ s.date = '2015-03-27'
24
24
  s.summary = 'forj command line'
25
25
  s.description = 'forj cli - See https://www.forj.io for documentation/information'
26
26
 
@@ -52,7 +52,7 @@ Gem::Specification.new do |s|
52
52
  s.add_runtime_dependency 'json', '1.7.5'
53
53
  s.add_runtime_dependency 'bundler'
54
54
  s.add_runtime_dependency 'nokogiri','1.5.11'
55
- s.add_runtime_dependency 'lorj', '~> 1.0.7'
55
+ s.add_runtime_dependency 'lorj', '~> 1.0.8'
56
56
 
57
57
  s.add_development_dependency "rake", "~> 10.0"
58
58
  s.add_development_dependency "rspec", "~> 3.1.0"
data/lib/destroy.rb CHANGED
@@ -36,62 +36,77 @@ module Forj
36
36
  o_forge = o_cloud.get(:forge, name)
37
37
 
38
38
  if o_forge[:servers].count > 0
39
- destroy_server(o_cloud, o_forge, options, account)
39
+ destroy_server(o_cloud, o_forge, options)
40
40
  else
41
41
  PrcLib.high_level_msg("No server(s) found on forge instance '%s'.\n",
42
42
  name)
43
43
  end
44
44
  end
45
45
 
46
- def self.destroy_server(o_cloud, o_forge, options, account)
46
+ def self.destroy_server(o_cloud, o_forge, options)
47
47
  if options[:force]
48
48
  # Destroy all servers found
49
49
  o_cloud.delete(:forge)
50
50
  else
51
- server_list = get_server_list(o_forge)
51
+ server_list, servers_id = get_server_list(o_forge)
52
52
 
53
- o_server_number = get_server_index(server_list)
53
+ server_name = choose_server(server_list)
54
54
 
55
- if o_server_number >= 0 && o_server_number < o_forge[:servers].count
56
- # Destroy selected server
57
- account.set(:forge_server, o_forge[:servers][o_server_number][:id])
55
+ case server_name
56
+ when 'abort'
57
+ PrcLib.high_level_msg("No server destroyed on your demand.\n", name)
58
+ return
59
+ when 'all'
60
+ # Destroy all servers found
58
61
  o_cloud.delete(:forge)
62
+ return
63
+ else
64
+ # Destroy selected server
65
+ found = server_name.match(/ - (.*)$/)
66
+ if found
67
+ o_cloud.delete(:forge, :forge_server => found[1])
68
+ else
69
+ o_cloud.delete(:forge, :forge_server => servers_id[server_name][0])
70
+ end
59
71
  end
60
-
61
- # Destroy all servers found
62
- o_cloud.delete(:forge) if o_server_number == server_list.index('all')
63
- # esc
64
- PrcLib.high_level_msg("No server destroyed on your demand.\n",
65
- name
66
- ) if o_server_number == server_list.index('esc')
67
72
  end
68
73
  end
69
74
 
70
- def self.get_server_list(o_forge)
75
+ def self.get_server_list(forge)
71
76
  # Ask the user to get server(s) to destroy
72
77
  server_list = []
73
- index = 0
78
+ servers_id = {}
79
+
80
+ forge[:servers].each do |_type, server|
81
+ server_name = server[:name]
82
+ if servers_id.key?(server_name)
83
+ servers_id[server_name] << server[:id]
84
+ else
85
+ servers_id[server_name] = [server[:id]]
86
+ end
87
+ end
74
88
 
75
- o_forge[:servers].each do |server|
76
- server_list[index] = server[:name]
77
- index += 1
89
+ servers_id.each do |name, servers|
90
+ if servers.length > 1
91
+ servers.each { |id| server_list << name + ' - ' + id }
92
+ else
93
+ server_list << name
94
+ end
78
95
  end
79
96
 
80
97
  server_list << 'all'
81
- server_list << 'esc'
98
+ server_list << 'abort'
82
99
 
83
- server_list
100
+ [server_list, servers_id]
84
101
  end
85
102
 
86
- def self.get_server_index(server_list)
87
- say('Select the index of the server you want to destroy')
103
+ def self.choose_server(server_list)
104
+ say('Please, choose what you want to destroy')
88
105
  value = choose do |q|
89
106
  q.choices(*server_list)
90
107
  end
91
108
 
92
- o_server_number = server_list.index(value)
93
-
94
- o_server_number
109
+ value
95
110
  end
96
111
  end
97
112
  end
data/lib/forj/ForjCore.rb CHANGED
@@ -66,6 +66,7 @@ class Lorj::BaseDefinition
66
66
  obj_needs :data, :os_enckey
67
67
  obj_needs :data, :account_id
68
68
  obj_needs :data, :account_key
69
+ obj_needs :data, :auth_uri
69
70
  obj_needs_optional
70
71
 
71
72
  # If requested by user, ask Maestro to manage the DNS.
@@ -107,4 +108,5 @@ class Lorj::BaseDefinition
107
108
  obj_needs :CloudObject, :public_ip, :for => [:create_e]
108
109
  obj_needs :CloudObject, :keypairs, :for => [:create_e]
109
110
  obj_needs :data, :blueprint
111
+ obj_needs :data, :forge_server, :for => [:delete_e]
110
112
  end
@@ -31,17 +31,22 @@ INFRA_VERSION = '0.0.37'
31
31
  # Functions for boot - build_forge
32
32
  class ForjCoreProcess
33
33
  def build_forge(sObjectType, hParams)
34
- forge_exist?(sObjectType)
34
+ # TODO: To be replaced by a migration task at install phase.
35
+ update_keypair_config
35
36
 
36
- o_server = hParams.refresh[:server, :ObjectData]
37
+ o_forge = forge_get_or_create(sObjectType, hParams)
37
38
 
38
- boot_options = boot_keypairs(hParams)
39
+ # Refresh full data on the server found or created.
40
+ server = controller_get(:server, o_forge[:servers, 'maestro'][:id])
41
+ o_forge[:servers, 'maestro'] = server
42
+
43
+ boot_options = boot_keypairs(server)
39
44
 
40
45
  # Define the log lines to get and test.
41
46
  config.set(:log_lines, 5)
42
47
 
43
48
  PrcLib.info("Maestro server '%s' id is '%s'.",
44
- o_server[:name], o_server[:id])
49
+ server[:name], server[:id])
45
50
  # Waiting for server to come online before assigning a public IP.
46
51
 
47
52
  s_status = :checking
@@ -49,11 +54,10 @@ class ForjCoreProcess
49
54
 
50
55
  o_address = hParams.refresh[:public_ip, :ObjectData]
51
56
 
52
- s_status = active_server?(o_server, o_address, boot_options[:keys],
53
- boot_options[:coherent], s_status
54
- )
57
+ s_status = active_server?(server, o_address, boot_options[:keys],
58
+ boot_options[:coherent], s_status)
55
59
 
56
- till_server_active(s_status, o_server, o_address, boot_options)
60
+ till_server_active(s_status, server, o_address, boot_options)
57
61
 
58
62
  o_forge = get_forge(sObjectType, config[:instance_name], hParams)
59
63
 
@@ -61,49 +65,91 @@ class ForjCoreProcess
61
65
  o_forge
62
66
  end
63
67
 
64
- def forge_exist?(sObjectType)
68
+ def forge_get_or_create(sObjectType, hParams)
65
69
  o_forge = process_get(sObjectType, config[:instance_name])
66
70
  if o_forge.empty? || o_forge[:servers].length == 0
67
71
  PrcLib.high_level_msg("\nBuilding your forge...\n")
68
72
  process_create(:internet_server)
73
+ o_forge[:servers, 'maestro'] = hParams.refresh[:server]
69
74
  else
70
- load_existing_forge(o_forge)
75
+ o_forge = load_existing_forge(o_forge, hParams)
71
76
  end
77
+ o_forge
72
78
  end
73
79
 
74
- def load_existing_forge(o_forge)
75
- o_forge[:servers].each do |oServerToFind|
76
- if /^maestro\./ =~ oServerToFind[:name]
77
- process_get(:server, oServerToFind[:id])
78
- end
79
- end
80
+ def load_existing_forge(o_forge, hParams)
80
81
  PrcLib.high_level_msg("\nChecking your forge...\n")
81
82
 
82
- o_server = data_objects(:server, :ObjectData)
83
+ o_server = o_forge[:servers, 'maestro']
83
84
  if o_server
84
- o_ip = process_query(:public_ip, :server_id => o_server[:id])
85
- register o_ip[0] if o_ip.length > 0
86
- process_create(:keypairs)
85
+ query = { :server_id => o_server[:id] }
86
+ register(o_server)
87
+ o_ip = process_query(:public_ip, query)
88
+ register(o_ip[0]) if o_ip.length > 0
87
89
  else
88
90
  PrcLib.high_level_msg("\nYour forge exist, without maestro." \
89
91
  " Building Maestro...\n")
90
92
  process_create(:internet_server)
93
+ o_forge[:servers, 'maestro'] = hParams.refresh[:server]
91
94
 
92
95
  PrcLib.high_level_msg("\nBuilding your forge...\n")
93
96
  end
97
+ o_forge
94
98
  end
99
+ end
95
100
 
96
- def boot_keypairs(params)
97
- o_server = params[:server, :ObjectData]
98
- h_keys = params[:keypairs]
101
+ # Functions for boot - build_forge
102
+ class ForjCoreProcess
103
+ def boot_keypairs(server)
104
+ h_keys = process_create(:keypairs)
105
+ keypair = process_get(:keypairs, server[:key_name])
106
+
107
+ h_keys = choose_best_kp(h_keys, keypair, server[:name])
108
+
109
+ h_keys[:keys] = File.join(h_keys[:keypair_path],
110
+ h_keys[:private_key_name])
111
+
112
+ unless h_keys[:coherent]
113
+ PrcLib.warning("The local keypair '%s' public key and '%s' server's "\
114
+ "public key are different.\n"\
115
+ "You won't be able to access it until "\
116
+ 'you get a copy of the key used to create the server.'\
117
+ "\nPublic key found in the cloud:\n%s",
118
+ h_keys[:name], server[:name], keypair[:public_key])
119
+ return h_keys
120
+ end
99
121
 
100
- if h_keys.nil? || o_server[:key_name] != h_keys[:name]
101
- h_keys = process_get(:keypairs, o_server[:key_name])
122
+ unless h_keys[:private_key_exist?]
123
+ PrcLib.warning("The local keypair '%s' private key '%s' is not found. "\
124
+ "You won't be able to access '%s' until you get a copy"\
125
+ 'of the private key use to create the server.'\
126
+ "\nPublic key found in the cloud:\n%s",
127
+ h_keys[:keys], server[:name], keypair[:public_key])
102
128
  end
103
- private_key_file = File.join(h_keys[:keypair_path],
104
- h_keys[:private_key_name])
105
129
 
106
- { :keys => private_key_file, :coherent => h_keys[:coherent] }
130
+ h_keys
131
+ end
132
+
133
+ def choose_best_kp(predef_keypair, server_keypair, server_name)
134
+ if server_keypair[:name] != predef_keypair[:name]
135
+ if coherent_keypair?(predef_keypair, server_keypair)
136
+ PrcLib.warning("Server '%s' is using keypair name '%s' instead of the"\
137
+ " your account keypair name '%s'.\n"\
138
+ 'Your predefined keypair name is compatible with '\
139
+ 'that server. (public key identical), so Forj will use'\
140
+ " '%s' by default",
141
+ server_name, server_keypair[:name],
142
+ server_keypair[:name], server_keypair[:name])
143
+ return predef_keypair
144
+ end
145
+ PrcLib.warning("Server '%s' is using keypair name '%s' instead of the "\
146
+ "your account keypair name '%s'.\n"\
147
+ "Forj will try to find and use a local keypair name '%s'"\
148
+ ' instead.', server_name, server_keypair[:name],
149
+ predef_keypair[:name], server_keypair[:name])
150
+ return server_keypair
151
+ end
152
+ predef_keypair
107
153
  end
108
154
 
109
155
  def active_server?(o_server, o_address, private_key_file,
@@ -112,22 +158,20 @@ class ForjCoreProcess
112
158
  if o_server[:attrs][:status] == :active
113
159
  image = server_get_image o_server
114
160
 
115
- s_msg = <<-END
116
- Your forj Maestro server is up and running and is publically accessible
117
- through IP '%s'.
118
-
119
- You can connect to '%s' with:
120
- ssh %s@%s -o StrictHostKeyChecking=no -i %s
121
- END
122
- s_msg = format(s_msg, o_address[:public_ip], o_server[:name],
123
- image[:ssh_user], o_address[:public_ip], private_key_file
124
- )
161
+ s_msg = format('Your forj Maestro server is up and running and is '\
162
+ "publically accessible through IP '%s'.\n\n"\
163
+ "You can connect to '%s' with:\n"\
164
+ 'ssh %s@%s -o StrictHostKeyChecking=no -i ',
165
+ o_address[:public_ip], o_server[:name],
166
+ image[:ssh_user], o_address[:public_ip])
125
167
 
126
- unless keypair_coherent
127
- s_msg += "\n" + ANSI.bold(
128
- 'Unfortunatelly'
129
- ) + ' your current keypair is not usable to connect to your server.' \
130
- "\n" + 'You need to fix this issue to gain access to your server.'
168
+ if keypair_coherent
169
+ s_msg += private_key_file
170
+ else
171
+ s_msg += ANSI.red(ANSI.bold('<no valid private key found>')) + "\n\n" +
172
+ ANSI.bold('Unfortunatelly') + ', Forj was not able to find a '\
173
+ 'valid keypair to connect to your server.' \
174
+ "\nYou need to fix this issue to gain access to your server."
131
175
  end
132
176
  PrcLib.info(s_msg)
133
177
 
@@ -223,8 +267,8 @@ class ForjCoreProcess
223
267
  "%s\n"\
224
268
  "#{highlight}\n"\
225
269
  "The server '%s' is not providing any output log for"\
226
- " more than 5 minutes.\nPlease review the current"\
227
- 'output show below to determine if this a normal '\
270
+ " more than 5 minutes.\nPlease review the current "\
271
+ 'output shown below to determine if this is a normal '\
228
272
  "situation.\nYou can connect to the server if you "\
229
273
  "want to.\nTo connect, use:\n"\
230
274
  'ssh %s@%s -o StrictHostKeyChecking=no -i %s',
@@ -425,7 +469,7 @@ class ForjCoreProcess
425
469
 
426
470
  def display_servers_with_ip(o_forge, s_msg)
427
471
  i_count = 0
428
- o_forge[:servers].each do |server|
472
+ o_forge[:servers].each do |_type, server|
429
473
  next if /^maestro\./ =~ server[:name]
430
474
  register(server)
431
475
  o_ip = process_query(:public_ip, :server_id => server[:id])
@@ -510,14 +554,15 @@ class ForjCoreProcess
510
554
  'PUPPET_DEBUG' => 'True',
511
555
  'image_name' => hParams[:image_name],
512
556
  'key_name' => hParams[:keypair_name],
513
- 'hpcloud_priv' => Base64.strict_encode64(
514
- hpcloud_priv
515
- ).gsub('=', '') # Remove pad
557
+ # Remove pad
558
+ 'hpcloud_priv' => Base64.strict_encode64(hpcloud_priv).gsub('=', ''),
559
+ 'compute_os_auth_url' => hParams[:auth_uri]
516
560
  }
517
561
 
518
562
  if hParams[:dns_service]
519
563
  h_meta['dns_zone'] = hParams[:dns_service]
520
564
  h_meta['dns_tenantid'] = hParams[:dns_tenant_id]
565
+ h_meta['dns_auth_url'] = hParams[:auth_uri]
521
566
  end
522
567
  # If requested by user, ask Maestro to instantiate a blueprint.
523
568
  h_meta['blueprint'] = hParams[:blueprint] if hParams[:blueprint]
@@ -878,14 +923,21 @@ class ForjCoreProcess
878
923
  cmd = format(
879
924
  "%s '%s' '%s' '%s' '%s' '%s' '%s' '%s'",
880
925
  bootstrap, # script
881
- PrcLib.data_path, # $1 = Forj data base dir
926
+ # $1 = Forj data base dir
927
+ PrcLib.data_path,
882
928
  # $2 = Maestro repository dir
883
929
  hParams[:maestro_repository, :maestro_repo],
884
- config[:bootstrap_dirs], # $3 = Bootstrap directories
885
- config[:bootstrap_extra_dir], # $4 = Bootstrap extra directory
886
- meta_data, # $5 = meta_data (string)
887
- mime_cmd, # $6: mime script file to execute.
888
- mime # $7: mime file generated.
930
+ # $3 = Bootstrap directories
931
+ hParams[:infra_repository, :infra_repo] + ' ' +
932
+ config.get(:bootstrap_dirs, ''),
933
+ # $4 = Bootstrap extra directory
934
+ config[:bootstrap_extra_dir],
935
+ # $5 = meta_data (string)
936
+ meta_data,
937
+ # $6: mime script file to execute.
938
+ mime_cmd,
939
+ # $7: mime file generated.
940
+ mime
889
941
  )
890
942
 
891
943
  run_userdata_cmd(cmd, bootstrap, mime)
@@ -927,11 +979,15 @@ class ForjCoreProcess
927
979
  end
928
980
  # end
929
981
  end
982
+
930
983
  # Check files existence
931
- def forj_check_keypairs_files(keypath)
984
+ def forj_check_keypairs_files(input_pathbase)
932
985
  key_name = config.get(:keypair_name)
933
986
 
934
- keys_entered = keypair_detect(key_name, keypath)
987
+ keypair_path = File.expand_path(File.dirname(input_pathbase))
988
+ keypair_base = File.expand_path(File.basename(input_pathbase))
989
+ keys_entered = keypair_detect(key_name, keypair_path, keypair_base)
990
+
935
991
  if !keys_entered[:private_key_exist?] && !keys_entered[:public_key_exist?]
936
992
  if agree('The key you entered was not found. Do you want to create' \
937
993
  ' this one?')
@@ -944,30 +1000,69 @@ class ForjCoreProcess
944
1000
  true
945
1001
  end
946
1002
 
947
- def duplicate_keyname?(keys_imported, keys, key_name)
948
- if keys_imported && keys_imported[:key_basename] != keys[:key_basename] &&
949
- Forj.keypairs_path != keys[:keypair_path]
950
- PrcLib.warning("The private key '%s' was assigned to a different private"\
951
- " key file '%s'.\nTo not overwrite it, we recommend you"\
952
- ' to choose a different keypair name.',
953
- keys, keys_imported[:key_basename])
954
- new_key_name = key_name
955
- s_msg = 'Please, provide a different keypair name:'
956
- while key_name == new_key_name
957
- new_key_name = ask(s_msg) do |q|
958
- q.validate = /.+/
959
- end
960
- new_key_name = new_key_name.to_s
961
- s_msg = 'Incorrect. You have to choose a keypair name different' \
962
- " than '#{key_name}'. If you want to interrupt, press Ctrl-C and" \
963
- ' retry later.\nSo, please, provide a different keypair' \
964
- ' name:' if key_name == new_key_name
1003
+ # Function to identify if the keypair name has already been imported.
1004
+ # If so, we can't change the original files used to import it.
1005
+ # The script will ask for another keypair_name.
1006
+ #
1007
+ # It will loop until keyname is new or until files originally used
1008
+ # is identical.
1009
+ def check_about_imported_key(setup_keys, key_name)
1010
+ loop do
1011
+ keys_imported = nil
1012
+ if config.local_exist?(key_name.to_sym, :imported_keys)
1013
+ keys_imported = keypair_detect(key_name,
1014
+ config.local_get(key_name.to_sym,
1015
+ :imported_keys))
1016
+ end
1017
+
1018
+ return setup_keys if keys_imported.nil?
1019
+
1020
+ unless keys_imported[:private_key_exist?] ||
1021
+ keys_imported[:public_key_exist?]
1022
+ PrcLib.warning("The local keypair '%s' imported files do not exist "\
1023
+ 'anymore. Removed from imported_keys.', key_name)
1024
+ local_del(key_name.to_sym, :imported_keys)
1025
+ break
965
1026
  end
966
- key_name = new_key_name
1027
+
1028
+ setup_keybase = File.join(setup_keys[:keypair_path],
1029
+ setup_keys[:key_basename])
1030
+ imported_keybase = File.join(keys_imported[:keypair_path],
1031
+ keys_imported[:key_basename])
1032
+
1033
+ break if setup_keybase == imported_keybase
1034
+
1035
+ PrcLib.warning("You entered a keypair base file '%s' for keypair name "\
1036
+ "'%s'. Originally, this keypair name was created from "\
1037
+ "'%s' instead.\n"\
1038
+ 'To not overwrite it, we recommend you'\
1039
+ ' to choose a different keypair name.',
1040
+ setup_keybase, key_name, imported_keybase)
1041
+ key_name = _keypair_files_ask(key_name)
967
1042
  config.set(:key_name, key_name)
968
- keys = keypair_detect(key_name, key_path)
1043
+
1044
+ setup_keys = keypair_detect(key_name,
1045
+ setup_keys[:keypair_path],
1046
+ setup_keys[:key_basename])
1047
+ end
1048
+ setup_keys
1049
+ end
1050
+
1051
+ # Function to change the keypair name, as already used.
1052
+ def _keypair_files_ask(key_name)
1053
+ new_key_name = key_name
1054
+ s_msg = 'Please, provide a different keypair base file:'
1055
+ while key_name == new_key_name
1056
+ new_key_name = ask(s_msg) do |q|
1057
+ q.validate = /.+/
1058
+ end
1059
+ new_key_name = new_key_name.to_s
1060
+ s_msg = 'Incorrect. You have to choose a keypair base file different'\
1061
+ " than '#{key_name}'. If you want to interrupt, press Ctrl-C."\
1062
+ "\nSo, please, provide a different keypair"\
1063
+ ' name:' if key_name == new_key_name
969
1064
  end
970
- keys
1065
+ new_key_name
971
1066
  end
972
1067
 
973
1068
  def create_keys_automatically(keys, private_key_file)
@@ -990,18 +1085,26 @@ end
990
1085
 
991
1086
  # Functions for setup
992
1087
  class ForjCoreProcess
1088
+ # Import the keypair base files setup by user in forj keypair files.
1089
+ #
1090
+ # This function is can be executed only if we copy files to internal
1091
+ # forj keypair storage. Otherwise this update is ignored.
993
1092
  def save_sequences(private_key_file, forj_private_key_file,
994
1093
  public_key_file, forj_public_key_file, key_name
995
1094
  )
996
1095
  PrcLib.info('Importing key pair to FORJ keypairs list.')
1096
+
997
1097
  FileUtils.copy(private_key_file, forj_private_key_file)
998
1098
  FileUtils.copy(public_key_file, forj_public_key_file)
999
1099
  # Attaching this keypair to the account
1000
1100
  config.set(:keypair_name, key_name, :name => 'account')
1001
- config.set(:keypair_path, forj_private_key_file, :name => 'account')
1002
- config.local_set(key_name.to_s, private_key_file, :imported_keys)
1101
+ config.local_set(key_name.to_sym, private_key_file, :imported_keys)
1003
1102
  end
1004
1103
 
1104
+ # Update the forj keypair base files copy from the original base files.
1105
+ #
1106
+ # This function is can be executed only if we copy files to internal
1107
+ # forj keypair storage. Otherwise this update is ignored.
1005
1108
  def save_md5(private_key_file, forj_private_key_file,
1006
1109
  public_key_file, forj_public_key_file
1007
1110
  )
@@ -1029,9 +1132,9 @@ end
1029
1132
 
1030
1133
  # Functions for setup
1031
1134
  class ForjCoreProcess
1032
- def save_internal_key(forj_private_key_file, keys)
1135
+ def save_internal_key(keys)
1033
1136
  # Saving internal copy of private key file for forj use.
1034
- config.set(:keypair_path, forj_private_key_file, :name => 'account')
1137
+ config.set(:keypair_base, keys[:keypair_name], :name => 'account')
1035
1138
  PrcLib.info("Configured forj keypair '%s' with '%s'",
1036
1139
  keys[:keypair_name],
1037
1140
  File.join(keys[:keypair_path], keys[:key_basename])
@@ -1039,19 +1142,17 @@ class ForjCoreProcess
1039
1142
  end
1040
1143
 
1041
1144
  # keypair_files post setup
1145
+ #
1146
+ # This function will get the keypair_files setup by user and it will:
1147
+ #
1148
+ # * In case keypair already exist, check if imported files is identical.
1149
+ # * Create SSH keys if missing (ssh-keygen - create_keys_automatically)
1150
+ # * exit if :keypair_change is not set to the internal forj dir.
1151
+ # * For new keys, copy new files and keep the original files import place.
1152
+ # * For existing keys, update them from their original places (imported from)
1153
+ # * done
1042
1154
  def forj_setup_keypairs_files
1043
- # Getting Account keypair information
1044
- key_name = config[:keypair_name]
1045
- key_path = File.expand_path(config[:keypair_files])
1046
-
1047
- keys_imported = nil
1048
- keys_imported = keypair_detect(
1049
- key_name,
1050
- config.local_get(key_name, :imported_keys)
1051
- ) if config.local_exist?(key_name, :imported_keys)
1052
- keys = keypair_detect(key_name, key_path)
1053
-
1054
- keys = duplicate_keyname?(keys_imported, keys, key_name)
1155
+ keys = check_setup_keypair
1055
1156
 
1056
1157
  private_key_file = File.join(keys[:keypair_path], keys[:private_key_name])
1057
1158
  public_key_file = File.join(keys[:keypair_path], keys[:public_key_name])
@@ -1059,38 +1160,87 @@ class ForjCoreProcess
1059
1160
  # Creation sequences
1060
1161
  create_keys_automatically(keys, private_key_file)
1061
1162
 
1062
- forj_private_key_file = File.join(Forj.keypairs_path, key_name)
1063
- forj_public_key_file = File.join(Forj.keypairs_path, key_name + '.pub')
1163
+ if Forj.keypairs_path != config[:keypair_path]
1164
+ # Do not save in a config keypair_path not managed by forj.
1165
+ save_internal_key(keys)
1166
+ return true
1167
+ end
1168
+
1169
+ forj_private_key_file = File.join(Forj.keypairs_path, keys[:keypair_name])
1170
+ forj_public_key_file = File.join(Forj.keypairs_path,
1171
+ keys[:keypair_name] + '.pub')
1064
1172
 
1065
1173
  # Saving sequences
1066
- if keys[:keypair_path] != Forj.keypairs_path
1067
- if !File.exist?(forj_private_key_file) ||
1068
- !File.exist?(forj_public_key_file)
1069
- save_sequences(private_key_file, forj_private_key_file,
1070
- public_key_file, forj_public_key_file, key_name
1071
- )
1072
- else
1073
- save_md5(private_key_file, forj_private_key_file,
1074
- public_key_file, forj_public_key_file
1075
- )
1076
- end
1174
+ if !File.exist?(forj_private_key_file) || !File.exist?(forj_public_key_file)
1175
+ save_sequences(private_key_file, forj_private_key_file,
1176
+ public_key_file, forj_public_key_file, keys[:keypair_name])
1177
+ else
1178
+ save_md5(private_key_file, forj_private_key_file,
1179
+ public_key_file, forj_public_key_file)
1077
1180
  end
1078
1181
 
1079
- save_internal_key(forj_private_key_file, keys)
1080
- true # forj_setup_keypairs_files successfull
1182
+ save_internal_key(keys)
1183
+ true # forj_setup_keypairs_files successful
1184
+ end
1185
+
1186
+ def check_setup_keypair
1187
+ key_name = config[:keypair_name]
1188
+ setup_keypair_path = File.expand_path(File.dirname(config[:keypair_files]))
1189
+ setup_keypair_base = File.basename(config[:keypair_files])
1190
+
1191
+ setup_keys = keypair_detect(key_name, setup_keypair_path,
1192
+ setup_keypair_base)
1193
+
1194
+ # Request different keypair_name, if exist and already imported from another
1195
+ # :keypair_files
1196
+ if config[:keypair_path] == Forj.keypairs_path
1197
+ check_about_imported_key(setup_keys, key_name)
1198
+ else
1199
+ setup_keys
1200
+ end
1201
+ end
1202
+
1203
+ # TODO: Change this by a migration function called at install time.
1204
+
1205
+ # Function to convert unclear data structure keypair_path, splitted.
1206
+ # Update config with keypair_base and keypair_path - forj 1.0.8
1207
+ #
1208
+ # * split it in path and base.
1209
+ # * Fix existing config about path&base (update_keypair_config)
1210
+ # * save it in account file respectively as :keypair_path and :keypair_base
1211
+ #
1212
+ # Used in keypair_name pre-step at setup time.
1213
+ # return true to not skip the data.
1214
+ #
1215
+ def update_keypair_config(_ = nil)
1216
+ %w(local account).each do |config_name|
1217
+ next if config.exist?(:keypair_base, :names => [config_name])
1218
+
1219
+ keypair_path = config.get(:keypair_path, nil, :name => config_name)
1220
+
1221
+ options = { :name => config_name }
1222
+ options.merge!(:section => :default) if config_name == 'local'
1223
+ config.set(:keypair_base, File.basename(keypair_path), options)
1224
+ config.set(:keypair_path, File.dirname(keypair_path), options)
1225
+ end
1226
+ true
1081
1227
  end
1082
1228
 
1083
1229
  def forj_dns_settings
1230
+ config[:dns_settings] = false
1231
+
1232
+ return true unless forj_dns_supported?
1233
+
1084
1234
  s_ask = 'Optionally, you can ask Maestro to use/manage a domain name on' \
1085
1235
  " your cloud. It requires your DNS cloud service to be enabled.\nDo" \
1086
1236
  ' you want to configure it?'
1087
- config.set(:dns_settings, agree(s_ask))
1237
+ config[:dns_settings] = agree(s_ask)
1088
1238
  true
1089
1239
  end
1090
1240
 
1091
1241
  def forj_dns_settings?(sKey)
1092
1242
  # Return true to ask the question. false otherwise
1093
- unless config.get(:dns_settings)
1243
+ unless config[:dns_settings]
1094
1244
  section = Lorj.data.first_section(sKey)
1095
1245
  config.del(sKey, :name => 'account', :section => section)
1096
1246
  return false # Do not ask
@@ -1098,6 +1248,19 @@ class ForjCoreProcess
1098
1248
  true
1099
1249
  end
1100
1250
 
1251
+ def forj_dns_supported?
1252
+ unless config[:provider] == 'hpcloud'
1253
+ PrcLib.message("maestro running under '%s' provider currently do "\
1254
+ "support DNS setting.\n", config.get(:provider))
1255
+ config[:dns_settings] = false
1256
+ return false # Do not ask
1257
+ end
1258
+ true
1259
+ end
1260
+ end
1261
+
1262
+ # Functions for setup
1263
+ class ForjCoreProcess
1101
1264
  def setup_tenant_name
1102
1265
  # TODO: To re-introduce with a Controller call instead.
1103
1266
  o_ssl_error = SSLErrorMgt.new # Retry object
@@ -1122,13 +1285,49 @@ class ForjCoreProcess
1122
1285
  end
1123
1286
  @oConfig.set('tenants', tenants)
1124
1287
  end
1288
+
1289
+ # post process after asking keypair name
1290
+ # return true go to next step
1291
+ # return false go back to ask keypair name again
1292
+ def forj_check_cloud_keypair
1293
+ key_name = config[:keypair_name]
1294
+ return true if key_name.nil?
1295
+ config[:key_cloud_coherence] = false
1296
+ cloud_key = process_get(:keypairs, key_name)
1297
+ if !cloud_key.empty?
1298
+ if cloud_key[:coherent]
1299
+ config[:key_cloud_coherence] = true
1300
+ return true
1301
+ end
1302
+ else
1303
+ return true
1304
+ end
1305
+ keypair_display(cloud_key)
1306
+ s_ask = 'Do you still want to create new key?'
1307
+ PrcLib.fatal(1, 'This keypair name cannot be used. ' \
1308
+ 'You may check keypair_path setting ' \
1309
+ 'in your account.') unless agree(s_ask)
1310
+ false
1311
+ end
1312
+
1313
+ # pre process before asking keypair files
1314
+ # return true continue to ask keypair files
1315
+ # return false skip asking keypair files
1316
+ def forj_cloud_keypair_coherent?(_keypair_files)
1317
+ if config[:key_cloud_coherence]
1318
+ PrcLib.message('Your local ssh keypair is detected ' \
1319
+ 'and valid to access the box.')
1320
+ return false
1321
+ end
1322
+ true
1323
+ end
1125
1324
  end
1126
1325
 
1127
1326
  # Funtions for get
1128
1327
  class ForjCoreProcess
1129
1328
  def get_forge(sCloudObj, sForgeId, _hParams)
1130
1329
  s_query = {}
1131
- h_servers = []
1330
+ servers = {}
1132
1331
  s_query[:name] = sForgeId
1133
1332
 
1134
1333
  o_servers = process_query(:server, s_query)
@@ -1136,14 +1335,18 @@ class ForjCoreProcess
1136
1335
  regex = Regexp.new(format('\.%s$', sForgeId))
1137
1336
 
1138
1337
  o_servers.each do |o_server|
1139
- o_name = o_server[:name]
1140
- h_servers << o_server if regex =~ o_name
1338
+ name = o_server[:name]
1339
+ next unless regex =~ name
1340
+
1341
+ type = name.clone
1342
+ type['.' + sForgeId] = ''
1343
+ servers[type] = o_server
1141
1344
  end
1142
1345
  PrcLib.info('%s server(s) were found under instance name %s ',
1143
- h_servers.count, s_query[:name])
1346
+ servers.count, s_query[:name])
1144
1347
 
1145
- o_forge = register(h_servers, sCloudObj)
1146
- o_forge[:servers] = h_servers
1348
+ o_forge = register({}, sCloudObj)
1349
+ o_forge[:servers] = servers
1147
1350
  o_forge[:name] = sForgeId
1148
1351
  o_forge
1149
1352
  end
@@ -1154,14 +1357,14 @@ class ForjCoreProcess
1154
1357
  def delete_forge(_sCloudObj, hParams)
1155
1358
  PrcLib.state('Destroying server(s) of your forge')
1156
1359
 
1157
- forge_serverid = config.get(:forge_server)
1360
+ forge_serverid = hParams[:forge_server]
1158
1361
 
1159
1362
  o_forge = hParams[:forge]
1160
1363
 
1161
- o_forge[:servers].each do|server|
1364
+ o_forge[:servers].each do|_type, server|
1162
1365
  next if forge_serverid && forge_serverid != server[:id]
1163
1366
  register(server)
1164
- PrcLib.state("Destroying server '%s'", server[:name])
1367
+ PrcLib.state("Destroying server '%s - %s'", server[:name], server[:id])
1165
1368
  process_delete(:server)
1166
1369
  end
1167
1370
  if forge_serverid.nil?
@@ -1178,17 +1381,10 @@ end
1178
1381
  class ForjCoreProcess
1179
1382
  def ssh_connection(sObjectType, hParams)
1180
1383
  o_forge = hParams[:forge]
1181
- o_server = nil
1182
-
1183
- o_forge[:servers].each do|server|
1184
- next if hParams[:forge_server] != server[:id]
1185
- o_server = server
1186
- break
1187
- end
1188
1384
 
1189
1385
  # Get server information
1190
1386
  PrcLib.state('Getting server information')
1191
- o_server = process_get(:server, o_server[:id])
1387
+ o_server = o_forge[:servers, hParams[:forge_server]]
1192
1388
  register(o_server)
1193
1389
 
1194
1390
  public_ip = ssh_server_public_ip(o_server)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: forj
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.7
4
+ version: 1.0.8
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-23 00:00:00.000000000 Z
11
+ date: 2015-03-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -142,14 +142,14 @@ dependencies:
142
142
  requirements:
143
143
  - - ~>
144
144
  - !ruby/object:Gem::Version
145
- version: 1.0.7
145
+ version: 1.0.8
146
146
  type: :runtime
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - ~>
151
151
  - !ruby/object:Gem::Version
152
- version: 1.0.7
152
+ version: 1.0.8
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: rake
155
155
  requirement: !ruby/object:Gem::Requirement