Added update module

This commit is contained in:
Alexey Berezhok
2026-05-03 00:54:14 +03:00
parent 54f549db62
commit 8add078e7c
9 changed files with 292 additions and 10 deletions

View File

@@ -189,11 +189,12 @@ class HestiaBunkerWebApi
variables = {
"USE_TEMPLATE" => options[:use_template] || "high",
"USE_REVERSE_PROXY" => options[:reverse_proxy_host].nil? ? "no" : "yes",
"LIMIT_REQ_RATE" => options[:limit_req_rate] || "10r/s",
}
# SSL configuration - only if USE_SSL != "no"
ssl_enabled = options[:ssl] && options[:ssl] != "no"
variables["USE_SSL"] = ssl_enabled ? "yes" : "no"
variables["USE_CUSTOM_SSL"] = ssl_enabled ? "yes" : "no"
if ssl_enabled
unless options[:certificate_path] && options[:key_path]
@@ -201,8 +202,8 @@ class HestiaBunkerWebApi
end
# Set certificate paths in variables
variables["SSL_CERTIFICATE_FILE_PATH"] = options[:certificate_path]
variables["SSL_KEY_FILE_PATH"] = options[:key_path]
variables["CUSTOM_SSL_CERT"] = options[:certificate_path]
variables["CUSTOM_SSL_KEY"] = options[:key_path]
variables["LISTEN_HTTPS_PORT"] = (options[:https_port] || "443").to_s
variables["USE_REVERSE_PROXY_SSL"] = options[:reverse_proxy_ssl] || "yes"
@@ -216,7 +217,7 @@ class HestiaBunkerWebApi
# Reverse proxy configuration if specified
if options[:reverse_proxy_host]
variables["REVERSE_PROXY_HOST"] = options[:reverse_proxy_host]
variables["REVERSE_PROXY_URL"] = options[:reverse_proxy_url] || "~ ^/(.*)$"
variables["REVERSE_PROXY_URL"] = options[:reverse_proxy_url] || "~ ^(?!/challenge)(.*)$"
# Real IP settings for reverse proxy
unless options[:real_ip_from].nil?
@@ -273,9 +274,9 @@ class HestiaBunkerWebApi
# Update SSL settings
updated_vars = {
"USE_SSL" => "yes",
"SSL_CERTIFICATE_FILE_PATH" => certificate_path,
"SSL_KEY_FILE_PATH" => key_path,
"USE_CUSTOM_SSL" => "yes",
"CUSTOM_SSL_CERT" => certificate_path,
"CUSTOM_SSL_KEY" => key_path,
"LISTEN_HTTPS_PORT" => (https_port || "443").to_s,
"USE_REVERSE_PROXY_SSL" => "yes"
}
@@ -300,6 +301,47 @@ class HestiaBunkerWebApi
return response[:body] || {}
end
def delete_service_ssl(service_name)
@extra_info = ""
# First get current service configuration to preserve existing settings
get_service_response = api_call("GET", "/services/#{service_name}", {})
if get_service_response[:status] != 200
raise BunkerWebApiError.new("Service '#{service_name}' not found")
end
# Extract current variables from the service configuration
current_vars = get_service_response[:body]["variables"] || {}
# Update SSL settings
updated_vars = {
"USE_CUSTOM_SSL" => "no",
"CUSTOM_SSL_CERT" => "",
"CUSTOM_SSL_KEY" => ""
}
# Merge with existing variables (keep non-SSL settings)
final_vars = current_vars.merge(updated_vars)
service_body = {
server_name: nil, # Not changing name
is_draft: false, # Keep as online
variables: final_vars
}
response = api_call("PATCH", "/services/#{service_name}", {}, JSON.generate(service_body))
if response[:status] == 200
puts "[INFO] SSL configuration updated for service '#{service_name}'"
else
raise BunkerWebApiError.new("Failed to update SSL configuration: status=#{response[:status]}, body=#{response[:raw_body]}")
end
return response[:body] || {}
end
def delete_service(service_name)
# Delete a service by its name.
#

View File

