Files
gluetun/internal/configuration/secrets.go
2021-02-06 11:05:50 -05:00

110 lines
2.9 KiB
Go

package configuration
import (
"errors"
"fmt"
"io/ioutil"
"strings"
"github.com/qdm12/golibs/os"
"github.com/qdm12/golibs/params"
)
var (
ErrGetSecretFilepath = errors.New("cannot get secret file path from env")
ErrReadSecretFile = errors.New("cannot read secret file")
ErrSecretFileIsEmpty = errors.New("secret file is empty")
ErrReadNonSecretFile = errors.New("cannot read non secret file")
ErrFilesDoNotExist = errors.New("files do not exist")
)
func (r *reader) getFromEnvOrSecretFile(envKey string, compulsory bool, retroKeys []string) (value string, err error) {
envOptions := []params.OptionSetter{
params.Compulsory(), // to fallback on file reading
params.CaseSensitiveValue(),
params.Unset(),
params.RetroKeys(retroKeys, r.onRetroActive),
}
value, envErr := r.env.Get(envKey, envOptions...)
if envErr == nil {
return value, nil
}
defaultSecretFile := "/run/secrets/" + strings.ToLower(envKey)
filepath, err := r.env.Get(envKey+"_SECRETFILE",
params.CaseSensitiveValue(),
params.Default(defaultSecretFile),
)
if err != nil {
return "", fmt.Errorf("%w: %s", ErrGetSecretFilepath, err)
}
file, fileErr := r.os.OpenFile(filepath, os.O_RDONLY, 0)
if os.IsNotExist(fileErr) {
if compulsory {
return "", envErr
}
return "", nil
} else if fileErr != nil {
return "", fmt.Errorf("%w: %s", ErrReadSecretFile, fileErr)
}
b, err := ioutil.ReadAll(file)
if err != nil {
return "", fmt.Errorf("%w: %s", ErrReadSecretFile, err)
}
value = string(b)
value = strings.TrimSuffix(value, "\n")
if compulsory && len(value) == 0 {
return "", ErrSecretFileIsEmpty
}
return value, nil
}
// Tries to read from the secret file then the non secret file.
func (r *reader) getFromFileOrSecretFile(secretName, filepath string) (
b []byte, err error) {
defaultSecretFile := "/run/secrets/" + strings.ToLower(secretName)
secretFilepath, err := r.env.Get(strings.ToUpper(secretName)+"_SECRETFILE",
params.CaseSensitiveValue(),
params.Default(defaultSecretFile),
)
if err != nil {
return b, fmt.Errorf("%w: %s", ErrGetSecretFilepath, err)
}
b, err = readFromFile(r.os.OpenFile, secretFilepath)
if err != nil && !os.IsNotExist(err) {
return b, fmt.Errorf("%w: %s", ErrReadSecretFile, err)
} else if err == nil {
return b, nil
}
// Secret file does not exist, try the non secret file
b, err = readFromFile(r.os.OpenFile, filepath)
if err != nil && !os.IsNotExist(err) {
return nil, fmt.Errorf("%w: %s", ErrReadSecretFile, err)
} else if err == nil {
return b, nil
}
return nil, fmt.Errorf("%w: %s and %s", ErrFilesDoNotExist, secretFilepath, filepath)
}
func readFromFile(openFile os.OpenFileFunc, filepath string) (b []byte, err error) {
file, err := openFile(filepath, os.O_RDONLY, 0)
if err != nil {
return nil, err
}
b, err = ioutil.ReadAll(file)
if err != nil {
_ = file.Close()
return nil, err
}
if err := file.Close(); err != nil {
return nil, err
}
return b, nil
}