Merge pull request #870 from tobychui/v3.2.9

V3.2.9
This commit is contained in:
Toby Chui
2025-11-01 15:07:16 +08:00
committed by GitHub
40 changed files with 42161 additions and 154301 deletions

View File

@@ -58,9 +58,7 @@ ENV DB="auto"
ENV DOCKER="true"
ENV EARLYRENEW="30"
ENV ENABLELOG="true"
ENV ENABLELOGCOMPRESS="true"
ENV FASTGEOIP="false"
ENV LOGROTATE="0"
ENV MDNS="true"
ENV MDNSNAME="''"
ENV NOAUTH="false"

View File

@@ -88,9 +88,7 @@ Variables are the same as those in [Start Parameters](https://github.com/tobychu
| `DOCKER` | `true` (Boolean) | Run Zoraxy in docker compatibility mode. |
| `EARLYRENEW` | `30` (Integer) | Number of days to early renew a soon expiring certificate. |
| `ENABLELOG` | `true` (Boolean) | Enable system wide logging, set to false for writing log to STDOUT only. |
| `ENABLELOGCOMPRESS` | `true` (Boolean) | Enable log compression for rotated log files. |
| `FASTGEOIP` | `false` (Boolean) | Enable high speed geoip lookup, require 1GB extra memory (Not recommend for low end devices). |
| `LOGROTATE` | `0` (String) | Enable log rotation and set the maximum log file size (Supports K, M, G suffixes). Set to 0 to disable. |
| `MDNS` | `true` (Boolean) | Enable mDNS scanner and transponder. |
| `MDNSNAME` | `''` (String) | mDNS name, leave empty to use default (zoraxy_{node-uuid}.local). |
| `NOAUTH` | `false` (Boolean) | Disable authentication for management interface. |

View File

@@ -93,9 +93,7 @@ def start_zoraxy():
f"-docker={ getenv('DOCKER', 'true') }",
f"-earlyrenew={ getenv('EARLYRENEW', '30') }",
f"-enablelog={ getenv('ENABLELOG', 'true') }",
f"-enablelogcompress={ getenv('ENABLELOGCOMPRESS', 'true') }",
f"-fastgeoip={ getenv('FASTGEOIP', 'false') }",
f"-logrotate={ getenv('LOGROTATE', '0') }",
f"-mdns={ getenv('MDNS', 'true') }",
f"-mdnsname={ getenv('MDNSNAME', "''") }",
f"-noauth={ getenv('NOAUTH', 'false') }",

View File

@@ -386,7 +386,9 @@ func initAPIs(targetMux *http.ServeMux) {
authRouter.HandleFunc("/api/log/read", LogViewer.HandleReadLog)
authRouter.HandleFunc("/api/log/summary", LogViewer.HandleReadLogSummary)
authRouter.HandleFunc("/api/log/errors", LogViewer.HandleLogErrorSummary)
authRouter.HandleFunc("/api/log/rotate/debug.trigger", SystemWideLogger.HandleDebugTriggerLogRotation)
authRouter.HandleFunc("/api/log/rotate/trigger", SystemWideLogger.HandleDebugTriggerLogRotation)
authRouter.HandleFunc("/api/logger/config", handleLoggerConfig)
//Debug
authRouter.HandleFunc("/api/info/pprof", pprof.Index)
}

View File

@@ -15,6 +15,7 @@ import (
"imuslab.com/zoraxy/mod/dynamicproxy"
"imuslab.com/zoraxy/mod/dynamicproxy/loadbalance"
"imuslab.com/zoraxy/mod/info/logger"
"imuslab.com/zoraxy/mod/tlscert"
"imuslab.com/zoraxy/mod/utils"
)
@@ -366,3 +367,13 @@ func ImportConfigFromZip(w http.ResponseWriter, r *http.Request) {
}
}
func handleLoggerConfig(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet {
logger.HandleGetLogConfig(CONF_LOG_CONFIG)(w, r)
} else if r.Method == http.MethodPost {
logger.HandleUpdateLogConfig(CONF_LOG_CONFIG, SystemWideLogger)(w, r)
} else {
utils.SendErrorResponse(w, "Method not allowed")
}
}

View File