@@ -1,5 +1,7 @@
#!/opt/brepo/ruby33/bin/ruby
require 'shellwords'
class BunkerwebWorker < Kernel::ModuleCoreWorker
MODULE_ID = "bunkerweb_module"
@@ -95,7 +97,7 @@ class BunkerwebWorker < Kernel::ModuleCoreWorker
if m_domain.nil? || m_ssl_cert.nil? || m_ssl_key.nil? || m_ssl_cert.empty? || m_ssl_key.empty?
log_return("Domain, SSL cert and SSL key must be specified. #{args}")
else
log("add ssl cert to bunkerweb protection")
log("update ssl cert to bunkerweb protection")
output = `/usr/local/hestia/bin/v-bunkerweb-module updssl #{m_domain} #{m_ssl_cert} #{m_ssl_key} shell`
exit_status = $?.exitstatus
if exit_status != 0
@@ -104,6 +106,21 @@ class BunkerwebWorker < Kernel::ModuleCoreWorker
ACTION_OK
end
end
when "deletessl"
m_domain = args[1].strip unless args[1].nil?
if m_domain.nil?
log_return("Domain should be specified. #{args}")
else
log("delete ssl cert to bunkerweb protection")
output = `/usr/local/hestia/bin/v-bunkerweb-module deletessl #{m_domain} shell`
exit_status = $?.exitstatus
if exit_status != 0
log_return("Command failed with status #{exit_status}")
else
ACTION_OK
end
end
when "list"
format = (args[1].nil? ? "shell" : args[1].strip)
log("list of services")
@@ -157,7 +174,6 @@ class BunkerwebWorker < Kernel::ModuleCoreWorker
hestia_print_array_of_hashes(result, format, "API_USERNAME,API_PASSWORD,ADMIN_USERNAME,ADMIN_PASSWORD")
ACTION_OK
when "configure"
require 'shellwords'
param1 = args[1]
param2 = args[2]
if param1 && param2 && !param1.strip.empty? && !param2.strip.empty?

View File

@@ -0,0 +1 @@
7

View File

@@ -0,0 +1,119 @@
#!/opt/brepo/ruby33/bin/ruby
require 'pathname'
require 'fileutils'
class UpdateWorker < Kernel::ModuleCoreWorker
MODULE_ID = "update_module"
def info
{
ID: 6,
NAME: MODULE_ID,
DESCR: "Module for updating HestiaCP data and templates",
REQ: "",
CONF: "yes",
}
end
def file_changed?(new_file, old_file)
require 'digest/sha256'
return true unless File.exist?(old_file)
new_hash = Digest::SHA256.file(new_file).hexdigest
old_hash = Digest::SHA256.file(old_file).hexdigest
new_hash != old_hash
end
def get_templates_map()
{ :templates=>
[
{:new=>"/usr/local/hestia/install/rpm/templates/web/awstats", :old=>"/usr/local/hestia/data/templates/web/awstats"},
{:new=>"/usr/local/hestia/install/rpm/templates/web/httpd", :old=>"/usr/local/hestia/data/templates/web/httpd"},
{:new=>"/usr/local/hestia/install/rpm/templates/web/nginx", :old=>"/usr/local/hestia/data/templates/web/nginx"},
{:new=>"/usr/local/hestia/install/rpm/templates/web/php-fpm", :old=>"/usr/local/hestia/data/templates/web/php-fpm"}
]
}
end
# New helper method to get list of changed template files
def get_changed_template_files
templates_map = get_templates_map()[:templates]
result = []
templates_map.each do |tpl|
new_dir = tpl[:new]
old_dir = tpl[:old]
Dir.glob(File.join(new_dir, '**', '*')).each do |new_file|
next if File.directory?(new_file)
rel_path = Pathname.new(new_file).relative_path_from(Pathname.new(new_dir)).to_s
old_file = File.join(old_dir, rel_path)
result << [new_dir, new_file, old_file] if file_changed?(new_file, old_file)
end
end
result
end
def command(args)
return log_return("Not enough arguments. Needed command") if args.length < 1
log_file = get_log
m_command = args[0].strip
case m_command
when "synctemplates"
result = get_changed_template_files
result.each do |new_dir, new_file, old_file|
if !File.exist?(old_file)
FileUtils.cp(new_file, old_file)
else
stat = File.stat(old_file)
uid = stat.uid
gid = stat.gid
mode = stat.mode & 0o7777
FileUtils.cp(new_file, old_file)
File.chown(uid, gid, old_file)
File.chmod(mode, old_file)
end
end
ACTION_OK
when "listsynctemplates"
format = (args[1].nil? ? "shell" : args[1].strip)
list = get_changed_template_files
result = []
result = list.map do |new_dir, new_file, old_file|
file_name = Pathname.new(new_file).relative_path_from(Pathname.new(new_dir)).to_s
{
"FILE_NAME" => file_name,
"NEW_SIZE" => File.size(new_file),
"OLD_SIZE" => File.exist?(old_file) ? File.size(old_file) : "-"
}
end
hestia_print_array_of_hashes(result, format, "FILE_NAME,NEW_SIZE,OLD_SIZE")
ACTION_OK
when "help"
puts "#{$0} update_module COMMAND [json|csv|plain]"
puts "COMMANDS:"
puts " synctemplates - sync web templates"
puts " listsynctemplates - show changed web templates"
puts " help - help"
ACTION_OK
else
log_return("Unknown command. #{args}")
end
end
implements IPluginInterface
end
module UpdateModule
def get_object
Proc.new { UpdateWorker.new }
end
module_function :get_object
end
class Kernel::PluginConfiguration
include UpdateModule
@@loaded_plugins[UpdateWorker::MODULE_ID] = UpdateModule.get_object
end