Skip to content

Commit

Permalink
adding models pkg
Browse files Browse the repository at this point in the history
  • Loading branch information
mfreeman451 committed Jan 20, 2025
1 parent 28eedf9 commit a08af0a
Show file tree
Hide file tree
Showing 15 changed files with 199 additions and 174 deletions.
12 changes: 12 additions & 0 deletions pkg/agent/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package agent

import "errors"

var (
errGrpcAddressRequired = errors.New("address is required for gRPC checker")
errUnknownCheckerType = errors.New("unknown checker type")
errGrpcMissingConfig = errors.New("no configuration or address provided for gRPC checker")
errNoLocalConfig = errors.New("no local config found")
errShutdown = errors.New("error while shutting down")
errServiceStartup = errors.New("error while starting services")
)
13 changes: 2 additions & 11 deletions pkg/agent/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"time"

"github.com/mfreeman451/serviceradar/pkg/checker"
"github.com/mfreeman451/serviceradar/pkg/sweeper"
"github.com/mfreeman451/serviceradar/pkg/models"
"github.com/mfreeman451/serviceradar/proto"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
Expand All @@ -25,15 +25,6 @@ const (
processConfigurationName = "process"
)

var (
errGrpcAddressRequired = errors.New("address is required for gRPC checker")
errUnknownCheckerType = errors.New("unknown checker type")
errGrpcMissingConfig = errors.New("no configuration or address provided for gRPC checker")
errNoLocalConfig = errors.New("no local config found")
errShutdown = errors.New("error while shutting down")
errServiceStartup = errors.New("error while starting services")
)

type Duration time.Duration

// SweepConfig represents sweep service configuration from JSON.
Expand Down Expand Up @@ -153,7 +144,7 @@ func loadSweepService(configDir string) (Service, error) {
}