@@ -44,7 +44,7 @@ import (
const (
/* Build Constants */
SYSTEM_NAME = "Zoraxy"
SYSTEM_VERSION = "3.2.8"
SYSTEM_VERSION = "3.2.9"
DEVELOPMENT_BUILD = false
/* System Constants */
@@ -76,6 +76,7 @@ const (
CONF_PATH_RULE = CONF_FOLDER + "/rules/pathrules"
CONF_PLUGIN_GROUPS = CONF_FOLDER + "/plugin_groups.json"
CONF_GEODB_PATH = CONF_FOLDER + "/geodb"
CONF_LOG_CONFIG = CONF_FOLDER + "/log_conf.json"
)
/* System Startup Flags */
@@ -95,9 +96,9 @@ var (
enableAutoUpdate = flag.Bool("cfgupgrade", true, "Enable auto config upgrade if breaking change is detected")
/* Logging Configuration Flags */
enableLog = flag.Bool("enablelog", true, "Enable system wide logging, set to false for writing log to STDOUT only")
enableLogCompression = flag.Bool("enablelogcompress", true, "Enable log compression for rotated log files")
logRotate = flag.String("logrotate", "0", "Enable log rotation and set the maximum log file size in KB, also support K, M, G suffix (e.g. 200M), set to 0 to disable")
enableLog = flag.Bool("enablelog", true, "Enable system wide logging, set to false for writing log to STDOUT only")
//enableLogCompression = flag.Bool("enablelogcompress", true, "Enable log compression for rotated log files")
//logRotate = flag.String("logrotate", "0", "Enable log rotation and set the maximum log file size in KB, also support K, M, G suffix (e.g. 200M), set to 0 to disable")
/* Default Configuration Flags */
defaultInboundPort = flag.Int("default_inbound_port", 443, "Default web server listening port")

View File

@@ -8,57 +8,64 @@ require (
github.com/armon/go-radix v1.0.0
github.com/boltdb/bolt v1.3.1
github.com/docker/docker v27.0.0+incompatible
github.com/go-acme/lego/v4 v4.25.2
github.com/go-acme/lego/v4 v4.28.0
github.com/go-ping/ping v1.1.0
github.com/google/uuid v1.6.0
github.com/gorilla/sessions v1.2.2
github.com/gorilla/websocket v1.5.1
github.com/grandcat/zeroconf v1.0.0
github.com/jellydator/ttlcache/v3 v3.4.0
github.com/likexian/whois v1.15.1
github.com/microcosm-cc/bluemonday v1.0.26
github.com/monperrus/crawler-user-agents v1.1.0
github.com/pires/go-proxyproto v0.8.1
github.com/shirou/gopsutil/v4 v4.25.1
github.com/stretchr/testify v1.10.0
github.com/stretchr/testify v1.11.1
github.com/syndtr/goleveldb v1.0.0
golang.org/x/net v0.42.0
golang.org/x/oauth2 v0.30.0
golang.org/x/text v0.27.0
golang.org/x/net v0.46.0
golang.org/x/oauth2 v0.32.0
golang.org/x/text v0.30.0
)
require (
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 // indirect
github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.8 // indirect
github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.13 // indirect
github.com/alibabacloud-go/debug v1.0.1 // indirect
github.com/alibabacloud-go/endpoint-util v1.1.0 // indirect
github.com/alibabacloud-go/openapi-util v0.1.1 // indirect
github.com/alibabacloud-go/tea v1.3.9 // indirect
github.com/alibabacloud-go/tea v1.3.13 // indirect
github.com/alibabacloud-go/tea-utils/v2 v2.0.7 // indirect
github.com/aliyun/credentials-go v1.4.6 // indirect
github.com/aziontech/azionapi-go-sdk v0.142.0 // indirect
github.com/baidubce/bce-sdk-go v0.9.235 // indirect
github.com/aliyun/credentials-go v1.4.7 // indirect
github.com/aziontech/azionapi-go-sdk v0.143.0 // indirect
github.com/baidubce/bce-sdk-go v0.9.250 // indirect
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
github.com/clbanning/mxj/v2 v2.7.0 // indirect
github.com/dnsimple/dnsimple-go/v4 v4.0.0 // indirect
github.com/go-acme/alidns-20150109/v4 v4.5.10 // indirect
github.com/go-acme/tencentclouddnspod v1.0.1208 // indirect
github.com/fatih/color v1.16.0 // indirect
github.com/go-acme/alidns-20150109/v4 v4.6.1 // indirect
github.com/go-acme/tencentclouddnspod v1.1.10 // indirect
github.com/go-acme/tencentedgdeone v1.1.48 // indirect
github.com/goccy/go-yaml v1.9.8 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/infobloxopen/infoblox-go-client/v2 v2.10.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/namedotcom/go/v4 v4.0.2 // indirect
github.com/nrdcg/goacmedns v0.2.0 // indirect
github.com/nrdcg/vegadns v0.3.0 // indirect
github.com/regfish/regfish-dnsapi-go v0.1.1 // indirect
github.com/yandex-cloud/go-sdk/services/dns v0.0.3 // indirect
github.com/yandex-cloud/go-sdk/v2 v2.0.8 // indirect
github.com/yandex-cloud/go-sdk/services/dns v0.0.16 // indirect
github.com/yandex-cloud/go-sdk/v2 v2.24.0 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
)
require (
github.com/AdamSLevy/jsonrpc2/v14 v14.1.0 // indirect
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns v1.2.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns v1.3.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resourcegraph/armresourcegraph v0.9.0 // indirect
@@ -71,29 +78,27 @@ require (
github.com/Azure/go-autorest/autorest/to v0.4.1 // indirect
github.com/Azure/go-autorest/logger v0.2.1 // indirect
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0 // indirect
github.com/Microsoft/go-winio v0.4.14 // indirect
github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87 // indirect
github.com/aws/aws-sdk-go-v2 v1.36.6 // indirect
github.com/aws/aws-sdk-go-v2/config v1.29.18 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.17.71 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.33 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.37 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.37 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.18 // indirect
github.com/aws/aws-sdk-go-v2/service/lightsail v1.43.5 // indirect
github.com/aws/aws-sdk-go-v2/service/route53 v1.53.1 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.25.6 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.4 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.34.1 // indirect
github.com/aws/smithy-go v1.22.4 // indirect
github.com/aws/aws-sdk-go-v2 v1.39.4 // indirect
github.com/aws/aws-sdk-go-v2/config v1.31.15 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.18.19 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.11 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.11 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.11 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.2 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.11 // indirect
github.com/aws/aws-sdk-go-v2/service/lightsail v1.50.2 // indirect
github.com/aws/aws-sdk-go-v2/service/route53 v1.59.1 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.29.8 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.3 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.38.9 // indirect
github.com/aws/smithy-go v1.23.1 // indirect
github.com/aymerick/douceur v0.2.0 // indirect
github.com/benbjohnson/clock v1.3.0 // indirect
github.com/benbjohnson/clock v1.3.5 // indirect
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dimchansky/utfbom v1.1.1 // indirect
@@ -106,15 +111,15 @@ require (
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/ghodss/yaml v1.0.0 // indirect
github.com/go-errors/errors v1.0.1 // indirect
github.com/go-jose/go-jose/v4 v4.1.1 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-jose/go-jose/v4 v4.1.3 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-resty/resty/v2 v2.16.5 // indirect
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
github.com/golang-jwt/jwt/v5 v5.2.2 // indirect
github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
github.com/golang/snappy v0.0.1 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/gophercloud/gophercloud v1.14.1 // indirect
@@ -123,19 +128,19 @@ require (
github.com/gorilla/securecookie v1.1.2 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.159 // indirect
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.173 // indirect
github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12 // indirect
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213 // indirect
github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/labbsr0x/bindman-dns-webhook v1.0.2 // indirect
github.com/labbsr0x/goh v1.0.1 // indirect
github.com/linode/linodego v1.53.0 // indirect
github.com/linode/linodego v1.60.0 // indirect
github.com/liquidweb/liquidweb-cli v0.6.9 // indirect
github.com/liquidweb/liquidweb-go v1.6.4 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/miekg/dns v1.1.67 // indirect
github.com/miekg/dns v1.1.68 // indirect
github.com/mimuret/golang-iij-dpf v0.9.1 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
@@ -145,13 +150,13 @@ require (
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/nrdcg/auroradns v1.1.0 // indirect
github.com/nrdcg/bunny-go v0.0.0-20250327222614-988a091fc7ea // indirect
github.com/nrdcg/desec v0.11.0 // indirect
github.com/nrdcg/bunny-go v0.1.0 // indirect
github.com/nrdcg/desec v0.11.1 // indirect
github.com/nrdcg/dnspod-go v0.4.0 // indirect
github.com/nrdcg/freemyip v0.3.0 // indirect
github.com/nrdcg/goinwx v0.11.0 // indirect
github.com/nrdcg/mailinabox v0.2.0 // indirect
github.com/nrdcg/namesilo v0.2.1 // indirect
github.com/nrdcg/mailinabox v0.3.0 // indirect
github.com/nrdcg/namesilo v0.5.0 // indirect
github.com/nrdcg/nodion v0.1.0 // indirect
github.com/nrdcg/porkbun v0.4.0 // indirect
github.com/nzdjb/go-metaname v1.0.0 // indirect
@@ -164,44 +169,44 @@ require (
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/pquerna/otp v1.5.0 // indirect
github.com/sacloud/api-client-go v0.3.2 // indirect
github.com/sacloud/api-client-go v0.3.3 // indirect
github.com/sacloud/go-http v0.1.9 // indirect
github.com/sacloud/iaas-api-go v1.16.1 // indirect
github.com/sacloud/iaas-api-go v1.20.0 // indirect
github.com/sacloud/packages-go v0.0.11 // indirect
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.34 // indirect
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.35 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 // indirect
github.com/softlayer/softlayer-go v1.1.7 // indirect
github.com/softlayer/softlayer-go v1.2.1 // indirect
github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1210 // indirect
github.com/spf13/cast v1.7.0 // indirect
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.1.48 // indirect
github.com/tjfoc/gmsm v1.4.1 // indirect
github.com/transip/gotransip/v6 v6.26.0 // indirect
github.com/ultradns/ultradns-go-sdk v1.8.0-20241010134910-243eeec // indirect
github.com/transip/gotransip/v6 v6.26.1 // indirect
github.com/ultradns/ultradns-go-sdk v1.8.1-20250722213956-faef419 // indirect
github.com/vinyldns/go-vinyldns v0.9.16 // indirect
github.com/vultr/govultr/v3 v3.21.1 // indirect
github.com/yandex-cloud/go-genproto v0.14.0 // indirect
github.com/vultr/govultr/v3 v3.24.0 // indirect
github.com/yandex-cloud/go-genproto v0.34.0 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.mongodb.org/mongo-driver v1.13.1 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
go.opentelemetry.io/otel v1.36.0 // indirect
go.opentelemetry.io/otel v1.37.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 // indirect
go.opentelemetry.io/otel/metric v1.36.0 // indirect
go.opentelemetry.io/otel/trace v1.36.0 // indirect
go.opentelemetry.io/otel/metric v1.37.0 // indirect
go.opentelemetry.io/otel/trace v1.37.0 // indirect
go.uber.org/ratelimit v0.3.1 // indirect
golang.org/x/crypto v0.40.0 // indirect
golang.org/x/mod v0.25.0 // indirect
golang.org/x/sync v0.16.0 // indirect
golang.org/x/sys v0.34.0 // indirect
golang.org/x/time v0.12.0 // indirect
golang.org/x/tools v0.34.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 // indirect
google.golang.org/grpc v1.73.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
golang.org/x/crypto v0.43.0 // indirect
golang.org/x/mod v0.28.0 // indirect
golang.org/x/sync v0.17.0 // indirect
golang.org/x/sys v0.37.0 // indirect
golang.org/x/time v0.14.0 // indirect
golang.org/x/tools v0.37.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250818200422-3122310a409c // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect
google.golang.org/grpc v1.76.0 // indirect
google.golang.org/protobuf v1.36.10 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/ns1/ns1-go.v2 v2.14.4 // indirect
gopkg.in/ns1/ns1-go.v2 v2.15.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gotest.tools/v3 v3.5.1 // indirect

View File

@@ -36,14 +36,14 @@ github.com/AdamSLevy/jsonrpc2/v14 v14.1.0 h1:Dy3M9aegiI7d7PF1LUdjbVigJReo+QOceYs
github.com/AdamSLevy/jsonrpc2/v14 v14.1.0/go.mod h1:ZakZtbCXxCz82NJvq7MoREtiQesnDfrtF6RFUGzQfLo=
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU=
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.1 h1:Wc1ml6QlJs2BHQ/9Bqu1jiyggbsSjramq2oUmp5WeIo=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.1/go.mod h1:Ot/6aikWnKWi4l9QB7qVSwa8iMphQNqkWALMoNT3rzM=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1 h1:B+blDbyVIG3WaikNxPnhPiJ1MThR03b3vKGtER95TP4=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1/go.mod h1:JdM5psgjfBf5fo2uWOZhflPWyDBZ/O/CNAH9CtsuZE4=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1 h1:5YTBM8QDVIBN3sxBil89WfdAAqDZbyJTgh688DSxX5w=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1/go.mod h1:YD5h/ldMsG0XiIw7PdyNhLxaM317eFh5yNLccNfGdyw=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.0 h1:KpMC6LFL7mqpExyMC9jVOYRiVhLmamjeZfRsUpB7l4s=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.0/go.mod h1:J7MUC/wtRpfGVbQ5sIItY5/FuVWmvzlY21WAOfQnq/I=
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY=
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 h1:FPKJS1T+clwv+OLGt13a8UjqeRuh0O4SJ3lUriThc+4=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1/go.mod h1:j2chePtV91HrC22tGoRX3sGY42uF13WzmmV80/OdVAA=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDozdmndjTm8DXdpCzPajMgA=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2/go.mod h1:XtLgD3ZD34DAaVIIAyG3objl5DynM3CQ/vMcbBNJZGI=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns v1.2.0 h1:lpOxwrQ919lCZoNCd69rVt8u1eLZuMORrGXqy8sNf3c=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns v1.2.0/go.mod h1:fSvRkb8d26z9dbL40Uf/OO6Vo9iExtZK3D0ulRV+8M0=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v3 v3.1.0 h1:2qsIIvxVT+uE6yrNldntJKlLRgxGbZ85kgtz5SNBhMw=
@@ -81,15 +81,13 @@ github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUM
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM=
github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE=
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJe7PpYPXT5A29ZkwJaPqcva7BVeemZOZs=
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0 h1:XkkQbfMyuH2jTSjQjSoihryI8GINRcs4xp8lNawg0FI=
github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87 h1:xPMsUicZ3iosVPSIP7bW5EcGUzjiiMl1OYTe14y/R24=
github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87/go.mod h1:iGLljf5n9GjT6kc0HBvyI1nOKnGQbNB66VzSNbK5iks=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alibabacloud-go/alibabacloud-gateway-pop v0.0.6 h1:eIf+iGJxdU4U9ypaUfbtOWCsZSbTb8AUHvyPrxu6mAA=
@@ -103,9 +101,9 @@ github.com/alibabacloud-go/darabonba-encode-util v0.0.2 h1:1uJGrbsGEVqWcWxrS9MyC
github.com/alibabacloud-go/darabonba-encode-util v0.0.2/go.mod h1:JiW9higWHYXm7F4PKuMgEUETNZasrDM6vqVr/Can7H8=
github.com/alibabacloud-go/darabonba-map v0.0.2 h1:qvPnGB4+dJbJIxOOfawxzF3hzMnIpjmafa0qOTp6udc=
github.com/alibabacloud-go/darabonba-map v0.0.2/go.mod h1:28AJaX8FOE/ym8OUFWga+MtEzBunJwQGceGQlvaPGPc=
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.11/go.mod h1:wHxkgZT1ClZdcwEVP/pDgYK/9HucsnCfMipmJgCz4xY=
github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.8 h1:AL+nH363NJFS1NXIjCdmj5MOElgKEqgFeoq7vjje350=
github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.8/go.mod h1:d+z3ScRqc7PFzg4h9oqE3h8yunRZvAvU7u+iuPYEhpU=
github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.12/go.mod h1:f2wDpbM7hK9SvLIH09zSKVU1TsyemUNOqErMscMMl7c=
github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.13 h1:Q00FU3H94Ts0ZIHDmY+fYGgB7dV9D/YX6FGsgorQPgw=
github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.13/go.mod h1:lxFGfobinVsQ49ntjpgWghXmIF0/Sm4+wvBJ1h5RtaE=
github.com/alibabacloud-go/darabonba-signature-util v0.0.7 h1:UzCnKvsjPFzApvODDNEYqBHMFt1w98wC7FOo0InLyxg=
github.com/alibabacloud-go/darabonba-signature-util v0.0.7/go.mod h1:oUzCYV2fcCH797xKdL6BDH8ADIHlzrtKVjeRtunBNTQ=
github.com/alibabacloud-go/darabonba-string v1.0.2 h1:E714wms5ibdzCqGeYJ9JCFywE5nDyvIXIIQbZVFkkqo=
@@ -126,63 +124,62 @@ github.com/alibabacloud-go/tea v1.1.11/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/Ke
github.com/alibabacloud-go/tea v1.1.17/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A=
github.com/alibabacloud-go/tea v1.1.20/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A=
github.com/alibabacloud-go/tea v1.2.2/go.mod h1:CF3vOzEMAG+bR4WOql8gc2G9H3EkH3ZLAQdpmpXMgwk=
github.com/alibabacloud-go/tea v1.3.9 h1:bjgt1bvdY780vz/17iWNNtbXl4A77HWntWMeaUF3So0=
github.com/alibabacloud-go/tea v1.3.9/go.mod h1:A560v/JTQ1n5zklt2BEpurJzZTI8TUT+Psg2drWlxRg=
github.com/alibabacloud-go/tea v1.3.12/go.mod h1:A560v/JTQ1n5zklt2BEpurJzZTI8TUT+Psg2drWlxRg=
github.com/alibabacloud-go/tea v1.3.13 h1:WhGy6LIXaMbBM6VBYcsDCz6K/TPsT1Ri2hPmmZffZ94=
github.com/alibabacloud-go/tea v1.3.13/go.mod h1:A560v/JTQ1n5zklt2BEpurJzZTI8TUT+Psg2drWlxRg=
github.com/alibabacloud-go/tea-utils v1.3.1/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQdSngxrpF8rKUDJjPE=
github.com/alibabacloud-go/tea-utils/v2 v2.0.5/go.mod h1:dL6vbUT35E4F4bFTHL845eUloqaerYBYPsdWR2/jhe4=
github.com/alibabacloud-go/tea-utils/v2 v2.0.6/go.mod h1:qxn986l+q33J5VkialKMqT/TTs3E+U9MJpd001iWQ9I=
github.com/alibabacloud-go/tea-utils/v2 v2.0.7 h1:WDx5qW3Xa5ZgJ1c8NfqJkF6w+AU5wB8835UdhPr6Ax0=
github.com/alibabacloud-go/tea-utils/v2 v2.0.7/go.mod h1:qxn986l+q33J5VkialKMqT/TTs3E+U9MJpd001iWQ9I=
github.com/alibabacloud-go/tea-xml v1.1.3/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8=
github.com/aliyun/credentials-go v1.1.2/go.mod h1:ozcZaMR5kLM7pwtCMEpVmQ242suV6qTJya2bDq4X1Tw=
github.com/aliyun/credentials-go v1.3.1/go.mod h1:8jKYhQuDawt8x2+fusqa1Y6mPxemTsBEN04dgcAcYz0=
github.com/aliyun/credentials-go v1.3.6/go.mod h1:1LxUuX7L5YrZUWzBrRyk0SwSdH4OmPrib8NVePL3fxM=
github.com/aliyun/credentials-go v1.4.5/go.mod h1:Jm6d+xIgwJVLVWT561vy67ZRP4lPTQxMbEYRuT2Ti1U=
github.com/aliyun/credentials-go v1.4.6 h1:CG8rc/nxCNKfXbZWpWDzI9GjF4Tuu3Es14qT8Y0ClOk=
github.com/aliyun/credentials-go v1.4.6/go.mod h1:Jm6d+xIgwJVLVWT561vy67ZRP4lPTQxMbEYRuT2Ti1U=
github.com/aliyun/credentials-go v1.4.7 h1:T17dLqEtPUFvjDRRb5giVvLh6dFT8IcNFJJb7MeyCxw=
github.com/aliyun/credentials-go v1.4.7/go.mod h1:Jm6d+xIgwJVLVWT561vy67ZRP4lPTQxMbEYRuT2Ti1U=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/aws/aws-sdk-go-v2 v1.36.6 h1:zJqGjVbRdTPojeCGWn5IR5pbJwSQSBh5RWFTQcEQGdU=
github.com/aws/aws-sdk-go-v2 v1.36.6/go.mod h1:EYrzvCCN9CMUTa5+6lf6MM4tq3Zjp8UhSGR/cBsjai0=
github.com/aws/aws-sdk-go-v2/config v1.29.18 h1:x4T1GRPnqKV8HMJOMtNktbpQMl3bIsfx8KbqmveUO2I=
github.com/aws/aws-sdk-go-v2/config v1.29.18/go.mod h1:bvz8oXugIsH8K7HLhBv06vDqnFv3NsGDt2Znpk7zmOU=
github.com/aws/aws-sdk-go-v2/credentials v1.17.71 h1:r2w4mQWnrTMJjOyIsZtGp3R3XGY3nqHn8C26C2lQWgA=
github.com/aws/aws-sdk-go-v2/credentials v1.17.71/go.mod h1:E7VF3acIup4GB5ckzbKFrCK0vTvEQxOxgdq4U3vcMCY=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.33 h1:D9ixiWSG4lyUBL2DDNK924Px9V/NBVpML90MHqyTADY=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.33/go.mod h1:caS/m4DI+cij2paz3rtProRBI4s/+TCiWoaWZuQ9010=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.37 h1:osMWfm/sC/L4tvEdQ65Gri5ZZDCUpuYJZbTTDrsn4I0=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.37/go.mod h1:ZV2/1fbjOPr4G4v38G3Ww5TBT4+hmsK45s/rxu1fGy0=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.37 h1:v+X21AvTb2wZ+ycg1gx+orkB/9U6L7AOp93R7qYxsxM=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.37/go.mod h1:G0uM1kyssELxmJ2VZEfG0q2npObR3BAkF3c1VsfVnfs=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 h1:CXV68E2dNqhuynZJPB80bhPQwAKqBWVer887figW6Jc=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4/go.mod h1:/xFi9KtvBXP97ppCz1TAEvU1Uf66qvid89rbem3wCzQ=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.18 h1:vvbXsA2TVO80/KT7ZqCbx934dt6PY+vQ8hZpUZ/cpYg=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.18/go.mod h1:m2JJHledjBGNMsLOF1g9gbAxprzq3KjC8e4lxtn+eWg=
github.com/aws/aws-sdk-go-v2/service/lightsail v1.43.5 h1:DYQbfSAWcMwRM0LbCDyQkPB1AcaZcLzLoaFrYcpyMag=
github.com/aws/aws-sdk-go-v2/service/lightsail v1.43.5/go.mod h1:Lav4KLgncVjjrwLWutOccjEgJ4T/RAdY+Ic0hmNIgI0=
github.com/aws/aws-sdk-go-v2/service/route53 v1.53.1 h1:R3nSX1hguRy6MnknHiepSvqnnL8ansFwK2hidPesAYU=
github.com/aws/aws-sdk-go-v2/service/route53 v1.53.1/go.mod h1:fmSiB4OAghn85lQgk7XN9l9bpFg5Bm1v3HuaXKytPEw=
github.com/aws/aws-sdk-go-v2/service/sso v1.25.6 h1:rGtWqkQbPk7Bkwuv3NzpE/scwwL9sC1Ul3tn9x83DUI=
github.com/aws/aws-sdk-go-v2/service/sso v1.25.6/go.mod h1:u4ku9OLv4TO4bCPdxf4fA1upaMaJmP9ZijGk3AAOC6Q=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.4 h1:OV/pxyXh+eMA0TExHEC4jyWdumLxNbzz1P0zJoezkJc=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.4/go.mod h1:8Mm5VGYwtm+r305FfPSuc+aFkrypeylGYhFim6XEPoc=
github.com/aws/aws-sdk-go-v2/service/sts v1.34.1 h1:aUrLQwJfZtwv3/ZNG2xRtEen+NqI3iesuacjP51Mv1s=
github.com/aws/aws-sdk-go-v2/service/sts v1.34.1/go.mod h1:3wFBZKoWnX3r+Sm7in79i54fBmNfwhdNdQuscCw7QIk=
github.com/aws/smithy-go v1.22.4 h1:uqXzVZNuNexwc/xrh6Tb56u89WDlJY6HS+KC0S4QSjw=
github.com/aws/smithy-go v1.22.4/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI=
github.com/aws/aws-sdk-go-v2 v1.39.4 h1:qTsQKcdQPHnfGYBBs+Btl8QwxJeoWcOcPcixK90mRhg=
github.com/aws/aws-sdk-go-v2 v1.39.4/go.mod h1:yWSxrnioGUZ4WVv9TgMrNUeLV3PFESn/v+6T/Su8gnM=
github.com/aws/aws-sdk-go-v2/config v1.31.15 h1:gE3M4xuNXfC/9bG4hyowGm/35uQTi7bUKeYs5e/6uvU=
github.com/aws/aws-sdk-go-v2/config v1.31.15/go.mod h1:HvnvGJoE2I95KAIW8kkWVPJ4XhdrlvwJpV6pEzFQa8o=
github.com/aws/aws-sdk-go-v2/credentials v1.18.19 h1:Jc1zzwkSY1QbkEcLujwqRTXOdvW8ppND3jRBb/VhBQc=
github.com/aws/aws-sdk-go-v2/credentials v1.18.19/go.mod h1:DIfQ9fAk5H0pGtnqfqkbSIzky82qYnGvh06ASQXXg6A=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.11 h1:X7X4YKb+c0rkI6d4uJ5tEMxXgCZ+jZ/D6mvkno8c8Uw=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.11/go.mod h1:EqM6vPZQsZHYvC4Cai35UDg/f5NCEU+vp0WfbVqVcZc=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.11 h1:7AANQZkF3ihM8fbdftpjhken0TP9sBzFbV/Ze/Y4HXA=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.11/go.mod h1:NTF4QCGkm6fzVwncpkFQqoquQyOolcyXfbpC98urj+c=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.11 h1:ShdtWUZT37LCAA4Mw2kJAJtzaszfSHFb5n25sdcv4YE=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.11/go.mod h1:7bUb2sSr2MZ3M/N+VyETLTQtInemHXb/Fl3s8CLzm0Y=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.2 h1:xtuxji5CS0JknaXoACOunXOYOQzgfTvGAc9s2QdCJA4=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.2/go.mod h1:zxwi0DIR0rcRcgdbl7E2MSOvxDyyXGBlScvBkARFaLQ=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.11 h1:GpMf3z2KJa4RnJ0ew3Hac+hRFYLZ9DDjfgXjuW+pB54=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.11/go.mod h1:6MZP3ZI4QQsgUCFTwMZA2V0sEriNQ8k2hmoHF3qjimQ=
github.com/aws/aws-sdk-go-v2/service/lightsail v1.50.2 h1:pr1dQ9vamhAf2mYOgiRRC/w9Ht4POFhy6+xXw7hOqwY=
github.com/aws/aws-sdk-go-v2/service/lightsail v1.50.2/go.mod h1:A4Ch93K7Wam4Qe0Wl0XbPgcgoL5KIJtFIe7wHw6OPWE=
github.com/aws/aws-sdk-go-v2/service/route53 v1.59.1 h1:KuoA/cmy/yK8n9v/d6WH36cZwGxFOrn0TmZ4lNN3MKQ=
github.com/aws/aws-sdk-go-v2/service/route53 v1.59.1/go.mod h1:BymbICXBfXQHO6i+yTBhocA9a6DM0uMDQqYelqa9wzs=
github.com/aws/aws-sdk-go-v2/service/sso v1.29.8 h1:M5nimZmugcZUO9wG7iVtROxPhiqyZX6ejS1lxlDPbTU=
github.com/aws/aws-sdk-go-v2/service/sso v1.29.8/go.mod h1:mbef/pgKhtKRwrigPPs7SSSKZgytzP8PQ6P6JAAdqyM=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.3 h1:S5GuJZpYxE0lKeMHKn+BRTz6PTFpgThyJ+5mYfux7BM=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.3/go.mod h1:X4OF+BTd7HIb3L+tc4UlWHVrpgwZZIVENU15pRDVTI0=
github.com/aws/aws-sdk-go-v2/service/sts v1.38.9 h1:Ekml5vGg6sHSZLZJQJagefnVe6PmqC2oiRkBq4F7fU0=
github.com/aws/aws-sdk-go-v2/service/sts v1.38.9/go.mod h1:/e15V+o1zFHWdH3u7lpI3rVBcxszktIKuHKCY2/py+k=
github.com/aws/smithy-go v1.23.1 h1:sLvcH6dfAFwGkHLZ7dGiYF7aK6mg4CgKA/iDKjLDt9M=
github.com/aws/smithy-go v1.23.1/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0=
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
github.com/aziontech/azionapi-go-sdk v0.142.0 h1:1NOHXlC0/7VgbfbTIGVpsYn1THCugM4/SCOXVdUHQ+A=
github.com/aziontech/azionapi-go-sdk v0.142.0/go.mod h1:cA5DY/VP4X5Eu11LpQNzNn83ziKjja7QVMIl4J45feA=
github.com/baidubce/bce-sdk-go v0.9.235 h1:iAi+seH9w1Go2szFNzyGumahLGDsuYZ3i8hduX3qiM8=
github.com/baidubce/bce-sdk-go v0.9.235/go.mod h1:zbYJMQwE4IZuyrJiFO8tO8NbtYiKTFTbwh4eIsqjVdg=
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/aziontech/azionapi-go-sdk v0.143.0 h1:4eEBlYT10prgeCVTNR9FIc7f59Crbl2zrH1a4D1BUqU=
github.com/aziontech/azionapi-go-sdk v0.143.0/go.mod h1:cA5DY/VP4X5Eu11LpQNzNn83ziKjja7QVMIl4J45feA=
github.com/baidubce/bce-sdk-go v0.9.250 h1:fnvV5clsNCAP6pCauj0eNaUnoLVmjQGnco7rcMqp984=
github.com/baidubce/bce-sdk-go v0.9.250/go.mod h1:zbYJMQwE4IZuyrJiFO8tO8NbtYiKTFTbwh4eIsqjVdg=
github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o=
github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
@@ -197,15 +194,13 @@ github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEe
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/clbanning/mxj/v2 v2.5.5/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME=
github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
@@ -224,8 +219,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U=
github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE=
@@ -246,6 +239,7 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
@@ -259,45 +253,61 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-acme/alidns-20150109/v4 v4.5.10 h1:epLD0VaHR5XUpiM6mjm4MzQFICrk+zpuqDz2aO1/R/k=
github.com/go-acme/alidns-20150109/v4 v4.5.10/go.mod h1:qGRq8kD0xVgn82qRSQmhHwh/oWxKRjF4Db5OI4ScV5g=
github.com/go-acme/lego/v4 v4.25.2 h1:+D1Q+VnZrD+WJdlkgUEGHFFTcDrwGlE7q24IFtMmHDI=
github.com/go-acme/lego/v4 v4.25.2/go.mod h1:OORYyVNZPaNdIdVYCGSBNRNZDIjhQbPuFxwGDgWj/yM=
github.com/go-acme/tencentclouddnspod v1.0.1208 h1:xAVy1lmg2KcKKeYmFSBQUttwc1o1S++9QTjAotGC+BM=
github.com/go-acme/tencentclouddnspod v1.0.1208/go.mod h1:yxG02mkbbVd7lTb97nOn7oj09djhm7hAwxNQw4B9dpQ=
github.com/go-acme/alidns-20150109/v4 v4.6.1 h1:Dch3aWRcw4U62+jKPjPQN3iW3TPvgIywATbvHzojXeo=
github.com/go-acme/alidns-20150109/v4 v4.6.1/go.mod h1:RBcqBA5IvUWtlpjx6dC6EkPVyBNLQ+mR18XoaP38BFY=
github.com/go-acme/lego/v4 v4.28.0 h1:URKsCcybo7SjqqZckeBcDN9Vl29/bKS///75tcNkMHQ=
github.com/go-acme/lego/v4 v4.28.0/go.mod h1:bzjilr03IgbaOwlH396hq5W56Bi0/uoRwW/JM8hP7m4=
github.com/go-acme/tencentclouddnspod v1.1.10 h1:ERVJ4mc3cT4Nb3+n6H/c1AwZnChGBqLoymE0NVYscKI=
github.com/go-acme/tencentclouddnspod v1.1.10/go.mod h1:Bo/0YQJ/99FM+44HmCQkByuptX1tJsJ9V14MGV/2Qco=
github.com/go-acme/tencentedgdeone v1.1.48 h1:WLyLBsRVhSLFmtbEFXk0naLODSQn7X6J0Fc/qR8xVUk=
github.com/go-acme/tencentedgdeone v1.1.48/go.mod h1:mu6tA+bPhlSd+CKUfzRikE0mfxmTlBI6dVTn9LY9dRI=
github.com/go-cmd/cmd v1.0.5/go.mod h1:y8q8qlK5wQibcw63djSl/ntiHUHXHGdCkPk0j4QeW4s=
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-jose/go-jose/v4 v4.1.1 h1:JYhSgy4mXXzAdF3nUx3ygx347LRXJRrpgyU3adRmkAI=
github.com/go-jose/go-jose/v4 v4.1.1/go.mod h1:BdsZGqgdO3b6tTc6LSE56wcDbMMLuPsw5d4ZD5f94kA=
github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs=
github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ping/ping v1.1.0 h1:3MCGhVX4fyEUuhsfwPrsEdQw6xspHkv5zHsiSoDFZYw=
github.com/go-ping/ping v1.1.0/go.mod h1:xIFjORFzTxqIV/tDVGO4eDy/bLuSyawEeojSm3GfRGk=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o=
github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/go-resty/resty/v2 v2.16.5 h1:hBKqmWrr7uRc3euHVqmh1HTHcKn99Smr7o5spptdhTM=
github.com/go-resty/resty/v2 v2.16.5/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b h1:/vQ+oYKu+JoyaMPDsv5FzwuL2wwWBgBbtj/YLCi4LuA=
github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b/go.mod h1:Xo4aNUOrJnVruqWQJBtW6+bTBDTniY8yZum5rF3b5jw=
github.com/goccy/go-yaml v1.9.8 h1:5gMyLUeU1/6zl+WFfR1hN7D2kf+1/eRGa7DFtToiBvQ=
github.com/goccy/go-yaml v1.9.8/go.mod h1:JubOolP3gh0HpiBc4BLRD4YmjEjHAmIIB2aaXKkTfoE=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
@@ -307,8 +317,8 @@ github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzw
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -373,8 +383,8 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k=
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg=
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -433,8 +443,8 @@ github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0m
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.159 h1:6LZysc4iyO4cHB1aJsRklWfSEJr8CEhW7BmcM0SkYcU=
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.159/go.mod h1:Y/+YLCFCJtS29i2MbYPTUlNNfwXvkzEsZKR0imY/2aY=
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.173 h1:Y4ixGadyrK9xHw6Z+cyiiME3SBXepEcUoiT+B8C5FoQ=
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.173/go.mod h1:M+yna96Fx9o5GbIUnF3OvVvQGjgfVSyeJbV9Yb1z/wI=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df h1:MZf03xP9WdakyXhOWuAD5uPK3wHh96wCsqe3hCMKh8E=
@@ -443,16 +453,19 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt
github.com/infobloxopen/infoblox-go-client/v2 v2.10.0 h1:AKsihjFT/t6Y0keEv3p59DACcOuh0inWXdUB0ZOzYH0=
github.com/infobloxopen/infoblox-go-client/v2 v2.10.0/go.mod h1:NeNJpz09efw/edzqkVivGv1bWqBXTomqYBRFbP+XBqg=
github.com/jarcoal/httpmock v1.0.8/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik=
github.com/jarcoal/httpmock v1.4.0 h1:BvhqnH0JAYbNudL2GMJKgOHe2CtKlzJ/5rWKyp+hc2k=
github.com/jarcoal/httpmock v1.4.0/go.mod h1:ftW1xULwo+j0R0JJkJIIi7UKigZUXCLLanykgjwBXL0=
github.com/jarcoal/httpmock v1.4.1 h1:0Ju+VCFuARfFlhVXFc2HxlcQkfB+Xq12/EotHko+x2A=
github.com/jarcoal/httpmock v1.4.1/go.mod h1:ftW1xULwo+j0R0JJkJIIi7UKigZUXCLLanykgjwBXL0=
github.com/jellydator/ttlcache/v3 v3.4.0 h1:YS4P125qQS0tNhtL6aeYkheEaB/m8HCqdMMP4mnWdTY=
github.com/jellydator/ttlcache/v3 v3.4.0/go.mod h1:Hw9EgjymziQD3yGsQdf1FqFdpp7YjFMd4Srg5EJlgD4=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12 h1:9Nu54bhS/H/Kgo2/7xNSUuC5G28VR8ljfrLKU2G4IjU=
github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12/go.mod h1:TBzl5BIHNXfS9+C35ZyJaklL7mLDbgUkcgXzSLa8Tk0=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
@@ -483,12 +496,15 @@ github.com/labbsr0x/bindman-dns-webhook v1.0.2 h1:I7ITbmQPAVwrDdhd6dHKi+MYJTJqPC
github.com/labbsr0x/bindman-dns-webhook v1.0.2/go.mod h1:p6b+VCXIR8NYKpDr8/dg1HKfQoRHCdcsROXKvmoehKA=
github.com/labbsr0x/goh v1.0.1 h1:97aBJkDjpyBZGPbQuOK5/gHcSFbcr5aRsq3RSRJFpPk=
github.com/labbsr0x/goh v1.0.1/go.mod h1:8K2UhVoaWXcCU7Lxoa2omWnC8gyW8px7/lmO61c027w=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/likexian/gokit v0.25.13 h1:p2Uw3+6fGG53CwdU2Dz0T6bOycdb2+bAFAa3ymwWVkM=
github.com/likexian/gokit v0.25.13/go.mod h1:qQhEWFBEfqLCO3/vOEo2EDKd+EycekVtUK4tex+l2H4=
github.com/likexian/whois v1.15.1 h1:6vTMI8n9s1eJdmcO4R9h1x99aQWIZZX1CD3am68gApU=
github.com/likexian/whois v1.15.1/go.mod h1:/nxmQ6YXvLz+qTxC/QFtEJNAt0zLuRxJrKiWpBJX8X0=
github.com/linode/linodego v1.53.0 h1:UWr7bUUVMtcfsuapC+6blm6+jJLPd7Tf9MZUpdOERnI=
github.com/linode/linodego v1.53.0/go.mod h1:bI949fZaVchjWyKIA08hNyvAcV6BAS+PM2op3p7PAWA=
github.com/linode/linodego v1.60.0 h1:SgsebJFRCi+lSmYy+C40wmKZeJllGGm+W12Qw4+yVdI=
github.com/linode/linodego v1.60.0/go.mod h1:1+Bt0oTz5rBnDOJbGhccxn7LYVytXTIIfAy7QYmijDs=
github.com/liquidweb/go-lwApi v0.0.0-20190605172801-52a4864d2738/go.mod h1:0sYF9rMXb0vlG+4SzdiGMXHheCZxjguMq+Zb4S2BfBs=
github.com/liquidweb/liquidweb-cli v0.6.9 h1:acbIvdRauiwbxIsOCEMXGwF75aSJDbDiyAWPjVnwoYM=
github.com/liquidweb/liquidweb-cli v0.6.9/go.mod h1:cE1uvQ+x24NGUL75D0QagOFCG8Wdvmwu8aL9TLmA/eQ=
@@ -506,6 +522,7 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
@@ -519,8 +536,8 @@ github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02C
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.27/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/miekg/dns v1.1.47/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
github.com/miekg/dns v1.1.67 h1:kg0EHj0G4bfT5/oOys6HhZw4vmMlnoZ+gDu8tJ/AlI0=
github.com/miekg/dns v1.1.67/go.mod h1:fujopn7TB3Pu3JM69XaawiU0wqjpL9/8xGop5UrTPps=
github.com/miekg/dns v1.1.68 h1:jsSRkNozw7G/mnmXULynzMNIsgY2dHC8LO6U6Ij2JEA=
github.com/miekg/dns v1.1.68/go.mod h1:fujopn7TB3Pu3JM69XaawiU0wqjpL9/8xGop5UrTPps=
github.com/mimuret/golang-iij-dpf v0.9.1 h1:Gj6EhHJkOhr+q2RnvRPJsPMcjuVnWPSccEHyoEehU34=
github.com/mimuret/golang-iij-dpf v0.9.1/go.mod h1:sl9KyOkESib9+KRD3HaGpgi1xk7eoN2+d96LCLsME2M=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
@@ -559,24 +576,28 @@ github.com/namedotcom/go/v4 v4.0.2/go.mod h1:J6sVueHMb0qbarPgdhrzEVhEaYp+R1SCaTG
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nrdcg/auroradns v1.1.0 h1:KekGh8kmf2MNwqZVVYo/fw/ZONt8QMEmbMFOeljteWo=
github.com/nrdcg/auroradns v1.1.0/go.mod h1:O7tViUZbAcnykVnrGkXzIJTHoQCHcgalgAe6X1mzHfk=
github.com/nrdcg/bunny-go v0.0.0-20250327222614-988a091fc7ea h1:OSgRS4kqOs/WuxuFOObP2gwrenL4/qiKXQbQugr/Two=
github.com/nrdcg/bunny-go v0.0.0-20250327222614-988a091fc7ea/go.mod h1:IDRRngAngb2eTEaWgpO0hukQFI/vJId46fT1KErMytA=
github.com/nrdcg/desec v0.11.0 h1:XZVHy07sg12y8FozMp+l7XvzPsdzog0AYXuQMaHBsfs=
github.com/nrdcg/desec v0.11.0/go.mod h1:5+4vyhMRTs49V9CNoODF/HwT8Mwxv9DJ6j+7NekUnBs=
github.com/nrdcg/bunny-go v0.1.0 h1:GAHTRpHaG/TxfLZlqoJ8OJFzw8rI74+jOTkzxWh0uHA=
github.com/nrdcg/bunny-go v0.1.0/go.mod h1:u+C9dgsspgtWVaAz6QkyV17s9fxD8viwwKoxb9XMz1A=
github.com/nrdcg/desec v0.11.1 h1:ilpKmCr4gGsLcyq3RHfHNmlRzm9fzT2XbWxoVaUCS0s=
github.com/nrdcg/desec v0.11.1/go.mod h1:2LuxHlOcwML/7cntu0eimONmA1U+ZxFDAonoSXr4igQ=
github.com/nrdcg/dnspod-go v0.4.0 h1:c/jn1mLZNKF3/osJ6mz3QPxTudvPArXTjpkmYj0uK6U=
github.com/nrdcg/dnspod-go v0.4.0/go.mod h1:vZSoFSFeQVm2gWLMkyX61LZ8HI3BaqtHZWgPTGKr6KQ=
github.com/nrdcg/freemyip v0.3.0 h1:0D2rXgvLwe2RRaVIjyUcQ4S26+cIS2iFwnhzDsEuuwc=
github.com/nrdcg/freemyip v0.3.0/go.mod h1:c1PscDvA0ukBF0dwelU/IwOakNKnVxetpAQ863RMJoM=
github.com/nrdcg/goacmedns v0.2.0 h1:ADMbThobzEMnr6kg2ohs4KGa3LFqmgiBA22/6jUWJR0=
github.com/nrdcg/goacmedns v0.2.0/go.mod h1:T5o6+xvSLrQpugmwHvrSNkzWht0UGAwj2ACBMhh73Cg=
github.com/nrdcg/goinwx v0.11.0 h1:GER0SE3POub7rxARt3Y3jRy1OON1hwF1LRxHz5xsFBw=
github.com/nrdcg/goinwx v0.11.0/go.mod h1:0BXSC0FxVtU4aTjX0Zw3x0DK32tjugLzeNIAGtwXvPQ=
github.com/nrdcg/mailinabox v0.2.0 h1:IKq8mfKiVwNW2hQii/ng1dJ4yYMMv3HAP3fMFIq2CFk=
github.com/nrdcg/mailinabox v0.2.0/go.mod h1:0yxqeYOiGyxAu7Sb94eMxHPIOsPYXAjTeA9ZhePhGnc=
github.com/nrdcg/namesilo v0.2.1 h1:kLjCjsufdW/IlC+iSfAqj0iQGgKjlbUUeDJio5Y6eMg=
github.com/nrdcg/namesilo v0.2.1/go.mod h1:lwMvfQTyYq+BbjJd30ylEG4GPSS6PII0Tia4rRpRiyw=
github.com/nrdcg/mailinabox v0.3.0 h1:PHkC1elKXKAjEvdx2HHFMgcEGZFqudAl7aU3L2JDhM4=
github.com/nrdcg/mailinabox v0.3.0/go.mod h1:1eFIGcM4lI+AfFOUpbs548SFGz1ZWoMOGbECBmkghw4=
github.com/nrdcg/namesilo v0.5.0 h1:6QNxT/XxE+f5B+7QlfWorthNzOzcGlBLRQxqi6YeBrE=
github.com/nrdcg/namesilo v0.5.0/go.mod h1:4UkwlwQfDt74kSGmhLaDylnBrD94IfflnpoEaj6T2qw=
github.com/nrdcg/nodion v0.1.0 h1:zLKaqTn2X0aDuBHHfyA1zFgeZfiCpmu/O9DM73okavw=
github.com/nrdcg/nodion v0.1.0/go.mod h1:inbuh3neCtIWlMPZHtEpe43TmRXxHV6+hk97iCZicms=
github.com/nrdcg/porkbun v0.4.0 h1:rWweKlwo1PToQ3H+tEO9gPRW0wzzgmI/Ob3n2Guticw=
github.com/nrdcg/porkbun v0.4.0/go.mod h1:/QMskrHEIM0IhC/wY7iTCUgINsxdT2WcOphktJ9+Q54=
github.com/nrdcg/vegadns v0.3.0 h1:11FQMw7xVIRUWO9o5+Z/5YZhmPWlm4oxUUH3F6EVqQU=
github.com/nrdcg/vegadns v0.3.0/go.mod h1:NqSyRKZuJlAsv8VI/7rSubfPXN68NwaJ0aG9KxQVFVo=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
@@ -590,15 +611,15 @@ github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
github.com/onsi/ginkgo/v2 v2.20.1 h1:YlVIbqct+ZmnEph770q9Q7NVAz4wwIiVNahee6JyUzo=
github.com/onsi/ginkgo/v2 v2.20.1/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI=
github.com/onsi/ginkgo/v2 v2.23.3 h1:edHxnszytJ4lD9D5Jjc4tiDkPBZ3siDeJJkUZJJVkp0=
github.com/onsi/ginkgo/v2 v2.23.3/go.mod h1:zXTP6xIp3U8aVuXN8ENK9IXRaTjFnpVB9mGmaSRvxnM=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y=
github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
@@ -644,8 +665,6 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/redis/go-redis/v9 v9.8.0 h1:q3nRvjrlge/6UD7eTu/DSg2uYiU2mCL0G/uzBWqhicI=
github.com/redis/go-redis/v9 v9.8.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
github.com/regfish/regfish-dnsapi-go v0.1.1 h1:TJFtbePHkd47q5GZwYl1h3DIYXmoxdLjW/SBsPtB5IE=
github.com/regfish/regfish-dnsapi-go v0.1.1/go.mod h1:ubIgXSfqarSnl3XHSn8hIFwFF3h0yrq0ZiWD93Y2VjY=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
@@ -654,16 +673,16 @@ github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sacloud/api-client-go v0.3.2 h1:INbdSpQbyGN9Ai4hQ+Gbv3UQcgtRPG2tJrOmqT7HGl0=
github.com/sacloud/api-client-go v0.3.2/go.mod h1:0p3ukcWYXRCc2AUWTl1aA+3sXLvurvvDqhRaLZRLBwo=
github.com/sacloud/api-client-go v0.3.3 h1:ZpSAyGpITA8UFO3Hq4qMHZLGuNI1FgxAxo4sqBnCKDs=
github.com/sacloud/api-client-go v0.3.3/go.mod h1:0p3ukcWYXRCc2AUWTl1aA+3sXLvurvvDqhRaLZRLBwo=
github.com/sacloud/go-http v0.1.9 h1:Xa5PY8/pb7XWhwG9nAeXSrYXPbtfBWqawgzxD5co3VE=
github.com/sacloud/go-http v0.1.9/go.mod h1:DpDG+MSyxYaBwPJ7l3aKLMzwYdTVtC5Bo63HActcgoE=
github.com/sacloud/iaas-api-go v1.16.1 h1:B5Lec9WyZkrOCjtGkVuPn5RxDm/zCzazVsHh7BQIjYQ=
github.com/sacloud/iaas-api-go v1.16.1/go.mod h1:QVPHLwYzpECMsuml55I3FWAggsb4XSuzYGE9re/SkrQ=
github.com/sacloud/iaas-api-go v1.20.0 h1:L4TfAzoFSwxrD3QXX8UxJa2o+GZrP9b863K+voTy3tQ=
github.com/sacloud/iaas-api-go v1.20.0/go.mod h1:XV995RM1I7k5AHb7UZrCVyDF/8bZXDxa+uk1EXoj/Zs=
github.com/sacloud/packages-go v0.0.11 h1:hrRWLmfPM9w7GBs6xb5/ue6pEMl8t1UuDKyR/KfteHo=
github.com/sacloud/packages-go v0.0.11/go.mod h1:XNF5MCTWcHo9NiqWnYctVbASSSZR3ZOmmQORIzcurJ8=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.34 h1:48+VFHsyVcAHIN2v1Ao9v1/RkjJS5AwctFucBrfYNIA=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.34/go.mod h1:zFWiHphneiey3s8HOtAEnGrRlWivNaxW5T6d5Xfco7g=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.35 h1:8xfn1RzeI9yoCUuEwDy08F+No6PcKZGEDOQ6hrRyLts=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.35/go.mod h1:47B1d/YXmSAxlJxUJxClzHR6b3T4M1WyCvwENPQNBWc=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/shirou/gopsutil/v4 v4.25.1 h1:QSWkTc+fu9LTAWfkZwZ6j8MSUk4A2LV7rbH0ZqmLjXs=
github.com/shirou/gopsutil/v4 v4.25.1/go.mod h1:RoUCUpndaJFtT+2zsZzzmhvbfGoDCJ7nFXKJf8GqJbI=
@@ -683,8 +702,8 @@ github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/smartystreets/gunit v1.0.4 h1:tpTjnuH7MLlqhoD21vRoMZbMIi5GmBsAJDFyF67GhZA=
github.com/smartystreets/gunit v1.0.4/go.mod h1:EH5qMBab2UclzXUcpR8b93eHsIlp9u+pDQIRp5DZNzQ=
github.com/softlayer/softlayer-go v1.1.7 h1:SgTL+pQZt1h+5QkAhVmHORM/7N9c1X0sljJhuOIHxWE=
github.com/softlayer/softlayer-go v1.1.7/go.mod h1:WeJrBLoTJcaT8nO1azeyHyNpo/fDLtbpbvh+pzts+Qw=
github.com/softlayer/softlayer-go v1.2.1 h1:8ucHxn5laVsVPb0/aMGnr6tOMt1I9BgEtU5mn70OGKw=
github.com/softlayer/softlayer-go v1.2.1/go.mod h1:Gz9/ktcmB7Z8EJlu+QEJJpkv8lAmnhYdB9Tc6gedjmo=
github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e h1:3OgWYFw7jxCZPcvAg+4R8A50GZ+CCkARF10lxu2qDsQ=
github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e/go.mod h1:fKZCUVdirrxrBpwd9wb+lSoVixvpwAu8eHzbQB2tums=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
@@ -693,8 +712,8 @@ github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B
github.com/spf13/afero v1.4.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w=
github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
@@ -706,6 +725,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
@@ -714,37 +734,38 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1208/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1210 h1:waSk2KyI2VvXtR+XQJm0v1lWfgbJg51iSWJh4hWnyeo=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1210/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.1.10/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.1.48 h1:aoRUrz2ag27jQWcOKHgeE+toSti6/xPqHKMLruOtJuM=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.1.48/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/transip/gotransip/v6 v6.26.0 h1:Aejfvh8rSp8Mj2GX/RpdBjMCv+Iy/DmgfNgczPDP550=
github.com/transip/gotransip/v6 v6.26.0/go.mod h1:x0/RWGRK/zob817O3tfO2xhFoP1vu8YOHORx6Jpk80s=
github.com/ultradns/ultradns-go-sdk v1.8.0-20241010134910-243eeec h1:2s/ghQ8wKE+UzD/hf3P4Gd1j0JI9ncbxv+nsypPoUYI=
github.com/ultradns/ultradns-go-sdk v1.8.0-20241010134910-243eeec/go.mod h1:BZr7Qs3ku1ckpqed8tCRSqTlp8NAeZfAVpfx4OzXMss=
github.com/transip/gotransip/v6 v6.26.1 h1:MeqIjkTBBsZwWAK6giZyMkqLmKMclVHEuTNmoBdx4MA=
github.com/transip/gotransip/v6 v6.26.1/go.mod h1:x0/RWGRK/zob817O3tfO2xhFoP1vu8YOHORx6Jpk80s=
github.com/ultradns/ultradns-go-sdk v1.8.1-20250722213956-faef419 h1:/VaznPrb/b68e3iMvkr27fU7JqPKU4j7tIITZnjQX1k=
github.com/ultradns/ultradns-go-sdk v1.8.1-20250722213956-faef419/go.mod h1:QN0/PdenvYWB0GRMz6JJbPeZz2Lph2iys1p8AFVHm2c=
github.com/vinyldns/go-vinyldns v0.9.16 h1:GZJStDkcCk1F1AcRc64LuuMh+ENL8pHA0CVd4ulRMcQ=
github.com/vinyldns/go-vinyldns v0.9.16/go.mod h1:5qIJOdmzAnatKjurI+Tl4uTus7GJKJxb+zitufjHs3Q=
github.com/vultr/govultr/v3 v3.21.1 h1:0cnA8fXiqayPGbAlNHaW+5oCQjpDNkkAm3Nt3LOHplM=
github.com/vultr/govultr/v3 v3.21.1/go.mod h1:9WwnWGCKnwDlNjHjtt+j+nP+0QWq6hQXzaHgddqrLWY=
github.com/vultr/govultr/v3 v3.24.0 h1:fTTTj0VBve+Miy+wGhlb90M2NMDfpGFi6Frlj3HVy6M=
github.com/vultr/govultr/v3 v3.24.0/go.mod h1:9WwnWGCKnwDlNjHjtt+j+nP+0QWq6hQXzaHgddqrLWY=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/yandex-cloud/go-genproto v0.14.0 h1:yDqD260mICkjodXyAaDhESfrLr6gIGwwRc9MYE0jvW0=
github.com/yandex-cloud/go-genproto v0.14.0/go.mod h1:0LDD/IZLIUIV4iPH+YcF+jysO3jkSvADFGm4dCAuwQo=
github.com/yandex-cloud/go-sdk/services/dns v0.0.3 h1:erphTBXKSpm/tETa6FXrw4niSHjhySzAKHUc2/BZKx0=
github.com/yandex-cloud/go-sdk/services/dns v0.0.3/go.mod h1:lbBaFJVouETfVnd3YzNF5vW6vgYR2FVfGLUzLexyGlI=
github.com/yandex-cloud/go-sdk/v2 v2.0.8 h1:wQNIzEZYnClSQyo2fjEgnGEErWjJNBpSAinaKcP+VSg=
github.com/yandex-cloud/go-sdk/v2 v2.0.8/go.mod h1:9Gqpq7d0EUAS+H2OunILtMi3hmMPav+fYoy9rmydM4s=
github.com/yandex-cloud/go-genproto v0.34.0 h1:qhTJpPxOTKQbV44rIqoZSdzxDtZW27fkFjAcipEy8Zs=
github.com/yandex-cloud/go-genproto v0.34.0/go.mod h1:0LDD/IZLIUIV4iPH+YcF+jysO3jkSvADFGm4dCAuwQo=
github.com/yandex-cloud/go-sdk/services/dns v0.0.16 h1:0UYrBlQjTO2ct5xcSx6rqkQB95wRBPMVwxfqLQD1sUE=
github.com/yandex-cloud/go-sdk/services/dns v0.0.16/go.mod h1:HlS3aIAdYEmJu2Ska/nzpcuv9LLVSMMXKGhzyLQwf5s=
github.com/yandex-cloud/go-sdk/v2 v2.24.0 h1:G53N/RB5g/jw2xNN0egspnwd2ByHA1OVH6wbTx/tIlo=
github.com/yandex-cloud/go-sdk/v2 v2.24.0/go.mod h1:ZRdpyOig8c/W3bNhwvkeXWWPeDScd9nmXv4AJzKvOsk=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -767,20 +788,20 @@ go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJyS
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 h1:QY7/0NeRPKlzusf40ZE4t1VlMKbqSNT7cJRYzWuja0s=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0/go.mod h1:HVkSiDhTM9BoUJU8qE6j2eSWLLXvi1USXjyd2BXT8PY=
go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=
go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=
go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis=
go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4=
go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc=
go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94=
go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
@@ -820,8 +841,8 @@ golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDf
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -832,8 +853,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20241210194714-1829a127f884 h1:Y/Mj/94zIQQGHVSv1tTtQBDaQaJe62U9bkDZKKyhPCU=
golang.org/x/exp v0.0.0-20241210194714-1829a127f884/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -860,8 +879,8 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=
golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U=
golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -915,16 +934,16 @@ golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY=
golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -940,8 +959,8 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -999,9 +1018,11 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220406163625-3f8b81556e12/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -1014,8 +1035,8 @@ golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -1029,8 +1050,8 @@ golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg=
golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0=
golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q=
golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1046,14 +1067,14 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -1107,12 +1128,16 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE=
golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
@@ -1164,10 +1189,10 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7 h1:FiusG7LWj+4byqhbvmB+Q93B/mOxJLN2DTozDuZm4EU=
google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:kXqgZtrWaf6qS3jZOCnCH7WYfrvFjkC51bM8fz3RsCA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 h1:pFyd6EwwL2TqFf8emdthzeX+gZE1ElRq3iM8pui4KBY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
google.golang.org/genproto/googleapis/api v0.0.0-20250818200422-3122310a409c h1:AtEkQdl5b6zsybXcbz00j1LwNodDuH6hVifIaNqk7NQ=
google.golang.org/genproto/googleapis/api v0.0.0-20250818200422-3122310a409c/go.mod h1:ea2MjsO70ssTfCjiwHgI0ZFqcw45Ksuk2ckf9G468GA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk=
google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@@ -1180,8 +1205,8 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok=
google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc=
google.golang.org/grpc v1.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A=
google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -1195,8 +1220,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -1211,8 +1236,8 @@ gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ns1/ns1-go.v2 v2.14.4 h1:77eP71rZ24I+9k1gITgjJXRyJzzmflA9oPUkYPB/wyc=
gopkg.in/ns1/ns1-go.v2 v2.14.4/go.mod h1:pfaU0vECVP7DIOr453z03HXS6dFJpXdNRwOyRzwmPSc=
gopkg.in/ns1/ns1-go.v2 v2.15.1 h1:8rri2TzAPYcVbBGXn48+dz1Xg30PzHfZ4k8A9JOS0Z0=
gopkg.in/ns1/ns1-go.v2 v2.15.1/go.mod h1:pfaU0vECVP7DIOr453z03HXS6dFJpXdNRwOyRzwmPSc=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=

View File

@@ -508,8 +508,8 @@ func (a *ACMEHandler) HandleRenewCertificate(w http.ResponseWriter, r *http.Requ
dns = true
}
// Default propagation timeout is 300 seconds
propagationTimeout := 300
// Default propagation timeout is 600 seconds (10 minutes)
propagationTimeout := 600
if dns {
ppgTimeout, err := utils.PostPara(r, "ppgTimeout")
if err == nil {

View File

@@ -9,9 +9,11 @@ import (
"time"
"github.com/go-acme/lego/v4/challenge"
"github.com/go-acme/lego/v4/providers/dns/acmedns"
"github.com/go-acme/lego/v4/providers/dns/active24"
"github.com/go-acme/lego/v4/providers/dns/alidns"
"github.com/go-acme/lego/v4/providers/dns/allinkl"
"github.com/go-acme/lego/v4/providers/dns/anexia"
"github.com/go-acme/lego/v4/providers/dns/arvancloud"
"github.com/go-acme/lego/v4/providers/dns/auroradns"
"github.com/go-acme/lego/v4/providers/dns/autodns"
@@ -20,6 +22,8 @@ import (
"github.com/go-acme/lego/v4/providers/dns/azure"
"github.com/go-acme/lego/v4/providers/dns/azuredns"
"github.com/go-acme/lego/v4/providers/dns/baiducloud"
"github.com/go-acme/lego/v4/providers/dns/beget"
"github.com/go-acme/lego/v4/providers/dns/binarylane"
"github.com/go-acme/lego/v4/providers/dns/bindman"
"github.com/go-acme/lego/v4/providers/dns/bluecat"
"github.com/go-acme/lego/v4/providers/dns/bookmyname"
@@ -51,6 +55,7 @@ import (
"github.com/go-acme/lego/v4/providers/dns/dyndnsfree"
"github.com/go-acme/lego/v4/providers/dns/dynu"
"github.com/go-acme/lego/v4/providers/dns/easydns"
"github.com/go-acme/lego/v4/providers/dns/edgeone"
"github.com/go-acme/lego/v4/providers/dns/efficientip"
"github.com/go-acme/lego/v4/providers/dns/epik"
"github.com/go-acme/lego/v4/providers/dns/f5xc"
@@ -63,6 +68,7 @@ import (
"github.com/go-acme/lego/v4/providers/dns/googledomains"
"github.com/go-acme/lego/v4/providers/dns/hetzner"
"github.com/go-acme/lego/v4/providers/dns/hostingde"
"github.com/go-acme/lego/v4/providers/dns/hostinger"
"github.com/go-acme/lego/v4/providers/dns/hosttech"
"github.com/go-acme/lego/v4/providers/dns/httpnet"
"github.com/go-acme/lego/v4/providers/dns/huaweicloud"
@@ -78,6 +84,7 @@ import (
"github.com/go-acme/lego/v4/providers/dns/ipv64"
"github.com/go-acme/lego/v4/providers/dns/iwantmyname"
"github.com/go-acme/lego/v4/providers/dns/joker"
"github.com/go-acme/lego/v4/providers/dns/keyhelp"
"github.com/go-acme/lego/v4/providers/dns/liara"
"github.com/go-acme/lego/v4/providers/dns/lightsail"
"github.com/go-acme/lego/v4/providers/dns/limacity"
@@ -104,6 +111,7 @@ import (
"github.com/go-acme/lego/v4/providers/dns/njalla"
"github.com/go-acme/lego/v4/providers/dns/nodion"
"github.com/go-acme/lego/v4/providers/dns/ns1"
"github.com/go-acme/lego/v4/providers/dns/octenium"
"github.com/go-acme/lego/v4/providers/dns/otc"
"github.com/go-acme/lego/v4/providers/dns/ovh"
"github.com/go-acme/lego/v4/providers/dns/pdns"
@@ -141,6 +149,7 @@ import (
"github.com/go-acme/lego/v4/providers/dns/vscale"
"github.com/go-acme/lego/v4/providers/dns/vultr"
"github.com/go-acme/lego/v4/providers/dns/webnames"
"github.com/go-acme/lego/v4/providers/dns/webnamesca"
"github.com/go-acme/lego/v4/providers/dns/websupport"
"github.com/go-acme/lego/v4/providers/dns/wedos"
"github.com/go-acme/lego/v4/providers/dns/westcn"
@@ -160,6 +169,13 @@ func GetDNSProviderByJsonConfig(name string, js string, propagationTimeout int64
plInterval := time.Duration(pollingInterval) * time.Second
switch name {
case "acmedns":
cfg := acmedns.NewDefaultConfig()
err := json.Unmarshal([]byte(js), &cfg)
if err != nil {
return nil, err
}
return acmedns.NewDNSProviderConfig(cfg)
case "active24":
cfg := active24.NewDefaultConfig()
err := json.Unmarshal([]byte(js), &cfg)
@@ -187,6 +203,15 @@ func GetDNSProviderByJsonConfig(name string, js string, propagationTimeout int64
cfg.PropagationTimeout = pgDuration
cfg.PollingInterval = plInterval
return allinkl.NewDNSProviderConfig(cfg)
case "anexia":
cfg := anexia.NewDefaultConfig()
err := json.Unmarshal([]byte(js), &cfg)
if err != nil {
return nil, err
}
cfg.PropagationTimeout = pgDuration
cfg.PollingInterval = plInterval
return anexia.NewDNSProviderConfig(cfg)
case "arvancloud":
cfg := arvancloud.NewDefaultConfig()
err := json.Unmarshal([]byte(js), &cfg)
@@ -259,6 +284,24 @@ func GetDNSProviderByJsonConfig(name string, js string, propagationTimeout int64
cfg.PropagationTimeout = pgDuration
cfg.PollingInterval = plInterval
return baiducloud.NewDNSProviderConfig(cfg)
case "beget":
cfg := beget.NewDefaultConfig()
err := json.Unmarshal([]byte(js), &cfg)
if err != nil {
return nil, err
}
cfg.PropagationTimeout = pgDuration
cfg.PollingInterval = plInterval
return beget.NewDNSProviderConfig(cfg)
case "binarylane":
cfg := binarylane.NewDefaultConfig()
err := json.Unmarshal([]byte(js), &cfg)
if err != nil {
return nil, err
}
cfg.PropagationTimeout = pgDuration
cfg.PollingInterval = plInterval
return binarylane.NewDNSProviderConfig(cfg)
case "bindman":
cfg := bindman.NewDefaultConfig()
err := json.Unmarshal([]byte(js), &cfg)
@@ -538,6 +581,15 @@ func GetDNSProviderByJsonConfig(name string, js string, propagationTimeout int64
cfg.PropagationTimeout = pgDuration
cfg.PollingInterval = plInterval
return easydns.NewDNSProviderConfig(cfg)
case "edgeone":
cfg := edgeone.NewDefaultConfig()
err := json.Unmarshal([]byte(js), &cfg)
if err != nil {
return nil, err
}
cfg.PropagationTimeout = pgDuration
cfg.PollingInterval = plInterval
return edgeone.NewDNSProviderConfig(cfg)
case "efficientip":
cfg := efficientip.NewDefaultConfig()
err := json.Unmarshal([]byte(js), &cfg)
@@ -646,6 +698,15 @@ func GetDNSProviderByJsonConfig(name string, js string, propagationTimeout int64
cfg.PropagationTimeout = pgDuration
cfg.PollingInterval = plInterval
return hostingde.NewDNSProviderConfig(cfg)
case "hostinger":
cfg := hostinger.NewDefaultConfig()
err := json.Unmarshal([]byte(js), &cfg)
if err != nil {
return nil, err
}
cfg.PropagationTimeout = pgDuration
cfg.PollingInterval = plInterval
return hostinger.NewDNSProviderConfig(cfg)
case "hosttech":
cfg := hosttech.NewDefaultConfig()
err := json.Unmarshal([]byte(js), &cfg)
@@ -781,6 +842,15 @@ func GetDNSProviderByJsonConfig(name string, js string, propagationTimeout int64
cfg.PropagationTimeout = pgDuration
cfg.PollingInterval = plInterval
return joker.NewDNSProviderConfig(cfg)
case "keyhelp":
cfg := keyhelp.NewDefaultConfig()
err := json.Unmarshal([]byte(js), &cfg)
if err != nil {
return nil, err
}
cfg.PropagationTimeout = pgDuration
cfg.PollingInterval = plInterval
return keyhelp.NewDNSProviderConfig(cfg)
case "liara":
cfg := liara.NewDefaultConfig()
err := json.Unmarshal([]byte(js), &cfg)
@@ -1015,6 +1085,15 @@ func GetDNSProviderByJsonConfig(name string, js string, propagationTimeout int64
cfg.PropagationTimeout = pgDuration
cfg.PollingInterval = plInterval
return ns1.NewDNSProviderConfig(cfg)
case "octenium":
cfg := octenium.NewDefaultConfig()
err := json.Unmarshal([]byte(js), &cfg)
if err != nil {
return nil, err
}
cfg.PropagationTimeout = pgDuration
cfg.PollingInterval = plInterval
return octenium.NewDNSProviderConfig(cfg)
case "otc":
cfg := otc.NewDefaultConfig()
err := json.Unmarshal([]byte(js), &cfg)
@@ -1348,6 +1427,15 @@ func GetDNSProviderByJsonConfig(name string, js string, propagationTimeout int64
cfg.PropagationTimeout = pgDuration
cfg.PollingInterval = plInterval
return webnames.NewDNSProviderConfig(cfg)
case "webnamesca":
cfg := webnamesca.NewDefaultConfig()
err := json.Unmarshal([]byte(js), &cfg)
if err != nil {
return nil, err
}
cfg.PropagationTimeout = pgDuration
cfg.PollingInterval = plInterval
return webnamesca.NewDNSProviderConfig(cfg)
case "websupport":
cfg := websupport.NewDefaultConfig()
err := json.Unmarshal([]byte(js), &cfg)

View File

@@ -1,4 +1,27 @@
{
"acmedns": {
"Name": "acmedns",
"ConfigableFields": [
{
"Title": "APIBase",
"Datatype": "string"
},
{
"Title": "StoragePath",
"Datatype": "string"
},
{
"Title": "StorageBaseURL",
"Datatype": "string"
}
],
"HiddenFields": [
{
"Title": "AllowList",
"Datatype": "[]string"
}
]
},
"active24": {
"Name": "active24",
"ConfigableFields": [
@@ -87,6 +110,33 @@
}
]
},
"anexia": {
"Name": "anexia",
"ConfigableFields": [
{
"Title": "Token",
"Datatype": "string"
},
{
"Title": "APIURL",
"Datatype": "string"
},
{
"Title": "PropagationTimeout",
"Datatype": "time.Duration"
},
{
"Title": "PollingInterval",
"Datatype": "time.Duration"
}
],
"HiddenFields": [
{
"Title": "HTTPClient",
"Datatype": "*http.Client"
}
]
},
"arvancloud": {
"Name": "arvancloud",
"ConfigableFields": [
@@ -327,6 +377,14 @@
"Title": "OIDCRequestToken",
"Datatype": "string"
},
{
"Title": "ServiceConnectionID",
"Datatype": "string"
},
{
"Title": "SystemAccessToken",
"Datatype": "string"
},
{
"Title": "AuthMethod",
"Datatype": "string"
@@ -381,6 +439,56 @@
],
"HiddenFields": []
},
"beget": {
"Name": "beget",
"ConfigableFields": [
{
"Title": "Username",
"Datatype": "string"
},
{
"Title": "Password",
"Datatype": "string"
},
{
"Title": "PropagationTimeout",
"Datatype": "time.Duration"
},
{
"Title": "PollingInterval",
"Datatype": "time.Duration"
}
],
"HiddenFields": [
{
"Title": "HTTPClient",
"Datatype": "*http.Client"
}
]
},
"binarylane": {
"Name": "binarylane",
"ConfigableFields": [
{
"Title": "APIToken",
"Datatype": "string"
},
{
"Title": "PropagationTimeout",
"Datatype": "time.Duration"
},
{
"Title": "PollingInterval",
"Datatype": "time.Duration"
}
],
"HiddenFields": [
{
"Title": "HTTPClient",
"Datatype": "*http.Client"
}
]
},
"bindman": {
"Name": "bindman",
"ConfigableFields": [
@@ -521,7 +629,12 @@
"Datatype": "time.Duration"
}
],
"HiddenFields": []
"HiddenFields": [
{
"Title": "HTTPClient",
"Datatype": "*http.Client"
}
]
},
"checkdomain": {
"Name": "checkdomain",
@@ -1272,6 +1385,36 @@
}
]
},
"edgeone": {
"Name": "edgeone",
"ConfigableFields": [
{
"Title": "SecretID",
"Datatype": "string"
},
{
"Title": "SecretKey",
"Datatype": "string"
},
{
"Title": "Region",
"Datatype": "string"
},
{
"Title": "SessionToken",
"Datatype": "string"
},
{
"Title": "PropagationTimeout",
"Datatype": "time.Duration"
},
{
"Title": "PollingInterval",
"Datatype": "time.Duration"
}
],
"HiddenFields": []
},
"efficientip": {
"Name": "efficientip",
"ConfigableFields": [
@@ -1549,6 +1692,10 @@
"Title": "APIKey",
"Datatype": "string"
},
{
"Title": "APIToken",
"Datatype": "string"
},
{
"Title": "PropagationTimeout",
"Datatype": "time.Duration"
@@ -1592,6 +1739,29 @@
}
]
},
"hostinger": {
"Name": "hostinger",
"ConfigableFields": [
{
"Title": "APIToken",
"Datatype": "string"
},
{
"Title": "PropagationTimeout",
"Datatype": "time.Duration"
},
{
"Title": "PollingInterval",
"Datatype": "time.Duration"
}
],
"HiddenFields": [
{
"Title": "HTTPClient",
"Datatype": "*http.Client"
}
]
},
"hosttech": {
"Name": "hosttech",
"ConfigableFields": [
@@ -2029,6 +2199,33 @@
}
]
},
"keyhelp": {
"Name": "keyhelp",
"ConfigableFields": [
{
"Title": "BaseURL",
"Datatype": "string"
},
{
"Title": "APIKey",
"Datatype": "string"
},
{
"Title": "PropagationTimeout",
"Datatype": "time.Duration"
},
{
"Title": "PollingInterval",
"Datatype": "time.Duration"
}
],
"HiddenFields": [
{
"Title": "HTTPClient",
"Datatype": "*http.Client"
}
]
},
"liara": {
"Name": "liara",
"ConfigableFields": [
@@ -2227,7 +2424,12 @@
"Datatype": "time.Duration"
}
],
"HiddenFields": []
"HiddenFields": [
{
"Title": "HTTPClient",
"Datatype": "*http.Client"
}
]
},
"manageengine": {
"Name": "manageengine",
@@ -2711,13 +2913,32 @@
}
]
},
"octenium": {
"Name": "octenium",
"ConfigableFields": [
{
"Title": "APIKey",
"Datatype": "string"
},
{
"Title": "PropagationTimeout",
"Datatype": "time.Duration"
},
{
"Title": "PollingInterval",
"Datatype": "time.Duration"
}
],
"HiddenFields": [
{
"Title": "HTTPClient",
"Datatype": "*http.Client"
}
]
},
"otc": {
"Name": "otc",
"ConfigableFields": [
{
"Title": "IdentityEndpoint",
"Datatype": "string"
},
{
"Title": "DomainName",
"Datatype": "string"
@@ -2734,6 +2955,10 @@
"Title": "Password",
"Datatype": "string"
},
{
"Title": "IdentityEndpoint",
"Datatype": "string"
},
{
"Title": "PropagationTimeout",
"Datatype": "time.Duration"
@@ -2744,6 +2969,10 @@
}
],
"HiddenFields": [
{
"Title": "PrivateZone",
"Datatype": "bool"
},
{
"Title": "HTTPClient",
"Datatype": "*http.Client"
@@ -3211,7 +3440,12 @@
"Datatype": "time.Duration"
}
],
"HiddenFields": []
"HiddenFields": [
{
"Title": "HTTPClient",
"Datatype": "*http.Client"
}
]
},
"selectel": {
"Name": "selectel",
@@ -3517,6 +3751,10 @@
{
"Title": "TTL",
"Datatype": "int64"
},
{
"Title": "HTTPClient",
"Datatype": "*http.Client"
}
]
},
@@ -3593,7 +3831,12 @@
"Datatype": "time.Duration"
}
],
"HiddenFields": []
"HiddenFields": [
{
"Title": "HTTPClient",
"Datatype": "*http.Client"
}
]
},
"vercel": {
"Name": "vercel",
@@ -3681,6 +3924,10 @@
{
"Title": "QuoteValue",
"Datatype": "bool"
},
{
"Title": "HTTPClient",
"Datatype": "*http.Client"
}
]
},
@@ -3795,6 +4042,33 @@
}
]
},
"webnamesca": {
"Name": "webnamesca",
"ConfigableFields": [
{
"Title": "APIUser",
"Datatype": "string"
},
{
"Title": "APIKey",
"Datatype": "string"
},
{
"Title": "PropagationTimeout",
"Datatype": "time.Duration"
},
{
"Title": "PollingInterval",
"Datatype": "time.Duration"
}
],
"HiddenFields": [
{
"Title": "HTTPClient",
"Datatype": "*http.Client"
}
]
},
"websupport": {
"Name": "websupport",
"ConfigableFields": [

View File

@@ -7,23 +7,33 @@ import (
"net/http"
"net/url"
"strings"
"time"
"github.com/jellydator/ttlcache/v3"
"golang.org/x/oauth2"
"imuslab.com/zoraxy/mod/database"
"imuslab.com/zoraxy/mod/info/logger"
"imuslab.com/zoraxy/mod/utils"
)
const (
// DefaultOAuth2ConfigCacheTime defines the default cache duration for OAuth2 configuration
DefaultOAuth2ConfigCacheTime = 60 * time.Second
)
type OAuth2RouterOptions struct {
OAuth2ServerURL string //The URL of the OAuth 2.0 server server
OAuth2TokenURL string //The URL of the OAuth 2.0 token server
OAuth2ClientId string //The client id for OAuth 2.0 Application
OAuth2ClientSecret string //The client secret for OAuth 2.0 Application
OAuth2WellKnownUrl string //The well-known url for OAuth 2.0 server
OAuth2UserInfoUrl string //The URL of the OAuth 2.0 user info endpoint
OAuth2Scopes string //The scopes for OAuth 2.0 Application
Logger *logger.Logger
Database *database.Database
OAuth2ServerURL string //The URL of the OAuth 2.0 server server
OAuth2TokenURL string //The URL of the OAuth 2.0 token server
OAuth2ClientId string //The client id for OAuth 2.0 Application
OAuth2ClientSecret string //The client secret for OAuth 2.0 Application
OAuth2WellKnownUrl string //The well-known url for OAuth 2.0 server
OAuth2UserInfoUrl string //The URL of the OAuth 2.0 user info endpoint
OAuth2Scopes string //The scopes for OAuth 2.0 Application
OAuth2CodeChallengeMethod string //The authorization code challenge method
OAuth2ConfigurationCacheTime *time.Duration
Logger *logger.Logger
Database *database.Database
OAuth2ConfigCache *ttlcache.Cache[string, *oauth2.Config]
}
type OIDCDiscoveryDocument struct {
@@ -57,11 +67,26 @@ func NewOAuth2Router(options *OAuth2RouterOptions) *OAuth2Router {
options.Database.Read("oauth2", "oauth2ClientId", &options.OAuth2ClientId)
options.Database.Read("oauth2", "oauth2ClientSecret", &options.OAuth2ClientSecret)
options.Database.Read("oauth2", "oauth2UserInfoUrl", &options.OAuth2UserInfoUrl)
options.Database.Read("oauth2", "oauth2CodeChallengeMethod", &options.OAuth2CodeChallengeMethod)
options.Database.Read("oauth2", "oauth2Scopes", &options.OAuth2Scopes)
options.Database.Read("oauth2", "oauth2ConfigurationCacheTime", &options.OAuth2ConfigurationCacheTime)
return &OAuth2Router{
ar := &OAuth2Router{
options: options,
}
if options.OAuth2ConfigurationCacheTime == nil ||
options.OAuth2ConfigurationCacheTime.Seconds() == 0 {
cacheTime := DefaultOAuth2ConfigCacheTime
options.OAuth2ConfigurationCacheTime = &cacheTime
}
options.OAuth2ConfigCache = ttlcache.New[string, *oauth2.Config](
ttlcache.WithTTL[string, *oauth2.Config](*options.OAuth2ConfigurationCacheTime),
)
go options.OAuth2ConfigCache.Start()
return ar
}
// HandleSetOAuth2Settings is the internal handler for setting the OAuth URL and HTTPS
@@ -81,13 +106,15 @@ func (ar *OAuth2Router) HandleSetOAuth2Settings(w http.ResponseWriter, r *http.R
func (ar *OAuth2Router) handleSetOAuthSettingsGET(w http.ResponseWriter, r *http.Request) {
//Return the current settings
js, _ := json.Marshal(map[string]interface{}{
"oauth2WellKnownUrl": ar.options.OAuth2WellKnownUrl,
"oauth2ServerUrl": ar.options.OAuth2ServerURL,
"oauth2TokenUrl": ar.options.OAuth2TokenURL,
"oauth2UserInfoUrl": ar.options.OAuth2UserInfoUrl,
"oauth2Scopes": ar.options.OAuth2Scopes,
"oauth2ClientSecret": ar.options.OAuth2ClientSecret,
"oauth2ClientId": ar.options.OAuth2ClientId,
"oauth2WellKnownUrl": ar.options.OAuth2WellKnownUrl,
"oauth2ServerUrl": ar.options.OAuth2ServerURL,
"oauth2TokenUrl": ar.options.OAuth2TokenURL,
"oauth2UserInfoUrl": ar.options.OAuth2UserInfoUrl,
"oauth2Scopes": ar.options.OAuth2Scopes,
"oauth2ClientSecret": ar.options.OAuth2ClientSecret,
"oauth2ClientId": ar.options.OAuth2ClientId,
"oauth2CodeChallengeMethod": ar.options.OAuth2CodeChallengeMethod,
"oauth2ConfigurationCacheTime": ar.options.OAuth2ConfigurationCacheTime.String(),
})
utils.SendJSONResponse(w, string(js))
@@ -95,7 +122,8 @@ func (ar *OAuth2Router) handleSetOAuthSettingsGET(w http.ResponseWriter, r *http
func (ar *OAuth2Router) handleSetOAuthSettingsPOST(w http.ResponseWriter, r *http.Request) {
//Update the settings
var oauth2ServerUrl, oauth2TokenURL, oauth2Scopes, oauth2UserInfoUrl string
var oauth2ServerUrl, oauth2TokenURL, oauth2Scopes, oauth2UserInfoUrl, oauth2CodeChallengeMethod string
var oauth2ConfigurationCacheTime *time.Duration
oauth2ClientId, err := utils.PostPara(r, "oauth2ClientId")
if err != nil {
@@ -109,6 +137,18 @@ func (ar *OAuth2Router) handleSetOAuthSettingsPOST(w http.ResponseWriter, r *htt
return
}
oauth2CodeChallengeMethod, err = utils.PostPara(r, "oauth2CodeChallengeMethod")
if err != nil {
utils.SendErrorResponse(w, "oauth2CodeChallengeMethod not found")
return
}
oauth2ConfigurationCacheTime, err = utils.PostDuration(r, "oauth2ConfigurationCacheTime")
if err != nil {
utils.SendErrorResponse(w, "oauth2ConfigurationCacheTime not found")
return
}
oauth2WellKnownUrl, err := utils.PostPara(r, "oauth2WellKnownUrl")
if err != nil {
oauth2ServerUrl, err = utils.PostPara(r, "oauth2ServerUrl")
@@ -146,6 +186,8 @@ func (ar *OAuth2Router) handleSetOAuthSettingsPOST(w http.ResponseWriter, r *htt
ar.options.OAuth2ClientId = oauth2ClientId
ar.options.OAuth2ClientSecret = oauth2ClientSecret
ar.options.OAuth2Scopes = oauth2Scopes
ar.options.OAuth2CodeChallengeMethod = oauth2CodeChallengeMethod
ar.options.OAuth2ConfigurationCacheTime = oauth2ConfigurationCacheTime
//Write changes to database
ar.options.Database.Write("oauth2", "oauth2WellKnownUrl", oauth2WellKnownUrl)
@@ -155,6 +197,11 @@ func (ar *OAuth2Router) handleSetOAuthSettingsPOST(w http.ResponseWriter, r *htt
ar.options.Database.Write("oauth2", "oauth2ClientId", oauth2ClientId)
ar.options.Database.Write("oauth2", "oauth2ClientSecret", oauth2ClientSecret)
ar.options.Database.Write("oauth2", "oauth2Scopes", oauth2Scopes)
ar.options.Database.Write("oauth2", "oauth2CodeChallengeMethod", oauth2CodeChallengeMethod)
ar.options.Database.Write("oauth2", "oauth2ConfigurationCacheTime", oauth2ConfigurationCacheTime)
// Flush caches
ar.options.OAuth2ConfigCache.DeleteAll()
utils.SendOK(w)
}
@@ -167,6 +214,7 @@ func (ar *OAuth2Router) handleSetOAuthSettingsDELETE(w http.ResponseWriter, r *h
ar.options.OAuth2ClientId = ""
ar.options.OAuth2ClientSecret = ""
ar.options.OAuth2Scopes = ""
ar.options.OAuth2CodeChallengeMethod = ""
ar.options.Database.Delete("oauth2", "oauth2WellKnownUrl")
ar.options.Database.Delete("oauth2", "oauth2ServerUrl")
@@ -175,6 +223,8 @@ func (ar *OAuth2Router) handleSetOAuthSettingsDELETE(w http.ResponseWriter, r *h
ar.options.Database.Delete("oauth2", "oauth2ClientId")
ar.options.Database.Delete("oauth2", "oauth2ClientSecret")
ar.options.Database.Delete("oauth2", "oauth2Scopes")
ar.options.Database.Delete("oauth2", "oauth2CodeChallengeMethod")
ar.options.Database.Delete("oauth2", "oauth2ConfigurationCacheTime")
utils.SendOK(w)
}
@@ -189,12 +239,10 @@ func (ar *OAuth2Router) fetchOAuth2Configuration(config *oauth2.Config) (*oauth2
return nil, err
} else {
defer resp.Body.Close()
oidcDiscoveryDocument := OIDCDiscoveryDocument{}
if err := json.NewDecoder(resp.Body).Decode(&oidcDiscoveryDocument); err != nil {
return nil, err
}
if len(config.Scopes) == 0 {
config.Scopes = oidcDiscoveryDocument.ScopesSupported
}
@@ -241,14 +289,24 @@ func (ar *OAuth2Router) newOAuth2Conf(redirectUrl string) (*oauth2.Config, error
func (ar *OAuth2Router) HandleOAuth2Auth(w http.ResponseWriter, r *http.Request) error {
const callbackPrefix = "/internal/oauth2"
const tokenCookie = "z-token"
const verifierCookie = "z-verifier"
scheme := "http"
if r.TLS != nil {
scheme = "https"
}
reqUrl := scheme + "://" + r.Host + r.RequestURI
oauthConfig, err := ar.newOAuth2Conf(scheme + "://" + r.Host + callbackPrefix)
if err != nil {
ar.options.Logger.PrintAndLog("OAuth2Router", "Failed to fetch OIDC configuration:", err)
oauthConfigCache, _ := ar.options.OAuth2ConfigCache.GetOrSetFunc(r.Host, func() *oauth2.Config {
oauthConfig, err := ar.newOAuth2Conf(scheme + "://" + r.Host + callbackPrefix)
if err != nil {
ar.options.Logger.PrintAndLog("OAuth2Router", "Failed to fetch OIDC configuration:", err)
return nil
}
return oauthConfig
})
oauthConfig := oauthConfigCache.Value()
if oauthConfig == nil {
w.WriteHeader(500)
return errors.New("failed to fetch OIDC configuration")
}
@@ -263,26 +321,48 @@ func (ar *OAuth2Router) HandleOAuth2Auth(w http.ResponseWriter, r *http.Request)
state := r.URL.Query().Get("state")
if r.Method == http.MethodGet && strings.HasPrefix(r.RequestURI, callbackPrefix) && code != "" && state != "" {
ctx := context.Background()
token, err := oauthConfig.Exchange(ctx, code)
var authCodeOptions []oauth2.AuthCodeOption
if ar.options.OAuth2CodeChallengeMethod == "PKCE" || ar.options.OAuth2CodeChallengeMethod == "PKCE_S256" {
verifierCookie, err := r.Cookie(verifierCookie)
if err != nil || verifierCookie.Value == "" {
ar.options.Logger.PrintAndLog("OAuth2Router", "Read OAuth2 verifier cookie failed", err)
w.WriteHeader(401)
return errors.New("unauthorized")
}
authCodeOptions = append(authCodeOptions, oauth2.VerifierOption(verifierCookie.Value))
}
token, err := oauthConfig.Exchange(ctx, code, authCodeOptions...)
if err != nil {
ar.options.Logger.PrintAndLog("OAuth2", "Token exchange failed", err)
w.WriteHeader(401)
return errors.New("unauthorized")
}
if !token.Valid() {
ar.options.Logger.PrintAndLog("OAuth2", "Invalid token", err)
w.WriteHeader(401)
return errors.New("unauthorized")
}
cookie := http.Cookie{Name: tokenCookie, Value: token.AccessToken, Path: "/"}
cookieExpiry := token.Expiry
if cookieExpiry.IsZero() || cookieExpiry.Before(time.Now()) {
cookieExpiry = time.Now().Add(time.Hour)
}
cookie := http.Cookie{Name: tokenCookie, Value: token.AccessToken, Path: "/", Expires: cookieExpiry}
if scheme == "https" {
cookie.Secure = true
cookie.SameSite = http.SameSiteLaxMode
}
w.Header().Add("Set-Cookie", cookie.String())
if ar.options.OAuth2CodeChallengeMethod == "PKCE" || ar.options.OAuth2CodeChallengeMethod == "PKCE_S256" {
cookie := http.Cookie{Name: verifierCookie, Value: "", Path: "/", Expires: time.Now().Add(-time.Hour * 1)}
if scheme == "https" {
cookie.Secure = true
cookie.SameSite = http.SameSiteLaxMode
}
w.Header().Add("Set-Cookie", cookie.String())
}
//Fix for #695
location := strings.TrimPrefix(state, "/internal/")
//Check if the location starts with http:// or https://. if yes, this is full URL
@@ -321,7 +401,25 @@ func (ar *OAuth2Router) HandleOAuth2Auth(w http.ResponseWriter, r *http.Request)
}
if unauthorized {
state := url.QueryEscape(reqUrl)
url := oauthConfig.AuthCodeURL(state, oauth2.AccessTypeOffline)
var url string
if ar.options.OAuth2CodeChallengeMethod == "PKCE" || ar.options.OAuth2CodeChallengeMethod == "PKCE_S256" {
cookie := http.Cookie{Name: verifierCookie, Value: oauth2.GenerateVerifier(), Path: "/", Expires: time.Now().Add(time.Hour * 1)}
if scheme == "https" {
cookie.Secure = true
cookie.SameSite = http.SameSiteLaxMode
}
w.Header().Add("Set-Cookie", cookie.String())
if ar.options.OAuth2CodeChallengeMethod == "PKCE" {
url = oauthConfig.AuthCodeURL(state, oauth2.AccessTypeOffline, oauth2.SetAuthURLParam("code_challenge", cookie.Value))
} else {
url = oauthConfig.AuthCodeURL(state, oauth2.AccessTypeOffline, oauth2.S256ChallengeOption(cookie.Value))
}
} else {
url = oauthConfig.AuthCodeURL(state, oauth2.AccessTypeOffline)
}
http.Redirect(w, r, url, http.StatusFound)
return errors.New("unauthorized")

View File

@@ -48,7 +48,7 @@ func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
//Check if this is a redirection url
if h.Parent.Option.RedirectRuleTable.IsRedirectable(r) {
statusCode := h.Parent.Option.RedirectRuleTable.HandleRedirect(w, r)
h.Parent.logRequest(r, statusCode != 500, statusCode, "redirect", r.Host, "")
h.Parent.logRequest(r, statusCode != 500, statusCode, "redirect", r.Host, "", nil)
return
}
@@ -70,7 +70,7 @@ func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
//Use default rule
ruleID = "default"
}
if h.handleAccessRouting(ruleID, w, r) {
if h.handleAccessRouting(ruleID, w, r, sep) {
//Request handled by subroute
return
}
@@ -79,7 +79,9 @@ func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if sep.RequireRateLimit {
err := h.handleRateLimitRouting(w, r, sep)
if err != nil {
h.Parent.Option.Logger.LogHTTPRequest(r, "host", 307, r.Host, "")
if !sep.DisableLogging {
h.Parent.Option.Logger.LogHTTPRequest(r, "host", 307, r.Host, "")
}
return
}
}
@@ -109,7 +111,9 @@ func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if potentialProxtEndpoint != nil && !potentialProxtEndpoint.Disabled {
//Missing tailing slash. Redirect to target proxy endpoint
http.Redirect(w, r, r.RequestURI+"/", http.StatusTemporaryRedirect)
h.Parent.Option.Logger.LogHTTPRequest(r, "redirect", 307, r.Host, "")
if !sep.DisableLogging {
h.Parent.Option.Logger.LogHTTPRequest(r, "redirect", 307, r.Host, "")
}
return
}
}
@@ -124,7 +128,7 @@ func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
*/
//Root access control based on default rule
blocked := h.handleAccessRouting("default", w, r)
blocked := h.handleAccessRouting("default", w, r, h.Parent.Root)
if blocked {
return
}
@@ -210,19 +214,19 @@ func (h *ProxyHandler) handleRootRouting(w http.ResponseWriter, r *http.Request)
}
hostname := parsedURL.Hostname()
if hostname == domainOnly {
h.Parent.logRequest(r, false, 500, "root-redirect", domainOnly, "")
h.Parent.logRequest(r, false, 500, "root-redirect", domainOnly, "", h.Parent.Root)
http.Error(w, "Loopback redirects due to invalid settings", 500)
return
}
h.Parent.logRequest(r, false, 307, "root-redirect", domainOnly, "")
h.Parent.logRequest(r, false, 307, "root-redirect", domainOnly, "", h.Parent.Root)
http.Redirect(w, r, redirectTarget, http.StatusTemporaryRedirect)
case DefaultSite_NotFoundPage:
//Serve the not found page, use template if exists
h.serve404PageWithTemplate(w, r)
case DefaultSite_NoResponse:
//No response. Just close the connection
h.Parent.logRequest(r, false, 444, "root-no_resp", domainOnly, "")
h.Parent.logRequest(r, false, 444, "root-no_resp", domainOnly, "", h.Parent.Root)
hijacker, ok := w.(http.Hijacker)
if !ok {
w.WriteHeader(http.StatusNoContent)
@@ -236,11 +240,11 @@ func (h *ProxyHandler) handleRootRouting(w http.ResponseWriter, r *http.Request)
conn.Close()
case DefaultSite_TeaPot:
//I'm a teapot
h.Parent.logRequest(r, false, 418, "root-teapot", domainOnly, "")
h.Parent.logRequest(r, false, 418, "root-teapot", domainOnly, "", h.Parent.Root)
http.Error(w, "I'm a teapot", http.StatusTeapot)
default:
//Unknown routing option. Send empty response
h.Parent.logRequest(r, false, 544, "root-unknown", domainOnly, "")
h.Parent.logRequest(r, false, 544, "root-unknown", domainOnly, "", h.Parent.Root)
http.Error(w, "544 - No Route Defined", 544)
}
}

View File

@@ -13,7 +13,7 @@ import (
// Handle access check (blacklist / whitelist), return true if request is handled (aka blocked)
// if the return value is false, you can continue process the response writer
func (h *ProxyHandler) handleAccessRouting(ruleID string, w http.ResponseWriter, r *http.Request) bool {
func (h *ProxyHandler) handleAccessRouting(ruleID string, w http.ResponseWriter, r *http.Request, sep *ProxyEndpoint) bool {
accessRule, err := h.Parent.Option.AccessController.GetAccessRuleByID(ruleID)
if err != nil {
//Unable to load access rule. Target rule not found?
@@ -25,7 +25,7 @@ func (h *ProxyHandler) handleAccessRouting(ruleID string, w http.ResponseWriter,
isBlocked, blockedReason := accessRequestBlocked(accessRule, h.Parent.Option.WebDirectory, w, r)
if isBlocked {
h.Parent.logRequest(r, false, 403, blockedReason, r.Host, "")
h.Parent.logRequest(r, false, 403, blockedReason, r.Host, "", sep)
}
return isBlocked
}

View File

@@ -156,7 +156,7 @@ func (router *Router) StartProxyService() error {
if err != nil {
http.ServeFile(w, r, "./web/hosterror.html")
router.Option.Logger.PrintAndLog("dprouter", "failed to get upstream for hostname", err)
router.logRequest(r, false, 404, "vdir-http", r.Host, "")
router.logRequest(r, false, 404, "vdir-http", r.Host, "", sep)
}
endpointProxyRewriteRules := GetDefaultHeaderRewriteRules()

View File

@@ -28,11 +28,14 @@ func (h2c *H2CRoundTripper) RoundTrip(req *http.Request) (*http.Response, error)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
req, err := http.NewRequestWithContext(ctx, req.Method, req.RequestURI, nil)
req, err := http.NewRequestWithContext(ctx, req.Method, req.URL.String(), req.Body)
if err != nil {
return nil, err
}
// Copy headers
req.Header = req.Header.Clone()
tr := &http2.Transport{
AllowHTTP: true,
DialTLSContext: func(ctx context.Context, network, addr string, cfg *tls.Config) (net.Conn, error) {
@@ -43,3 +46,20 @@ func (h2c *H2CRoundTripper) RoundTrip(req *http.Request) (*http.Response, error)
return tr.RoundTrip(req)
}
func (h2c *H2CRoundTripper) CheckServerSupportsH2C(serverURL string) bool {
req, err := http.NewRequest("GET", serverURL, nil)
if err != nil {
return false
}
tr := &http2.Transport{
AllowHTTP: true,
DialTLSContext: func(ctx context.Context, network, addr string, cfg *tls.Config) (net.Conn, error) {
var d net.Dialer
return d.DialContext(ctx, network, addr)
},
}
_, err = tr.RoundTrip(req)
return err == nil
}

View File

@@ -0,0 +1,83 @@
package modh2c
import (
"net/http"
"net/http/httptest"
"testing"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
)
func TestH2CRoundTripper_RoundTrip(t *testing.T) {
// Create a test server that supports h2c
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if r.Proto != "HTTP/2.0" {
t.Errorf("Expected HTTP/2.0, got %s", r.Proto)
}
w.WriteHeader(http.StatusOK)
w.Write([]byte("Hello, h2c!"))
})
server := httptest.NewServer(h2c.NewHandler(mux, &http2.Server{}))
defer server.Close()
// Create the round tripper
rt := NewH2CRoundTripper()
// Create a request
req, err := http.NewRequest("GET", server.URL, nil)
if err != nil {
t.Fatalf("Failed to create request: %v", err)
}
// Perform the round trip
resp, err := rt.RoundTrip(req)
if err != nil {
t.Fatalf("RoundTrip failed: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
t.Errorf("Expected status 200, got %d", resp.StatusCode)
}
// Check the response body
body := make([]byte, 1024)
n, err := resp.Body.Read(body)
if err != nil && err.Error() != "EOF" {
t.Fatalf("Failed to read body: %v", err)
}
if string(body[:n]) != "Hello, h2c!" {
t.Errorf("Expected 'Hello, h2c!', got '%s'", string(body[:n]))
}
}
func TestH2CRoundTripper_CheckServerSupportsH2C(t *testing.T) {
// Test with h2c server
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
server := httptest.NewServer(h2c.NewHandler(mux, &http2.Server{}))
defer server.Close()
rt := NewH2CRoundTripper()
supports := rt.CheckServerSupportsH2C(server.URL)
if !supports {
t.Error("Expected server to support h2c")
}
// Test with non-h2c server (regular HTTP/1.1)
server2 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}))
defer server2.Close()
supports2 := rt.CheckServerSupportsH2C(server2.URL)
if supports2 {
t.Error("Expected server to not support h2c")
}
}

View File

@@ -51,6 +51,11 @@ func (router *Router) GetProxyEndpointFromHostname(hostname string) *ProxyEndpoi
matchProxyEndpoints := []*ProxyEndpoint{}
router.ProxyEndpoints.Range(func(k, v interface{}) bool {
ep := v.(*ProxyEndpoint)
if ep.Disabled {
//Skip disabled endpoint
return true
}
match, err := filepath.Match(ep.RootOrMatchingDomain, hostname)
if err != nil {
//Bad pattern. Skip this rule
@@ -83,12 +88,24 @@ func (router *Router) GetProxyEndpointFromHostname(hostname string) *ProxyEndpoi
})
if len(matchProxyEndpoints) == 1 {
//Only 1 match
return matchProxyEndpoints[0]
} else if len(matchProxyEndpoints) > 1 {
//More than one match. Get the best match one
sort.Slice(matchProxyEndpoints, func(i, j int) bool {
return matchProxyEndpoints[i].RootOrMatchingDomain < matchProxyEndpoints[j].RootOrMatchingDomain
// More than one match, pick one that is:
// 1. longer RootOrMatchingDomain (more specific)
// 2. fewer wildcard characters (* and ?) (more specific)
// 3. fallback to lexicographic order
sort.SliceStable(matchProxyEndpoints, func(i, j int) bool {
a := matchProxyEndpoints[i].RootOrMatchingDomain
b := matchProxyEndpoints[j].RootOrMatchingDomain
if len(a) != len(b) {
return len(a) > len(b)
}
aw := strings.Count(a, "*") + strings.Count(a, "?")
bw := strings.Count(b, "*") + strings.Count(b, "?")
if aw != bw {
return aw < bw
}
return a < b
})
return matchProxyEndpoints[0]
}
@@ -110,13 +127,13 @@ func (router *Router) rewriteURL(rooturl string, requestURL string) string {
// upstreamHostSwap check if this loopback to one of the proxy rule in the system. If yes, do a shortcut target swap
// this prevents unnecessary external DNS lookup and connection, return true if swapped and request is already handled
// by the loopback handler. Only continue if return is false
func (h *ProxyHandler) upstreamHostSwap(w http.ResponseWriter, r *http.Request, selectedUpstream *loadbalance.Upstream) bool {
func (h *ProxyHandler) upstreamHostSwap(w http.ResponseWriter, r *http.Request, selectedUpstream *loadbalance.Upstream, currentTarget *ProxyEndpoint) bool {
upstreamHostname := selectedUpstream.OriginIpOrDomain
if strings.Contains(upstreamHostname, ":") {
upstreamHostname = strings.Split(upstreamHostname, ":")[0]
}
loopbackProxyEndpoint := h.Parent.GetProxyEndpointFromHostname(upstreamHostname)
if loopbackProxyEndpoint != nil {
if loopbackProxyEndpoint != nil && loopbackProxyEndpoint != currentTarget {
//This is a loopback request. Swap the target to the loopback target
//h.Parent.Option.Logger.PrintAndLog("proxy", "Detected a loopback request to self. Swap the target to "+loopbackProxyEndpoint.RootOrMatchingDomain, nil)
if loopbackProxyEndpoint.IsEnabled() {
@@ -124,7 +141,7 @@ func (h *ProxyHandler) upstreamHostSwap(w http.ResponseWriter, r *http.Request,
} else {
//Endpoint disabled, return 503
http.ServeFile(w, r, "./web/rperror.html")
h.Parent.logRequest(r, false, 521, "host-http", r.Host, upstreamHostname)
h.Parent.logRequest(r, false, 521, "host-http", r.Host, upstreamHostname, currentTarget)
}
return true
}
@@ -142,12 +159,12 @@ func (h *ProxyHandler) hostRequest(w http.ResponseWriter, r *http.Request, targe
if err != nil {
http.ServeFile(w, r, "./web/rperror.html")
h.Parent.Option.Logger.PrintAndLog("proxy", "Failed to assign an upstream for this request", err)
h.Parent.logRequest(r, false, 521, "subdomain-http", r.URL.Hostname(), r.Host)
h.Parent.logRequest(r, false, 521, "subdomain-http", r.URL.Hostname(), r.Host, target)
return
}
/* Upstream Host Swap (use to detect loopback to self) */
if h.upstreamHostSwap(w, r, selectedUpstream) {
if h.upstreamHostSwap(w, r, selectedUpstream, target) {
//Request handled by the loopback handler
return
}
@@ -170,7 +187,7 @@ func (h *ProxyHandler) hostRequest(w http.ResponseWriter, r *http.Request, targe
if selectedUpstream.RequireTLS {
u, _ = url.Parse("wss://" + wsRedirectionEndpoint + requestURL)
}
h.Parent.logRequest(r, true, 101, "host-websocket", reqHostname, selectedUpstream.OriginIpOrDomain)
h.Parent.logRequest(r, true, 101, "host-websocket", reqHostname, selectedUpstream.OriginIpOrDomain, target)
if target.HeaderRewriteRules == nil {
target.HeaderRewriteRules = GetDefaultHeaderRewriteRules()
@@ -232,18 +249,18 @@ func (h *ProxyHandler) hostRequest(w http.ResponseWriter, r *http.Request, targe
if err != nil {
if errors.As(err, &dnsError) {
http.ServeFile(w, r, "./web/hosterror.html")
h.Parent.logRequest(r, false, 404, "host-http", reqHostname, upstreamHostname)
h.Parent.logRequest(r, false, 404, "host-http", reqHostname, upstreamHostname, target)
} else if errors.Is(err, context.Canceled) {
//Request canceled by client, usually due to manual refresh before page load
http.Error(w, "Request canceled", http.StatusRequestTimeout)
h.Parent.logRequest(r, false, http.StatusRequestTimeout, "host-http", reqHostname, upstreamHostname)
h.Parent.logRequest(r, false, http.StatusRequestTimeout, "host-http", reqHostname, upstreamHostname, target)
} else {
http.ServeFile(w, r, "./web/rperror.html")
h.Parent.logRequest(r, false, 521, "host-http", reqHostname, upstreamHostname)
h.Parent.logRequest(r, false, 521, "host-http", reqHostname, upstreamHostname, target)
}
}
h.Parent.logRequest(r, true, statusCode, "host-http", reqHostname, upstreamHostname)
h.Parent.logRequest(r, true, statusCode, "host-http", reqHostname, upstreamHostname, target)
}
// Handle vdir type request
@@ -269,7 +286,7 @@ func (h *ProxyHandler) vdirRequest(w http.ResponseWriter, r *http.Request, targe
target.parent.HeaderRewriteRules = GetDefaultHeaderRewriteRules()
}
h.Parent.logRequest(r, true, 101, "vdir-websocket", r.Host, target.Domain)
h.Parent.logRequest(r, true, 101, "vdir-websocket", r.Host, target.Domain, target.parent)
wspHandler := websocketproxy.NewProxy(u, websocketproxy.Options{
SkipTLSValidation: target.SkipCertValidations,
SkipOriginCheck: true, //You should not use websocket via virtual directory. But keep this to true for compatibility
@@ -325,19 +342,25 @@ func (h *ProxyHandler) vdirRequest(w http.ResponseWriter, r *http.Request, targe
if errors.As(err, &dnsError) {
http.ServeFile(w, r, "./web/hosterror.html")
log.Println(err.Error())
h.Parent.logRequest(r, false, 404, "vdir-http", reqHostname, target.Domain)
h.Parent.logRequest(r, false, 404, "vdir-http", reqHostname, target.Domain, target.parent)
} else {
http.ServeFile(w, r, "./web/rperror.html")
log.Println(err.Error())
h.Parent.logRequest(r, false, 521, "vdir-http", reqHostname, target.Domain)
h.Parent.logRequest(r, false, 521, "vdir-http", reqHostname, target.Domain, target.parent)
}
}
h.Parent.logRequest(r, true, statusCode, "vdir-http", reqHostname, target.Domain)
h.Parent.logRequest(r, true, statusCode, "vdir-http", reqHostname, target.Domain, target.parent)
}
// This logger collect data for the statistical analysis. For log to file logger, check the Logger and LogHTTPRequest handler
func (router *Router) logRequest(r *http.Request, succ bool, statusCode int, forwardType string, originalHostname string, upstreamHostname string) {
func (router *Router) logRequest(r *http.Request, succ bool, statusCode int, forwardType string, originalHostname string, upstreamHostname string, endpoint *ProxyEndpoint) {
if endpoint != nil && endpoint.DisableLogging {
// Notes: endpoint can be nil if the request has been handled before a host name can be resolved
// e.g. Redirection matching rule
// in that case we will log it by default and will not enter this routine
return
}
if router.Option.StatisticCollector != nil {
go func() {
requestInfo := statistic.RequestInfo{

View File

@@ -51,7 +51,7 @@ func (t *RequestCountPerIpTable) Clear() {
func (h *ProxyHandler) handleRateLimitRouting(w http.ResponseWriter, r *http.Request, pe *ProxyEndpoint) error {
err := h.Parent.handleRateLimit(w, r, pe)
if err != nil {
h.Parent.logRequest(r, false, 429, "ratelimit", r.URL.Hostname(), "")
h.Parent.logRequest(r, false, 429, "ratelimit", r.URL.Hostname(), "", pe)
}
return err
}

View File

@@ -208,6 +208,7 @@ type ProxyEndpoint struct {
//Uptime Monitor
DisableUptimeMonitor bool //Disable uptime monitor for this endpoint
DisableLogging bool //Disable logging of reverse proxy requests
// Chunked Transfer Encoding
DisableChunkedTransferEncoding bool //Disable chunked transfer encoding for this endpoint

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,164 @@
package logger
import (
"encoding/json"
"fmt"
"net/http"
"os"
"path/filepath"
"imuslab.com/zoraxy/mod/utils"
)
// LogConfig represents the log rotation configuration
type LogConfig struct {
Enabled bool `json:"enabled"` // Whether log rotation is enabled
MaxSize string `json:"maxSize"` // Maximum size as string (e.g., "200M", "10K")
MaxBackups int `json:"maxBackups"` // Maximum number of backup files to keep
Compress bool `json:"compress"` // Whether to compress rotated logs
}
// LoadLogConfig loads the log configuration from the config file
func LoadLogConfig(configPath string) (*LogConfig, error) {
// Ensure config directory exists
configDir := filepath.Dir(configPath)
if err := os.MkdirAll(configDir, 0755); err != nil {
return nil, err
}
// Default config
defaultConfig := &LogConfig{
Enabled: false,
MaxSize: "0",
MaxBackups: 16,
Compress: true,
}
// Try to read existing config
file, err := os.Open(configPath)
if err != nil {
if os.IsNotExist(err) {
// File doesn't exist, save default config
if saveErr := SaveLogConfig(configPath, defaultConfig); saveErr != nil {
return nil, saveErr
}
return defaultConfig, nil
}
return nil, err
}
defer file.Close()
var config LogConfig
decoder := json.NewDecoder(file)
if err := decoder.Decode(&config); err != nil {
// If decode fails, use default
return defaultConfig, nil
}
return &config, nil
}
// SaveLogConfig saves the log configuration to the config file
func SaveLogConfig(configPath string, config *LogConfig) error {
// Ensure config directory exists
configDir := filepath.Dir(configPath)
if err := os.MkdirAll(configDir, 0755); err != nil {
return err
}
file, err := os.Create(configPath)
if err != nil {
return err
}
defer file.Close()
encoder := json.NewEncoder(file)
encoder.SetIndent("", " ")
return encoder.Encode(config)
}
// ApplyLogConfig applies the log configuration to the logger
func (l *Logger) ApplyLogConfig(config *LogConfig) error {
maxSizeBytes, err := utils.SizeStringToBytes(config.MaxSize)
if err != nil {
return err
}
if maxSizeBytes == 0 {
// Use default value of 25MB
maxSizeBytes = 25 * 1024 * 1024
}
rotateOption := &RotateOption{
Enabled: config.Enabled,
MaxSize: int64(maxSizeBytes),
MaxBackups: config.MaxBackups,
Compress: config.Compress,
BackupDir: "",
}
l.SetRotateOption(rotateOption)
return nil
}
// HandleGetLogConfig handles GET /api/logger/config
func HandleGetLogConfig(configPath string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
config, err := LoadLogConfig(configPath)
if err != nil {
utils.SendErrorResponse(w, "Failed to load log config: "+err.Error())
return
}
js, err := json.Marshal(config)
if err != nil {
utils.SendErrorResponse(w, "Failed to marshal config: "+err.Error())
return
}
utils.SendJSONResponse(w, string(js))
}
}
// HandleUpdateLogConfig handles POST /api/logger/config
func HandleUpdateLogConfig(configPath string, logger *Logger) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
utils.SendErrorResponse(w, "Method not allowed")
return
}
var config LogConfig
if err := json.NewDecoder(r.Body).Decode(&config); err != nil {
utils.SendErrorResponse(w, "Invalid JSON: "+err.Error())
return
}
// Validate MaxSize
if _, err := utils.SizeStringToBytes(config.MaxSize); err != nil {
utils.SendErrorResponse(w, "Invalid maxSize: "+err.Error())
return
}
// Validate MaxBackups
if config.MaxBackups < 1 {
utils.SendErrorResponse(w, "maxBackups must be at least 1")
return
}
// Save config
if err := SaveLogConfig(configPath, &config); err != nil {
utils.SendErrorResponse(w, "Failed to save config: "+err.Error())
return
}
// Apply to logger
if err := logger.ApplyLogConfig(&config); err != nil {
utils.SendErrorResponse(w, "Failed to apply config: "+err.Error())
return
}
// Pretty print config as key: value pairs
configStr := fmt.Sprintf("enabled=%t, maxSize=%s, maxBackups=%d, compress=%t", config.Enabled, config.MaxSize, config.MaxBackups, config.Compress)
logger.PrintAndLog("logger", "Updated log rotation setting: "+configStr, nil)
utils.SendOK(w)
}
}

View File

@@ -1,7 +1,7 @@
package logger
import (
"archive/zip"
"compress/gzip"
"fmt"
"io"
"net/http"
@@ -176,17 +176,17 @@ func (l *Logger) RotateLog() error {
return nil
}
// compressFile compresses the given file using zip format and creates a .gz file.
// compressFile compresses the given file using gzip format and creates a .gz file.
func compressFile(filename string) error {
zipFilename := filename + ".gz"
outFile, err := os.Create(zipFilename)
gzipFilename := filename + ".gz"
outFile, err := os.Create(gzipFilename)
if err != nil {
return err
}
defer outFile.Close()
zipWriter := zip.NewWriter(outFile)
defer zipWriter.Close()
gzipWriter := gzip.NewWriter(outFile)
defer gzipWriter.Close()
fileToCompress, err := os.Open(filename)
if err != nil {
@@ -194,11 +194,6 @@ func compressFile(filename string) error {
}
defer fileToCompress.Close()
w, err := zipWriter.Create(filepath.Base(filename))
if err != nil {
return err
}
_, err = io.Copy(w, fileToCompress)
_, err = io.Copy(gzipWriter, fileToCompress)
return err
}

View File

@@ -1,8 +1,11 @@
package logviewer
import (
"archive/zip"
"compress/gzip"
"encoding/json"
"errors"
"io"
"io/fs"
"net/http"
"os"
@@ -15,7 +18,6 @@ import (
type ViewerOption struct {
RootFolder string //The root folder to scan for log
Extension string //The extension the root files use, include the . in your ext (e.g. .log)
}
type Viewer struct {
@@ -72,6 +74,11 @@ func (v *Viewer) HandleReadLog(w http.ResponseWriter, r *http.Request) {
filter = ""
}
linesParam, err := utils.GetPara(r, "lines")
if err != nil {
linesParam = "all"
}
content, err := v.LoadLogFile(strings.TrimSpace(filepath.Base(filename)))
if err != nil {
utils.SendErrorResponse(w, err.Error())
@@ -107,6 +114,18 @@ func (v *Viewer) HandleReadLog(w http.ResponseWriter, r *http.Request) {
content = strings.Join(filteredLines, "\n")
}
// Apply lines limit after filtering
if linesParam != "all" {
if lineLimit, err := strconv.Atoi(linesParam); err == nil && lineLimit > 0 {
allLines := strings.Split(content, "\n")
if len(allLines) > lineLimit {
// Keep only the last lineLimit lines
allLines = allLines[len(allLines)-lineLimit:]
content = strings.Join(allLines, "\n")
}
}
}
utils.SendTextResponse(w, content)
}
@@ -158,7 +177,7 @@ func (v *Viewer) HandleLogErrorSummary(w http.ResponseWriter, r *http.Request) {
line = line[strings.LastIndex(line, "]")+1:]
fields := strings.Fields(strings.TrimSpace(line))
if len(fields) > 0 {
if len(fields) >= 3 {
statusStr := fields[2]
if len(statusStr) == 3 && (statusStr[0] != '1' && statusStr[0] != '2' && statusStr[0] != '3') {
fieldsWithTimestamp := append([]string{timestamp}, strings.Fields(strings.TrimSpace(line))...)
@@ -179,7 +198,7 @@ func (v *Viewer) HandleLogErrorSummary(w http.ResponseWriter, r *http.Request) {
func (v *Viewer) ListLogFiles(showFullpath bool) map[string][]*LogFile {
result := map[string][]*LogFile{}
filepath.WalkDir(v.option.RootFolder, func(path string, di fs.DirEntry, err error) error {
if filepath.Ext(path) == v.option.Extension {
if filepath.Ext(path) == ".log" || strings.HasSuffix(path, ".log.gz") {
catergory := filepath.Base(filepath.Dir(path))
logList, ok := result[catergory]
if !ok {
@@ -197,9 +216,12 @@ func (v *Viewer) ListLogFiles(showFullpath bool) map[string][]*LogFile {
return nil
}
filename := filepath.Base(path)
filename = strings.TrimSuffix(filename, ".log") //to handle cases where the filename ends of .log.gz
logList = append(logList, &LogFile{
Title: strings.TrimSuffix(filepath.Base(path), filepath.Ext(path)),
Filename: filepath.Base(path),
Filename: filename,
Fullpath: fullpath,
Filesize: st.Size(),
})
@@ -212,13 +234,78 @@ func (v *Viewer) ListLogFiles(showFullpath bool) map[string][]*LogFile {
return result
}
func (v *Viewer) LoadLogFile(filename string) (string, error) {
// readLogFileContent reads a log file, handling both compressed (.gz) and uncompressed files
func (v *Viewer) readLogFileContent(filepath string) ([]byte, error) {
file, err := os.Open(filepath)
if err != nil {
return nil, err
}
defer file.Close()
// Check if file is compressed
if strings.HasSuffix(filepath, ".gz") {
gzipReader, err := gzip.NewReader(file)
if err != nil {
// Try zip reader for older logs that use zip compression despite .gz extension
zipReader, err := zip.OpenReader(filepath)
if err != nil {
return nil, err
}
defer zipReader.Close()
if len(zipReader.File) == 0 {
return nil, errors.New("zip file is empty")
}
zipFile := zipReader.File[0]
rc, err := zipFile.Open()
if err != nil {
return nil, err
}
defer rc.Close()
return io.ReadAll(rc)
}
defer gzipReader.Close()
return io.ReadAll(gzipReader)
}
// Regular file
return io.ReadAll(file)
}
func (v *Viewer) senatizeLogFilenameInput(filename string) string {
filename = strings.TrimSuffix(filename, ".log.gz")
filename = strings.TrimSuffix(filename, ".log")
filename = filepath.ToSlash(filename)
filename = strings.ReplaceAll(filename, "../", "")
logFilepath := filepath.Join(v.option.RootFolder, filename)
//Check if .log.gz or .log exists
if utils.FileExists(filepath.Join(v.option.RootFolder, filename+".log")) {
return filepath.Join(v.option.RootFolder, filename+".log")
}
if utils.FileExists(filepath.Join(v.option.RootFolder, filename+".log.gz")) {
return filepath.Join(v.option.RootFolder, filename+".log.gz")
}
return filepath.Join(v.option.RootFolder, filename)
}
func (v *Viewer) LoadLogFile(filename string) (string, error) {
// filename might be in (no extension), .log or .log.gz format
// so we trim those first before proceeding
logFilepath := v.senatizeLogFilenameInput(filename)
if utils.FileExists(logFilepath) {
//Load it
content, err := os.ReadFile(logFilepath)
content, err := v.readLogFileContent(logFilepath)
if err != nil {
return "", err
}
return string(content), nil
}
//Also check .log.gz
logFilepathGz := logFilepath + ".gz"
if utils.FileExists(logFilepathGz) {
content, err := v.readLogFileContent(logFilepathGz)
if err != nil {
return "", err
}
@@ -230,12 +317,10 @@ func (v *Viewer) LoadLogFile(filename string) (string, error) {
}
func (v *Viewer) LoadLogSummary(filename string) (string, error) {
filename = filepath.ToSlash(filename)
filename = strings.ReplaceAll(filename, "../", "")
logFilepath := filepath.Join(v.option.RootFolder, filename)
logFilepath := v.senatizeLogFilenameInput(filename)
if utils.FileExists(logFilepath) {
//Load it
content, err := os.ReadFile(logFilepath)
content, err := v.readLogFileContent(logFilepath)
if err != nil {
return "", err
}

View File

@@ -84,18 +84,27 @@ func (m *Manager) SetCertAsDefault(w http.ResponseWriter, r *http.Request) {
}
//Check if the previous default cert exists. If yes, get its hostname from cert contents
defaultPubKey := filepath.Join(m.CertStore, "default.key")
defaultPriKey := filepath.Join(m.CertStore, "default.pem")
defaultPubKey := filepath.Join(m.CertStore, "default.pem")
defaultPriKey := filepath.Join(m.CertStore, "default.key")
defaultJSON := filepath.Join(m.CertStore, "default.json")
if utils.FileExists(defaultPubKey) && utils.FileExists(defaultPriKey) {
//Move the existing default cert to its original name
certBytes, err := os.ReadFile(defaultPriKey)
certBytes, err := os.ReadFile(defaultPubKey)
if err == nil {
block, _ := pem.Decode(certBytes)
if block != nil {
cert, err := x509.ParseCertificate(block.Bytes)
if err == nil {
os.Rename(defaultPubKey, filepath.Join(m.CertStore, domainToFilename(cert.Subject.CommonName, "key")))
os.Rename(defaultPriKey, filepath.Join(m.CertStore, domainToFilename(cert.Subject.CommonName, "pem")))
originalKeyName := filepath.Join(m.CertStore, domainToFilename(cert.Subject.CommonName, "key"))
originalPemName := filepath.Join(m.CertStore, domainToFilename(cert.Subject.CommonName, "pem"))
originalJSONName := filepath.Join(m.CertStore, domainToFilename(cert.Subject.CommonName, "json"))
os.Rename(defaultPubKey, originalPemName)
os.Rename(defaultPriKey, originalKeyName)
if utils.FileExists(defaultJSON) {
os.Rename(defaultJSON, originalJSONName)
}
}
}
}
@@ -103,11 +112,15 @@ func (m *Manager) SetCertAsDefault(w http.ResponseWriter, r *http.Request) {
//Check if the cert exists
certname = filepath.Base(certname) //prevent path escape
pubKey := filepath.Join(filepath.Join(m.CertStore), certname+".key")
priKey := filepath.Join(filepath.Join(m.CertStore), certname+".pem")
pubKey := filepath.Join(filepath.Join(m.CertStore), certname+".pem")
priKey := filepath.Join(filepath.Join(m.CertStore), certname+".key")
certJSON := filepath.Join(filepath.Join(m.CertStore), certname+".json")
if utils.FileExists(pubKey) && utils.FileExists(priKey) {
os.Rename(pubKey, filepath.Join(m.CertStore, "default.key"))
os.Rename(priKey, filepath.Join(m.CertStore, "default.pem"))
os.Rename(pubKey, filepath.Join(m.CertStore, "default.pem"))
os.Rename(priKey, filepath.Join(m.CertStore, "default.key"))
if utils.FileExists(certJSON) {
os.Rename(certJSON, filepath.Join(m.CertStore, "default.json"))
}
utils.SendOK(w)
//Update cert list

View File

@@ -59,7 +59,7 @@ func (m *Monitor) ExecuteUptimeCheck() {
//For each target to check online, do the following
var thisRecord Record
if target.Protocol == "http" || target.Protocol == "https" {
online, laterncy, statusCode := m.getWebsiteStatusWithLatency(target.URL)
online, laterncy, statusCode := m.getWebsiteStatusWithLatency(target)
thisRecord = Record{
Timestamp: time.Now().Unix(),
ID: target.ID,
@@ -167,30 +167,40 @@ func (m *Monitor) HandleUptimeLogRead(w http.ResponseWriter, r *http.Request) {
*/
// Get website stauts with latency given URL, return is conn succ and its latency and status code
func (m *Monitor) getWebsiteStatusWithLatency(url string) (bool, int64, int) {
func (m *Monitor) getWebsiteStatusWithLatency(target *Target) (bool, int64, int) {
start := time.Now().UnixNano() / int64(time.Millisecond)
statusCode, err := getWebsiteStatus(url)
statusCode, err := getWebsiteStatus(target.URL)
end := time.Now().UnixNano() / int64(time.Millisecond)
if err != nil {
m.Config.Logger.PrintAndLog(logModuleName, "Ping upstream timeout. Assume offline", err)
m.Config.OnlineStateNotify(url, false)
return false, 0, 0
} else {
diff := end - start
succ := false
if statusCode >= 200 && statusCode < 300 {
//OK
succ = true
} else if statusCode >= 300 && statusCode < 400 {
//Redirection code
succ = true
} else {
succ = false
// Check if this is the first record
// sometime after startup the first check may fail due to network issues
// we will log it as failed but not notify dynamic proxy to take down the upstream
records, ok := m.OnlineStatusLog[target.ID]
if !ok || len(records) == 0 {
return false, 0, 0
}
m.Config.OnlineStateNotify(url, true)
return succ, diff, statusCode
// Otherwise assume offline
m.Config.OnlineStateNotify(target.URL, false)
return false, 0, 0
}
diff := end - start
succ := false
if statusCode >= 200 && statusCode < 300 {
//OK
succ = true
} else if statusCode >= 300 && statusCode < 400 {
//Redirection code
succ = true
} else {
succ = false
}
m.Config.OnlineStateNotify(target.URL, true)
return succ, diff, statusCode
}
func getWebsiteStatus(url string) (int, error) {

View File

@@ -18,7 +18,7 @@ func TestSizeStringToBytes(t *testing.T) {
{"1k", 1024, false},
{"1K", 1024, false},
{"2kb", 2 * 1024, false},
{"1m", 1024 * 1024, false},
{"1M", 1024 * 1024, false},
{"3mb", 3 * 1024 * 1024, false},
{"1g", 1024 * 1024 * 1024, false},
{"2gb", 2 * 1024 * 1024 * 1024, false},

View File

@@ -81,6 +81,26 @@ func PostPara(r *http.Request, key string) (string, error) {
return x, nil
}
// Get POST parameter as time.Duration
func PostDuration(r *http.Request, key string) (*time.Duration, error) {
// Try to parse the form
if err := r.ParseForm(); err != nil {
return nil, err
}
// Get first value from the form
x := r.Form.Get(key)
if len(x) == 0 {
return nil, errors.New("invalid " + key + " given")
}
duration, err := time.ParseDuration(x)
if err != nil {
return nil, errors.Join(errors.New("invalid "+key+" duration"), err)
}
return &duration, nil
}
// Get POST paramter as boolean, accept 1 or true
func PostBool(r *http.Request, key string) (bool, error) {
x, err := PostPara(r, key)

View File

@@ -244,6 +244,9 @@ func ReverseProxyHandleAddEndpoint(w http.ResponseWriter, r *http.Request) {
enableUtm = true
}
// Disable logging?
disableLog, _ := utils.PostBool(r, "disableLog")
useBypassGlobalTLS := bypassGlobalTLS == "true"
//Enable TLS validation?
@@ -416,6 +419,7 @@ func ReverseProxyHandleAddEndpoint(w http.ResponseWriter, r *http.Request) {
Tags: tags,
DisableUptimeMonitor: !enableUtm,
DisableLogging: disableLog,
}
preparedEndpoint, err := dynamicProxyRouter.PrepareProxyRoute(&thisProxyEndpoint)
@@ -570,6 +574,9 @@ func ReverseProxyHandleEditEndpoint(w http.ResponseWriter, r *http.Request) {
// Disable chunked Encoding
disableChunkedEncoding, _ := utils.PostBool(r, "dChunkedEnc")
// Disable logging
disableLogging, _ := utils.PostBool(r, "dLogging")
//Load the previous basic auth credentials from current proxy rules
targetProxyEntry, err := dynamicProxyRouter.LoadProxy(rootNameOrMatchingDomain)
if err != nil {
@@ -611,6 +618,7 @@ func ReverseProxyHandleEditEndpoint(w http.ResponseWriter, r *http.Request) {
newProxyEndpoint.UseStickySession = useStickySession
newProxyEndpoint.DisableUptimeMonitor = disbleUtm
newProxyEndpoint.DisableChunkedTransferEncoding = disableChunkedEncoding
newProxyEndpoint.DisableLogging = disableLogging
newProxyEndpoint.Tags = tags
//Prepare to replace the current routing rule

View File

@@ -12,7 +12,6 @@ import (
"imuslab.com/zoraxy/mod/auth/sso/oauth2"
"imuslab.com/zoraxy/mod/eventsystem"
"imuslab.com/zoraxy/mod/utils"
"github.com/gorilla/csrf"
"imuslab.com/zoraxy/mod/access"
@@ -77,30 +76,33 @@ func startupSequence() {
SystemWideLogger = l
SystemWideLogger.Println("System wide logging is disabled, all logs will be printed to STDOUT only")
} else {
logRotateSize, err := utils.SizeStringToBytes(*logRotate)
// Load log configuration from file
logConfig, err := logger.LoadLogConfig(CONF_LOG_CONFIG)
if err != nil {
//Default disable
logRotateSize = 0
SystemWideLogger.Println("Failed to load log config, using defaults: " + err.Error())
logConfig = &logger.LogConfig{
Enabled: false,
MaxSize: "0",
Compress: true,
}
}
l.SetRotateOption(&logger.RotateOption{
Enabled: logRotateSize != 0,
MaxSize: int64(logRotateSize),
MaxBackups: 10,
Compress: *enableLogCompression,
BackupDir: "",
})
// Apply the configuration
if err := l.ApplyLogConfig(logConfig); err != nil {
SystemWideLogger.Println("Failed to apply log config: " + err.Error())
}
SystemWideLogger = l
if logRotateSize == 0 {
if !logConfig.Enabled {
SystemWideLogger.Println("Log rotation is disabled")
} else {
SystemWideLogger.Println("Log rotation is enabled, max log file size " + utils.BytesToHumanReadable(int64(logRotateSize)))
SystemWideLogger.Println("Log rotation is enabled, max log file size " + logConfig.MaxSize)
}
SystemWideLogger.Println("System wide logging is enabled")
}
LogViewer = logviewer.NewLogViewer(&logviewer.ViewerOption{
RootFolder: *path_logFile,
Extension: LOG_EXTENSION,
})
//Create database

View File

@@ -1568,6 +1568,15 @@
var access_ip_country_map = {};
function initIpAccessTable(ipAccessCounts){
// Filter out IPs with less than 100 requests
var filteredCounts = {};
for (var ip in ipAccessCounts) {
if (ipAccessCounts[ip] >= 100) {
filteredCounts[ip] = ipAccessCounts[ip];
}
}
ipAccessCounts = filteredCounts;
blacklist_currentPage = 1; // Reset to first page
blacklist_totalPages = Math.ceil(Object.keys(ipAccessCounts).length / blacklist_entriesPerPage);
function sortkv(obj) {

View File

@@ -284,6 +284,12 @@
<label>Allow plain HTTP access<br>
<small>Allow inbound connections without TLS/SSL</small></label>
</div>
<br>
<div class="ui checkbox" style="margin-top: 0.4em;">
<input type="checkbox" class="DisableLogging">
<label>Disable Requests Logging<br>
<small>Disable logging for all incoming requests for this hostname</small></label>
</div>
</div>
</div>
@@ -885,6 +891,7 @@
let rateLimit = $(editor).find(".RateLimit").val();
let bypassGlobalTLS = $(editor).find(".BypassGlobalTLS")[0].checked;
let disableChunkedTransferEncoding = $(editor).find(".DisableChunkedTransferEncoding")[0].checked;
let disableLogging = $(editor).find(".DisableLogging")[0].checked;
let tags = getTagsArrayFromEndpoint(uuid);
if (tags.length > 0){
tags = tags.join(",");
@@ -901,6 +908,7 @@
"authprovider" :authProviderType,
"rate" :requireRateLimit,
"dChunkedEnc": disableChunkedTransferEncoding,
"dLogging": disableLogging,
"ratenum" :rateLimit,
"tags": tags,
};
@@ -1238,6 +1246,12 @@
editor.find(".BypassGlobalTLS").on("change", function() {
saveProxyInlineEdit(uuid);
});
editor.find(".DisableLogging").off('change');
editor.find(".DisableLogging").prop("checked", subd.DisableLogging);
editor.find(".DisableLogging").on("change", function() {
saveProxyInlineEdit(uuid);
});
//Bind the edit button
editor.find(".downstream_primary_hostname_edit_btn").off("click").on("click", function(){

View File

@@ -178,7 +178,7 @@
<tr>
<th>Plugin Name</th>
<th>Descriptions</th>
<th>Catergory</th>
<th>Category</th>
<th>Action</th>
</tr></thead>
<tbody id="pluginTable">

View File

@@ -63,13 +63,20 @@
<label>Sticky Session<br><small>Enable stick session on upstream load balancing</small></label>
</div>
</div>
<div class="field">
<div class="field">
<div class="ui checkbox">
<input type="checkbox" id="enableUtm" checked>
<label>Enable uptime monitor<br><small>Automatically check upstream status and switch to another if offline</small>
</label>
</div>
</div>
<div class="field">
<div class="ui checkbox">
<input type="checkbox" id="disableLog">
<label>Disable Requests Logging<br><small>Disable requests logging for this host, recommended for high traffic sites</small>
</label>
</div>
</div>
<div class="field">
<label>Tags</label>
<input type="text" id="proxyTags" placeholder="e.g. mediaserver, management">
@@ -268,6 +275,7 @@
let useStickySessionLB = $("#useStickySessionLB")[0].checked;
let tags = $("#proxyTags").val().trim();
let enableUtm = $("#enableUtm")[0].checked;
let disableLog = $("#disableLog")[0].checked;
if (rootname.trim() == ""){
$("#rootname").parent().addClass("error");
@@ -302,7 +310,8 @@
access: accessRuleToUse,
stickysess: useStickySessionLB,
tags: tags,
enableUtm: enableUtm,
enableUtm: enableUtm,
disableLog: disableLog,
},
success: function(data){
if (data.error != undefined){

View File

@@ -109,6 +109,26 @@
<input type="password" id="oauth2ClientSecret" name="oauth2ClientSecret" placeholder="Enter Client Secret">
<small>Secret key of the OAuth2 application</small>
</div>
<div class="field">
<label for="oauth2CodeChallengeMethod">Code Challenge Method</label>
<div class="ui selection dropdown" id="oauth2CodeChallengeMethod">
<input type="hidden" name="oauth2CodeChallengeMethod">
<i class="dropdown icon"></i>
<div class="default text">Plain</div>
<div class="menu">
<div class="item" data-value="plain">Plain</div>
<div class="item" data-value="PKCE">PKCE</div>
<div class="item" data-value="PKCE_S256">PKCE (S256)</div>
</div>
</div>
<small>Options: <br>
Plain: No code challenge is used.<br>
PKCE: Uses a code challenge for added security.<br>
PKCE (S256): Uses a hashed code challenge (SHA-256) for maximum protection.<br>
<strong>Note:</strong> PKCE (especially S256) is recommended for better security.
</small>
</div>
<div class="field">
<label for="oauth2WellKnownUrl">Discovery URL</label>
<input type="text" id="oauth2WellKnownUrl" name="oauth2WellKnownUrl" placeholder="Enter Well-Known URL">
@@ -138,6 +158,13 @@
<input type="text" id="oauth2Scopes" name="oauth2Scopes" placeholder="Enter Scopes">
<small>Scopes required by the OAuth2 provider to retrieve information about the authenticated user. Refer to your OAuth2 provider documentation for more information about this. Optional if Well-Known url is configured.</small>
</div>
<div class="field">
<label for="oauth2ConfigurationCacheTime">Configuration cache time</label>
<input type="text" id="oauth2ConfigurationCacheTime" name="oauth2ConfigurationCacheTime" placeholder="Enter Configuration Cache Time">
<small>Time to cache OAuth2 configuration before refresh. Accepts Go time.Duration format (e.g. 1m, 10m, 1h). Defaults to 60s.</small>
</div>
<button class="ui basic button" type="submit"><i class="green check icon"></i> Apply Change</button>
<button class="ui basic button" type="button" id="oauth2Clear"><i class="red trash icon"></i> Clear</button>
</form>
@@ -299,6 +326,8 @@
$('#oauth2ClientId').val(data.oauth2ClientId);
$('#oauth2ClientSecret').val(data.oauth2ClientSecret);
$('#oauth2Scopes').val(data.oauth2Scopes);
$('#oauth2ConfigurationCacheTime').val(data.oauth2ConfigurationCacheTime);
$('[data-value="'+data.oauth2CodeChallengeMethod+'"]').click();
},
error: function(jqXHR, textStatus, errorThrown) {
console.error('Error fetching SSO settings:', textStatus, errorThrown);

View File

@@ -5,8 +5,9 @@
</div>
<div class="ui top attached tabular menu">
<a class="utils item active" data-tab="utiltab1"><i class="ui user circle blue icon"></i> Accounts</a>
<a class="utils item" data-tab="utiltab2">Toolbox</a>
<a class="utils item" data-tab="utiltab3">System</a>
<a class="utils item" data-tab="utiltab2"><i class="ui grey file alternate outline icon"></i> Logger</a>
<a class="utils item" data-tab="utiltab3">Toolbox</a>
<a class="utils item" data-tab="utiltab4">System</a>
</div>
<div class="ui bottom attached tab segment utilitiesTabs active" data-tab="utiltab1">
@@ -88,6 +89,60 @@
</div>
</div>
<div class="ui bottom attached tab segment utilitiesTabs" data-tab="utiltab2">
<!-- Log Settings -->
<h3>Log Settings</h3>
<p>Configure log rotation settings for the system logger</p>
<div class="ui basic segment">
<form id="log-settings-form" class="ui form">
<div class="field">
<div class="ui toggle checkbox">
<input type="checkbox" id="logRotationEnabled" name="enabled">
<label>Enable Log Rotation</label>
</div>
</div>
<div class="field">
<label>Maximum Log File Size</label>
<div class="ui right labeled input">
<input type="text" id="logMaxSize" name="maxSize" placeholder="e.g. 200M, 10K, 500" value="0">
<div class="ui basic label">bytes</div>
</div>
<small>Enter size with suffix (K, M, G) or plain number. Set to 0 to disable.</small>
</div>
<div class="field">
<label>Maximum Backup Files</label>
<input type="number" id="logMaxBackups" name="maxBackups" placeholder="10" min="1" value="16">
<small>Maximum number of rotated log files to keep.</small>
</div>
<div class="field">
<div class="ui checkbox">
<input type="checkbox" id="logCompressionEnabled" name="compress">
<label>Enable Log Compression</label>
</div>
<small>When enabled, rotated log files will be compressed using ZIP format.</small>
</div>
<button class="ui basic button" type="submit">
<i class="green save icon"></i> Save Settings
</button>
<button class="ui basic button" id="rotateLogBtn" onclick="triggerLogRotation(event)">
<i class="yellow archive icon" ></i> Rotate Log Now
</button>
<div id="logSettingsSuccessMsg" class="ui green message" style="display:none;">
<i class="checkmark icon"></i> Log settings updated successfully
</div>
<div id="logSettingsErrorMsg" class="ui red message" style="display:none;">
<i class="exclamation triangle icon"></i> <span id="logSettingsErrorText"></span>
</div>
</form>
</div>
<div class="ui divider"></div>
<!-- Log Viewer -->
<h3>System Log Viewer</h3>
<p>View and download Zoraxy log</p>
<a class="ui basic button" href="snippet/logview.html" target="_blank"><i class="ui blue file icon"></i> Open Log Viewer</a>
<div class="ui divider"></div>
</div>
<div class="ui bottom attached tab segment utilitiesTabs" data-tab="utiltab3">
<h3> IP Address to CIDR</h3>
<p>No experience with CIDR notations? Here are some tools you can use to make setting up easier.</p>
<div class="ui basic segment">
@@ -116,17 +171,13 @@
</div>
<div class="ui divider"></div>
</div>
<div class="ui bottom attached tab segment utilitiesTabs" data-tab="utiltab3">
<div class="ui bottom attached tab segment utilitiesTabs" data-tab="utiltab4">
<!-- Config Tools -->
<h3>System Backup & Restore</h3>
<p>Options related to system backup, migrate and restore.</p>
<button class="ui basic button" onclick="showSideWrapper('snippet/configTools.html');"><i class="ui green undo icon icon"></i> Open Config Tools</button>
<div class="ui divider"></div>
<!-- Log Viewer -->
<h3>System Log Viewer</h3>
<p>View and download Zoraxy log</p>
<a class="ui basic button" href="snippet/logview.html" target="_blank"><i class="ui blue file icon"></i> Open Log Viewer</a>
<div class="ui divider"></div>
<!-- System Information -->
<div id="zoraxyinfo">
<h3 class="ui header">
@@ -269,14 +320,6 @@
adminAddr: $('input[name=recvAddr]').val()
};
/*
var inputValid = validateSMTPInputs();
if (!inputValid){
msgbox("SMTP input not valid", false, 5000);
return;
}
*/
$.cjax({
type: "POST",
url: "/api/tools/smtp/set",
@@ -307,6 +350,7 @@
});
}
initSMTPSettings();
loadLogSettings();
function sendTestEmail(btn){
$(btn).addClass("loading").addClass("disabled");
@@ -472,4 +516,111 @@
}
return [ip >>> 24 & 0xFF, ip >>> 16 & 0xFF, ip >>> 8 & 0xFF, ip & 0xFF].join('.')
}
/*
Log Settings
*/
function loadLogSettings() {
$.get("/api/logger/config", function(data) {
if (data.error) {
console.error("Failed to load log settings:", data.error);
return;
}
$("#logRotationEnabled").prop("checked", data.enabled);
$("#logMaxSize").val(data.maxSize);
$("#logMaxBackups").val(data.maxBackups || 16);
$("#logCompressionEnabled").prop("checked", data.compress);
// Re-initialize checkboxes after setting values
$('.ui.checkbox').checkbox();
}).fail(function(xhr, status, error) {
console.error("Failed to load log settings:", error);
});
}
function saveLogSettings() {
const settings = {
enabled: $("#logRotationEnabled").is(":checked"),
maxSize: $("#logMaxSize").val().trim(),
maxBackups: parseInt($("#logMaxBackups").val()) || 16,
compress: $("#logCompressionEnabled").is(":checked")
};
// Validate maxSize format
const maxSizeRegex = /^\d+[KMG]?$/i;
if (!maxSizeRegex.test(settings.maxSize)) {
showLogSettingsError("Max size must be a number optionally followed by K, M, or G (e.g., 200M, 10K, 500)");
return;
}
// Basic validation
if (settings.maxSize === "") {
showLogSettingsError("Max size cannot be empty");
return;
}
if (settings.maxBackups < 1) {
showLogSettingsError("Max backups must be at least 1");
return;
}
$.cjax({
type: "POST",
url: "/api/logger/config",
data: JSON.stringify(settings),
success: function(data) {
if (data.error) {
showLogSettingsError(data.error);
} else {
showLogSettingsSuccess();
}
},
error: function(xhr, status, error) {
showLogSettingsError("Failed to save settings: " + error);
}
});
}
function showLogSettingsSuccess() {
$("#logSettingsErrorMsg").hide();
$("#logSettingsSuccessMsg").stop().finish().slideDown("fast").delay(3000).slideUp("fast");
}
function showLogSettingsError(message) {
$("#logSettingsSuccessMsg").hide();
$("#logSettingsErrorText").text(message);
$("#logSettingsErrorMsg").stop().finish().slideDown("fast").delay(5000).slideUp("fast");
}
function triggerLogRotation(event) {
event.preventDefault();
event.stopImmediatePropagation();
// Show loading state on button
const rotateBtn = $('#rotateLogBtn');
const originalText = rotateBtn.html();
rotateBtn.html('<i class="spinner loading icon"></i> Rotating...').addClass('loading disabled');
$.get("/api/log/rotate/trigger", function(data) {
if (data.error) {
showLogSettingsError("Failed to rotate log: " + data.error);
} else {
showLogSettingsSuccess();
// Update success message for rotation
$("#logSettingsSuccessMsg").html('<i class="archive icon"></i> Log rotation triggered successfully').stop().finish().slideDown("fast").delay(3000).slideUp("fast");
}
}).fail(function(xhr, status, error) {
showLogSettingsError("Failed to rotate log: " + error);
}).always(function() {
// Restore button state
rotateBtn.html(originalText).removeClass('loading disabled');
});
}
// Initialize Semantic UI checkboxes
$('.ui.checkbox').checkbox();
// Bind form submission
$("#log-settings-form").submit(function(e) {
e.preventDefault();
saveLogSettings();
});
</script>

View File

@@ -408,8 +408,10 @@
$("#kidInput").show();
$("#hmacInput").show();
$("#skipTLS").show();
$("#dnsChallenge").hide();
$(".dnsChallengeOnly").hide();
$("#dnsChallenge").show();
if ($("#useDnsChallenge")[0].checked){
$(".dnsChallengeOnly").show();
}
} else if (this.value == "ZeroSSL") {
$("#kidInput").show();
$("#hmacInput").show();
@@ -468,7 +470,7 @@
defaultIntValue = 2;
defaultMinValue = 1;
}else if (key == "PropagationTimeout"){
defaultIntValue = 120;
defaultIntValue = 600;
defaultMinValue = 30;
}
optionalFieldsHTML += (`<div class="ui fluid labeled dnsConfigField small input" key="${key}" style="margin-top: 0.2em;">

View File

@@ -10,7 +10,7 @@
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
<script type="text/javascript" src="../script/jquery-3.6.0.min.js"></script>
<script type="text/javascript" src="../script/semantic/semantic.min.js"></script>
<link rel="stylesheet" href="main.css">
<link rel="stylesheet" href="../main.css">
<style>
.clickable{
cursor: pointer;
@@ -149,6 +149,20 @@
<!-- Log files will be populated here -->
</div>
</div>
<!-- Lines Dropdown -->
<div class="ui selection dropdown" id="linesDropdown" style="margin-left: 0.4em; margin-top: 0.4em; height: 2.8em;">
<div class="text">Last 100 Lines</div>
<i class="dropdown icon"></i>
<div class="menu">
<div class="item selected" data-value="100">Last 100 Lines</div>
<div class="item" data-value="300">Last 300 Lines</div>
<div class="item" data-value="500">Last 500 Lines</div>
<div class="item" data-value="1000">Last 1000 Lines</div>
<div class="item" data-value="2000">Last 2000 Lines</div>
<div class="item" data-value="all">All Lines</div>
</div>
</div>
<!-- Download Button -->
<button class="ui icon basic button logfile_menu_btn" id="downloadLogBtn" title="Download Current Log File">
@@ -263,11 +277,13 @@ Pick a log file from the menu to start debugging
<script>
//LogView Implementation
var currentFilter = "all";
var currentLines = "100";
var currentOpenedLogURL = "";
var currentLogFile = "";
var autoscroll = false;
$(".checkbox").checkbox();
$(".dropdown").dropdown();
/* Menu Subpanel Switch */
$(".subpanel").hide();
@@ -289,7 +305,7 @@ Pick a log file from the menu to start debugging
/* Refresh Button */
$("#refreshLogBtn").on("click", function() {
if (currentLogFile) {
openLog(null, null, currentLogFile, currentFilter);
openLog(null, null, currentLogFile, currentFilter, currentLines);
loadLogSummary(currentLogFile);
} else {
alert('Please select a log file first.');
@@ -299,6 +315,7 @@ Pick a log file from the menu to start debugging
/* Log file dropdown */
function populateLogfileDropdown() {
$.get("/api/log/list", function(data){
console.log(data);
let $menu = $("#logfileDropdownMenu");
$menu.html("");
for (let [key, value] of Object.entries(data)) {
@@ -310,17 +327,12 @@ Pick a log file from the menu to start debugging
});
}
$('#logfileDropdown').dropdown('refresh');
//let firstItem = $menu.find('.item').first();
//if (firstItem.length) {
// $('#logfileDropdown').dropdown('set selected', firstItem.data('value'));
//}
});
}
$('#logfileDropdown').dropdown({
onChange: function(value, text, $choice) {
if (value) {
openLog(null, $choice.data('category'), value, currentFilter || "all");
openLog(null, $choice.data('category'), value, currentFilter, currentLines);
loadLogSummary(value);
}
}
@@ -336,7 +348,7 @@ Pick a log file from the menu to start debugging
}
$(".filterbtn.active").removeClass("active");
$(`.filterbtn[filter="${value}"]`).addClass("active");
openLog(null, null, currentLogFile, currentFilter);
openLog(null, null, currentLogFile, currentFilter, currentLines);
}
});
@@ -344,17 +356,30 @@ Pick a log file from the menu to start debugging
$('#filterDropdown').dropdown('set selected', 'all');
currentFilter = "all";
/* Lines dropdown */
$('#linesDropdown').dropdown({
onChange: function(value) {
currentLines = value;
if (!currentLogFile) {
return;
}
openLog(null, null, currentLogFile, currentFilter, currentLines);
}
});
// Set default lines to 100
$('#linesDropdown').dropdown('set selected', '100');
currentLines = "100";
/* Log download button */
$("#downloadLogBtn").on("click", function() {
if (!currentLogFile) {
alert("Please select a log file first.");
return;
}
if (!currentOpenedLogURL) {
alert("No log file is currently opened.");
return;
}
$.get(currentOpenedLogURL, function(data) {
// Always download the full log file, regardless of current line limit
let downloadURL = "/api/log/read?file=" + currentLogFile + "&filter=" + currentFilter + "&lines=all";
$.get(downloadURL, function(data) {
if (data.error !== undefined) {
alert(data.error);
return;
@@ -566,11 +591,11 @@ Pick a log file from the menu to start debugging
}
function openLog(object, catergory, filename, filter="all"){
function openLog(object, catergory, filename, filter="all", lines="100"){
$(".logfile.active").removeClass('active');
$(object).addClass("active");
currentLogFile = filename;
currentOpenedLogURL = "/api/log/read?file=" + filename + "&filter=" + filter;
currentOpenedLogURL = "/api/log/read?file=" + filename + "&filter=" + filter + "&lines=" + lines;
$.get(currentOpenedLogURL, function(data){
if (data.error !== undefined){
alert(data.error);

View File

@@ -79,7 +79,6 @@ func getExcludedDNSProviders() []string {
"dnshomede", //Multi-credentials arch
"myaddr", //Multi-credentials arch
"oraclecloud", //Evil company
"acmedns", //Not a DNS provider
"selectelv2", //Not sure why not working with our code generator
"designate", //OpenStack, if you are using this you shd not be using zoraxy
"mythicbeasts", //Module require url.URL, which cannot be automatically parsed
@@ -297,6 +296,16 @@ func main() {
cfg.PropagationTimeout = pgDuration
cfg.PollingInterval = plInterval
return ` + providerName + `.NewDNSProviderConfig(cfg)`
if providerName == "acmedns" {
codeSegment = `
case "` + providerName + `":
cfg := ` + providerName + `.NewDefaultConfig()
err := json.Unmarshal([]byte(js), &cfg)
if err != nil {
return nil, err
}
return ` + providerName + `.NewDNSProviderConfig(cfg)`
}
generatedConvertcode += codeSegment
importList += ` "github.com/go-acme/lego/v4/providers/dns/` + providerName + "\"\n"
}