Skip to content

Commit c25a5fd

Browse files
sarg3ntclaude
andcommitted
feat: create HAProxy plugin settings page and clean up boxes page
- Add dedicated HAProxy settings page at /settings/plugins/haproxy with Disabled Entities button, Config Editor link, and HAProxy git config - Move HAProxy git configuration from box git settings to plugin settings - Remove Disabled Entities button from boxes page (now on HAProxy settings) - Remove HAProxy config icon from box action buttons - Rename "HAProxy Servers" to "Boxes" in settings sidebar - Update description to "Manage monitored boxes" - Update all "Back to Servers/HAProxy Servers" links to "Back to Boxes" Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 205c8ad commit c25a5fd

9 files changed

Lines changed: 382 additions & 185 deletions

File tree

gearbox/cmd/server/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,7 @@ func main() {
599599

600600
// Plugins management (requires ComponentPlugins/PermissionManage - checked in handlers)
601601
r.Get("/plugins", h.PluginsPage)
602+
r.Post("/plugins/haproxy/git", h.HAProxyGitSettingsSave)
602603
r.Get("/plugins/{name}", h.PluginDetailPage)
603604
r.Post("/plugins/{name}", h.PluginUpdatePost)
604605
r.Post("/plugins/{name}/toggle", h.PluginTogglePost)

gearbox/internal/framework/handler/config.go

Lines changed: 3 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -397,11 +397,10 @@ func (h *Handler) BoxGitSettingsPage(w http.ResponseWriter, r *http.Request) {
397397
return
398398
}
399399

400-
// Get git configs for both haproxy and firewall
401-
haproxyGitConfig, _ := h.db.GetBoxGitConfig(server.ID, database.ConfigTypeHAProxy)
400+
// Get firewall git config (HAProxy git config is on the HAProxy plugin settings page)
402401
firewallGitConfig, _ := h.db.GetBoxGitConfig(server.ID, database.ConfigTypeFirewall)
403402

404-
component := pages.BoxGitSettingsPage(user, server, haproxyGitConfig, firewallGitConfig, "", "")
403+
component := pages.BoxGitSettingsPage(user, server, firewallGitConfig, "", "")
405404
if err := component.Render(r.Context(), w); err != nil {
406405
h.logger.Error("Failed to render git settings page", "error", err)
407406
http.Error(w, "Internal server error", http.StatusInternalServerError)
@@ -444,38 +443,7 @@ func (h *Handler) BoxGitSettingsSave(w http.ResponseWriter, r *http.Request) {
444443
return
445444
}
446445

447-
// Save HAProxy git config
448-
haproxyConfig := &database.BoxGitConfig{
449-
HAProxyBoxID: server.ID,
450-
ConfigType: database.ConfigTypeHAProxy,
451-
GitRepoURL: r.FormValue("haproxy_git_repo"),
452-
GitBranch: r.FormValue("haproxy_git_branch"),
453-
GitFilePath: r.FormValue("haproxy_git_path"),
454-
AutoApplyEnabled: r.FormValue("haproxy_auto_apply") == "on",
455-
SyncIntervalMinutes: 60, // Default, could make configurable
456-
}
457-
458-
// Handle PAT
459-
if pat := r.FormValue("haproxy_git_pat"); pat != "" {
460-
haproxyConfig.GitPATEncrypted, _ = encryptor.EncryptString(pat)
461-
} else {
462-
// Keep existing PAT if not provided
463-
existing, _ := h.db.GetBoxGitConfig(server.ID, database.ConfigTypeHAProxy)
464-
if existing != nil {
465-
haproxyConfig.GitPATEncrypted = existing.GitPATEncrypted
466-
}
467-
}
468-
469-
if haproxyConfig.GitRepoURL != "" {
470-
if err := h.db.SaveBoxGitConfig(haproxyConfig); err != nil {
471-
h.logger.Error("Failed to save HAProxy git config", "error", err)
472-
}
473-
} else {
474-
// Clear config if repo URL is empty
475-
_ = h.db.DeleteBoxGitConfig(server.ID, database.ConfigTypeHAProxy)
476-
}
477-
478-
// Save Firewall git config
446+
// Save Firewall git config (HAProxy git config is saved via the HAProxy plugin settings page)
479447
firewallConfig := &database.BoxGitConfig{
480448
HAProxyBoxID: server.ID,
481449
ConfigType: database.ConfigTypeFirewall,

gearbox/internal/framework/handler/plugins.go

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,13 @@ func (h *Handler) PluginDetailPage(w http.ResponseWriter, r *http.Request) {
120120
http.Error(w, "No servers configured", http.StatusBadRequest)
121121
return
122122
}
123+
124+
// HAProxy has its own dedicated settings page
125+
if pluginName == database.PluginHAProxy {
126+
h.renderHAProxySettingsPage(w, r, user, boxID)
127+
return
128+
}
129+
123130
plugin, err := h.db.GetPlugin(boxID, pluginName)
124131
if err != nil {
125132
h.logger.Error("failed to get plugin", "plugin", pluginName, "error", err)
@@ -1010,3 +1017,101 @@ func (h *Handler) deployPluginDashboards(pluginName string) error {
10101017

10111018
return nil
10121019
}
1020+
1021+
// renderHAProxySettingsPage renders the HAProxy-specific plugin settings page.
1022+
func (h *Handler) renderHAProxySettingsPage(w http.ResponseWriter, r *http.Request, user *models.User, boxID string) {
1023+
successMsg := r.URL.Query().Get("success")
1024+
errorMsg := r.URL.Query().Get("error")
1025+
1026+
var serverName string
1027+
if serverConfig, exists := h.getServerConfig(boxID); exists {
1028+
serverName = serverConfig.Name
1029+
}
1030+
1031+
// Look up the BoxDB record to get the database ID for git config lookup
1032+
server, _ := h.db.GetBoxByBoxID(boxID)
1033+
1034+
var haproxyGit *database.BoxGitConfig
1035+
if server != nil {
1036+
haproxyGit, _ = h.db.GetBoxGitConfig(server.ID, database.ConfigTypeHAProxy)
1037+
}
1038+
1039+
component := pages.HAProxyPluginSettingsPage(user, boxID, serverName, server, haproxyGit, successMsg, errorMsg)
1040+
if err := component.Render(r.Context(), w); err != nil {
1041+
h.logger.Error("Failed to render HAProxy settings template", "error", err)
1042+
http.Error(w, "Internal server error", http.StatusInternalServerError)
1043+
}
1044+
}
1045+
1046+
// HAProxyGitSettingsSave saves the HAProxy git configuration from the plugin settings page.
1047+
func (h *Handler) HAProxyGitSettingsSave(w http.ResponseWriter, r *http.Request) {
1048+
user, err := h.authManager.GetUser(r)
1049+
if err != nil {
1050+
http.Redirect(w, r, "/login", http.StatusSeeOther)
1051+
return
1052+
}
1053+
1054+
if !h.authManager.HasPermission(r, models.ComponentPlugins, models.PermissionConfigure) {
1055+
http.Error(w, "Forbidden", http.StatusForbidden)
1056+
return
1057+
}
1058+
1059+
boxID := r.URL.Query().Get("server")
1060+
if boxID == "" {
1061+
http.Error(w, "No server specified", http.StatusBadRequest)
1062+
return
1063+
}
1064+
1065+
server, err := h.db.GetBoxByBoxID(boxID)
1066+
if err != nil || server == nil {
1067+
http.Error(w, "Server not found", http.StatusNotFound)
1068+
return
1069+
}
1070+
1071+
if err := r.ParseForm(); err != nil {
1072+
http.Error(w, "Invalid form data", http.StatusBadRequest)
1073+
return
1074+
}
1075+
1076+
encryptor, err := h.getEncryptor()
1077+
if err != nil {
1078+
h.logger.Error("Failed to get encryptor", "error", err)
1079+
http.Error(w, "Encryption error", http.StatusInternalServerError)
1080+
return
1081+
}
1082+
1083+
haproxyConfig := &database.BoxGitConfig{
1084+
HAProxyBoxID: server.ID,
1085+
ConfigType: database.ConfigTypeHAProxy,
1086+
GitRepoURL: r.FormValue("haproxy_git_repo"),
1087+
GitBranch: r.FormValue("haproxy_git_branch"),
1088+
GitFilePath: r.FormValue("haproxy_git_path"),
1089+
AutoApplyEnabled: r.FormValue("haproxy_auto_apply") == "on",
1090+
SyncIntervalMinutes: 60,
1091+
}
1092+
1093+
if pat := r.FormValue("haproxy_git_pat"); pat != "" {
1094+
haproxyConfig.GitPATEncrypted, _ = encryptor.EncryptString(pat)
1095+
} else {
1096+
existing, _ := h.db.GetBoxGitConfig(server.ID, database.ConfigTypeHAProxy)
1097+
if existing != nil {
1098+
haproxyConfig.GitPATEncrypted = existing.GitPATEncrypted
1099+
}
1100+
}
1101+
1102+
if haproxyConfig.GitRepoURL != "" {
1103+
if err := h.db.SaveBoxGitConfig(haproxyConfig); err != nil {
1104+
h.logger.Error("Failed to save HAProxy git config", "error", err)
1105+
redirectURL := fmt.Sprintf("/settings/plugins/haproxy?server=%s&error=%s", url.QueryEscape(boxID), url.QueryEscape("Failed to save git settings"))
1106+
http.Redirect(w, r, redirectURL, http.StatusSeeOther)
1107+
return
1108+
}
1109+
} else {
1110+
_ = h.db.DeleteBoxGitConfig(server.ID, database.ConfigTypeHAProxy)
1111+
}
1112+
1113+
h.logAudit(r, user.ID, "haproxy_git_settings_update", fmt.Sprintf("Updated HAProxy git settings for server %s", server.Name))
1114+
1115+
redirectURL := fmt.Sprintf("/settings/plugins/haproxy?server=%s&success=%s", url.QueryEscape(boxID), url.QueryEscape("Git settings saved"))
1116+
http.Redirect(w, r, redirectURL, http.StatusSeeOther)
1117+
}

gearbox/internal/framework/templates/pages/haproxy_config.templ

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ templ HAProxyConfigPageWithError(user *models.User, server *database.BoxDB, erro
4646
</div>
4747
<div class="mt-4">
4848
<a href="/settings/boxes" class="text-blue-600 dark:text-blue-400 hover:underline">
49-
← Back to HAProxy Servers
49+
← Back to Boxes
5050
</a>
5151
</div>
5252
</div>

0 commit comments

Comments
 (0)