// Convert to sweeper.Config
config := &sweeper.Config{
config := &models.Config{
Networks: sweepConfig.Networks,
Ports: sweepConfig.Ports,
Interval: time.Duration(sweepConfig.Interval),
Expand Down
31 changes: 16 additions & 15 deletions pkg/agent/sweep_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"sync"
"time"

"github.com/mfreeman451/serviceradar/pkg/models"
"github.com/mfreeman451/serviceradar/pkg/sweeper"
"github.com/mfreeman451/serviceradar/proto"
)
Expand All @@ -20,11 +21,11 @@ type SweepService struct {
processor sweeper.ResultProcessor
mu sync.RWMutex
closed chan struct{}
config *sweeper.Config
config *models.Config
}

// NewSweepService creates a new sweep service with default configuration.
func NewSweepService(config *sweeper.Config) (*SweepService, error) {
func NewSweepService(config *models.Config) (*SweepService, error) {
// Apply default configuration
config = applyDefaultConfig(config)

Expand All @@ -44,12 +45,12 @@ func NewSweepService(config *sweeper.Config) (*SweepService, error) {
}, nil
}

func applyDefaultConfig(config *sweeper.Config) *sweeper.Config {
func applyDefaultConfig(config *models.Config) *models.Config {
// Ensure we have default sweep modes
if len(config.SweepModes) == 0 {
config.SweepModes = []sweeper.SweepMode{
sweeper.ModeTCP,
sweeper.ModeICMP,
config.SweepModes = []models.SweepMode{
models.ModeTCP,
models.ModeICMP,
}
}

Expand Down Expand Up @@ -200,7 +201,7 @@ func (s *SweepService) GetStatus(_ context.Context) (*proto.StatusResponse, erro
}

// UpdateConfig updates the sweep configuration.
func (s *SweepService) UpdateConfig(config *sweeper.Config) error {
func (s *SweepService) UpdateConfig(config *models.Config) error {
s.mu.Lock()
defer s.mu.Unlock()

Expand All @@ -216,8 +217,8 @@ func (s *SweepService) Close() error {
return s.Stop()
}

func generateTargets(config *sweeper.Config) ([]sweeper.Target, error) {
var targets []sweeper.Target
func generateTargets(config *models.Config) ([]models.Target, error) {
var targets []models.Target

// For each network
for _, network := range config.Networks {
Expand All @@ -230,20 +231,20 @@ func generateTargets(config *sweeper.Config) ([]sweeper.Target, error) {
// For each IP, create appropriate targets
for _, ip := range ips {
// Add ICMP target if enabled
if sweeper.ContainsMode(config.SweepModes, sweeper.ModeICMP) {
targets = append(targets, sweeper.Target{
if models.ContainsMode(config.SweepModes, models.ModeICMP) {
targets = append(targets, models.Target{
Host: ip.String(),
Mode: sweeper.ModeICMP,
Mode: models.ModeICMP,
})
}

// Add TCP targets if enabled
if sweeper.ContainsMode(config.SweepModes, sweeper.ModeTCP) {
if models.ContainsMode(config.SweepModes, models.ModeTCP) {
for _, port := range config.Ports {
targets = append(targets, sweeper.Target{
targets = append(targets, models.Target{
Host: ip.String(),
Port: port,
Mode: sweeper.ModeTCP,
Mode: models.ModeTCP,
})
}
}
Expand Down
74 changes: 74 additions & 0 deletions pkg/models/sweeper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package models

import "time"

// SweepData represents network sweep results.
type SweepData struct {
Network string `json:"network"`
TotalHosts int32 `json:"total_hosts"`
AvailableHosts int32 `json:"available_hosts"`
LastSweep int64 `json:"last_sweep"`
Ports []PortStatus `json:"ports"`
}

// PortStatus represents port availability information.
type PortStatus struct {
Port int32 `json:"port"`
Available int32 `json:"available"`
}

// Config defines sweeper configuration.
type Config struct {
Networks []string `json:"networks"`
Ports []int `json:"ports"`
SweepModes []SweepMode `json:"sweep_modes"`
Interval time.Duration `json:"interval"`
Concurrency int `json:"concurrency"`
Timeout time.Duration `json:"timeout"`
ICMPCount int `json:"icmp_count"`
}

type SweepMode string

const (
ModeTCP SweepMode = "tcp"
ModeICMP SweepMode = "icmp"
)

// Target represents a network target to be scanned.
type Target struct {
Host string
Port int
Mode SweepMode
}

// Result represents the outcome of a sweep against a target.
type Result struct {
Target Target
Available bool
FirstSeen time.Time
LastSeen time.Time
RespTime time.Duration
PacketLoss float64
Error error
}

// ResultFilter defines criteria for retrieving results.
type ResultFilter struct {
Host string
Port int
StartTime time.Time
EndTime time.Time
Available *bool
}

// ContainsMode checks if a mode is in a list of modes.
func ContainsMode(modes []SweepMode, mode SweepMode) bool {
for _, m := range modes {
if m == mode {
return true
}
}

return false
}
3 changes: 2 additions & 1 deletion pkg/poller/poller.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"time"

"github.com/mfreeman451/serviceradar/pkg/grpc"
"github.com/mfreeman451/serviceradar/pkg/models"
"github.com/mfreeman451/serviceradar/proto"
)

Expand Down Expand Up @@ -75,7 +76,7 @@ func (p *Poller) ensureAgentHealth(ctx context.Context, agentName string, config

// processSweepStatus handles sweep status processing.
func (*Poller) processSweepStatus(status *proto.ServiceStatus) error {
var sweepData SweepData
var sweepData models.SweepData
if err := json.Unmarshal([]byte(status.Message), &sweepData); err != nil {
return fmt.Errorf("failed to parse sweep data: %w", err)
}
Expand Down
15 changes: 0 additions & 15 deletions pkg/poller/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,6 @@ type Poller struct {
agents map[string]*AgentConnection
}

// SweepData represents network sweep results.
type SweepData struct {
Network string `json:"network"`
TotalHosts int32 `json:"total_hosts"`
AvailableHosts int32 `json:"available_hosts"`
LastSweep int64 `json:"last_sweep"`
Ports []PortStatus `json:"ports"`
}

// PortStatus represents port availability information.
type PortStatus struct {
Port int32 `json:"port"`
Available int32 `json:"available"`
}

// Duration is a wrapper around time.Duration for JSON unmarshaling.
type Duration time.Duration

Expand Down
24 changes: 13 additions & 11 deletions pkg/sweeper/combined_scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"log"
"sync"
"time"

"github.com/mfreeman451/serviceradar/pkg/models"
)

type CombinedScanner struct {
Expand All @@ -30,12 +32,12 @@ func (s *CombinedScanner) Stop() error {
}

type scanTargets struct {
tcp []Target
icmp []Target
tcp []models.Target
icmp []models.Target
}

func (s *CombinedScanner) Scan(ctx context.Context, targets []Target) (<-chan Result, error) {
results := make(chan Result)
func (s *CombinedScanner) Scan(ctx context.Context, targets []models.Target) (<-chan models.Result, error) {
results := make(chan models.Result)
separated := s.separateTargets(targets)

var wg sync.WaitGroup
Expand All @@ -50,14 +52,14 @@ func (s *CombinedScanner) Scan(ctx context.Context, targets []Target) (<-chan Re
return results, nil
}

func (*CombinedScanner) separateTargets(targets []Target) scanTargets {
func (*CombinedScanner) separateTargets(targets []models.Target) scanTargets {
var separated scanTargets

for _, target := range targets {
switch target.Mode {
case ModeTCP:
case models.ModeTCP:
separated.tcp = append(separated.tcp, target)
case ModeICMP:
case models.ModeICMP:
separated.icmp = append(separated.icmp, target)
default:
log.Printf("Unknown scan mode for target %v: %v", target, target.Mode)
Expand All @@ -67,7 +69,7 @@ func (*CombinedScanner) separateTargets(targets []Target) scanTargets {
return separated
}

func (s *CombinedScanner) startScanners(ctx context.Context, wg *sync.WaitGroup, targets scanTargets, results chan<- Result) {
func (s *CombinedScanner) startScanners(ctx context.Context, wg *sync.WaitGroup, targets scanTargets, results chan<- models.Result) {
if len(targets.tcp) > 0 {
wg.Add(1)

Expand All @@ -81,7 +83,7 @@ func (s *CombinedScanner) startScanners(ctx context.Context, wg *sync.WaitGroup,
}
}

func (s *CombinedScanner) runTCPScanner(ctx context.Context, wg *sync.WaitGroup, targets []Target, results chan<- Result) {
func (s *CombinedScanner) runTCPScanner(ctx context.Context, wg *sync.WaitGroup, targets []models.Target, results chan<- models.Result) {
defer wg.Done()

tcpResults, err := s.tcpScanner.Scan(ctx, targets)
Expand All @@ -93,7 +95,7 @@ func (s *CombinedScanner) runTCPScanner(ctx context.Context, wg *sync.WaitGroup,
s.processResults(ctx, tcpResults, results)
}

func (s *CombinedScanner) runICMPScanner(ctx context.Context, wg *sync.WaitGroup, targets []Target, results chan<- Result) {
func (s *CombinedScanner) runICMPScanner(ctx context.Context, wg *sync.WaitGroup, targets []models.Target, results chan<- models.Result) {
defer wg.Done()

icmpResults, err := s.icmpScanner.Scan(ctx, targets)
Expand All @@ -105,7 +107,7 @@ func (s *CombinedScanner) runICMPScanner(ctx context.Context, wg *sync.WaitGroup
s.processResults(ctx, icmpResults, results)
}

func (s *CombinedScanner) processResults(ctx context.Context, scanResults <-chan Result, results chan<- Result) {
func (s *CombinedScanner) processResults(ctx context.Context, scanResults <-chan models.Result, results chan<- models.Result) {
for result := range scanResults {
select {
case <-ctx.Done():
Expand Down
23 changes: 12 additions & 11 deletions pkg/sweeper/icmp_scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"sync"
"time"

"github.com/mfreeman451/serviceradar/pkg/models"
"golang.org/x/net/icmp"
"golang.org/x/net/ipv4"
)
Expand All @@ -30,7 +31,7 @@ type ICMPScanner struct {

type ICMPWorkerConfig struct {
conn *icmp.PacketConn
target Target
target models.Target
attempts int
timeout time.Duration
}
Expand All @@ -54,9 +55,9 @@ func (s *ICMPScanner) Stop() error {
return nil
}

func (s *ICMPScanner) Scan(ctx context.Context, targets []Target) (<-chan Result, error) {
results := make(chan Result)
targetChan := make(chan Target)
func (s *ICMPScanner) Scan(ctx context.Context, targets []models.Target) (<-chan models.Result, error) {
results := make(chan models.Result)
targetChan := make(chan models.Target)

conn, err := s.createICMPConnection()
if err != nil {
Expand Down Expand Up @@ -116,7 +117,7 @@ func (*ICMPScanner) createICMPConnection() (*icmp.PacketConn, error) {
return icmp.ListenPacket("ip4:icmp", "0.0.0.0")
}

func (s *ICMPScanner) worker(ctx context.Context, config *ICMPWorkerConfig, targets <-chan Target, results chan<- Result) {
func (s *ICMPScanner) worker(ctx context.Context, config *ICMPWorkerConfig, targets <-chan models.Target, results chan<- models.Result) {
for {
select {
case <-ctx.Done():
Expand All @@ -142,9 +143,9 @@ func (s *ICMPScanner) worker(ctx context.Context, config *ICMPWorkerConfig, targ
}
}

func (s *ICMPScanner) pingHost(ctx context.Context, config *ICMPWorkerConfig) Result {
func (s *ICMPScanner) pingHost(ctx context.Context, config *ICMPWorkerConfig) models.Result {
start := time.Now()
result := Result{
result := models.Result{
Target: config.target,
FirstSeen: start,
LastSeen: start,
Expand Down Expand Up @@ -255,15 +256,15 @@ func (*ICMPScanner) sendPing(_ context.Context, config *ICMPWorkerConfig) (bool,
return success, elapsed
}

func (s *ICMPScanner) fallbackScan(ctx context.Context, targets []Target) (<-chan Result, error) {
func (s *ICMPScanner) fallbackScan(ctx context.Context, targets []models.Target) (<-chan models.Result, error) {
// Convert ICMP targets to TCP targets
tcpTargets := make([]Target, len(targets))
tcpTargets := make([]models.Target, len(targets))

for i, target := range targets {
tcpTargets[i] = Target{
tcpTargets[i] = models.Target{
Host: target.Host,
Port: 80, // Try a common port for host discovery
Mode: ModeTCP,
Mode: models.ModeTCP,
}
}

Expand Down
Loading

0 comments on commit a08af0a

Please sign in to comment.