@@ -65,7 +65,9 @@ def init_config(
6565 path : Path | None = typer .Option (None , "--path" , help = "Write credentials to this file. Defaults to global config." ),
6666 cpanel_host : str | None = typer .Option (None , "--cpanel-host" , help = "cPanel host, for example saule.o2switch.net." ),
6767 cpanel_user : str | None = typer .Option (None , "--cpanel-user" , help = "cPanel username." ),
68- cpanel_token : str | None = typer .Option (None , "--cpanel-token" , help = "cPanel API token." ),
68+ cpanel_token : str | None = typer .Option (None , "--cpanel-token" , help = "cPanel API token (if using token auth)." ),
69+ cpanel_password : str | None = typer .Option (None , "--cpanel-password" , help = "cPanel password (if using password auth)." ),
70+ use_password : bool = typer .Option (False , "--password" , "-p" , help = "Use password instead of API token." ),
6971 default_ttl : int | None = typer .Option (None , "--default-ttl" , help = "Default TTL to write into the env file." ),
7072 audit_log_path : str | None = typer .Option (
7173 None ,
@@ -78,6 +80,13 @@ def init_config(
7880 force : bool = typer .Option (False , "--force" , help = "Overwrite an existing env file without confirmation." ),
7981 test_api : bool = typer .Option (False , "--test-api/--no-test-api" , help = "Test cPanel API access after writing." ),
8082) -> None :
83+ """Configure cPanel credentials.
84+
85+ Examples:
86+ o2switch-cli config setup # Interactive setup
87+ o2switch-cli config setup --password # Use password instead of token
88+ o2switch-cli config setup --cpanel-user xxx # Pre-fill username
89+ """
8190 def action (app_context ):
8291 ui = TerminalUI (app_context .console , app_context .output_format )
8392 current = app_context .settings
@@ -90,9 +99,22 @@ def action(app_context):
9099 elif target .exists () and not force and non_interactive :
91100 raise ValidationAppError ("config_init" , f"{ target } already exists. Use --force to overwrite." , str (target ))
92101
102+ # Determine auth method
103+ auth_method = "password" if use_password or cpanel_password else current .auth_method
104+ if not non_interactive and not cpanel_token and not cpanel_password :
105+ auth_choice = questionary .select (
106+ "Authentication method:" ,
107+ choices = [
108+ {"name" : "Password (cPanel login password)" , "value" : "password" },
109+ {"name" : "API Token (generate in cPanel > Security > Manage API Tokens)" , "value" : "token" },
110+ ],
111+ default = "password" ,
112+ ).ask ()
113+ auth_method = auth_choice or "password"
114+
93115 host = cpanel_host or current .cpanel_host
94116 user = cpanel_user or current .cpanel_user
95- token = cpanel_token or (current .cpanel_token .get_secret_value () if current .cpanel_token else None )
117+ secret = cpanel_password or cpanel_token or (current .cpanel_token .get_secret_value () if current .cpanel_token else None )
96118 ttl = default_ttl if default_ttl is not None else current .default_ttl
97119 audit_path = (
98120 audit_log_path
@@ -101,36 +123,59 @@ def action(app_context):
101123 )
102124
103125 if not non_interactive :
104- host = host or questionary .text ("cPanel host" , default = current .cpanel_host or "" ).ask ()
105- user = user or questionary .text ("cPanel user" , default = current .cpanel_user or "" ).ask ()
106- token = token or questionary .password ("cPanel API token" ).ask ()
107- ttl_text = questionary .text ("Default TTL" , default = str (ttl )).ask () or str (ttl )
108- try :
109- ttl = int (ttl_text )
110- except ValueError as exc :
111- raise ValidationAppError ("config_init" , "Default TTL must be an integer." , str (target )) from exc
112- audit_path = questionary .text ("Audit log path" , default = audit_path ).ask () or audit_path
126+ user = user or questionary .text ("cPanel username" ).ask ()
127+ # o2switch server selection
128+ if not host :
129+ ui .console .print ("\n [dim]Your o2switch server name is shown in your cPanel URL:[/]" )
130+ ui .console .print ("[dim] https://[bold]SERVER[/].o2switch.net:2083[/]\n " )
131+ server_name = questionary .text (
132+ "o2switch server name" ,
133+ instruction = "(just the name: saule, if, herse, etc.)"
134+ ).ask ()
135+ if server_name :
136+ server_name = server_name .strip ().lower ()
137+ if not server_name .endswith (".o2switch.net" ):
138+ host = f"{ server_name } .o2switch.net"
139+ else :
140+ host = server_name
141+ else :
142+ host = questionary .text ("cPanel server" , default = host ).ask ()
143+
144+ if auth_method == "password" :
145+ secret = secret or questionary .password ("cPanel password" ).ask ()
146+ else :
147+ ui .console .print ("\n [dim]Generate a token in cPanel:[/]" )
148+ ui .console .print ("[dim] Security > Manage API Tokens > Create[/]\n " )
149+ secret = secret or questionary .password ("cPanel API token" ).ask ()
113150
114151 host = host .strip () if host else None
115152 user = user .strip () if user else None
116- token = token .strip () if token else None
153+ secret = secret .strip () if secret else None
117154 audit_path = (
118155 audit_path .strip ()
119156 if isinstance (audit_path , str ) and audit_path .strip ()
120157 else default_audit_log_path ()
121158 )
122159
123- if not host or not user or not token :
160+ if not host or not user or not secret :
161+ missing = []
162+ if not host :
163+ missing .append ("host" )
164+ if not user :
165+ missing .append ("user" )
166+ if not secret :
167+ missing .append ("password" if auth_method == "password" else "token" )
124168 raise ValidationAppError (
125169 "config_init" ,
126- "cpanel host, user, and token are required. " ,
170+ f"Missing required fields: { ', ' . join ( missing ) } " ,
127171 str (target ),
128172 )
129173
130174 settings = AppSettings (
131175 cpanel_host = host ,
132176 cpanel_user = user ,
133- cpanel_token = token ,
177+ cpanel_token = secret ,
178+ auth_method = auth_method ,
134179 port = current .port ,
135180 timeout_seconds = current .timeout_seconds ,
136181 default_ttl = ttl ,
@@ -141,13 +186,12 @@ def action(app_context):
141186 )
142187 written = write_env_file (target , settings )
143188 ui .print_mapping (
144- "Setup Written " ,
189+ "Setup Complete " ,
145190 {
146- "path " : str (written ),
191+ "config_file " : str (written ),
147192 "cpanel_host" : host ,
148193 "cpanel_user" : user ,
149- "default_ttl" : ttl ,
150- "audit_log_path" : audit_path ,
194+ "auth_method" : auth_method ,
151195 },
152196 )
153197
0 commit comments