Automatically generate flags (#1988)

This commit is contained in:
Philip O'Toole
2024-12-03 08:23:46 -05:00
committed by GitHub
parent 5f587c5724
commit 58240d2e5d
9 changed files with 929 additions and 60 deletions

4
.gitignore vendored
View File

@@ -11,6 +11,10 @@ rqbench
**/rqbench
!**/rqbench/
genflags
**/genflags
!**/genflags/
walr
**/walr

View File

@@ -1,3 +1,8 @@
## v8.34.4 (unreleased)
### Implementation changes and bug fixes
- [PR #1988](https://github.com/rqlite/rqlite/pull/1988): Automatically generate flags and associated documentation.
- [PR #1988](https://github.com/rqlite/rqlite/pull/1988): Upgrade dependencies.
## v8.34.3 (November 27th 2024)
### Implementation changes and bug fixes
- [PR #1986](https://github.com/rqlite/rqlite/pull/1986): Improve logging a little bit, making operation clearer and easier.

535
flags/flags.toml Normal file
View File

@@ -0,0 +1,535 @@
[[flags]]
name = "ExtensionPaths"
cli = "--extensions-path"
type = "stringslicevalue"
short_help = "Comma-delimited list of paths to directories, zipfiles, or tar.gz files containing SQLite extensions"
long_help = """
"""
default = ""
[[flags]]
name = "HTTPAddr"
cli = "--http-addr"
type = "string"
short_help = "HTTP server bind address. To enable HTTPS, set X.509 certificate and key"
long_help = """
This is the interface rqlite will listen on for API requests. 0.0.0.0 is an acceptable address and will mean that rqlited will listen on all interfaces.
"""
default = "localhost:4001"
[[flags]]
name = "HTTPAdv"
cli = "--http-adv-addr"
type = "string"
short_help = "Advertised HTTP server network address If not set, same as HTTP server bind address"
long_help = """
This is the HTTP API address an rqlited node will advertise to other nodes (and clients) as needed. This will need to be set if your rqlited node binds to all network addresses via 0.0.0.0, or if it binds to a private network address behind a firewall.
"""
default = ""
[[flags]]
name = "HTTPAllowOrigin"
cli = "--http-allow-origin"
type = "string"
short_help = "Value to set for Access-Control-Allow-Origin HTTP header"
long_help = """
You usually need to set this if if you're using a browser-based application to interfact with rqlite. You should set it to the the website that is serving the browser-based application e.g. --http-allow-origin="https://example.com".
"""
default = ""
[[flags]]
name = "AuthFile"
cli = "--auth"
type = "string"
short_help = "Path to the authentication file. If not set, authentication is not enabled"
long_help = """
"""
default = ""
[[flags]]
name = "AutoBackupFile"
cli = "--auto-backup"
type = "string"
short_help = "Path to the auto-backup file. If not set, automatic backup is not enabled"
long_help = """
"""
default = ""
[[flags]]
name = "AutoRestoreFile"
cli = "--auto-restore"
type = "string"
short_help = "Path to the auto-restore file. If not set, automatic restore is not enabled"
long_help = """
"""
default = ""
[[flags]]
name = "HTTPx509CACert"
cli = "--http-ca-cert"
type = "string"
short_help = "Path to the CA certificate file for HTTPS communications"
long_help = """
If this value is set rqlite will use this CA certificate to validate any other X509 certficate presented to it, if the node needs to contact another node's HTTP API. It also uses this CA to verify any X509 certificates presented to it by clients connecting to its HTTPS API.
"""
default = ""
[[flags]]
name = "HTTPx509Cert"
cli = "--http-cert"
type = "string"
short_help = "Path to the X509 certificate for the HTTPS server. If not set HTTPS is not enabled"
long_help = """
This is the certificate rqlite will present to any client connecting to it via HTTPS.
"""
default = ""
[[flags]]
name = "HTTPx509Key"
cli = "--http-key"
type = "string"
short_help = "Path to the private key for the HTTPS server"
long_help = """
This is the private key corresponding to the X509 certificate.
"""
default = ""
[[flags]]
name = "HTTPVerifyClient"
cli = "--http-verify-client"
type = "bool"
short_help = "Whether the HTTP server should verify client X509 certificates"
long_help = """
This allows you to control which clients can connect to the HTTPS API, as only clients presenting certificates that have been signed by the CA will be able to connect to the node.
"""
default = false
[[flags]]
name = "NodeX509CACert"
cli = "--node-ca-cert"
type = "string"
short_help = "Path to the CA certificate file for inter-node communications. May not be set"
long_help = """
If this path is set, and nodes enable TLS inter-node communications i.e. over the Raft TCP port, then the certificates presented by a node must be signed by this Certificate Authority.
"""
default = ""
[[flags]]
name = "NodeX509Cert"
cli = "--node-cert"
type = "string"
short_help = "Path to the X509 certificate for inter-node communications"
long_help = """
Setting this path enables TLS-encrypted inter-node communications. Specifically this is the certificate presented by this node when another node connects to it. If not set the node does not enable TLS.
"""
default = ""
[[flags]]
name = "NodeX509Key"
cli = "--node-key"
type = "string"
short_help = "Path to the X509 key for inter-node communications"
long_help = """
This is the private key corresponding to the node's X509 certificate, which it uses for inter-node communications.
"""
default = ""
[[flags]]
name = "NoNodeVerify"
cli = "--node-no-verify"
type = "bool"
short_help = "Disables checking other nodes' X509 certificates for validity. Checking is enabled by default"
long_help = """
Validity is defined as signed by an acceptable CA, that the hostname in the certificate matches the hostname of the connecting node, and that the presented certificates are not expired.
"""
default = false
[[flags]]
name = "NodeVerifyClient"
cli = "--node-verify-client"
type = "bool"
short_help = "Enable mutual TLS for node-to-node communication. Disabled by default"
long_help = """
This allows a node to control which other nodes can connect to it. If a node attempting to connect to this node does not present a certificate signed by an acceptable CA, the connection will be refused.
"""
default = false
[[flags]]
name = "NodeVerifyServerName"
cli = "--node-verify-server-name"
type = "string"
short_help = "Hostname to verify on certificates returned by nodes"
long_help = """
When node verifies a certificate it normally checks that the hostname in the certificate matches the hostname of the connecting node. This flags explicitly tells the node which hostname will actually be in the presented certificate. This allows you to sign a single certificate, with a single hostname, and distribute that to all nodes. It's mostly useful when enabling mutual TLS.
"""
default = ""
[[flags]]
name = "NodeID"
cli = "--node-id"
type = "string"
short_help = "Unique Raft ID for the node. If not set, defaults to the advertised Raft address"
long_help = """
While not required, providing an explicit ID to a node makes cluster management simpler. Once set a node's ID cannot change. If you do change it your cluster will not operate correctly.
"""
default = ""
[[flags]]
name = "RaftAddr"
cli = "--raft-addr"
type = "string"
short_help = "Bind network address for the Raft server in the form address:port"
long_help = """
This is the interace rqlite will listen on for connections from other node, as part of managing Raft consensus. 0.0.0.0 is an acceptable address and will mean that `rqlited` will listen on all interfaces.
"""
default = "localhost:4002"
[[flags]]
name = "RaftAdv"
cli = "--raft-adv-addr"
type = "string"
short_help = "Advertised Raft server address. If not set, same as Raft server bind address"
long_help = """
This is the Raft address an rqlite node will advertise to other nodes, as part of managing Raft consensus. This will need to be set if your node binds to all network addresses via 0.0.0.0, or if it binds to a private network address behind a firewall.
"""
default = ""
[[flags]]
name = "JoinAddrs"
cli = "--join"
type = "string"
short_help = "List of Raft addresses to use for a join attempt. Comma-delimited list of nodes in host:port format"
long_help = """
The node will try each join addresss, one after the other, until one succeeds or the join-attempt limit is reached.
"""
default = ""
[[flags]]
name = "JoinAttempts"
cli = "--join-attempts"
type = "int"
short_help = "Number of times a node should attempt to join a cluster using a given address"
long_help = """
"""
default = 5
[[flags]]
name = "JoinInterval"
cli = "--join-interval"
type = "duration"
short_help = "Time between retrying failed join operations"
long_help = """
"""
default = "3s"
[[flags]]
name = "JoinAs"
cli = "--join-as"
type = "string"
short_help = "User to perform join attempts as. If not set, joins anonymously"
long_help = """
If joining a cluster requires credentials you can a tell a node to read those credentials from a credential file, for the specified user. By using this flag you can avoid setting credentials in the command line you pass to rqlited, which can expose those credentials if someone has access to the process table.
"""
default = ""
[[flags]]
name = "BootstrapExpect"
cli = "--bootstrap-expect"
type = "int"
short_help = "Minimum number of nodes required for a bootstrap"
long_help = """
This flag provides the number of expected nodes in the cluster. Either this value should not be provided or the value must agree with other nodes in the cluster. When provided, rqlite waits until the specified number of servers are available and then bootstraps the cluster. This allows an initial leader to be elected automatically.
"""
default = 0
[[flags]]
name = "BootstrapExpectTimeout"
cli = "--bootstrap-expect-timeout"
type = "duration"
short_help = "Maximum time a bootstrap operation can take"
long_help = """
If a bootstrap operation does not succeed with this time, cluster formation will abort.
"""
default = "120s"
[[flags]]
name = "DiscoMode"
cli = "--disco-mode"
type = "string"
short_help = "Discovery mode. If not set, no node discovery is performed"
long_help = """
"""
default = ""
[[flags]]
name = "DiscoKey"
cli = "--disco-key"
type = "string"
short_help = "Discovery prefix key"
long_help = """
This allows you to use the same Discovery infrastructure e.g. Consul with multiple different rqlite clusters. Each rqlite cluster can use a different prefix key to separate its Discovery information from other clusters using the same infrastructure.
"""
default = "rqlite"
[[flags]]
name = "DiscoConfig"
cli = "--disco-config"
type = "string"
short_help = "Path to Discovery configuration file. May not be set."
long_help = """
"""
default = ""
[[flags]]
name = "OnDiskPath"
cli = "--on-disk-path"
type = "string"
short_help = "Path to the SQLite on-disk database file. If not set, uses a file in the data directory."
long_help = """
Generally speaking you shouldn't need to set this. Your system is easiest to manage if you let rqlite manage the SQLite database. However this can be useful under certain performance-sensitive scenarious.
"""
default = ""
[[flags]]
name = "FKConstraints"
cli = "--fk"
type = "bool"
short_help = "Enable SQLite foreign key constraints"
long_help = """
SQLite doesn't enable foreign key constraints by default. If you'd like rqlite to automatically do so then set this flag. This flag must be set on every node in your cluster.
"""
default = false
[[flags]]
name = "AutoVacInterval"
cli = "--auto-vacuum-int"
type = "duration"
short_help = "Automatic VACUUM interval. Use 0s to disable. If not set, automatic VACUUM is not enabled"
long_help = """
If set to a non-zero interval rqlite will execute VACUUM on the specified interval. This can help reduce SQLite disk usage, but writes are blocked while a VACUUM takes place. See the SQLite documentation for more information.
"""
default = "0s"
[[flags]]
name = "AutoOptimizeInterval"
cli = "--auto-optimize-int"
type = "duration"
short_help = "Automatic optimization interval. Use 0h to disable"
long_help = """
If set to a non-zero interval rqlite will execute PRAGMA OPTIMIZE on the specified interval. This can help SQLite query performance. See the SQLite documentation for more information.
"""
default = "24h"
[[flags]]
name = "RaftLogLevel"
cli = "--raft-log-level"
type = "string"
short_help = "Minimum logging level for the Raft subsystem"
long_help = """
Acceptable log levels are ERROR, WARN, INFO and DEBUG.
"""
default = "WARN"
[[flags]]
name = "RaftNonVoter"
cli = "--raft-non-voter"
type = "bool"
short_help = "Configure as a non-voting node"
long_help = """
Adding non-voting (also known as read-only) nodes can help scale out query performance. Read-only nodes don't particpate in the Raft consensus system, but do receive the same stream of updates from the Leader as voting nodes do.
"""
default = false
[[flags]]
name = "RaftSnapThreshold"
cli = "--raft-snap"
type = "uint64"
short_help = "Number of outstanding log entries that trigger a snapshot"
long_help = """
Snapshotting is a critical part of the Raft subsystem, which involves storing a copy of the SQLite database and then truncating the Raft log. Writes are blocked during the Snapshot process, but more regular snapshotting can mean faster start-up times, as there will generally be fewer logs to apply when a node restarts.
"""
default = 8192
[[flags]]
name = "RaftSnapThresholdWALSize"
cli = "--raft-snap-wal-size"
type = "uint64"
short_help = "Size of a SQLite WAL file which triggers a snapshot.Set to 0 to disable"
long_help = """
rqlite, by default, will also trigger a snapshot if the WAL gets larger than 4MB. Large SQLite WAL files can decrease query performance, and since snapshotting involves checkpointing the WAL file, snapshotting is an effective way to limit WAL size. However writes are blocked during the snapshotting process, so it's trade-off.
"""
default = 4194304
[[flags]]
name = "RaftSnapInterval"
cli = "--raft-snap-int"
type = "duration"
short_help = "Snapshot threshold check interval"
long_help = """
This controls how often the Raft subsystem will check if snapshotting is required, either due to the number of oustanding log entries, or due to WAL size.
"""
default = "10s"
[[flags]]
name = "RaftLeaderLeaseTimeout"
cli = "--raft-leader-lease-timeout"
type = "duration"
short_help = "Leader lease timeout. Use 0s for Raft default"
long_help = """
This is used to control how long the "lease" lasts for being the Leader without being able to contact a quorum If a Leader reaches this interval without contact, it will step down as Leader.
"""
default = "0s"
[[flags]]
name = "RaftHeartbeatTimeout"
cli = "--raft-timeout"
type = "duration"
short_help = "Heartbeat timeout for Raft consensus"
long_help = """
Specifies the time a Follower will wait without contact from a Leader before the Follower initiates an election.
"""
default = "1s"
[[flags]]
name = "RaftElectionTimeout"
cli = "--raft-election-timeout"
type = "duration"
short_help = "Election timeout for Raft consensus"
long_help = """
Specifies the time a Candidate will wait without contact from a Leader before the Candidate initiates a new election.
"""
default = "1s"
[[flags]]
name = "RaftApplyTimeout"
cli = "--raft-apply-timeout"
type = "duration"
short_help = "Log-apply timeout"
long_help = """
"""
default = "10s"
[[flags]]
name = "RaftShutdownOnRemove"
cli = "--raft-remove-shutdown"
type = "bool"
short_help = "Shutdown Raft if the node is removed from the cluster"
long_help = """
This ensures a node doesn't self-elect itself as Leader if it finds itself as the sole node in a single-node cluster.
"""
default = false
[[flags]]
name = "RaftClusterRemoveOnShutdown"
cli = "--raft-cluster-remove-shutdown"
type = "bool"
short_help = "Node removes itself from the cluster on shutdown"
long_help = """
If enabled a node will attempt to remove itself from the cluster just before it shuts down. This is a best effort operation, and only occurs if the node is shut down gracefully.
"""
default = false
[[flags]]
name = "RaftStepdownOnShutdown"
cli = "--raft-shutdown-stepdown"
type = "bool"
short_help = "Relinquish leadership on shutdown."
long_help = """
If a node is being shutdown, and it's the Leader, this helps minimize the time the cluster is without a Leader. The leader will stop accepting client requests, make sure a target node is up to date and starts the transfer with a _TimeoutNow_ message. This message has the same effect as if the election timeout on the target server fires.
"""
default = true
[[flags]]
name = "RaftReapNodeTimeout"
cli = "--raft-reap-node-timeout"
type = "duration"
short_help = "Duration after which a non-reachable voting node is reaped. If not set, no reaping takes place"
long_help = """
Use this feature with caution, otherwise you may reap a node which has simply become unreachable.
"""
default = "0h"
[[flags]]
name = "RaftReapReadOnlyNodeTimeout"
cli = "--raft-reap-read-only-node-timeout"
type = "duration"
short_help = "Duration after which a non-reachable non-voting node is reaped. If not set, no reaping takes place"
long_help = """
This can be useful if you have a deployment where non-voting nodes tend to come and go, and you want to avoid explicitly removing those nodes.
"""
default = "0h"
[[flags]]
name = "ClusterConnectTimeout"
cli = "--cluster-connect-timeout"
type = "duration"
short_help = "Timeout when connecting to another node in the cluster"
long_help = """
This sets the maximum time a node will wait when attempting to connect to another node over the inter-node network connection.
"""
default = "30s"
[[flags]]
name = "WriteQueueCap"
cli = "--write-queue-capacity"
type = "int"
short_help = "Default capacity of execute queues"
long_help = """
The larger this value the more Queued Write requests can be queued up internally by the node. This queue is asynchronously drained, as requests are transmitted through the Raft log. Any time the queue is full Queued Writes requests are blocked.
"""
default = 1024
[[flags]]
name = "WriteQueueBatchSz"
cli = "--write-queue-batch-size"
type = "int"
short_help = "Default batch size for execute queues"
long_help = """
The larger the batch size the more Queued Write statements will be batched from the internal queue and stored in a single Raft log entry. However, larger batches will consume more memory, and may increase latency.
"""
default = 128
[[flags]]
name = "WriteQueueTimeout"
cli = "--write-queue-timeout"
type = "duration"
short_help = "Time after which internally queued Queued Writes will be sent on if the batch size isn't reached"
long_help = """
"""
default = "50ms"
[[flags]]
name = "WriteQueueTx"
cli = "--write-queue-tx"
type = "bool"
short_help = "Use a transaction when executing a Queued Write batch"
long_help = """
"""
default = false
[[flags]]
name = "CPUProfile"
cli = "--cpu-profile"
type = "string"
short_help = "Write CPU profie information to a file at this path"
long_help = """
"""
default = ""
[[flags]]
name = "MemProfile"
cli = "--mem-profile"
type = "string"
short_help = "Write memory profie information to a file at this path"
long_help = """
"""
default = ""
[[flags]]
name = "TraceProfile"
cli = "--trace-profile"
type = "string"
short_help = "Write trace profie information to a file at this path"
long_help = """
"""
default = ""

2
flags/gen.go Normal file
View File

@@ -0,0 +1,2 @@
//go:generate genflags flags.toml flags.go
package flags

54
go.mod
View File

@@ -6,11 +6,11 @@ toolchain go1.23.3
require (
github.com/Bowery/prompt v0.0.0-20190916142128-fa8279994f75
github.com/aws/aws-sdk-go-v2 v1.32.4
github.com/aws/aws-sdk-go-v2/config v1.28.4
github.com/aws/aws-sdk-go-v2/credentials v1.17.45
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.38
github.com/aws/aws-sdk-go-v2/service/s3 v1.67.0
github.com/aws/aws-sdk-go-v2 v1.32.5
github.com/aws/aws-sdk-go-v2/config v1.28.5
github.com/aws/aws-sdk-go-v2/credentials v1.17.46
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.41
github.com/aws/aws-sdk-go-v2/service/s3 v1.69.0
github.com/hashicorp/go-hclog v1.6.3
github.com/hashicorp/raft v1.7.1
github.com/mkideal/cli v0.2.7
@@ -19,6 +19,7 @@ require (
github.com/rqlite/raft-boltdb/v2 v2.0.0-20230523104317-c08e70f4de48
github.com/rqlite/rqlite-disco-clients v0.0.0-20231230135307-118e35426347
github.com/rqlite/sql v0.0.0-20241111133259-a4122fabb196
github.com/spf13/viper v1.19.0
go.etcd.io/bbolt v1.3.11
golang.org/x/net v0.31.0
google.golang.org/protobuf v1.35.2
@@ -26,23 +27,24 @@ require (
require (
github.com/armon/go-metrics v0.5.3 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.19 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.23 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.23 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.20 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.24 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.24 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.23 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.4 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.4 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.4 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.24.5 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.4 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.33.0 // indirect
github.com/aws/smithy-go v1.22.0 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.24 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.5 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.5 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.5 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.24.6 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.5 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.33.1 // indirect
github.com/aws/smithy-go v1.22.1 // indirect
github.com/coreos/go-semver v0.3.1 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/fsnotify/fsnotify v1.8.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/hashicorp/consul/api v1.30.0 // indirect
@@ -54,13 +56,23 @@ require (
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/serf v0.10.1 // indirect
github.com/labstack/gommon v0.4.2 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mkideal/expr v0.1.0 // indirect
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
github.com/sagikazarmark/locafero v0.6.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.7.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
go.etcd.io/etcd/api/v3 v3.5.17 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.17 // indirect
go.etcd.io/etcd/client/v3 v3.5.17 // indirect
@@ -71,9 +83,11 @@ require (
golang.org/x/sys v0.27.0 // indirect
golang.org/x/term v0.26.0 // indirect
golang.org/x/text v0.20.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20241113202542-65e8d215514f // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241113202542-65e8d215514f // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 // indirect
google.golang.org/grpc v1.68.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
replace (

116
go.sum
View File

@@ -8,44 +8,44 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/aws/aws-sdk-go-v2 v1.32.4 h1:S13INUiTxgrPueTmrm5DZ+MiAo99zYzHEFh1UNkOxNE=
github.com/aws/aws-sdk-go-v2 v1.32.4/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 h1:pT3hpW0cOHRJx8Y0DfJUEQuqPild8jRGmSFmBgvydr0=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6/go.mod h1:j/I2++U0xX+cr44QjHay4Cvxj6FUbnxrgmqN3H1jTZA=
github.com/aws/aws-sdk-go-v2/config v1.28.4 h1:qgD0MKmkIzZR2DrAjWJcI9UkndjR+8f6sjUQvXh0mb0=
github.com/aws/aws-sdk-go-v2/config v1.28.4/go.mod h1:LgnWnNzHZw4MLplSyEGia0WgJ/kCGD86zGCjvNpehJs=
github.com/aws/aws-sdk-go-v2/credentials v1.17.45 h1:DUgm5lFso57E7150RBgu1JpVQoF8fAPretiDStIuVjg=
github.com/aws/aws-sdk-go-v2/credentials v1.17.45/go.mod h1:dnBpENcPC1ekZrGpSWspX+ZRGzhkvqngT2Qp5xBR1dY=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.19 h1:woXadbf0c7enQ2UGCi8gW/WuKmE0xIzxBF/eD94jMKQ=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.19/go.mod h1:zminj5ucw7w0r65bP6nhyOd3xL6veAUMc3ElGMoLVb4=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.38 h1:xN0PViSptTHJ7QIKyWeWntuTCZoejutTPfhsZIoMDy0=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.38/go.mod h1:orUzUoWBICDyc+hz49KpySb3sa2Tw3c0IaFqrH4c4dg=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.23 h1:A2w6m6Tmr+BNXjDsr7M90zkWjsu4JXHwrzPg235STs4=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.23/go.mod h1:35EVp9wyeANdujZruvHiQUAo9E3vbhnIO1mTCAxMlY0=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.23 h1:pgYW9FCabt2M25MoHYCfMrVY2ghiiBKYWUVXfwZs+sU=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.23/go.mod h1:c48kLgzO19wAu3CPkDWC28JbaJ+hfQlsdl7I2+oqIbk=
github.com/aws/aws-sdk-go-v2 v1.32.5 h1:U8vdWJuY7ruAkzaOdD7guwJjD06YSKmnKCJs7s3IkIo=
github.com/aws/aws-sdk-go-v2 v1.32.5/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 h1:lL7IfaFzngfx0ZwUGOZdsFFnQ5uLvR0hWqqhyE7Q9M8=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7/go.mod h1:QraP0UcVlQJsmHfioCrveWOC1nbiWUl3ej08h4mXWoc=
github.com/aws/aws-sdk-go-v2/config v1.28.5 h1:Za41twdCXbuyyWv9LndXxZZv3QhTG1DinqlFsSuvtI0=
github.com/aws/aws-sdk-go-v2/config v1.28.5/go.mod h1:4VsPbHP8JdcdUDmbTVgNL/8w9SqOkM5jyY8ljIxLO3o=
github.com/aws/aws-sdk-go-v2/credentials v1.17.46 h1:AU7RcriIo2lXjUfHFnFKYsLCwgbz1E7Mm95ieIRDNUg=
github.com/aws/aws-sdk-go-v2/credentials v1.17.46/go.mod h1:1FmYyLGL08KQXQ6mcTlifyFXfJVCNJTVGuQP4m0d/UA=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.20 h1:sDSXIrlsFSFJtWKLQS4PUWRvrT580rrnuLydJrCQ/yA=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.20/go.mod h1:WZ/c+w0ofps+/OUqMwWgnfrgzZH1DZO1RIkktICsqnY=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.41 h1:hqcxMc2g/MwwnRMod9n6Bd+t+9Nf7d5qRg7RaXKPd6o=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.41/go.mod h1:d1eH0VrttvPmrCraU68LOyNdu26zFxQFjrVSb5vdhog=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.24 h1:4usbeaes3yJnCFC7kfeyhkdkPtoRYPa/hTmCqMpKpLI=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.24/go.mod h1:5CI1JemjVwde8m2WG3cz23qHKPOxbpkq0HaoreEgLIY=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.24 h1:N1zsICrQglfzaBnrfM0Ys00860C+QFwu6u/5+LomP+o=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.24/go.mod h1:dCn9HbJ8+K31i8IQ8EWmWj0EiIk0+vKiHNMxTTYveAg=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.23 h1:1SZBDiRzzs3sNhOMVApyWPduWYGAX0imGy06XiBnCAM=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.23/go.mod h1:i9TkxgbZmHVh2S0La6CAXtnyFhlCX/pJ0JsOvBAS6Mk=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 h1:TToQNkvGguu209puTojY/ozlqy2d/SFNcoLIqTFi42g=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0/go.mod h1:0jp+ltwkf+SwG2fm/PKo8t4y8pJSgOCO4D8Lz3k0aHQ=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.4 h1:aaPpoG15S2qHkWm4KlEyF01zovK1nW4BBbyXuHNSE90=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.4/go.mod h1:eD9gS2EARTKgGr/W5xwgY/ik9z/zqpW+m/xOQbVxrMk=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.4 h1:tHxQi/XHPK0ctd/wdOw0t7Xrc2OxcRCnVzv8lwWPu0c=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.4/go.mod h1:4GQbF1vJzG60poZqWatZlhP31y8PGCCVTvIGPdaaYJ0=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.4 h1:E5ZAVOmI2apR8ADb72Q63KqwwwdW1XcMeXIlrZ1Psjg=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.4/go.mod h1:wezzqVUOVVdk+2Z/JzQT4NxAU0NbhRe5W8pIE72jsWI=
github.com/aws/aws-sdk-go-v2/service/s3 v1.67.0 h1:SwaJ0w0MOp0pBTIKTamLVeTKD+iOWyNJRdJ2KCQRg6Q=
github.com/aws/aws-sdk-go-v2/service/s3 v1.67.0/go.mod h1:TMhLIyRIyoGVlaEMAt+ITMbwskSTpcGsCPDq91/ihY0=
github.com/aws/aws-sdk-go-v2/service/sso v1.24.5 h1:HJwZwRt2Z2Tdec+m+fPjvdmkq2s9Ra+VR0hjF7V2o40=
github.com/aws/aws-sdk-go-v2/service/sso v1.24.5/go.mod h1:wrMCEwjFPms+V86TCQQeOxQF/If4vT44FGIOFiMC2ck=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.4 h1:zcx9LiGWZ6i6pjdcoE9oXAB6mUdeyC36Ia/QEiIvYdg=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.4/go.mod h1:Tp/ly1cTjRLGBBmNccFumbZ8oqpZlpdhFf80SrRh4is=
github.com/aws/aws-sdk-go-v2/service/sts v1.33.0 h1:s7LRgBqhwLaxcocnAniBJp7gaAB+4I4vHzqUqjH18yc=
github.com/aws/aws-sdk-go-v2/service/sts v1.33.0/go.mod h1:9XEUty5v5UAsMiFOBJrNibZgwCeOma73jgGwwhgffa8=
github.com/aws/smithy-go v1.22.0 h1:uunKnWlcoL3zO7q+gG2Pk53joueEOsnNB28QdMsmiMM=
github.com/aws/smithy-go v1.22.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.24 h1:JX70yGKLj25+lMC5Yyh8wBtvB01GDilyRuJvXJ4piD0=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.24/go.mod h1:+Ln60j9SUTD0LEwnhEB0Xhg61DHqplBrbZpLgyjoEHg=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 h1:iXtILhvDxB6kPvEXgsDhGaZCSC6LQET5ZHSdJozeI0Y=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1/go.mod h1:9nu0fVANtYiAePIBh2/pFUSwtJ402hLnp854CNoDOeE=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.5 h1:gvZOjQKPxFXy1ft3QnEyXmT+IqneM9QAUWlM3r0mfqw=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.5/go.mod h1:DLWnfvIcm9IET/mmjdxeXbBKmTCm0ZB8p1za9BVteM8=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.5 h1:wtpJ4zcwrSbwhECWQoI/g6WM9zqCcSpHDJIWSbMLOu4=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.5/go.mod h1:qu/W9HXQbbQ4+1+JcZp0ZNPV31ym537ZJN+fiS7Ti8E=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.5 h1:P1doBzv5VEg1ONxnJss1Kh5ZG/ewoIE4MQtKKc6Crgg=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.5/go.mod h1:NOP+euMW7W3Ukt28tAxPuoWao4rhhqJD3QEBk7oCg7w=
github.com/aws/aws-sdk-go-v2/service/s3 v1.69.0 h1:Q2ax8S21clKOnHhhr933xm3JxdJebql+R7aNo7p7GBQ=
github.com/aws/aws-sdk-go-v2/service/s3 v1.69.0/go.mod h1:ralv4XawHjEMaHOWnTFushl0WRqim/gQWesAMF6hTow=
github.com/aws/aws-sdk-go-v2/service/sso v1.24.6 h1:3zu537oLmsPfDMyjnUS2g+F2vITgy5pB74tHI+JBNoM=
github.com/aws/aws-sdk-go-v2/service/sso v1.24.6/go.mod h1:WJSZH2ZvepM6t6jwu4w/Z45Eoi75lPN7DcydSRtJg6Y=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.5 h1:K0OQAsDywb0ltlFrZm0JHPY3yZp/S9OaoLU33S7vPS8=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.5/go.mod h1:ORITg+fyuMoeiQFiVGoqB3OydVTLkClw/ljbblMq6Cc=
github.com/aws/aws-sdk-go-v2/service/sts v1.33.1 h1:6SZUVRQNvExYlMLbHdlKB48x0fLbc2iVROyaNEwBHbU=
github.com/aws/aws-sdk-go-v2/service/sts v1.33.1/go.mod h1:GqWyYCwLXnlUB1lOAXQyNSPqPLQJvmo8J0DWBzp9mtg=
github.com/aws/smithy-go v1.22.1 h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro=
github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
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=
@@ -67,6 +67,10 @@ github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
@@ -135,6 +139,8 @@ github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc=
github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM=
@@ -153,11 +159,17 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
@@ -200,6 +212,8 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -220,6 +234,8 @@ github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8b
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rqlite/go-sqlite3 v1.36.0 h1:dNW9Hn4v3HVVlO+q6QmQC5glZYIWFOzOWUjrKOxK3cE=
github.com/rqlite/go-sqlite3 v1.36.0/go.mod h1:R9H7CatgYBt3c+fSV/5yo2vLh4ZjCB0aMHdkv69fP4A=
github.com/rqlite/raft-boltdb/v2 v2.0.0-20230523104317-c08e70f4de48 h1:NZ62M+kT0JqhyFUMc8I4SMmfmD4NGJxhb2ePJQXjryc=
@@ -229,10 +245,24 @@ github.com/rqlite/rqlite-disco-clients v0.0.0-20231230135307-118e35426347/go.mod
github.com/rqlite/sql v0.0.0-20241111133259-a4122fabb196 h1:SjRKMwKLTEE3STO6unJlz4VlMjMv5NZgIdI9HikBeAc=
github.com/rqlite/sql v0.0.0-20241111133259-a4122fabb196/go.mod h1:ib9zVtNgRKiGuoMyUqqL5aNpk+r+++YlyiVIkclVqPg=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk=
github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0=
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
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/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
@@ -243,6 +273,8 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
@@ -349,10 +381,10 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
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=
google.golang.org/genproto/googleapis/api v0.0.0-20241113202542-65e8d215514f h1:M65LEviCfuZTfrfzwwEoxVtgvfkFkBUbFnRbxCXuXhU=
google.golang.org/genproto/googleapis/api v0.0.0-20241113202542-65e8d215514f/go.mod h1:Yo94eF2nj7igQt+TiJ49KxjIH8ndLYPZMIRSiRcEbg0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20241113202542-65e8d215514f h1:C1QccEa9kUwvMgEUORqQD9S17QesQijxjZ84sO82mfo=
google.golang.org/genproto/googleapis/rpc v0.0.0-20241113202542-65e8d215514f/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697 h1:pgr/4QbFyktUv9CtQ/Fq4gzEE6/Xs7iCXbktaGzLHbQ=
google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697/go.mod h1:+D9ySVjN8nY8YCVjc5O7PZDIdZporIDY3KaGfJunh88=
google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 h1:LWZqQOEjDyONlF1H6afSWpAL/znlREo2tHfLoe+8LMA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU=
google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0=
google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA=
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
@@ -360,6 +392,10 @@ google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojt
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-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
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/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

273
tools/genflags/genflags.go Normal file
View File

@@ -0,0 +1,273 @@
package main
import (
"bytes"
"flag"
"fmt"
"log"
"os"
"strings"
"text/template"
"github.com/spf13/viper"
)
// Template for generating flags.go
const flagTemplate = `
// Code generated by go generate; DO NOT EDIT.
package flags
import (
"fmt"
"flag"
"os"
"strings"
"time"
)
// StringSlice is a slice of strings which implements the flag.Value interface.
type StringSliceValue []string
// String returns a string representation of the slice.
func (s *StringSliceValue) String() string {
return fmt.Sprintf("%v", *s)
}
// Set sets the value of the slice.
func (s *StringSliceValue) Set(value string) error {
*s = strings.Split(value, ",")
var r []string
for _, v := range *s {
if v != "" {
r = append(r, v)
}
}
*s = r
return nil
}
// Config represents all configuration options.
type Config struct {
{{- range .Flags }}
// {{ .ShortHelp }}
{{ .Name }} {{ .GoType }}
{{- end }}
}
// ParseFlags sets up and parses command-line flags.
func ParseFlags() *Config {
config := &Config{}
fs := flag.NewFlagSet("rqlite", flag.ExitOnError)
{{- range .Flags }}
{{- if eq .Type "string" }}
fs.StringVar(&config.{{ .Name }}, "{{ .CLI }}", "{{ .Default }}", "{{ .ShortHelp }}")
{{- else if eq .Type "bool" }}
fs.BoolVar(&config.{{ .Name }}, "{{ .CLI }}", {{ .Default }}, "{{ .ShortHelp }}")
{{- else if eq .Type "int" }}
fs.IntVar(&config.{{ .Name }}, "{{ .CLI }}", {{ .Default }}, "{{ .ShortHelp }}")
{{- else if eq .Type "duration" }}
fs.DurationVar(&config.{{ .Name }}, "{{ .CLI }}", mustParseDuration("{{ .Default }}"), "{{ .ShortHelp }}")
{{- end }}
{{- end }}
fs.Parse(os.Args[1:])
return config
}
func mustParseDuration(d string) time.Duration {
td, err := time.ParseDuration(d)
if err != nil {
panic(err)
}
return td
}
`
// Flag represents a single flag configuration.
type Flag struct {
Name string `mapstructure:"name"`
CLI string `mapstructure:"cli"`
Type string `mapstructure:"type"`
Default interface{} `mapstructure:"default"`
ShortHelp string `mapstructure:"short_help"`
LongHelp string `mapstructure:"long_help"`
}
// GoType converts the flag type to Go type.
func (f Flag) GoType() string {
switch f.Type {
case "string":
return "string"
case "stringslicevalue":
return "StringSliceValue"
case "bool":
return "bool"
case "int":
return "int"
case "uint64":
return "uint64"
case "duration":
return "time.Duration"
default:
panic(fmt.Sprintf("unknown type: %s", f.Type))
}
}
func generateFlagsFile(flags []Flag, out string) {
// Parse the template.
tmpl, err := template.New("flags").Funcs(template.FuncMap{
"GoType": Flag.GoType,
}).Parse(flagTemplate)
if err != nil {
log.Fatalf("Error parsing template: %v", err)
}
// Execute the template with the flags data.
var output bytes.Buffer
if err := tmpl.Execute(&output, struct {
Flags []Flag
}{Flags: flags}); err != nil {
log.Fatalf("Error executing template: %v", err)
}
// Write the output to flags.go.
if err := os.WriteFile(out, output.Bytes(), 0644); err != nil {
log.Fatalf("Error writing flags.go: %v", err)
}
}
func generateMarkdownTable(flags []Flag, out string) {
var output bytes.Buffer
// Write the markdown table header.
output.WriteString("| Flag | Default | Purpose | Usage notes |\n")
output.WriteString("|------|---------|---------|-------------|\n")
// Write each flag as a row in the table.
for _, flag := range flags {
cli := escapeMarkdown(flag.CLI)
shortHelp := escapeMarkdown(flag.ShortHelp)
longHelp := escapeMarkdown(flag.LongHelp)
defaultVal := fmt.Sprintf("%v", flag.Default)
defaultVal = escapeMarkdown(defaultVal)
output.WriteString(fmt.Sprintf("| `%s` | %s | %s | %s |\n", cli, defaultVal, shortHelp, longHelp))
}
// Write the output to the specified file.
if err := os.WriteFile(out, output.Bytes(), 0644); err != nil {
log.Fatalf("Error writing markdown file: %v", err)
}
}
// escapeMarkdown escapes markdown special characters.
func escapeMarkdown(text string) string {
text = strings.ReplaceAll(text, "|", "\\|")
text = strings.ReplaceAll(text, "\n", "<br>")
return text
}
func generateHTMLTable(flags []Flag, out string) {
// Define the HTML template with precise control over column widths.
const htmlTemplate = `
<!DOCTYPE html>
<html>
<head>
<style>
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
}
th {
background-color: #f2f2f2;
text-align: left;
}
.col-cli { width: 30%; }
.col-usage { width: 70%; }
</style>
</head>
<body>
<table>
<tr>
<th class="col-cli">Flag</th>
<th class="col-usage">Usage</th>
</tr>
{{- range .Flags }}
<tr>
<td><code>{{ .CLI | html }}</code></td>
<td>{{ .ShortHelp | html }}.
{{- if .LongHelp }}
<br><br>{{ .LongHelp | html }}
{{- end }}</td>
</tr>
{{- end }}
</table>
</body>
</html>
`
// Parse the template.
tmpl, err := template.New("htmlTable").Funcs(template.FuncMap{
"html": func(s string) string {
return template.HTMLEscapeString(s)
},
}).Parse(htmlTemplate)
if err != nil {
log.Fatalf("Error parsing HTML template: %v", err)
}
// Execute the template with the flags data.
var output bytes.Buffer
if err := tmpl.Execute(&output, struct {
Flags []Flag
}{Flags: flags}); err != nil {
log.Fatalf("Error executing HTML template: %v", err)
}
// Write the output to the specified file.
if err := os.WriteFile(out, output.Bytes(), 0644); err != nil {
log.Fatalf("Error writing HTML file: %v", err)
}
}
func main() {
// Define the markdown flag.
var format = flag.String("format", "go", "Output format (go, markdown, html)")
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage: %s [--format] <input> <output>\n", os.Args[0])
flag.PrintDefaults()
}
flag.Parse()
if flag.NArg() != 2 {
fmt.Fprintf(os.Stderr, "Usage: %s [--format] <input> <output>\n", os.Args[0])
os.Exit(1)
}
inPath := flag.Arg(0)
outPath := flag.Arg(1)
viper.SetConfigFile(inPath)
if err := viper.ReadInConfig(); err != nil {
log.Fatalf("Error reading config file: %v", err)
}
var flags []Flag
if err := viper.UnmarshalKey("flags", &flags); err != nil {
log.Fatalf("Error unmarshaling config: %v", err)
}
switch *format {
case "go":
generateFlagsFile(flags, outPath)
case "markdown":
generateMarkdownTable(flags, outPath)
case "html":
generateHTMLTable(flags, outPath)
default:
log.Fatalf("Unknown format: %s", *format)
}
}