mirror of
https://github.com/offen/docker-volume-backup.git
synced 2024-11-14 02:25:49 +01:00
Try pathenvconfig
This commit is contained in:
parent
cc4492d2c0
commit
4c806006a4
@ -16,86 +16,66 @@ import (
|
|||||||
// Config holds all configuration values that are expected to be set
|
// Config holds all configuration values that are expected to be set
|
||||||
// by users.
|
// by users.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
AwsS3BucketName string `env:"AWS_S3_BUCKET_NAME"`
|
AwsS3BucketName string
|
||||||
AwsS3Path string `env:"AWS_S3_PATH"`
|
AwsS3Path string
|
||||||
AwsEndpoint string `envDefault:"s3.amazonaws.com"`
|
AwsEndpoint string `default:"s3.amazonaws.com"`
|
||||||
AwsEndpointProto string `envDefault:"https"`
|
AwsEndpointProto string
|
||||||
AwsEndpointInsecure bool
|
AwsEndpointInsecure bool
|
||||||
AwsEndpointCACert CertDecoder `env:"AWS_ENDPOINT_CA_CERT"`
|
AwsEndpointCACert CertDecoder
|
||||||
AwsStorageClass string
|
AwsStorageClass string
|
||||||
AwsAccessKeyID string `env:"AWS_ACCESS_KEY_ID"`
|
AwsAccessKeyID string
|
||||||
AwsAccessKeyIDFile string `env:"AWS_ACCESS_KEY_ID_FILE,file"`
|
AwsSecretAccessKey string
|
||||||
AwsSecretAccessKey string `env:"AWS_SECRET_ACCESS_KEY"`
|
|
||||||
AwsSecretAccessKeyFile string `env:"AWS_SECRET_ACCESS_KEY_FILE,file"`
|
|
||||||
AwsIamRoleEndpoint string
|
AwsIamRoleEndpoint string
|
||||||
AwsPartSize int64
|
AwsPartSize int64
|
||||||
BackupCompression CompressionType `envDefault:"gz"`
|
BackupCompression CompressionType `default:"gz"`
|
||||||
BackupSources string `envDefault:"/backup"`
|
BackupSources string `default:"/backup"`
|
||||||
BackupFilename string `envDefault:"backup-%Y-%m-%dT%H-%M-%S.{{ .Extension }}"`
|
BackupFilename string `default:"backup-%Y-%m-%dT%H-%M-%S.{{ .Extension }}"`
|
||||||
BackupFilenameExpand bool
|
BackupFilenameExpand bool
|
||||||
BackupLatestSymlink string
|
BackupLatestSymlink string
|
||||||
BackupArchive string `envDefault:"/archive"`
|
BackupArchive string `default:"/archive"`
|
||||||
BackupRetentionDays int32 `envDefault:"-1"`
|
BackupRetentionDays int32 `default:"-1"`
|
||||||
BackupPruningLeeway time.Duration `envDefault:"1m"`
|
BackupPruningLeeway time.Duration `default:"1m"`
|
||||||
BackupPruningPrefix string
|
BackupPruningPrefix string
|
||||||
BackupStopContainerLabel string `envDefault:"true"`
|
BackupStopContainerLabel string `default:"true"`
|
||||||
BackupFromSnapshot bool
|
BackupFromSnapshot bool
|
||||||
BackupExcludeRegexp RegexpDecoder
|
BackupExcludeRegexp RegexpDecoder
|
||||||
BackupSkipBackendsFromPrune []string
|
BackupSkipBackendsFromPrune []string
|
||||||
GpgPassphrase string `env:"GPG_PASSPHRASE"`
|
GpgPassphrase string
|
||||||
GpgPassphraseFile string `env:"GPG_PASSPHRASE_FILE,file"`
|
NotificationURLs []string
|
||||||
NotificationURLs []string `env:"NOTIFICATION_URLS"`
|
NotificationLevel string `default:"error"`
|
||||||
NotificationLevel string `envDefault:"error"`
|
|
||||||
EmailNotificationRecipient string
|
EmailNotificationRecipient string
|
||||||
EmailNotificationSender string `envDefault:"noreply@nohost"`
|
EmailNotificationSender string `default:"noreply@nohost"`
|
||||||
EmailSMTPHost string `env:"EMAIL_SMTP_HOST"`
|
EmailSMTPHost string
|
||||||
EmailSMTPPort int `env:"EMAIL_SMTP_PORT" envDefault:"587"`
|
EmailSMTPPort int `default:"587"`
|
||||||
EmailSMTPUsername string `env:"EMAIL_SMTP_USERNAME"`
|
EmailSMTPUsername string
|
||||||
EmailSMTPPassword string `env:"EMAIL_SMTP_PASSWORD"`
|
EmailSMTPPassword string
|
||||||
EmailSMTPPasswordFile string `env:"EMAIL_SMTP_PASSWORD_FILE,file"`
|
|
||||||
WebdavUrl string
|
WebdavUrl string
|
||||||
WebdavUrlInsecure bool
|
WebdavUrlInsecure bool
|
||||||
WebdavPath string `envDefault:"/"`
|
WebdavPath string `default:"/"`
|
||||||
WebdavUsername string
|
WebdavUsername string
|
||||||
WebdavPassword string `env:"WEBDAV_PASSWORD"`
|
WebdavPassword string
|
||||||
WebdavPasswordFile string `env:"WEBDAV_PASSWORD_FILE,file"`
|
SSHHostName string
|
||||||
SSHHostName string `env:"SSH_HOST_NAME"`
|
SSHPort string `default:"22"`
|
||||||
SSHPort string `env:"SSH_PORT" envDefault:"22"`
|
SSHUser string
|
||||||
SSHUser string `env:"SSH_USER"`
|
SSHPassword string
|
||||||
SSHPassword string `env:"SSH_PASSWORD"`
|
SSHIdentityFile string `default:"/root/.ssh/id_rsa"`
|
||||||
SSHPasswordFile string `env:"SSH_PASSWORD_FILE,file"`
|
SSHIdentityPassphrase string
|
||||||
SSHIdentityFile string `env:"SSH_IDENTITY_FILE" envDefault:"/root/.ssh/id_rsa"`
|
SSHRemotePath string
|
||||||
SSHIdentityPassphrase string `env:"SSH_IDENTITY_PASSPHRASE"`
|
|
||||||
SSHIdentityPassphraseFile string `env:"SSH_IDENTITY_PASSPHRASE_FILE,file"`
|
|
||||||
SSHRemotePath string `env:"SSH_REMOTE_PATH"`
|
|
||||||
ExecLabel string
|
ExecLabel string
|
||||||
ExecForwardOutput bool
|
ExecForwardOutput bool
|
||||||
LockTimeout time.Duration `envDefault:"60m"`
|
LockTimeout time.Duration `default:"60m"`
|
||||||
AzureStorageAccountName string
|
AzureStorageAccountName string
|
||||||
AzureStoragePrimaryAccountKey string
|
AzureStoragePrimaryAccountKey string
|
||||||
AzureStorageContainerName string
|
AzureStorageContainerName string
|
||||||
AzureStoragePath string
|
AzureStoragePath string
|
||||||
AzureStorageEndpoint string `envDefault:"https://{{ .AccountName }}.blob.core.windows.net/"`
|
AzureStorageEndpoint string `default:"https://{{ .AccountName }}.blob.core.windows.net/"`
|
||||||
DropboxEndpoint string `envDefault:"https://api.dropbox.com/"`
|
DropboxEndpoint string `default:"https://api.dropbox.com/"`
|
||||||
DropboxOAuth2Endpoint string `env:"DROPBOX_OAUTH2_ENDPOINT" envDefault:"https://api.dropbox.com/"`
|
DropboxOAuth2Endpoint string `default:"https://api.dropbox.com/"`
|
||||||
DropboxRefreshToken string `env:"DROPBOX_REFRESH_TOKEN"`
|
DropboxRefreshToken string
|
||||||
DropboxRefreshTokenFile string `env:"DROPBOX_REFRESH_TOKEN_FILE,file"`
|
DropboxAppKey string
|
||||||
DropboxAppKey string `env:"DROPBOX_APP_KEY"`
|
DropboxAppSecret string
|
||||||
DropboxAppKeyFile string `env:"DROPBOX_APP_KEY_FILE,file"`
|
|
||||||
DropboxAppSecret string `env:"DROPBOX_APP_SECRET"`
|
|
||||||
DropboxAppSecretFile string `env:"DROPBOX_APP_SECRET_FILE,file"`
|
|
||||||
DropboxRemotePath string
|
DropboxRemotePath string
|
||||||
DropboxConcurrencyLevel NaturalNumber `envDefault:"6"`
|
DropboxConcurrencyLevel NaturalNumber `default:"6"`
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Config) getSecret(preferred string, fallback string) string {
|
|
||||||
if preferred != "" {
|
|
||||||
return preferred
|
|
||||||
}
|
|
||||||
if fallback != "" {
|
|
||||||
return fallback
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type CompressionType string
|
type CompressionType string
|
||||||
|
@ -28,7 +28,6 @@ import (
|
|||||||
"github.com/offen/docker-volume-backup/internal/storage/webdav"
|
"github.com/offen/docker-volume-backup/internal/storage/webdav"
|
||||||
|
|
||||||
"github.com/ProtonMail/go-crypto/openpgp"
|
"github.com/ProtonMail/go-crypto/openpgp"
|
||||||
"github.com/caarlos0/env/v9"
|
|
||||||
"github.com/containrrr/shoutrrr"
|
"github.com/containrrr/shoutrrr"
|
||||||
"github.com/containrrr/shoutrrr/pkg/router"
|
"github.com/containrrr/shoutrrr/pkg/router"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
@ -36,6 +35,7 @@ import (
|
|||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
|
"github.com/johnstairs/pathenvconfig"
|
||||||
"github.com/leekchan/timeutil"
|
"github.com/leekchan/timeutil"
|
||||||
"github.com/otiai10/copy"
|
"github.com/otiai10/copy"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
@ -89,13 +89,12 @@ func newScript() (*script, error) {
|
|||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
envOptions := env.Options{
|
if err := pathenvconfig.Process("", s.c); err != nil {
|
||||||
UseFieldNameByDefault: true,
|
|
||||||
}
|
|
||||||
if err := env.ParseWithOptions(s.c, envOptions); err != nil {
|
|
||||||
return nil, fmt.Errorf("newScript: failed to process configuration values: %w", err)
|
return nil, fmt.Errorf("newScript: failed to process configuration values: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Using configuration: %+v\n", s.c) // Debug
|
||||||
|
|
||||||
s.file = path.Join("/tmp", s.c.BackupFilename)
|
s.file = path.Join("/tmp", s.c.BackupFilename)
|
||||||
|
|
||||||
tmplFileName, tErr := template.New("extension").Parse(s.file)
|
tmplFileName, tErr := template.New("extension").Parse(s.file)
|
||||||
@ -140,13 +139,10 @@ func newScript() (*script, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if s.c.AwsS3BucketName != "" {
|
if s.c.AwsS3BucketName != "" {
|
||||||
accessKeyID := s.c.getSecret(s.c.AwsAccessKeyIDFile, s.c.AwsAccessKeyID)
|
|
||||||
secretAccessKey := s.c.getSecret(s.c.AwsSecretAccessKeyFile, s.c.AwsSecretAccessKey)
|
|
||||||
|
|
||||||
s3Config := s3.Config{
|
s3Config := s3.Config{
|
||||||
Endpoint: s.c.AwsEndpoint,
|
Endpoint: s.c.AwsEndpoint,
|
||||||
AccessKeyID: accessKeyID,
|
AccessKeyID: s.c.AwsAccessKeyID,
|
||||||
SecretAccessKey: secretAccessKey,
|
SecretAccessKey: s.c.AwsSecretAccessKey,
|
||||||
IamRoleEndpoint: s.c.AwsIamRoleEndpoint,
|
IamRoleEndpoint: s.c.AwsIamRoleEndpoint,
|
||||||
EndpointProto: s.c.AwsEndpointProto,
|
EndpointProto: s.c.AwsEndpointProto,
|
||||||
EndpointInsecure: s.c.AwsEndpointInsecure,
|
EndpointInsecure: s.c.AwsEndpointInsecure,
|
||||||
@ -164,13 +160,11 @@ func newScript() (*script, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if s.c.WebdavUrl != "" {
|
if s.c.WebdavUrl != "" {
|
||||||
webdavPassword := s.c.getSecret(s.c.WebdavPasswordFile, s.c.WebdavPassword)
|
|
||||||
|
|
||||||
webDavConfig := webdav.Config{
|
webDavConfig := webdav.Config{
|
||||||
URL: s.c.WebdavUrl,
|
URL: s.c.WebdavUrl,
|
||||||
URLInsecure: s.c.WebdavUrlInsecure,
|
URLInsecure: s.c.WebdavUrlInsecure,
|
||||||
Username: s.c.WebdavUsername,
|
Username: s.c.WebdavUsername,
|
||||||
Password: webdavPassword,
|
Password: s.c.WebdavPassword,
|
||||||
RemotePath: s.c.WebdavPath,
|
RemotePath: s.c.WebdavPath,
|
||||||
}
|
}
|
||||||
if webdavBackend, err := webdav.NewStorageBackend(webDavConfig, logFunc); err != nil {
|
if webdavBackend, err := webdav.NewStorageBackend(webDavConfig, logFunc); err != nil {
|
||||||
@ -181,16 +175,13 @@ func newScript() (*script, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if s.c.SSHHostName != "" {
|
if s.c.SSHHostName != "" {
|
||||||
sshPassword := s.c.getSecret(s.c.SSHPasswordFile, s.c.SSHPassword)
|
|
||||||
sshIdentityPassphrase := s.c.getSecret(s.c.SSHIdentityPassphraseFile, s.c.SSHIdentityPassphrase)
|
|
||||||
|
|
||||||
sshConfig := ssh.Config{
|
sshConfig := ssh.Config{
|
||||||
HostName: s.c.SSHHostName,
|
HostName: s.c.SSHHostName,
|
||||||
Port: s.c.SSHPort,
|
Port: s.c.SSHPort,
|
||||||
User: s.c.SSHUser,
|
User: s.c.SSHUser,
|
||||||
Password: sshPassword,
|
Password: s.c.SSHPassword,
|
||||||
IdentityFile: s.c.SSHIdentityFile,
|
IdentityFile: s.c.SSHIdentityFile,
|
||||||
IdentityPassphrase: sshIdentityPassphrase,
|
IdentityPassphrase: s.c.SSHIdentityPassphrase,
|
||||||
RemotePath: s.c.SSHRemotePath,
|
RemotePath: s.c.SSHRemotePath,
|
||||||
}
|
}
|
||||||
if sshBackend, err := ssh.NewStorageBackend(sshConfig, logFunc); err != nil {
|
if sshBackend, err := ssh.NewStorageBackend(sshConfig, logFunc); err != nil {
|
||||||
@ -225,16 +216,12 @@ func newScript() (*script, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if s.c.DropboxRefreshToken != "" && s.c.DropboxAppKey != "" && s.c.DropboxAppSecret != "" {
|
if s.c.DropboxRefreshToken != "" && s.c.DropboxAppKey != "" && s.c.DropboxAppSecret != "" {
|
||||||
dropboxRefreshToken := s.c.getSecret(s.c.DropboxRefreshTokenFile, s.c.DropboxRefreshToken)
|
|
||||||
dropboxAppKey := s.c.getSecret(s.c.DropboxAppKeyFile, s.c.DropboxAppKey)
|
|
||||||
dropboxAppSecret := s.c.getSecret(s.c.DropboxAppSecretFile, s.c.DropboxAppSecret)
|
|
||||||
|
|
||||||
dropboxConfig := dropbox.Config{
|
dropboxConfig := dropbox.Config{
|
||||||
Endpoint: s.c.DropboxEndpoint,
|
Endpoint: s.c.DropboxEndpoint,
|
||||||
OAuth2Endpoint: s.c.DropboxOAuth2Endpoint,
|
OAuth2Endpoint: s.c.DropboxOAuth2Endpoint,
|
||||||
RefreshToken: dropboxRefreshToken,
|
RefreshToken: s.c.DropboxRefreshToken,
|
||||||
AppKey: dropboxAppKey,
|
AppKey: s.c.DropboxAppKey,
|
||||||
AppSecret: dropboxAppSecret,
|
AppSecret: s.c.DropboxAppSecret,
|
||||||
RemotePath: s.c.DropboxRemotePath,
|
RemotePath: s.c.DropboxRemotePath,
|
||||||
ConcurrencyLevel: s.c.DropboxConcurrencyLevel.Int(),
|
ConcurrencyLevel: s.c.DropboxConcurrencyLevel.Int(),
|
||||||
}
|
}
|
||||||
@ -246,12 +233,10 @@ func newScript() (*script, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if s.c.EmailNotificationRecipient != "" {
|
if s.c.EmailNotificationRecipient != "" {
|
||||||
smtpPassword := s.c.getSecret(s.c.EmailSMTPPasswordFile, s.c.EmailSMTPPassword)
|
|
||||||
|
|
||||||
emailURL := fmt.Sprintf(
|
emailURL := fmt.Sprintf(
|
||||||
"smtp://%s:%s@%s:%d/?from=%s&to=%s",
|
"smtp://%s:%s@%s:%d/?from=%s&to=%s",
|
||||||
s.c.EmailSMTPUsername,
|
s.c.EmailSMTPUsername,
|
||||||
smtpPassword,
|
s.c.EmailSMTPPassword,
|
||||||
s.c.EmailSMTPHost,
|
s.c.EmailSMTPHost,
|
||||||
s.c.EmailSMTPPort,
|
s.c.EmailSMTPPort,
|
||||||
s.c.EmailNotificationSender,
|
s.c.EmailNotificationSender,
|
||||||
@ -512,8 +497,7 @@ func (s *script) createArchive() error {
|
|||||||
// In case no passphrase is given it returns early, leaving the backup file
|
// In case no passphrase is given it returns early, leaving the backup file
|
||||||
// untouched.
|
// untouched.
|
||||||
func (s *script) encryptArchive() error {
|
func (s *script) encryptArchive() error {
|
||||||
gpgPassphrase := s.c.getSecret(s.c.GpgPassphraseFile, s.c.GpgPassphrase)
|
if s.c.GpgPassphrase == "" {
|
||||||
if gpgPassphrase == "" {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -535,7 +519,7 @@ func (s *script) encryptArchive() error {
|
|||||||
defer outFile.Close()
|
defer outFile.Close()
|
||||||
|
|
||||||
_, name := path.Split(s.file)
|
_, name := path.Split(s.file)
|
||||||
dst, err := openpgp.SymmetricallyEncrypt(outFile, []byte(gpgPassphrase), &openpgp.FileHints{
|
dst, err := openpgp.SymmetricallyEncrypt(outFile, []byte(s.c.GpgPassphrase), &openpgp.FileHints{
|
||||||
IsBinary: true,
|
IsBinary: true,
|
||||||
FileName: name,
|
FileName: name,
|
||||||
}, nil)
|
}, nil)
|
||||||
|
3
go.mod
3
go.mod
@ -22,6 +22,7 @@ require (
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/cloudflare/circl v1.3.3 // indirect
|
github.com/cloudflare/circl v1.3.3 // indirect
|
||||||
|
github.com/dlclark/regexp2 v1.4.0 // indirect
|
||||||
github.com/golang/protobuf v1.5.2 // indirect
|
github.com/golang/protobuf v1.5.2 // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
google.golang.org/protobuf v1.28.1 // indirect
|
google.golang.org/protobuf v1.28.1 // indirect
|
||||||
@ -33,7 +34,6 @@ require (
|
|||||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 // indirect
|
github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 // indirect
|
||||||
github.com/Microsoft/go-winio v0.5.2 // indirect
|
github.com/Microsoft/go-winio v0.5.2 // indirect
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95
|
github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95
|
||||||
github.com/caarlos0/env/v9 v9.0.0
|
|
||||||
github.com/docker/distribution v2.8.2+incompatible // indirect
|
github.com/docker/distribution v2.8.2+incompatible // indirect
|
||||||
github.com/docker/go-connections v0.4.0 // indirect
|
github.com/docker/go-connections v0.4.0 // indirect
|
||||||
github.com/docker/go-units v0.4.0 // indirect
|
github.com/docker/go-units v0.4.0 // indirect
|
||||||
@ -43,6 +43,7 @@ require (
|
|||||||
github.com/gogo/protobuf v1.3.2 // indirect
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
||||||
github.com/google/uuid v1.3.0 // indirect
|
github.com/google/uuid v1.3.0 // indirect
|
||||||
|
github.com/johnstairs/pathenvconfig v0.2.1
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
|
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
|
||||||
github.com/kr/fs v0.1.0 // indirect
|
github.com/kr/fs v0.1.0 // indirect
|
||||||
|
6
go.sum
6
go.sum
@ -221,8 +221,6 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce
|
|||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||||
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||||
github.com/caarlos0/env/v9 v9.0.0 h1:SI6JNsOA+y5gj9njpgybykATIylrRMklbs5ch6wO6pc=
|
|
||||||
github.com/caarlos0/env/v9 v9.0.0/go.mod h1:ye5mlCVMYh6tZ+vCgrs/B95sj88cg5Tlnc0XIzgZ020=
|
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
@ -254,6 +252,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
|
|||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E=
|
||||||
|
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||||
github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
|
github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
|
||||||
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
|
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
|
||||||
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
|
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
|
||||||
@ -442,6 +442,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:
|
|||||||
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
github.com/jarcoal/httpmock v1.2.0 h1:gSvTxxFR/MEMfsGrvRbdfpRUMBStovlSRLw0Ep1bwwc=
|
github.com/jarcoal/httpmock v1.2.0 h1:gSvTxxFR/MEMfsGrvRbdfpRUMBStovlSRLw0Ep1bwwc=
|
||||||
github.com/jarcoal/httpmock v1.2.0/go.mod h1:oCoTsnAz4+UoOUIf5lJOWV2QQIW5UoeUI6aM2YnWAZk=
|
github.com/jarcoal/httpmock v1.2.0/go.mod h1:oCoTsnAz4+UoOUIf5lJOWV2QQIW5UoeUI6aM2YnWAZk=
|
||||||
|
github.com/johnstairs/pathenvconfig v0.2.1 h1:hay0C2ddNdej569b4GXwjwZyjRagei97ppjRW8XcvMQ=
|
||||||
|
github.com/johnstairs/pathenvconfig v0.2.1/go.mod h1:XqBReihWnlfmCkHqvJAfsRCfa/JJCYXZds8fwtuz8cM=
|
||||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
|
Loading…
Reference in New Issue
Block a user