chore: remove more dead code

Remove 330 lines of unreachable code:
- internal/monitoring/temperature_service.go: unused temperature service abstraction
- internal/monitoring/temperature.go: unused NewTemperatureCollector wrapper
- internal/mock/generator.go: unused GenerateAlerts function
- internal/mock/integration.go: unused ToggleMockMode wrapper
- internal/notifications/notifications.go: unused sendEmailWithContent,
  generatePayloadFromTemplate, isPrivateRange172, groupAlerts
- internal/notifications/email_providers.go: unused GetProviderDefaults
This commit is contained in:
rcourtman 2025-11-27 00:10:55 +00:00
parent 28aaecd74d
commit 25542ae51d
6 changed files with 0 additions and 330 deletions

View file

@ -1989,125 +1989,6 @@ func generateTags() []string {
return tags
}
// GenerateAlerts generates random alerts for testing
func GenerateAlerts(nodes []models.Node, vms []models.VM, containers []models.Container) []models.Alert {
alerts := []models.Alert{}
// Generate some node alerts
for _, node := range nodes {
// Add offline alert for offline nodes
if node.Status == "offline" {
alerts = append(alerts, models.Alert{
ID: fmt.Sprintf("node-offline-%s", node.ID),
Type: "connectivity",
Level: "critical",
ResourceID: node.ID,
ResourceName: node.Name,
Node: node.Name,
Message: fmt.Sprintf("Node '%s' is offline", node.Name),
Value: 0,
Threshold: 0,
StartTime: time.Now().Add(-time.Minute * 5), // Offline for 5 minutes
})
continue // Skip other checks for offline nodes
}
if node.CPU > 0.8 {
alerts = append(alerts, models.Alert{
ID: fmt.Sprintf("alert-%s-cpu", node.Name),
Type: "threshold",
Level: "warning",
ResourceID: node.ID,
ResourceName: node.Name,
Node: node.Name,
Message: fmt.Sprintf("Node %s CPU usage is %.0f%%", node.Name, node.CPU*100),
Value: node.CPU * 100,
Threshold: 80,
StartTime: time.Now(),
})
}
}
// Generate some VM/container alerts
allGuests := make([]interface{}, 0, len(vms)+len(containers))
for _, vm := range vms {
allGuests = append(allGuests, vm)
}
for _, ct := range containers {
allGuests = append(allGuests, ct)
}
// Pick random guests to have alerts
numAlerts := rand.Intn(5) + 1
for i := 0; i < numAlerts && i < len(allGuests); i++ {
guestIdx := rand.Intn(len(allGuests))
var name, id string
var cpu float64
var memUsage float64
switch g := allGuests[guestIdx].(type) {
case models.VM:
name = g.Name
id = g.ID
cpu = g.CPU
memUsage = g.Memory.Usage
case models.Container:
name = g.Name
id = g.ID
cpu = g.CPU
memUsage = g.Memory.Usage
}
// Randomly choose alert type
switch rand.Intn(3) {
case 0: // CPU alert
if cpu > 0.7 {
alerts = append(alerts, models.Alert{
ID: fmt.Sprintf("alert-%s-cpu", id),
Type: "threshold",
Level: "warning",
ResourceID: id,
ResourceName: name,
Message: fmt.Sprintf("%s CPU usage is %.0f%%", name, cpu*100),
Value: cpu * 100,
Threshold: 70,
StartTime: time.Now(),
})
}
case 1: // Memory alert
if memUsage > 80 {
alerts = append(alerts, models.Alert{
ID: fmt.Sprintf("alert-%s-mem", id),
Type: "threshold",
Level: "warning",
ResourceID: id,
ResourceName: name,
Message: fmt.Sprintf("%s memory usage is %.0f%%", name, memUsage),
Value: memUsage,
Threshold: 80,
StartTime: time.Now(),
})
}
case 2: // Disk alert
diskUsage := 70 + rand.Float64()*25
alerts = append(alerts, models.Alert{
ID: fmt.Sprintf("alert-%s-disk", id),
Type: "threshold",
Level: "critical",
ResourceID: id,
ResourceName: name,
Message: fmt.Sprintf("%s disk usage is %.0f%%", name, diskUsage),
Value: diskUsage,
Threshold: 90,
StartTime: time.Now(),
})
}
}
return alerts
}
// generateZFSPoolWithIssues creates a ZFS pool with various issues for testing
func generateZFSPoolWithIssues(poolName string) *models.ZFSPool {
scenarios := []func() *models.ZFSPool{

View file

@ -43,11 +43,6 @@ func SetEnabled(enable bool) {
setEnabled(enable, false)
}
// ToggleMockMode enables or disables mock mode at runtime (backwards-compatible helper).
func ToggleMockMode(enable bool) {
SetEnabled(enable)
}
func setEnabled(enable bool, fromInit bool) {
current := enabled.Load()
if current == enable {

View file

@ -61,11 +61,6 @@ type ProxyHostDiagnostics struct {
LastError string
}
// NewTemperatureCollector creates a new temperature collector with default SSH port (22)
func NewTemperatureCollector(sshUser, sshKeyPath string) *TemperatureCollector {
return NewTemperatureCollectorWithPort(sshUser, sshKeyPath, 22)
}
// NewTemperatureCollectorWithPort creates a new temperature collector with custom SSH port
func NewTemperatureCollectorWithPort(sshUser, sshKeyPath string, sshPort int) *TemperatureCollector {
if sshPort <= 0 {

View file

@ -1,104 +0,0 @@
package monitoring
import (
"context"
stderrors "errors"
"sync"
"github.com/rcourtman/pulse-go-rewrite/internal/models"
)
var (
// ErrTemperatureMonitoringDisabled indicates that temperature polling is disabled globally.
ErrTemperatureMonitoringDisabled = stderrors.New("temperature monitoring disabled")
// ErrTemperatureCollectorUnavailable indicates the collector could not be created or is misconfigured.
ErrTemperatureCollectorUnavailable = stderrors.New("temperature collector unavailable")
)
// TemperatureService defines the contract used by the monitor to collect temperature data.
type TemperatureService interface {
Enabled() bool
Collect(ctx context.Context, host, nodeName string) (*models.Temperature, error)
Enable()
Disable()
}
type temperatureService struct {
mu sync.RWMutex
enabled bool
user string
keyPath string
sshPort int
collector *TemperatureCollector
}
func newTemperatureService(enabled bool, user, keyPath string, sshPort int) TemperatureService {
if sshPort <= 0 {
sshPort = 22
}
return &temperatureService{
enabled: enabled,
user: user,
keyPath: keyPath,
sshPort: sshPort,
}
}
func (s *temperatureService) Enabled() bool {
s.mu.RLock()
defer s.mu.RUnlock()
return s.enabled
}
func (s *temperatureService) Enable() {
s.mu.Lock()
defer s.mu.Unlock()
if s.enabled {
return
}
s.enabled = true
if s.collector == nil && s.user != "" && s.keyPath != "" {
s.collector = NewTemperatureCollectorWithPort(s.user, s.keyPath, s.sshPort)
}
}
func (s *temperatureService) Disable() {
s.mu.Lock()
defer s.mu.Unlock()
s.enabled = false
s.collector = nil
}
func (s *temperatureService) Collect(ctx context.Context, host, nodeName string) (*models.Temperature, error) {
s.mu.RLock()
enabled := s.enabled
collector := s.collector
s.mu.RUnlock()
if !enabled {
return nil, ErrTemperatureMonitoringDisabled
}
if collector == nil {
s.mu.Lock()
if s.enabled && s.collector == nil && s.user != "" && s.keyPath != "" {
s.collector = NewTemperatureCollectorWithPort(s.user, s.keyPath, s.sshPort)
}
collector = s.collector
enabled = s.enabled
s.mu.Unlock()
if !enabled {
return nil, ErrTemperatureMonitoringDisabled
}
}
if collector == nil {
return nil, ErrTemperatureCollectorUnavailable
}
return collector.CollectTemperature(ctx, host, nodeName)
}

View file

@ -192,25 +192,3 @@ type EmailProviderConfig struct {
SkipTLSVerify bool `json:"skipTLSVerify"` // Skip TLS cert verification
AuthRequired bool `json:"authRequired"` // Require authentication
}
// GetProviderDefaults returns default configuration for a provider
func GetProviderDefaults(providerName string) *EmailProviderConfig {
providers := GetEmailProviders()
for _, provider := range providers {
if provider.Name == providerName {
return &EmailProviderConfig{
EmailConfig: EmailConfig{
SMTPHost: provider.SMTPHost,
SMTPPort: provider.SMTPPort,
TLS: provider.TLS,
},
Provider: providerName,
StartTLS: provider.StartTLS,
MaxRetries: 3,
RetryDelay: 5,
RateLimit: 60, // Default 60 emails/minute
}
}
}
return nil
}

View file

@ -1517,12 +1517,6 @@ func (n *NotificationManager) sendHTMLEmail(subject, htmlBody, textBody string,
}
}
// sendEmailWithContent sends email with given content (plain text)
func (n *NotificationManager) sendEmailWithContent(subject, body string, config EmailConfig) {
// For backward compatibility, send as plain text
n.sendHTMLEmail(subject, "", body, config)
}
// sendGroupedWebhook sends a grouped webhook notification
func (n *NotificationManager) sendGroupedWebhook(webhook WebhookConfig, alertList []*alerts.Alert) error {
var jsonData []byte
@ -2224,11 +2218,6 @@ func templateFuncMap() template.FuncMap {
}
}
// generatePayloadFromTemplate renders the payload using Go templates
func (n *NotificationManager) generatePayloadFromTemplate(templateStr string, data WebhookPayloadData) ([]byte, error) {
return n.generatePayloadFromTemplateWithService(templateStr, data, "")
}
// generatePayloadFromTemplateWithService renders the payload using Go templates with service-specific handling
func (n *NotificationManager) generatePayloadFromTemplateWithService(templateStr string, data WebhookPayloadData, service string) ([]byte, error) {
tmpl, err := template.New("webhook").Funcs(templateFuncMap()).Parse(templateStr)
@ -2474,32 +2463,6 @@ func isNumericIP(host string) bool {
return len(host) > 0 && (strings.Contains(host, ".") || strings.Contains(host, ":"))
}
// isPrivateRange172 checks if an IP is in the 172.16.0.0/12 range
func isPrivateRange172(host string) bool {
parts := strings.Split(host, ".")
if len(parts) < 2 {
return false
}
if parts[0] != "172" {
return false
}
// Check if second octet is between 16 and 31
if len(parts[1]) == 0 {
return false
}
second := 0
for _, char := range parts[1] {
if char < '0' || char > '9' {
return false
}
second = second*10 + int(char-'0')
}
return second >= 16 && second <= 31
}
// UpdateAllowedPrivateCIDRs parses and updates the list of allowed private CIDR ranges for webhooks
func (n *NotificationManager) UpdateAllowedPrivateCIDRs(cidrsString string) error {
n.allowedPrivateMu.Lock()
@ -2600,44 +2563,6 @@ func (n *NotificationManager) GetWebhookHistory() []WebhookDelivery {
return history
}
// groupAlerts groups alerts based on configuration
func (n *NotificationManager) groupAlerts(alertList []*alerts.Alert) map[string][]*alerts.Alert {
groups := make(map[string][]*alerts.Alert)
if !n.groupByNode && !n.groupByGuest {
// No grouping - all alerts in one group
groups["all"] = alertList
return groups
}
for _, alert := range alertList {
var key string
if n.groupByNode && n.groupByGuest {
// Group by both node and guest type
guestType := "unknown"
if metadata, ok := alert.Metadata["resourceType"].(string); ok {
guestType = metadata
}
key = fmt.Sprintf("%s-%s", alert.Node, guestType)
} else if n.groupByNode {
// Group by node only
key = alert.Node
} else if n.groupByGuest {
// Group by guest type only
if metadata, ok := alert.Metadata["resourceType"].(string); ok {
key = metadata
} else {
key = "unknown"
}
}
groups[key] = append(groups[key], alert)
}
return groups
}
func buildNotificationTestAlert() *alerts.Alert {
return &alerts.Alert{
ID: "test-alert",