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:
parent
28aaecd74d
commit
25542ae51d
6 changed files with 0 additions and 330 deletions
|
|
@ -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{
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
Loading…
Reference in a new issue