aboutsummaryrefslogtreecommitdiff
path: root/service_config.go
diff options
context:
space:
mode:
Diffstat (limited to 'service_config.go')
-rw-r--r--service_config.go112
1 files changed, 112 insertions, 0 deletions
diff --git a/service_config.go b/service_config.go
new file mode 100644
index 0000000..9f9e0fc
--- /dev/null
+++ b/service_config.go
@@ -0,0 +1,112 @@
+// SPDX-FileCopyrightText: 2025 M. Shulhan <ms@kilabit.info>
+// SPDX-License-Identifier: GPL-3.0-only
+
+package lilin
+
+import (
+ "fmt"
+ "log"
+ "net"
+ "net/http"
+ "net/url"
+ "strings"
+ "time"
+)
+
+const (
+ serviceKindHTTP = `http`
+ serviceKindHTTPS = `https`
+ serviceKindTCP = `tcp`
+ serviceKindUDP = `udp`
+)
+
+// defInterval define default interval in between scanning run.
+const defInterval = 10 * time.Second
+
+type ServiceConfig struct {
+ scanURL *url.URL
+
+ Name string
+
+ // The Address of service, using scheme based, for example
+ // - http://example.com/health for HTTP service,
+ // - tcp://127.0.0.1:22 for TCP service,
+ // - udp://127.0.0.1:53 for UDP service.
+ Address string `ini:"::address"`
+
+ // HTTPMethod define HTTP method to be used to scan the HTTP service.
+ // Valid value is either DELETE, GET, HEAD, PATCH, POST, or PUT.
+ HTTPMethod string `ini:"::method"`
+
+ // Timeout for connecting and reading response from service.
+ Timeout string `ini:"::timeout"`
+
+ // Interval between each scan.
+ // The minimum value is 60 seconds or 1 minute.
+ Interval string `ini:"::interval"`
+
+ timeout time.Duration
+ interval time.Duration
+}
+
+func (cfg *ServiceConfig) init() (err error) {
+ cfg.scanURL, err = url.Parse(cfg.Address)
+ if err != nil {
+ return fmt.Errorf(`invalid address %s`, cfg.Address)
+ }
+
+ var scheme = strings.ToLower(cfg.scanURL.Scheme)
+ switch scheme {
+ case `http`, `https`:
+ var httpMethod = strings.ToUpper(cfg.HTTPMethod)
+ switch httpMethod {
+ case ``:
+ cfg.HTTPMethod = http.MethodGet
+ case http.MethodDelete, http.MethodGet, http.MethodHead,
+ http.MethodOptions, http.MethodPatch, http.MethodPost,
+ http.MethodPut:
+ cfg.HTTPMethod = httpMethod
+ default:
+ return fmt.Errorf(`invalid HTTP method %s`, cfg.HTTPMethod)
+ }
+
+ case serviceKindTCP:
+ _, err = net.ResolveTCPAddr(scheme, cfg.scanURL.Host)
+ if err != nil {
+ return fmt.Errorf(`invalid TCP address %s`, cfg.Address)
+ }
+
+ case serviceKindUDP:
+ _, err = net.ResolveUDPAddr(scheme, cfg.scanURL.Host)
+ if err != nil {
+ return fmt.Errorf(`invalid UDP address %s`, cfg.Address)
+ }
+
+ default:
+ return fmt.Errorf(`unknown scheme in address %s`, scheme)
+ }
+
+ if len(cfg.Timeout) == 0 {
+ cfg.timeout = defTimeout
+ } else {
+ cfg.timeout, err = time.ParseDuration(cfg.Timeout)
+ if err != nil {
+ return fmt.Errorf(`invalid Timeout %s`, cfg.Timeout)
+ }
+ }
+
+ if len(cfg.Interval) == 0 {
+ cfg.interval = defInterval
+ } else {
+ cfg.interval, err = time.ParseDuration(cfg.Interval)
+ if err != nil {
+ return fmt.Errorf(`invalid Interval %s`, cfg.Interval)
+ }
+ if cfg.interval < defInterval {
+ log.Printf(`%s: interval is less than %s, revert to default`,
+ cfg.Name, defInterval)
+ cfg.interval = defInterval
+ }
+ }
+ return nil
+}