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
|
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
|
// generateZFSPoolWithIssues creates a ZFS pool with various issues for testing
|
||||||
func generateZFSPoolWithIssues(poolName string) *models.ZFSPool {
|
func generateZFSPoolWithIssues(poolName string) *models.ZFSPool {
|
||||||
scenarios := []func() *models.ZFSPool{
|
scenarios := []func() *models.ZFSPool{
|
||||||
|
|
|
||||||
|
|
@ -43,11 +43,6 @@ func SetEnabled(enable bool) {
|
||||||
setEnabled(enable, false)
|
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) {
|
func setEnabled(enable bool, fromInit bool) {
|
||||||
current := enabled.Load()
|
current := enabled.Load()
|
||||||
if current == enable {
|
if current == enable {
|
||||||
|
|
|
||||||
|
|
@ -61,11 +61,6 @@ type ProxyHostDiagnostics struct {
|
||||||
LastError string
|
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
|
// NewTemperatureCollectorWithPort creates a new temperature collector with custom SSH port
|
||||||
func NewTemperatureCollectorWithPort(sshUser, sshKeyPath string, sshPort int) *TemperatureCollector {
|
func NewTemperatureCollectorWithPort(sshUser, sshKeyPath string, sshPort int) *TemperatureCollector {
|
||||||
if sshPort <= 0 {
|
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
|
SkipTLSVerify bool `json:"skipTLSVerify"` // Skip TLS cert verification
|
||||||
AuthRequired bool `json:"authRequired"` // Require authentication
|
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
|
// sendGroupedWebhook sends a grouped webhook notification
|
||||||
func (n *NotificationManager) sendGroupedWebhook(webhook WebhookConfig, alertList []*alerts.Alert) error {
|
func (n *NotificationManager) sendGroupedWebhook(webhook WebhookConfig, alertList []*alerts.Alert) error {
|
||||||
var jsonData []byte
|
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
|
// generatePayloadFromTemplateWithService renders the payload using Go templates with service-specific handling
|
||||||
func (n *NotificationManager) generatePayloadFromTemplateWithService(templateStr string, data WebhookPayloadData, service string) ([]byte, error) {
|
func (n *NotificationManager) generatePayloadFromTemplateWithService(templateStr string, data WebhookPayloadData, service string) ([]byte, error) {
|
||||||
tmpl, err := template.New("webhook").Funcs(templateFuncMap()).Parse(templateStr)
|
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, ":"))
|
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
|
// UpdateAllowedPrivateCIDRs parses and updates the list of allowed private CIDR ranges for webhooks
|
||||||
func (n *NotificationManager) UpdateAllowedPrivateCIDRs(cidrsString string) error {
|
func (n *NotificationManager) UpdateAllowedPrivateCIDRs(cidrsString string) error {
|
||||||
n.allowedPrivateMu.Lock()
|
n.allowedPrivateMu.Lock()
|
||||||
|
|
@ -2600,44 +2563,6 @@ func (n *NotificationManager) GetWebhookHistory() []WebhookDelivery {
|
||||||
return history
|
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 {
|
func buildNotificationTestAlert() *alerts.Alert {
|
||||||
return &alerts.Alert{
|
return &alerts.Alert{
|
||||||
ID: "test-alert",
|
ID: "test-alert",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue