2022-11-17 07:34:58 +00:00
import os
2024-02-04 07:28:17 +00:00
from pathlib import Path
from typing import Any
2022-11-17 07:34:58 +00:00
2024-08-02 09:50:02 +00:00
from flask import render_template , g
from flask_jwt_extended import get_jwt
from flask_jwt_extended import verify_jwt_in_request
2023-05-17 17:38:13 +00:00
2024-02-04 07:28:17 +00:00
import app . modules . db . sql as sql
2024-03-03 07:11:48 +00:00
import app . modules . db . user as user_sql
import app . modules . db . server as server_sql
import app . modules . db . config as config_sql
import app . modules . db . service as service_sql
2024-02-04 07:28:17 +00:00
import app . modules . server . ssh as mod_ssh
import app . modules . server . server as server_mod
import app . modules . common . common as common
import app . modules . roxywi . common as roxywi_common
2024-03-03 07:11:48 +00:00
import app . modules . roxy_wi_tools as roxy_wi_tools
2024-02-04 07:28:17 +00:00
import app . modules . service . common as service_common
import app . modules . service . action as service_action
import app . modules . config . common as config_common
2022-11-17 07:34:58 +00:00
time_zone = sql . get_setting ( ' time_zone ' )
get_date = roxy_wi_tools . GetDate ( time_zone )
get_config_var = roxy_wi_tools . GetConfigVar ( )
2024-02-04 07:28:17 +00:00
def _replace_config_path_to_correct ( config_path : str ) - > str :
"""
Replace the characters ' 92 ' with ' / ' in the given config_path string .
: param config_path : The config path to be sanitized .
: return : The sanitized config path string .
"""
config_path = common . checkAjaxInput ( config_path )
try :
return config_path . replace ( ' 92 ' , ' / ' )
except Exception as e :
2024-03-04 06:34:24 +00:00
roxywi_common . handle_exceptions ( e , ' Roxy-WI server ' , ' Cannot sanitize config file ' , roxywi = 1 )
2022-11-17 07:34:58 +00:00
2024-02-04 07:28:17 +00:00
def get_config ( server_ip , cfg , service = ' haproxy ' , * * kwargs ) :
"""
: param service : The service for what needed to get config . Valid values are ' haproxy ' , ' nginx ' , ' apache ' and ' keepalived ' .
: param server_ip : The IP address of the server from which to retrieve the configuration .
: param cfg : The name of the configuration file .
: param kwargs : Additional keyword arguments .
- service : The name of the service for which the configuration is retrieved .
- config_file_name : The name of the configuration file for ' nginx ' or ' apache ' services .
- waf : The name of the Web Application Firewall ( WAF ) service .
- waf_rule_file : The name of the WAF rule file .
: return : None
Retrieves the configuration file for the specified service on the given server IP . The configuration file is stored in the provided ' cfg ' variable .
The method first determines the correct path for the configuration file based on the ' service ' parameter :
- If the service is ' keepalived ' or ' haproxy ' , the method retrieves the configuration path from the SQL database using the service name appended with ' _config_path ' .
- If the service is ' nginx ' or ' apache ' , the method replaces the configuration file name with the correct path using the ' _replace_config_path_to_correct ' function and the ' config_file
* _name ' parameter.
- If the ' waf ' parameter is provided , the method retrieves the service directory from the SQL database using the ' waf ' parameter appended with ' _dir ' . If the ' waf ' parameter is ' hap
* roxy ' or ' nginx ' , the method constructs the configuration path by appending the service directory with ' / waf / rules / ' and the ' waf_rule_file ' parameter.
After determining the configuration path , the method validates that the configuration file exists using the ' common.check_is_conf ' function .
Finally , the method establishes an SSH connection to the server IP using the ' mod_ssh.ssh_connect ' function and retrieves the configuration file using the ' ssh.get_sftp ' function . Any
* exceptions that occur during this process are handled by the ' roxywi_common.handle_exceptions ' function , displaying an error message with the relevant details .
"""
config_path = ' '
2024-06-16 16:20:18 +00:00
if service in ( ' keepalived ' , ' haproxy ' ) and not kwargs . get ( " waf " ) :
2024-02-04 07:28:17 +00:00
config_path = sql . get_setting ( f ' { service } _config_path ' )
elif service in ( ' nginx ' , ' apache ' ) :
config_path = _replace_config_path_to_correct ( kwargs . get ( ' config_file_name ' ) )
elif kwargs . get ( " waf " ) :
service_dir = sql . get_setting ( f " { kwargs . get ( ' waf ' ) } _dir " )
if kwargs . get ( " waf " ) in ( ' haproxy ' , ' nginx ' ) :
config_path = f ' { service_dir } /waf/rules/ { kwargs . get ( " waf_rule_file " ) } '
common . check_is_conf ( config_path )
2023-03-03 20:03:41 +00:00
2022-11-17 07:34:58 +00:00
try :
2022-12-07 09:27:46 +00:00
with mod_ssh . ssh_connect ( server_ip ) as ssh :
2022-11-17 07:34:58 +00:00
ssh . get_sftp ( config_path , cfg )
except Exception as e :
2024-03-03 07:11:48 +00:00
roxywi_common . handle_exceptions ( e , ' Roxy-WI server ' , ' Cannot get config ' , roxywi = 1 )
2024-02-04 07:28:17 +00:00
2022-11-17 07:34:58 +00:00
2024-02-04 07:28:17 +00:00
def upload ( server_ip : str , path : str , file : str ) - > None :
"""
Uploads a file to a remote server using secure shell ( SSH ) protocol .
2022-11-17 07:34:58 +00:00
2024-02-04 07:28:17 +00:00
: param server_ip : The IP address or hostname of the remote server .
: param path : The remote path on the server where the file will be uploaded .
: param file : The file to be uploaded .
: return : None
"""
2022-11-17 07:34:58 +00:00
try :
2022-12-07 09:27:46 +00:00
with mod_ssh . ssh_connect ( server_ip ) as ssh :
2023-09-17 09:42:39 +00:00
ssh . put_sftp ( file , path )
2022-11-17 07:34:58 +00:00
except Exception as e :
2024-03-03 07:11:48 +00:00
roxywi_common . handle_exceptions ( e , ' Roxy-WI server ' , f ' Cannot upload { file } to { path } to server: { server_ip } ' , roxywi = 1 )
2024-02-04 07:28:17 +00:00
2024-03-03 07:11:48 +00:00
def _generate_command ( service : str , server_id : int , just_save : str , config_path : str , tmp_file : str , cfg : str , server_ip : str ) - > str :
2024-02-04 07:28:17 +00:00
"""
: param service : The name of the service .
: param server_id : The ID of the server .
: param just_save : Indicates whether the configuration should only be saved or not . Possible values are ' test ' , ' save ' , ' restart ' or ' reload ' .
: param config_path : The path to the configuration file .
: param tmp_file : The temporary file path .
: param cfg : The configuration object .
: param server_ip : The IP address of the server .
: return : A list of commands .
This method generates a list of commands based on the given parameters .
"""
container_name = sql . get_setting ( f ' { service } _container_name ' )
2024-03-03 07:11:48 +00:00
is_dockerized = service_sql . select_service_setting ( server_id , service , ' dockerized ' )
2024-02-04 07:28:17 +00:00
reload_or_restart_command = f ' && { service_action . get_action_command ( service , just_save , server_id ) } '
move_config = f " sudo mv -f { tmp_file } { config_path } "
command_for_docker = f ' sudo docker exec -it { container_name } '
command = {
2024-04-01 14:04:38 +00:00
' haproxy ' : { ' 0 ' : f ' sudo haproxy -c -f { tmp_file } ' , ' 1 ' : f ' { command_for_docker } haproxy -c -f { tmp_file } ' } ,
2024-02-04 07:28:17 +00:00
' nginx ' : { ' 0 ' : ' sudo nginx -t ' , ' 1 ' : f ' { command_for_docker } nginx -t ' } ,
' apache ' : { ' 0 ' : ' sudo apachectl -t ' , ' 1 ' : f ' { command_for_docker } apachectl -t ' } ,
' keepalived ' : { ' 0 ' : f ' keepalived -t -f { tmp_file } ' , ' 1 ' : ' ' } ,
' waf ' : { ' 0 ' : ' ' , ' 1 ' : ' ' }
}
2022-11-17 07:34:58 +00:00
2024-02-04 07:28:17 +00:00
try :
check_config = command [ service ] [ is_dockerized ]
except Exception as e :
raise Exception ( f ' error: Cannot generate command: { e } ' )
2022-11-17 07:34:58 +00:00
2024-02-04 07:28:17 +00:00
if just_save == ' test ' :
2024-03-03 07:11:48 +00:00
return f " { check_config } && sudo rm -f { tmp_file } "
2024-02-04 07:28:17 +00:00
elif just_save == ' save ' :
reload_or_restart_command = ' '
else :
if service_common . is_not_allowed_to_restart ( server_id , service , just_save ) :
2024-03-04 06:34:24 +00:00
raise Exception ( ' error: This server is not allowed to be restarted ' )
2022-11-17 07:34:58 +00:00
2024-03-03 07:11:48 +00:00
if service == ' waf ' :
commands = f ' { move_config } { reload_or_restart_command } '
2024-02-04 07:28:17 +00:00
elif service in ( ' nginx ' , ' apache ' ) :
2024-03-03 07:11:48 +00:00
commands = f ' { move_config } && { check_config } { reload_or_restart_command } '
2024-02-04 07:28:17 +00:00
else :
2024-03-03 07:11:48 +00:00
commands = f ' { check_config } && { move_config } { reload_or_restart_command } '
2023-09-17 09:42:39 +00:00
2024-02-04 07:28:17 +00:00
if service in ( ' haproxy ' , ' nginx ' ) :
2024-03-03 07:11:48 +00:00
if server_sql . return_firewall ( server_ip ) :
commands + = _open_port_firewalld ( cfg , server_ip , service )
2024-02-04 07:28:17 +00:00
return commands
2023-09-17 09:42:39 +00:00
2023-05-17 17:38:13 +00:00
2024-02-04 07:28:17 +00:00
def _create_config_version ( server_id : int , server_ip : str , service : str , config_path : str , login : str , cfg : str , old_cfg : str , tmp_file : str ) - > None :
"""
Create a new version of the configuration file .
2022-11-17 07:34:58 +00:00
2024-02-04 07:28:17 +00:00
: param server_id : The ID of the server .
: param server_ip : The IP address of the server .
: param service : The service name .
: param config_path : The path to the configuration file .
: param login : The login of the user .
: param cfg : The new configuration string .
: param old_cfg : The path to the old configuration file .
: param tmp_file : A temporary file name .
2023-09-17 09:42:39 +00:00
2024-02-04 07:28:17 +00:00
: return : None
"""
diff = ' '
2022-11-17 07:34:58 +00:00
2024-02-04 07:28:17 +00:00
if old_cfg :
path = Path ( old_cfg )
2022-11-17 07:34:58 +00:00
else :
2024-02-04 07:28:17 +00:00
old_cfg = ' '
path = Path ( old_cfg )
2022-11-17 07:34:58 +00:00
2024-02-04 07:28:17 +00:00
if not path . is_file ( ) :
old_cfg = f ' { tmp_file } .old '
try :
get_config ( server_ip , old_cfg , service = service , config_file_name = config_path )
except Exception :
roxywi_common . logging ( ' Roxy-WI server ' , ' Cannot download config for diff ' , roxywi = 1 )
2022-11-17 07:34:58 +00:00
try :
2024-02-04 07:28:17 +00:00
diff = diff_config ( old_cfg , cfg , return_diff = 1 )
except Exception as e :
roxywi_common . logging ( ' Roxy-WI server ' , f ' error: Cannot create diff config version: { e } ' , roxywi = 1 )
2022-11-17 07:34:58 +00:00
2024-02-04 07:28:17 +00:00
try :
2024-07-08 07:17:28 +00:00
user = user_sql . get_user_id_by_username ( login )
2024-06-19 17:52:24 +00:00
config_sql . insert_config_version ( server_id , user . user_id , service , cfg , config_path , diff )
2024-02-04 07:28:17 +00:00
except Exception as e :
roxywi_common . logging ( ' Roxy-WI server ' , f ' error: Cannot insert config version: { e } ' , roxywi = 1 )
2022-11-17 07:34:58 +00:00
2024-02-04 07:28:17 +00:00
def upload_and_restart ( server_ip : str , cfg : str , just_save : str , service : str , * * kwargs ) :
"""
: param server_ip : IP address of the server
: param cfg : Path to the config file to be uploaded
: param just_save : Option specifying whether to just save the config or perform an action such as reload or restart
: param service : Service name for which the config is being uploaded
: param kwargs : Additional keyword arguments
: return : Error message or service title
"""
2024-07-08 12:53:05 +00:00
user_id = g . user_params [ ' user_id ' ]
user = user_sql . get_user_id ( user_id )
2024-02-04 07:28:17 +00:00
file_format = config_common . get_file_format ( service )
config_path = kwargs . get ( ' config_file_name ' )
config_date = get_date . return_date ( ' config ' )
2024-03-03 07:11:48 +00:00
server_id = server_sql . select_server_id_by_ip ( server_ip = server_ip )
2024-02-04 07:28:17 +00:00
if config_path and config_path != ' undefined ' :
config_path = _replace_config_path_to_correct ( kwargs . get ( ' config_file_name ' ) )
if service in ( ' haproxy ' , ' keepalived ' ) :
config_path = sql . get_setting ( f ' { service } _config_path ' )
common . check_is_conf ( config_path )
tmp_file = f " { sql . get_setting ( ' tmp_config_path ' ) } / { config_date } . { file_format } "
try :
os . system ( f " dos2unix -q { cfg } " )
except OSError as e :
2024-07-08 12:53:05 +00:00
roxywi_common . handle_exceptions ( e , ' Roxy-WI server ' , ' There is no dos2unix ' , login = user . username )
2022-11-17 07:34:58 +00:00
try :
2023-09-17 09:42:39 +00:00
upload ( server_ip , tmp_file , cfg )
except Exception as e :
2024-07-08 12:53:05 +00:00
roxywi_common . handle_exceptions ( e , ' Roxy-WI server ' , ' Cannot upload config ' , login = user . username )
2022-11-17 07:34:58 +00:00
2023-09-17 09:42:39 +00:00
try :
2024-02-04 07:28:17 +00:00
if just_save != ' test ' :
2024-07-08 12:53:05 +00:00
roxywi_common . logging ( server_ip , ' A new config file has been uploaded ' , login = user . username , keep_history = 1 , service = service )
2023-09-17 09:42:39 +00:00
except Exception as e :
roxywi_common . logging ( ' Roxy-WI server ' , str ( e ) , roxywi = 1 )
2024-06-05 07:20:43 +00:00
# If master then save a version of config in a new way
2023-09-17 09:42:39 +00:00
if not kwargs . get ( ' slave ' ) and service != ' waf ' :
2024-07-08 12:53:05 +00:00
_create_config_version ( server_id , server_ip , service , config_path , user . username , cfg , kwargs . get ( ' oldcfg ' ) , tmp_file )
2022-11-17 07:34:58 +00:00
2024-02-04 07:28:17 +00:00
try :
commands = _generate_command ( service , server_id , just_save , config_path , tmp_file , cfg , server_ip )
except Exception as e :
2024-08-02 09:50:02 +00:00
roxywi_common . handle_exceptions ( e , ' Roxy-WI server ' , f ' Cannot generate command for service { service } ' )
2022-11-17 07:34:58 +00:00
2023-09-17 09:42:39 +00:00
try :
error = server_mod . ssh_command ( server_ip , commands )
2022-11-17 07:34:58 +00:00
except Exception as e :
2024-03-03 07:11:48 +00:00
roxywi_common . handle_exceptions ( e , ' Roxy-WI server ' , f ' Cannot { just_save } { service } ' , roxywi = 1 )
2022-11-17 07:34:58 +00:00
try :
2024-02-04 07:28:17 +00:00
if just_save in ( ' reload ' , ' restart ' ) :
2024-07-08 12:53:05 +00:00
roxywi_common . logging ( server_ip , f ' Service has been { just_save } ed ' , login = user . username , keep_history = 1 , service = service )
2022-11-17 07:34:58 +00:00
except Exception as e :
roxywi_common . logging ( ' Roxy-WI server ' , str ( e ) , roxywi = 1 )
if error . strip ( ) != ' haproxy ' and error . strip ( ) != ' nginx ' :
2024-02-04 07:28:17 +00:00
return error . strip ( ) or service . title ( )
2022-11-17 07:34:58 +00:00
2024-02-04 07:28:17 +00:00
def master_slave_upload_and_restart ( server_ip : str , cfg : str , just_save : str , service : str , * * kwargs : Any ) - > str :
"""
2022-11-17 07:34:58 +00:00
2024-02-04 07:28:17 +00:00
This method ` master_slave_upload_and_restart ` performs the upload and restart operation on a master server and its associated slave servers . It takes the following parameters :
: param server_ip : The IP address of the server to perform the operation on .
: param cfg : The configuration file to upload and restart .
: param just_save : A flag indicating whether to just save the configuration or also restart the server .
: param service : The name of the service to restart .
: param kwargs : Additional optional keyword arguments .
: return : The output of the operation .
"""
2022-11-17 07:34:58 +00:00
slave_output = ' '
2024-03-03 07:11:48 +00:00
masters = server_sql . is_master ( server_ip )
2023-09-17 09:42:39 +00:00
config_file_name = kwargs . get ( ' config_file_name ' )
2024-02-04 07:28:17 +00:00
old_cfg = kwargs . get ( ' oldcfg ' )
2023-09-17 09:42:39 +00:00
waf = kwargs . get ( ' waf ' )
2024-03-03 07:11:48 +00:00
server_name = server_sql . get_hostname_by_server_ip ( server_ip )
2022-11-17 07:34:58 +00:00
2022-12-09 20:08:32 +00:00
for master in masters :
if master [ 0 ] is not None :
2023-09-17 09:42:39 +00:00
try :
slv_output = upload_and_restart (
master [ 0 ] , cfg , just_save , service , waf = waf , config_file_name = config_file_name , slave = 1
)
slave_output + = f ' <br>slave_server: \n { slv_output } '
except Exception as e :
2023-10-06 19:15:47 +00:00
slave_output + = f ' <br>slave_server: \n error: { e } '
2023-09-17 09:42:39 +00:00
try :
output = upload_and_restart (
2024-07-08 12:53:05 +00:00
server_ip , cfg , just_save , service , waf = waf , config_file_name = config_file_name , oldcfg = old_cfg
2023-09-17 09:42:39 +00:00
)
except Exception as e :
2023-10-06 19:15:47 +00:00
output = f ' error: { e } '
2022-11-17 07:34:58 +00:00
output = server_name + ' : \n ' + output
output = output + slave_output
2023-09-17 09:42:39 +00:00
2022-11-17 07:34:58 +00:00
return output
2024-02-04 07:28:17 +00:00
def _open_port_firewalld ( cfg : str , server_ip : str , service : str ) - > str :
"""
: param cfg : The path to the configuration file for Firewalld .
: param server_ip : The IP address of the server .
: param service : The name of the service to open ports for ( e . g . , nginx ) .
: return : The Firewalld commands to open the specified ports .
2022-11-17 07:34:58 +00:00
2024-02-04 07:28:17 +00:00
This method reads the provided Service configuration file and opens ports based on the specified service . It returns the Firewalld commands as a string .
"""
2022-11-17 07:34:58 +00:00
firewalld_commands = ' && '
ports = ' '
2024-02-04 07:28:17 +00:00
try :
conf = open ( cfg , " r " )
except IOError as e :
raise Exception ( f ' error: Cannot open config file for Firewalld { e } ' )
2022-11-17 07:34:58 +00:00
for line in conf :
2024-02-04 07:28:17 +00:00
if service == ' nginx ' :
2022-11-17 07:34:58 +00:00
if " listen " in line and ' # ' not in line :
try :
listen = ' ' . join ( line . split ( ) )
listen = listen . split ( " " ) [ 1 ]
listen = listen . split ( " ; " ) [ 0 ]
try :
listen = int ( listen )
ports + = str ( listen ) + ' '
firewalld_commands + = f ' sudo firewall-cmd --zone=public --add-port= { listen } /tcp --permanent -q && '
except Exception :
pass
except Exception :
pass
else :
if " bind " in line :
try :
bind = line . split ( " : " )
bind [ 1 ] = bind [ 1 ] . strip ( ' ' )
bind = bind [ 1 ] . split ( " ssl " )
bind = bind [ 0 ] . strip ( ' \t \n \r ' )
try :
bind = int ( bind )
firewalld_commands + = f ' sudo firewall-cmd --zone=public --add-port= { bind } /tcp --permanent -q && '
ports + = str ( bind ) + ' '
except Exception :
pass
except Exception :
pass
2024-03-03 07:11:48 +00:00
firewalld_commands + = ' sudo firewall-cmd --reload -q '
roxywi_common . logging ( server_ip , f ' Next ports have been opened: { ports } ' )
2022-11-17 07:34:58 +00:00
return firewalld_commands
2024-02-04 07:28:17 +00:00
def diff_config ( old_cfg , cfg , * * kwargs ) :
"""
Function to compare two configuration files and log the differences .
: param old_cfg : The path of the old configuration file .
: param cfg : The path of the new configuration file .
: param kwargs : Additional keyword arguments . Currently , supports :
- return_diff : If True , returns the difference between the two files as a string .
: return : If kwargs [ ' return_diff ' ] is True , returns the difference between the two files as a string .
Otherwise , logs the differences with user information and writes it to a log file .
"""
2022-11-17 07:34:58 +00:00
log_path = get_config_var . get_config_var ( ' main ' , ' log_path ' )
user_group = roxywi_common . get_user_group ( )
diff = " "
date = get_date . return_date ( ' date_in_log ' )
log_date = get_date . return_date ( ' logs ' )
2024-02-04 07:28:17 +00:00
cmd = f " /bin/diff -ub { old_cfg } { cfg } "
log_file = f " { log_path } /config_edit- { log_date } "
output , stderr = server_mod . subprocess_execute ( cmd )
if kwargs . get ( ' return_diff ' ) :
for line in output :
diff + = line + " \n "
return diff
2022-11-17 07:34:58 +00:00
try :
2024-08-02 09:50:02 +00:00
verify_jwt_in_request ( )
claims = get_jwt ( )
login = user_sql . get_user_id ( claims [ ' user_id ' ] )
2022-11-17 07:34:58 +00:00
except Exception :
login = ' '
2024-02-04 07:28:17 +00:00
for line in output :
2024-08-02 09:50:02 +00:00
diff + = f " { date } user: { login . username } , group: { user_group } { line } \n "
2022-11-17 07:34:58 +00:00
try :
with open ( log_file , ' a ' ) as log :
log . write ( diff )
2024-02-04 07:28:17 +00:00
except IOError as e :
2024-08-02 09:50:02 +00:00
roxywi_common . logging ( ' Roxy-WI server ' , f ' error: Cannot write a diff config to the log file: { e } , { stderr } ' , login = login . username , roxywi = 1 )
2022-11-17 07:34:58 +00:00
2024-02-04 07:28:17 +00:00
def _classify_line ( line : str ) - > str :
"""
Classifies the line as ' line ' or ' line3 ' based on if it contains ' -- ' .
"""
return " line " if ' -- ' in line else " line3 "
def show_finding_in_config ( stdout : str , * * kwargs ) - > str :
"""
: param stdout : The stdout of a command execution .
: param kwargs : Additional keyword arguments .
2024-08-02 09:50:02 +00:00
: keyword grep : The word to find and highlight in the output . ( Optional )
2024-02-04 07:28:17 +00:00
: return : The output with highlighted lines and formatted dividers .
This method takes the stdout of a command execution and additional keyword arguments . It searches for a word specified by the ` grep ` keyword argument in each line of the stdout and highlights
* the word if found . It then classifies each line based on its content and wraps it in a line with appropriate CSS class . Finally , it adds formatted dividers before and after the output
* .
The formatted output string is returned .
"""
2024-03-03 07:11:48 +00:00
css_class_divider = common . wrap_line ( " -- " )
2024-02-04 07:28:17 +00:00
output = css_class_divider
word_to_find = kwargs . get ( ' grep ' )
if word_to_find :
2024-03-03 07:11:48 +00:00
word_to_find = common . sanitize_input_word ( word_to_find )
2024-02-04 07:28:17 +00:00
for line in stdout :
if word_to_find :
2024-03-03 07:11:48 +00:00
line = common . highlight_word ( line , word_to_find )
2024-02-04 07:28:17 +00:00
line_class = _classify_line ( line )
2024-03-03 07:11:48 +00:00
output + = common . wrap_line ( line , line_class )
2024-02-04 07:28:17 +00:00
output + = css_class_divider
return output
2022-11-17 07:34:58 +00:00
2023-09-17 09:42:39 +00:00
def show_compare_config ( server_ip : str , service : str ) - > str :
2024-02-04 07:28:17 +00:00
"""
Display the comparison of configurations for a service .
2023-09-17 09:42:39 +00:00
2024-02-04 07:28:17 +00:00
: param server_ip : The IP address of the server .
: param service : The service name .
: return : Returns the rendered template as a string .
"""
lang = roxywi_common . get_user_lang_for_flask ( )
config_dir = config_common . get_config_dir ( service )
file_format = config_common . get_file_format ( service )
return_files = roxywi_common . get_files ( config_dir , file_format , server_ip = server_ip )
2022-12-09 20:08:32 +00:00
2023-09-17 09:42:39 +00:00
return render_template ( ' ajax/show_compare_configs.html ' , serv = server_ip , return_files = return_files , lang = lang )
2022-12-09 20:08:32 +00:00
2023-09-17 09:42:39 +00:00
def compare_config ( service : str , left : str , right : str ) - > str :
2024-02-04 07:28:17 +00:00
"""
Compares the configuration files of a service .
: param service : The name of the service .
: param left : The name of the left configuration file .
: param right : The name of the right configuration file .
: return : The rendered template with the diff output and the user language for Flask .
"""
2023-09-17 09:42:39 +00:00
lang = roxywi_common . get_user_lang_for_flask ( )
2024-02-04 07:28:17 +00:00
config_dir = config_common . get_config_dir ( service )
cmd = f ' diff -pub { config_dir } { left } { config_dir } { right } '
2022-12-09 20:08:32 +00:00
output , stderr = server_mod . subprocess_execute ( cmd )
2023-09-17 09:42:39 +00:00
return render_template ( ' ajax/compare.html ' , stdout = output , lang = lang )
2022-12-09 20:08:32 +00:00
2024-08-02 09:50:02 +00:00
def show_config ( server_ip : str , service : str , config_file_name : str , configver : str , claims : dict ) - > str :
2024-02-04 07:28:17 +00:00
"""
Get and display the configuration file for a given server .
2024-08-02 09:50:02 +00:00
: param claims :
2024-02-04 07:28:17 +00:00
: param server_ip : The IP address of the server .
: param service : The name of the service .
: param config_file_name : The name of the configuration file .
: param configver : The version of the configuration .
: return : The rendered template for displaying the configuration .
"""
2024-08-02 09:50:02 +00:00
user_id = claims [ ' user_id ' ]
group_id = claims [ ' group ' ]
2024-02-04 07:28:17 +00:00
configs_dir = config_common . get_config_dir ( service )
2024-03-03 07:11:48 +00:00
server_id = server_sql . select_server_id_by_ip ( server_ip )
2023-09-17 09:42:39 +00:00
2022-12-09 20:08:32 +00:00
try :
2023-09-17 09:42:39 +00:00
config_file_name = config_file_name . replace ( ' / ' , ' 92 ' )
2022-12-09 20:08:32 +00:00
except Exception :
config_file_name = ' '
2023-05-17 17:38:13 +00:00
if ' .. ' in configs_dir :
2023-09-17 09:42:39 +00:00
raise Exception ( ' error: nice try ' )
2023-05-17 17:38:13 +00:00
2023-09-17 09:42:39 +00:00
if configver is None :
2024-02-04 07:28:17 +00:00
cfg = config_common . generate_config_path ( service , server_ip )
2023-04-06 07:48:00 +00:00
try :
2023-09-17 09:42:39 +00:00
get_config ( server_ip , cfg , service = service , config_file_name = config_file_name )
2023-04-06 07:48:00 +00:00
except Exception as e :
2023-09-17 09:42:39 +00:00
raise Exception ( e )
2022-12-09 20:08:32 +00:00
else :
2023-09-17 09:42:39 +00:00
cfg = configs_dir + configver
2022-12-09 20:08:32 +00:00
try :
2023-09-17 09:42:39 +00:00
with open ( cfg , ' r ' ) as file :
conf = file . readlines ( )
except Exception as e :
raise Exception ( f ' error: Cannot read config file: { e } ' )
if configver is None :
os . remove ( cfg )
2022-12-09 20:08:32 +00:00
2024-02-04 07:28:17 +00:00
kwargs = {
' conf ' : conf ,
' serv ' : server_ip ,
' configver ' : configver ,
2024-08-02 09:50:02 +00:00
' role ' : user_sql . get_user_role_in_group ( user_id , group_id ) ,
2024-02-04 07:28:17 +00:00
' service ' : service ,
' config_file_name ' : config_file_name ,
2024-03-03 07:11:48 +00:00
' is_serv_protected ' : server_sql . is_serv_protected ( server_ip ) ,
' is_restart ' : service_sql . select_service_setting ( server_id , service , ' restart ' ) ,
2024-02-04 07:28:17 +00:00
' lang ' : roxywi_common . get_user_lang_for_flask ( ) ,
2024-03-03 07:11:48 +00:00
' hostname ' : server_sql . get_hostname_by_server_ip ( server_ip )
2024-02-04 07:28:17 +00:00
}
2023-09-17 09:42:39 +00:00
2024-02-04 07:28:17 +00:00
return render_template ( ' ajax/config_show.html ' , * * kwargs )
2022-12-09 20:08:32 +00:00
2023-09-17 09:42:39 +00:00
def show_config_files ( server_ip : str , service : str , config_file_name : str ) - > str :
2024-02-04 07:28:17 +00:00
"""
Displays the configuration files for a given server IP , service , and config file name .
: param server_ip : The IP address of the server .
: param service : The name of the service .
: param config_file_name : The name of the config file .
: return : The rendered template .
"""
2022-12-09 20:08:32 +00:00
service_config_dir = sql . get_setting ( f ' { service } _dir ' )
return_files = server_mod . get_remote_files ( server_ip , service_config_dir , ' conf ' )
2024-02-04 07:28:17 +00:00
return_files + = ' ' + sql . get_setting ( f ' { service } _config_path ' )
lang = roxywi_common . get_user_lang_for_flask ( )
2022-12-09 20:08:32 +00:00
if ' error: ' in return_files :
2023-09-17 09:42:39 +00:00
raise Exception ( return_files )
2022-12-09 20:08:32 +00:00
try :
2024-02-04 07:28:17 +00:00
config_file_name = _replace_config_path_to_correct ( config_file_name )
2022-12-09 20:08:32 +00:00
except Exception :
config_file_name = ' '
2023-09-17 09:42:39 +00:00
return render_template (
' ajax/show_configs_files.html ' , serv = server_ip , service = service , return_files = return_files , lang = lang ,
config_file_name = config_file_name , path_dir = service_config_dir
)
2023-05-17 17:38:13 +00:00
2023-09-17 09:42:39 +00:00
def list_of_versions ( server_ip : str , service : str , configver : str , for_delver : int ) - > str :
2024-02-04 07:28:17 +00:00
"""
Retrieve a list of versions for a given server IP , service , configuration version .
: param server_ip : The IP address of the server .
: param service : The service to retrieve versions for .
: param configver : The configuration version to retrieve .
: param for_delver : The delete version to use .
: return : The rendered HTML template with the list of versions .
"""
2024-03-03 07:11:48 +00:00
users = user_sql . select_users ( )
configs = config_sql . select_config_version ( server_ip , service )
2023-09-17 09:42:39 +00:00
lang = roxywi_common . get_user_lang_for_flask ( )
2024-02-04 07:28:17 +00:00
action = f ' /app/config/versions/ { service } / { server_ip } '
config_dir = config_common . get_config_dir ( service )
file_format = config_common . get_file_format ( service )
files = roxywi_common . get_files ( config_dir , file_format , server_ip )
2023-05-17 17:38:13 +00:00
2023-09-17 09:42:39 +00:00
return render_template (
' ajax/show_list_version.html ' , server_ip = server_ip , service = service , action = action , return_files = files ,
configver = configver , for_delver = for_delver , configs = configs , users = users , lang = lang
)
def return_cfg ( service : str , server_ip : str , config_file_name : str ) - > str :
2024-02-04 07:28:17 +00:00
"""
: param service : The name of the service ( e . g . , ' nginx ' , ' apache ' )
: param server_ip : The IP address of the server
: param config_file_name : The name of the configuration file
: return : The path to the generated configuration file
2023-09-17 09:42:39 +00:00
2024-02-04 07:28:17 +00:00
This method returns the path to the generated configuration file based on the provided parameters . The file format is determined by the service . If the service is ' nginx ' or ' apache
* ' , then the config_file_name is replaced with the correct path, and the resulting configuration file is named using the server_ip and the original file name. If the service is not '
* nginx ' or ' apache ' , then the resulting configuration file is named using the server_ip. The file format is determined by calling the config_common.get_file_format() method.
Any existing old configuration files in the config_dir are removed before generating the new configuration file .
Note : This method depends on the config_common . get_file_format ( ) , config_common . get_config_dir ( ) , and get_date . return_date ( ) methods .
"""
file_format = config_common . get_file_format ( service )
config_dir = config_common . get_config_dir ( service )
2023-05-17 17:38:13 +00:00
2023-09-17 09:42:39 +00:00
if service in ( ' nginx ' , ' apache ' ) :
2024-02-04 07:28:17 +00:00
config_file_name = _replace_config_path_to_correct ( config_file_name )
2023-09-17 09:42:39 +00:00
conf_file_name_short = config_file_name . split ( ' / ' ) [ - 1 ]
2024-02-04 07:28:17 +00:00
cfg = f " { config_dir } { server_ip } - { conf_file_name_short } - { get_date . return_date ( ' config ' ) } . { file_format } "
2023-09-17 09:42:39 +00:00
else :
2024-02-04 07:28:17 +00:00
cfg = config_common . generate_config_path ( service , server_ip )
2023-09-17 09:42:39 +00:00
try :
2024-02-04 07:28:17 +00:00
os . remove ( f ' { config_dir } *.old ' )
2023-09-17 09:42:39 +00:00
except Exception :
pass
2023-05-17 17:38:13 +00:00
2023-09-17 09:42:39 +00:00
return cfg