11import sys
2-
32import click
3+ import os
44from utilities_common .cli import AbbreviationGroup , pass_db
5-
6-
5+ from ipaddress import ip_address , AddressValueError
6+ import re
77#
88# 'kdump' group ('sudo config kdump ...')
99#
10+
1011@click .group (cls = AbbreviationGroup , name = "kdump" )
1112def kdump ():
1213 """Configure the KDUMP mechanism"""
1314 pass
1415
15-
1616def check_kdump_table_existence (kdump_table ):
1717 """Checks whether the 'KDUMP' table is configured in Config DB.
1818
@@ -32,40 +32,46 @@ def check_kdump_table_existence(kdump_table):
3232 sys .exit (2 )
3333
3434
35+ def echo_reboot_warning ():
36+ """Prints the warning message about reboot requirements."""
37+ click .echo ("KDUMP configuration changes may require a reboot to take effect." )
38+ click .echo ("Save SONiC configuration using 'config save' before issuing the reboot command." )
3539#
3640# 'disable' command ('sudo config kdump disable')
3741#
38- @kdump .command (name = "disable" , short_help = "Disable the KDUMP mechanism" )
42+
43+
44+ @kdump .command (name = "disable" , help = "Disable the KDUMP mechanism" )
3945@pass_db
4046def kdump_disable (db ):
4147 """Disable the KDUMP mechanism"""
4248 kdump_table = db .cfgdb .get_table ("KDUMP" )
4349 check_kdump_table_existence (kdump_table )
4450
4551 db .cfgdb .mod_entry ("KDUMP" , "config" , {"enabled" : "false" })
46- click .echo ("KDUMP configuration changes may require a reboot to take effect." )
47- click .echo ("Save SONiC configuration using 'config save' before issuing the reboot command." )
48-
52+ echo_reboot_warning ()
4953
5054#
5155# 'enable' command ('sudo config kdump enable')
5256#
53- @kdump .command (name = "enable" , short_help = "Enable the KDUMP mechanism" )
57+
58+
59+ @kdump .command (name = "enable" , help = "Enable the KDUMP mechanism" )
5460@pass_db
5561def kdump_enable (db ):
5662 """Enable the KDUMP mechanism"""
5763 kdump_table = db .cfgdb .get_table ("KDUMP" )
5864 check_kdump_table_existence (kdump_table )
5965
6066 db .cfgdb .mod_entry ("KDUMP" , "config" , {"enabled" : "true" })
61- click .echo ("KDUMP configuration changes may require a reboot to take effect." )
62- click .echo ("Save SONiC configuration using 'config save' before issuing the reboot command." )
63-
67+ echo_reboot_warning ()
6468
6569#
6670# 'memory' command ('sudo config kdump memory ...')
6771#
68- @kdump .command (name = "memory" , short_help = "Configure the memory for KDUMP mechanism" )
72+
73+
74+ @kdump .command (name = "memory" , help = "Configure the memory for KDUMP mechanism" )
6975@click .argument ('kdump_memory' , metavar = '<kdump_memory>' , required = True )
7076@pass_db
7177def kdump_memory (db , kdump_memory ):
@@ -74,14 +80,14 @@ def kdump_memory(db, kdump_memory):
7480 check_kdump_table_existence (kdump_table )
7581
7682 db .cfgdb .mod_entry ("KDUMP" , "config" , {"memory" : kdump_memory })
77- click .echo ("KDUMP configuration changes may require a reboot to take effect." )
78- click .echo ("Save SONiC configuration using 'config save' before issuing the reboot command." )
79-
83+ echo_reboot_warning ()
8084
8185#
82- # 'num_dumps' command ('sudo config keump num_dumps ...')
86+ # 'num_dumps' command ('sudo config kdump num_dumps ...')
8387#
84- @kdump .command (name = "num_dumps" , short_help = "Configure the maximum dump files of KDUMP mechanism" )
88+
89+
90+ @kdump .command (name = "num_dumps" , help = "Configure the maximum dump files of KDUMP mechanism" )
8591@click .argument ('kdump_num_dumps' , metavar = '<kdump_num_dumps>' , required = True , type = int )
8692@pass_db
8793def kdump_num_dumps (db , kdump_num_dumps ):
@@ -90,3 +96,160 @@ def kdump_num_dumps(db, kdump_num_dumps):
9096 check_kdump_table_existence (kdump_table )
9197
9298 db .cfgdb .mod_entry ("KDUMP" , "config" , {"num_dumps" : kdump_num_dumps })
99+ echo_reboot_warning ()
100+
101+
102+ @kdump .command (name = "remote" , help = "Configure the remote enable/disable for KDUMP mechanism" )
103+ @click .argument ('action' , metavar = '<enable/disable>' , required = True , type = click .STRING ) # Corrected this line
104+ @pass_db
105+ def remote (db , action ):
106+ """Enable or disable remote kdump feature"""
107+ kdump_table = db .cfgdb .get_table ("KDUMP" )
108+ check_kdump_table_existence (kdump_table )
109+
110+ # Get the current status of the remote feature as string
111+ current_status = kdump_table ["config" ].get ("remote" , "false" ).lower ()
112+
113+ if action .lower () == 'enable' :
114+ if current_status == "true" :
115+ click .echo ("Remote kdump feature is already enabled." )
116+ else :
117+ db .cfgdb .mod_entry ("KDUMP" , "config" , {"remote" : "true" })
118+ click .echo ("Remote kdump feature enabled." )
119+ echo_reboot_warning ()
120+ elif action .lower () == 'disable' :
121+ if current_status == "false" :
122+ click .echo ("Remote kdump feature is already disabled." )
123+ else :
124+ db .cfgdb .mod_entry ("KDUMP" , "config" , {"remote" : "false" })
125+ click .echo ("Remote kdump feature disabled." )
126+ echo_reboot_warning ()
127+ else :
128+ click .echo ("Invalid action. Use 'enable' or 'disable'." )
129+
130+
131+ @kdump .group (name = "add" , help = "Add configuration items to KDUMP" )
132+ def add ():
133+ """Group of commands to add configuration items to KDUMP"""
134+ pass
135+
136+
137+ @add .command (name = "ssh_string" , help = "Add an SSH string to the KDUMP configuration" )
138+ @click .argument ('ssh_string' , metavar = '<ssh_key>' , required = True )
139+ @pass_db
140+ def add_ssh_key (db , ssh_string ):
141+ """Add an SSH string to KDUMP configuration"""
142+
143+ def is_valid_ssh_key (ssh_string ):
144+ """Validate the SSH key format"""
145+ # Check if it contains username and hostname/IP (format: username@host)
146+ if "@" not in ssh_string :
147+ return "Invalid format. SSH key must be in 'username@host' format."
148+
149+ username , host = ssh_string .split ("@" , 1 )
150+
151+ # Validate username
152+ if not username or not username .isalnum ():
153+ return "Invalid username. Ensure it contains only alphanumeric characters."
154+
155+ # Validate host (IP or hostname)
156+ try :
157+ # Check if it's a valid IP address
158+ ip_address (host )
159+ except AddressValueError :
160+ # If not an IP, validate hostname
161+ hostname_regex = r'^[a-zA-Z0-9.-]+$'
162+ if not re .match (hostname_regex , host ) or host .startswith ('-' ) or host .endswith ('-' ):
163+ return "Invalid host. Must be a valid IP or hostname."
164+
165+ return None # Validation successful
166+
167+ kdump_table = db .cfgdb .get_table ("KDUMP" )
168+ check_kdump_table_existence (kdump_table )
169+ current_status = kdump_table ["config" ].get ("remote" , "false" ).lower ()
170+
171+ if current_status == 'false' :
172+ click .echo ("Remote feature is not enabled. Please enable the remote feature first." )
173+ return
174+
175+ # Validate SSH key
176+ validation_error = is_valid_ssh_key (ssh_string )
177+ if validation_error :
178+ click .echo (f"Error: { validation_error } " )
179+ return
180+
181+ # Add or update the 'ssh_key' entry in the KDUMP table
182+ db .cfgdb .mod_entry ("KDUMP" , "config" , {"ssh_string" : ssh_string })
183+ click .echo (f"SSH string added to KDUMP configuration: { ssh_string } " )
184+
185+
186+ @add .command (name = "ssh_path" , help = "Add an SSH path to the KDUMP configuration" )
187+ @click .argument ('ssh_path' , metavar = '<ssh_path>' , required = True )
188+ @pass_db
189+ def add_ssh_path (db , ssh_path ):
190+ """Add an SSH path to KDUMP configuration"""
191+
192+ def is_valid_ssh_path (ssh_path ):
193+ """Validate the SSH path"""
194+ # Check if the path is absolute
195+ if not os .path .isabs (ssh_path ):
196+ return "Invalid path. SSH path must be an absolute path."
197+
198+ # (Optional) Check if the path exists on the system
199+ if not os .path .exists (ssh_path ):
200+ return f"Invalid path. The path '{ ssh_path } ' does not exist."
201+
202+ return None # Validation successful
203+
204+ kdump_table = db .cfgdb .get_table ("KDUMP" )
205+ check_kdump_table_existence (kdump_table )
206+ current_status = kdump_table ["config" ].get ("remote" , "false" ).lower ()
207+ if current_status == 'false' :
208+ click .echo ("Remote feature is not enabled. Please enable the remote feature first." )
209+ return
210+
211+ # Validate SSH path
212+ validation_error = is_valid_ssh_path (ssh_path )
213+ if validation_error :
214+ click .echo (f"Error: { validation_error } " )
215+ return
216+
217+ # Add or update the 'ssh_path' entry in the KDUMP table
218+ db .cfgdb .mod_entry ("KDUMP" , "config" , {"ssh_path" : ssh_path })
219+ click .echo (f"SSH path added to KDUMP configuration: { ssh_path } " )
220+
221+
222+ @kdump .group (name = "remove" , help = "remove configuration items to KDUMP" )
223+ def remove ():
224+ """Group of commands to remove configuration items to KDUMP"""
225+ pass
226+
227+
228+ @remove .command (name = "ssh_string" , help = "Remove the SSH string from the KDUMP configuration" )
229+ @pass_db
230+ def remove_ssh_string (db ):
231+ """Remove the SSH string from KDUMP configuration"""
232+ kdump_table = db .cfgdb .get_table ("KDUMP" )
233+ check_kdump_table_existence (kdump_table )
234+
235+ # Check if ssh_string exists
236+ if "ssh_string" in kdump_table ["config" ]:
237+ db .cfgdb .mod_entry ("KDUMP" , "config" , {"ssh_string" : None })
238+ click .echo ("SSH string removed from KDUMP configuration." )
239+ else :
240+ click .echo ("SSH string not found in KDUMP configuration." )
241+
242+
243+ @remove .command (name = "ssh_path" , help = "Remove the SSH path from the KDUMP configuration" )
244+ @pass_db
245+ def remove_ssh_path (db ):
246+ """Remove the SSH path from KDUMP configuration"""
247+ kdump_table = db .cfgdb .get_table ("KDUMP" )
248+ check_kdump_table_existence (kdump_table )
249+
250+ # Check if ssh_string exists
251+ if "ssh_path" in kdump_table ["config" ]:
252+ db .cfgdb .mod_entry ("KDUMP" , "config" , {"ssh_path" : None })
253+ click .echo ("SSH path removed from KDUMP configuration." )
254+ else :
255+ click .echo ("SSH path not found in KDUMP configuration." )
0 commit comments