diff options
Diffstat (limited to 'service_config.go')
| -rw-r--r-- | service_config.go | 112 |
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 +} |
