2
2
import subprocess
3
3
from typing import Any , Dict
4
4
from pathlib import Path
5
-
5
+ from uuid import uuid4
6
6
import inquirer
7
7
from inquirer import errors
8
8
from ibm_ray_config .modules .config_builder import ConfigBuilder , update_decorator , spinner
9
9
from ibm_ray_config .modules .utils import (Color , color_msg , find_default , find_name_id ,
10
- validate_exists , validate_not_empty )
10
+ validate_exists , validate_not_empty , free_dialog )
11
11
12
12
from ibm_cloud_sdk_core import ApiException
13
- DEFAULT_KEY_NAME = 'default-ssh-key '
13
+ DEFAULT_KEY_NAME = f'ray- { os . environ . get ( "USERNAME" ) } - { str ( uuid4 ())[: 5 ] } '
14
14
15
- def generate_keypair (keyname ):
15
+ def generate_keypair ():
16
16
"""Returns newly generated public ssh-key's contents and private key's path"""
17
- home = str (Path .home ())
18
- filename = f"{ home } { os .sep } .ssh{ os .sep } id.rsa.{ keyname } "
19
- try :
20
- os .remove (filename )
21
- except Exception :
22
- pass
17
+ filename = f"{ os .sep } tmp{ os .sep } { DEFAULT_KEY_NAME } "
23
18
24
19
os .system (f'ssh-keygen -b 2048 -t rsa -f { filename } -q -N ""' )
25
20
print (f"\n \n \033 [92mSSH key pair been generated\n " )
26
- print (f"private key: { os .path .abspath (filename )} " )
27
- print (f"public key { os .path .abspath (filename )} .pub\033 [0m" )
21
+ print (f"private key intermediate location : { os .path .abspath (filename )} " )
22
+ print (f"public key intermediate location: { os .path .abspath (filename )} .pub\033 [0m" )
28
23
with open (f"{ filename } .pub" , 'r' ) as file :
29
24
ssh_key_data = file .read ()
30
25
ssh_key_path = os .path .abspath (filename )
@@ -37,28 +32,20 @@ def get_ssh_key(ibm_vpc_client, name):
37
32
return key
38
33
39
34
def register_ssh_key (ibm_vpc_client , config , auto = False ):
40
- """Returns the key's name on the VPC platform, it's public key's contents and the local path to it.
35
+ """Returns:
36
+ 1. key's name on the VPC platform.
37
+ 2. it's public key's contents.
38
+ 3. local path to private key ONLY if user generated a key, ELSE None.
41
39
Registers an either existing or newly generated ssh-key to a specific VPC. """
40
+
42
41
if config .get ('ibm_vpc' ):
43
42
resource_group_id = config ['ibm_vpc' ]['resource_group_id' ]
44
43
else :
45
44
for available_node_type in config ['available_node_types' ]:
46
45
resource_group_id = config ['available_node_types' ][available_node_type ]['node_config' ]['resource_group_id' ]
47
46
break
48
47
49
-
50
- questions = [
51
- inquirer .Text (
52
- 'keyname' , message = 'Please specify a name for the new key' , validate = validate_not_empty )
53
- ]
54
-
55
- answers = {}
56
- if not auto :
57
- answers = inquirer .prompt (questions , raise_keyboard_interrupt = True )
58
- else :
59
- answers ['keyname' ] = DEFAULT_KEY_NAME
60
-
61
- keyname = answers ['keyname' ]
48
+ keyname = DEFAULT_KEY_NAME
62
49
63
50
EXISTING_CONTENTS = 'Paste existing public key contents'
64
51
EXISTING_PATH = 'Provide path to existing public key'
@@ -76,11 +63,11 @@ def register_ssh_key(ibm_vpc_client, config, auto=False):
76
63
else :
77
64
answers ["answer" ] = GENERATE_NEW
78
65
79
- ssh_key_data = ""
80
- ssh_key_path = None
66
+ public_ssh_key_data = ""
67
+ private_ssh_key_path = None
81
68
if answers ["answer" ] == EXISTING_CONTENTS :
82
69
print ("Registering from file contents" )
83
- ssh_key_data = input (
70
+ public_ssh_key_data = input (
84
71
"[\033 [33m?\033 [0m] Please paste the contents of your public ssh key. It should start with ssh-rsa: " )
85
72
elif answers ["answer" ] == EXISTING_PATH :
86
73
print ("Register in vpc existing key from path" )
@@ -90,31 +77,26 @@ def register_ssh_key(ibm_vpc_client, config, auto=False):
90
77
]
91
78
answers = inquirer .prompt (questions , raise_keyboard_interrupt = True )
92
79
with open (os .path .abspath (os .path .expanduser (answers ["public_key_path" ])), 'r' ) as file :
93
- ssh_key_data = file .read ()
94
- else :
95
- ssh_key_data , ssh_key_path = generate_keypair (keyname )
80
+ public_ssh_key_data = file .read ()
81
+ else : # choice GENERATE_NEW
82
+ public_ssh_key_data , private_ssh_key_path = generate_keypair ()
96
83
97
- response = None
98
- try : # regardless of the above, try registering an ssh-key
99
- response = ibm_vpc_client .create_key (public_key = ssh_key_data , name = keyname , resource_group = {
84
+ try : # regardless of the above choices, try registering an ssh-key
85
+ response = ibm_vpc_client .create_key (public_key = public_ssh_key_data , name = keyname , resource_group = {
100
86
"id" : resource_group_id }, type = 'rsa' )
101
87
except ApiException as e :
102
- print (e )
103
-
104
- if "Key with name already exists" in e .message and keyname == DEFAULT_KEY_NAME :
105
- key = get_ssh_key (ibm_vpc_client , DEFAULT_KEY_NAME )
106
- ibm_vpc_client .delete_key (id = key ['id' ])
107
- response = ibm_vpc_client .create_key (public_key = ssh_key_data , name = keyname , resource_group = {
108
- "id" : resource_group_id }, type = 'rsa' )
88
+ if "Key with name already exists" in e .message :
89
+ print (color_msg (f"Key by the name '{ keyname } ' already exists" ,Color .RED ))
90
+ keyname = free_dialog ("Please specify a *unique* name for the new key" )["answer" ]
109
91
else :
110
92
if "Key with fingerprint already exists" in e .message :
111
93
print (color_msg ("Can't register an SSH key with the same fingerprint" ,Color .RED ))
112
- raise # can't continue the configuration process without a valid ssh key
94
+ exit ( 1 ) # can't continue the configuration process without a valid ssh key
113
95
114
- print (f"\033 [92mnew SSH key { keyname } been registered in vpc\033 [0m" )
96
+ print (f"\033 [92mnew SSH key: ' { keyname } ' been registered in vpc\033 [0m" )
115
97
116
98
result = response .get_result ()
117
- return result ['name' ], result ['id' ], ssh_key_path
99
+ return result ['name' ], result ['id' ], private_ssh_key_path
118
100
119
101
120
102
DEPENDENCIES = {'ibm_vpc' : {'resource_group_id' : None }}
@@ -151,28 +133,32 @@ def get_ssh_key_objects():
151
133
CREATE_NEW_SSH_KEY = f"""Register new SSH key in IBM VPC { color_msg ("[Best Practice]" ,Color .LIGHTGREEN )} """
152
134
153
135
default = find_default (self .defaults , ssh_key_objects , id = 'key_id' )
136
+ default = default if default else CREATE_NEW_SSH_KEY
154
137
ssh_key_name , ssh_key_id = find_name_id (
155
- ssh_key_objects , 'Choose ssh key' , do_nothing = CREATE_NEW_SSH_KEY , default = CREATE_NEW_SSH_KEY )
156
-
157
- ssh_key_path = None
158
- if not ssh_key_name :
159
- ssh_key_name , ssh_key_id , ssh_key_path = register_ssh_key (
138
+ ssh_key_objects , 'Choose ssh key' , do_nothing = CREATE_NEW_SSH_KEY , default = default )
139
+
140
+ private_ssh_key_path = None
141
+ if not ssh_key_name : # user chose to create a new key / no keys registered
142
+ ssh_key_name , ssh_key_id , private_ssh_key_path = register_ssh_key (
160
143
self .ibm_vpc_client , self .base_config )
161
144
162
145
self .ssh_key_id = ssh_key_id
163
146
self .ssh_key_name = ssh_key_name
164
147
165
- if not ssh_key_path :
148
+ # private_ssh_key_path is known only if user generated a key.
149
+ if not private_ssh_key_path :
166
150
questions = [
167
151
inquirer .Text (
168
- "private_key_path" , message = f'Please paste path to \033 [92mprivate\033 [0m ssh key associated with selected public key { ssh_key_name } ' , validate = self ._validate_keypair , default = self .defaults .get ('ssh_key_filename' ) or "~/.ssh/id_rsa" )
152
+ "private_key_path" , message = f'Please paste path to \033 [92mprivate\033 [0m ssh key associated with selected public key { ssh_key_name } ' ,
153
+ validate = self ._validate_keypair ,
154
+ default = self .defaults .get ('ssh_key_filename' ) or "~/.ssh/id_rsa" )
169
155
]
170
156
answers = inquirer .prompt (questions , raise_keyboard_interrupt = True )
171
- ssh_key_path = os .path .abspath (
157
+ private_ssh_key_path = os .path .abspath (
172
158
os .path .expanduser (answers ["private_key_path" ]))
173
159
174
160
# currently the user is hardcoded to root
175
- return ssh_key_id , ssh_key_path , 'root'
161
+ return ssh_key_id , private_ssh_key_path , 'root'
176
162
177
163
@update_decorator
178
164
def verify (self , base_config ):
0 commit comments