feat: improve error handling.
- skip EOF error
This commit is contained in:
parent
8c8f1ea37f
commit
1ef3d37498
@ -92,7 +92,7 @@ func createTLSConfig(cmd *cobra.Command) (*tls.Config, error) {
|
||||
|
||||
cert, err := getCertificate(privateKey, certContent)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load TLS keypair: %s", err)
|
||||
return nil, fmt.Errorf("failed to load TLS keypair: %w", err)
|
||||
}
|
||||
|
||||
return &tls.Config{
|
||||
@ -109,7 +109,7 @@ func getCertPool(ca string) (*x509.CertPool, error) {
|
||||
if ca != "" {
|
||||
caContent, err := getCAContent(ca)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read CA. %s", err)
|
||||
return nil, fmt.Errorf("failed to read CA. %w", err)
|
||||
}
|
||||
|
||||
if !caPool.AppendCertsFromPEM(caContent) {
|
||||
|
||||
@ -109,7 +109,7 @@ func runE(apply func(*dumper.BaseConfig, *cobra.Command) error) func(*cobra.Comm
|
||||
func tree(root, indent string) error {
|
||||
fi, err := os.Stat(root)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not stat %s: %v", root, err)
|
||||
return fmt.Errorf("could not stat %s: %w", root, err)
|
||||
}
|
||||
|
||||
fmt.Println(fi.Name())
|
||||
@ -119,7 +119,7 @@ func tree(root, indent string) error {
|
||||
|
||||
fis, err := ioutil.ReadDir(root)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not read dir %s: %v", root, err)
|
||||
return fmt.Errorf("could not read dir %s: %w", root, err)
|
||||
}
|
||||
|
||||
var names []string
|
||||
|
||||
@ -4,6 +4,8 @@ import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
@ -34,20 +36,24 @@ func Dump(acmeFile string, baseConfig *dumper.BaseConfig) error {
|
||||
|
||||
func dump(acmeFile string, baseConfig *dumper.BaseConfig) error {
|
||||
if baseConfig.Version == "v2" {
|
||||
return dumpV2(acmeFile, baseConfig)
|
||||
err := dumpV2(acmeFile, baseConfig)
|
||||
if err != nil {
|
||||
return fmt.Errorf("v2: dump failed: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
return dumpV1(acmeFile, baseConfig)
|
||||
err := dumpV1(acmeFile, baseConfig)
|
||||
if err != nil {
|
||||
return fmt.Errorf("v1: dump failed: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func dumpV1(acmeFile string, baseConfig *dumper.BaseConfig) error {
|
||||
source, err := os.Open(acmeFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data := &v1.StoredData{}
|
||||
if err = json.NewDecoder(source).Decode(data); err != nil {
|
||||
err := readJSONFile(acmeFile, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -55,23 +61,38 @@ func dumpV1(acmeFile string, baseConfig *dumper.BaseConfig) error {
|
||||
}
|
||||
|
||||
func dumpV2(acmeFile string, baseConfig *dumper.BaseConfig) error {
|
||||
source, err := os.Open(acmeFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data := map[string]*acme.StoredData{}
|
||||
if err = json.NewDecoder(source).Decode(&data); err != nil {
|
||||
err := readJSONFile(acmeFile, &data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return v2.Dump(data, baseConfig)
|
||||
}
|
||||
|
||||
func readJSONFile(acmeFile string, data interface{}) error {
|
||||
source, err := os.Open(acmeFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open file %q: %w", acmeFile, err)
|
||||
}
|
||||
defer func() { _ = source.Close() }()
|
||||
|
||||
err = json.NewDecoder(source).Decode(data)
|
||||
if errors.Is(err, io.EOF) {
|
||||
log.Printf("warn: file %q may not be ready: %v", acmeFile, err)
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to unmarshal file %q: %w", acmeFile, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func watch(acmeFile string, baseConfig *dumper.BaseConfig) error {
|
||||
watcher, err := fsnotify.NewWatcher()
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("failed to create new watcher: %w", err)
|
||||
}
|
||||
|
||||
defer func() { _ = watcher.Close() }()
|
||||
@ -114,7 +135,7 @@ func watch(acmeFile string, baseConfig *dumper.BaseConfig) error {
|
||||
|
||||
err = watcher.Add(acmeFile)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("failed to add a new watcher: %w", err)
|
||||
}
|
||||
|
||||
<-done
|
||||
@ -125,12 +146,12 @@ func watch(acmeFile string, baseConfig *dumper.BaseConfig) error {
|
||||
func manageEvent(watcher *fsnotify.Watcher, event fsnotify.Event, acmeFile string, previousHash []byte, baseConfig *dumper.BaseConfig) ([]byte, error) {
|
||||
err := manageRename(watcher, event, acmeFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("watcher renewal failed: %w", err)
|
||||
}
|
||||
|
||||
hash, err := calculateHash(acmeFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("file hash calculation failed: %w", err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(previousHash, hash) {
|
||||
|
||||
@ -45,13 +45,15 @@ type DomainsCertificate struct {
|
||||
|
||||
// convertOldAccount converts account information from old account format.
|
||||
func convertOldAccount(account *AccountOld) *v1.StoredData {
|
||||
storedData := &v1.StoredData{}
|
||||
storedData.Account = &v1.Account{
|
||||
PrivateKey: account.PrivateKey,
|
||||
Registration: account.Registration,
|
||||
Email: account.Email,
|
||||
KeyType: account.KeyType,
|
||||
storedData := &v1.StoredData{
|
||||
Account: &v1.Account{
|
||||
PrivateKey: account.PrivateKey,
|
||||
Registration: account.Registration,
|
||||
Email: account.Email,
|
||||
KeyType: account.KeyType,
|
||||
},
|
||||
}
|
||||
|
||||
var certs []*v1.Certificate
|
||||
for _, oldCert := range account.DomainsCertificate.Certs {
|
||||
certs = append(certs, &v1.Certificate{
|
||||
@ -61,5 +63,6 @@ func convertOldAccount(account *AccountOld) *v1.StoredData {
|
||||
})
|
||||
}
|
||||
storedData.Certificates = certs
|
||||
|
||||
return storedData
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ const DefaultStoreKeySuffix = "/acme/account/object"
|
||||
func Dump(config *Config, baseConfig *dumper.BaseConfig) error {
|
||||
kvStore, err := valkeyrie.NewStore(config.Backend, config.Endpoints, config.Options)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to create client of the store: %v", err)
|
||||
return fmt.Errorf("unable to create client of the store: %w", err)
|
||||
}
|
||||
|
||||
storeKey := config.Prefix + config.Suffix
|
||||
@ -35,7 +35,7 @@ func Dump(config *Config, baseConfig *dumper.BaseConfig) error {
|
||||
|
||||
pair, err := kvStore.Get(storeKey, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to retrieve %s value: %v", storeKey, err)
|
||||
return fmt.Errorf("unable to retrieve %s value: %w", storeKey, err)
|
||||
}
|
||||
|
||||
return dumpPair(pair, baseConfig)
|
||||
@ -80,17 +80,17 @@ func dumpPair(pair *store.KVPair, baseConfig *dumper.BaseConfig) error {
|
||||
func getStoredDataFromGzip(pair *store.KVPair) (*v1.StoredData, error) {
|
||||
reader, err := gzip.NewReader(bytes.NewBuffer(pair.Value))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("fail to create GZip reader: %v", err)
|
||||
return nil, fmt.Errorf("fail to create GZip reader: %w", err)
|
||||
}
|
||||
|
||||
acmeData, err := ioutil.ReadAll(reader)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to read the pair content: %v", err)
|
||||
return nil, fmt.Errorf("unable to read the pair content: %w", err)
|
||||
}
|
||||
|
||||
account := &AccountOld{}
|
||||
if err := json.Unmarshal(acmeData, &account); err != nil {
|
||||
return nil, fmt.Errorf("unable marshal AccountOld: %v", err)
|
||||
return nil, fmt.Errorf("unable marshal AccountOld: %w", err)
|
||||
}
|
||||
|
||||
return convertOldAccount(account), nil
|
||||
|
||||
@ -2,6 +2,7 @@ package v1
|
||||
|
||||
import (
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@ -20,29 +21,29 @@ func Dump(data *StoredData, baseConfig *dumper.BaseConfig) error {
|
||||
if baseConfig.Clean {
|
||||
err := cleanDir(baseConfig.DumpPath)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("folder cleaning failed: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if !baseConfig.DomainSubDir {
|
||||
if err := os.MkdirAll(filepath.Join(baseConfig.DumpPath, certsSubDir), 0755); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("certs folder creation failure: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(filepath.Join(baseConfig.DumpPath, keysSubDir), 0755); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("keys folder creation failure: %w", err)
|
||||
}
|
||||
|
||||
for _, cert := range data.Certificates {
|
||||
err := writeCert(baseConfig.DumpPath, cert, baseConfig.CrtInfo, baseConfig.DomainSubDir)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("failed to write certificates: %w", err)
|
||||
}
|
||||
|
||||
err = writeKey(baseConfig.DumpPath, cert, baseConfig.KeyInfo, baseConfig.DomainSubDir)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("failed to write certificate keys: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ package v2
|
||||
|
||||
import (
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@ -21,30 +22,30 @@ func Dump(data map[string]*acme.StoredData, baseConfig *dumper.BaseConfig) error
|
||||
if baseConfig.Clean {
|
||||
err := cleanDir(baseConfig.DumpPath)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("folder cleaning failed: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if !baseConfig.DomainSubDir {
|
||||
if err := os.MkdirAll(filepath.Join(baseConfig.DumpPath, certsSubDir), 0755); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("certs folder creation failure: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(filepath.Join(baseConfig.DumpPath, keysSubDir), 0755); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("keys folder creation failure: %w", err)
|
||||
}
|
||||
|
||||
for _, store := range data {
|
||||
for _, cert := range store.Certificates {
|
||||
err := writeCert(baseConfig.DumpPath, cert.Certificate, baseConfig.CrtInfo, baseConfig.DomainSubDir)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("failed to write certificates: %w", err)
|
||||
}
|
||||
|
||||
err = writeKey(baseConfig.DumpPath, cert.Certificate, baseConfig.KeyInfo, baseConfig.DomainSubDir)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("failed to write certificate keys: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,7 +57,7 @@ func Dump(data map[string]*acme.StoredData, baseConfig *dumper.BaseConfig) error
|
||||
|
||||
err := ioutil.WriteFile(filepath.Join(baseConfig.DumpPath, keysSubDir, "letsencrypt"+baseConfig.KeyInfo.Ext), privateKeyPem, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("failed to write private key: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user