NETRAVE/lib/utils/first_run_init.rb
VetheonGames 54d348c99f Enhancements to Command Execution and Logging Mechanisms
This commit introduces several significant enhancements to the way commands are executed and logged in the application. The changes are primarily focused on improving the robustness, reliability, and transparency of the command execution process, as well as enhancing the quality and usefulness of the log output.

   1. Command Execution Enhancements: The use_sudo method has been refactored to handle commands that do not return any output. Previously, the method was designed to capture and return the output of the command being executed. However, some commands (such as modprobe) do not return any output, which caused issues with the previous implementation. The method now checks the exit status of the command to determine whether it was successful or not, and returns a success or failure message accordingly. This change improves the robustness of the command execution process and ensures that it can handle a wider range of commands.

   2. Error Handling Improvements: The use_sudo method now includes more comprehensive error handling. If a command fails to execute within a specified timeout period, an error message is logged and the method returns a failure message. Additionally, if a command fails to execute for any other reason, the method logs the error and returns a failure message with the command's exit status. These changes make it easier to identify and troubleshoot issues with command execution.

   3.  Logging Enhancements: The logging mechanism has been enhanced to provide more detailed and useful information. The use_sudo method now logs the command being executed and its outcome (success or failure). If a command fails, the method logs the command's exit status. These changes improve the transparency of the command execution process and make it easier to identify and troubleshoot issues.

   4. Code Refactoring: Several methods have been refactored for improved readability and maintainability. The use_sudo method has been refactored to reduce its complexity and improve its readability. The first_run_setup method has been refactored to ensure that the main interface name and the dummy interface name are properly passed to the setup_traffic_mirroring method.

   5. Bug Fixes: A bug in the create_dummy_interface method that caused it to return an array of Alert objects instead of the dummy interface name has been fixed. The method now correctly returns the dummy interface name.

These changes represent a significant improvement to the command execution and logging mechanisms in the application, and lay the groundwork for further enhancements in the future.
2023-07-07 11:25:08 -06:00

142 lines
4.5 KiB
Ruby

# frozen_string_literal: true
require 'curses'
require 'dynamic_curses_input'
require 'dotenv'
require_relative 'database_manager'
require_relative 'system_information_gather'
require_relative 'utilities'
require_relative 'alert_manager'
require_relative 'networking_genie'
# first run class
class FirstRunInit
include Utilities
include Curses
def initialize(logger, alert_queue_manager, db_manager = nil)
@loggman = logger
@db_manager = db_manager
@alert_queue_manager = alert_queue_manager
@info_gatherer = SystemInformationGather.new(@db_manager, @loggman)
Dotenv.load
end
def run
first_run_setup
end
def first_run_setup # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
ask_for_db_details
dec_pass = decrypt_string_chacha20(ENV['DB_PASSWORD'], ENV['DB_SECRET_KEY'])
connection_established = @db_manager.test_db_connection(ENV['DB_USERNAME'], dec_pass.to_s, ENV['DB_DATABASE'])
until connection_established
Curses.setpos(4, 0)
alert = Alert.new("We couldn't connect to the database with the details you provided Please try again!", :warning)
@alert_queue_manager.enqueue_alert(alert)
Curses.refresh
ask_for_db_details
connection_established = @db_manager.test_db_connection(ENV['DB_USERNAME'], dec_pass.to_s, ENV['DB_DATABASE'])
end
@db_manager.create_system_info_table
@db_manager.create_services_table
uplink_speed = @info_gatherer.ask_for_uplink_speed
downlink_speed = @info_gatherer.ask_for_downlink_speed
total_bandwidth = calculate_total_bandwidth(uplink_speed, downlink_speed)
services = @info_gatherer.ask_for_services
system_info = {
uplink_speed:,
downlink_speed:,
total_bandwidth:
}
@db_manager.store_system_info(system_info)
@db_manager.store_services(services)
# ask for sudo permissions to setup the networking stuff we need
ask_for_sudo(@loggman)
# Set up networking
networking_genie = NetworkingGenie.new(@loggman, @alert_queue_manager)
main_interface = networking_genie.find_main_interface
dummy_interface = networking_genie.create_dummy_interface('netrave0')
networking_genie.setup_traffic_mirroring(main_interface, dummy_interface)
end
def ask_for_db_details # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
@loggman.log_info('Asking for Database details...')
Curses.clear
Curses.setpos(1, 0)
Curses.addstr('Please enter your database username: ')
Curses.refresh
username = DCI.catch_input(true)
@loggman.log_info('Database Username entered!')
Curses.setpos(2, 0)
Curses.addstr('Please enter your database password: ')
Curses.refresh
Curses.noecho
password = DCI.catch_input(false)
@loggman.log_info('Database Password Stored Securely!')
Curses.echo
Curses.setpos(3, 0)
Curses.addstr('Please enter your database name: ')
Curses.refresh
database = DCI.catch_input(true)
@loggman.log_info('Database Name entered!')
# Generate a secret key
key = generate_key
@loggman.log_info('Secret Key Generated!')
# Encrypt the password
encrypted_password = encrypt_string_chacha20(password, key)
@loggman.log_info('Password Encrypted!')
db_details = { username:, password: encrypted_password, key:, database: }
write_db_details_to_config_file(db_details)
@loggman.log_info('Wiriting Database details to a file!')
end
def write_db_details_to_config_file(db_details) # rubocop:disable Metrics/MethodLength
# Write the database details to the .env file
File.open('.env', 'w') do |file|
file.puts %(DB_USERNAME="#{db_details[:username]}")
file.puts %(DB_PASSWORD="#{db_details[:password]}")
file.puts %(DB_SECRET_KEY="#{db_details[:key]}")
file.puts %(DB_DATABASE="#{db_details[:database]}")
end
@loggman.log_info('Database details saved! Reloading environment...')
# Load the .env file using dotenv
Dotenv.load
@loggman.log_info('Environment restarted!')
rescue StandardError => e
@loggman.log_error("Failed to write to .env file: #{e.message}")
end
def ask_for_default_mode
loop do
Curses.setpos(8, 0)
Curses.addstr('Please enter the default mode (TUI, GUI, or WebApp): ')
Curses.refresh
mode = Curses.getstr.strip.downcase
return mode if valid_mode?(mode)
Curses.setpos(9, 0)
Curses.addstr("Whoops! That didn't appear to be a valid mode. Please try again!")
Curses.refresh
end
end
def valid_mode?(mode)
%w[tui gui webapp].include?(mode)
end
end