77 lines
1.6 KiB
Go
77 lines
1.6 KiB
Go
package scanner
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"net/url"
|
|
"sync"
|
|
)
|
|
|
|
type Context = context.Context
|
|
|
|
type ServiceConfig struct {
|
|
Description string
|
|
Url string
|
|
}
|
|
|
|
func (s ServiceConfig) URL() *url.URL {
|
|
res, err := url.Parse(s.Url)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return res
|
|
}
|
|
|
|
type ServiceStatus struct {
|
|
Name string `json:"name"`
|
|
Url string `json:"url"`
|
|
Type string `json:"type"`
|
|
Ok bool `json:"ok"`
|
|
Status string `json:"status"`
|
|
}
|
|
|
|
func CheckService(service ServiceConfig, ctx context.Context) ServiceStatus {
|
|
var serviceResult bool
|
|
var status string
|
|
|
|
url := service.URL()
|
|
switch url.Scheme {
|
|
case "http", "https":
|
|
serviceResult, status = CheckHTTP200(ctx, url.String())
|
|
case "tcp":
|
|
// go includes port in host (url.Host is actually "authority")
|
|
serviceResult, status = CheckTCPOpen(ctx, url.Host)
|
|
case "icmp":
|
|
// go includes port in host (url.Host is actually "authority")
|
|
serviceResult, status = CheckICMPUp(ctx, url.Host)
|
|
default:
|
|
log.Panicf("I can't handle service with scheme: %#v", url.Scheme)
|
|
}
|
|
|
|
return ServiceStatus{
|
|
Name: service.Description,
|
|
Type: url.Scheme,
|
|
Url: service.Url,
|
|
Ok: serviceResult,
|
|
Status: status,
|
|
}
|
|
}
|
|
|
|
type ServiceStatusBatch []ServiceStatus
|
|
|
|
func CheckServiceBatch(ctx Context, services []ServiceConfig) ServiceStatusBatch {
|
|
var wg sync.WaitGroup
|
|
|
|
var data []ServiceStatus = make([]ServiceStatus, len(services))
|
|
|
|
for i, v := range services {
|
|
wg.Add(1)
|
|
go func(i int, config ServiceConfig) {
|
|
defer wg.Done()
|
|
data[i] = CheckService(config, ctx)
|
|
}(i, v)
|
|
}
|
|
wg.Wait()
|
|
|
|
return data
|
|
}
|