Feature: Docker secrets, refers to #306
This commit is contained in:
108
internal/params/secrets.go
Normal file
108
internal/params/secrets.go
Normal file
@@ -0,0 +1,108 @@
|
||||
package params
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/os"
|
||||
libparams "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 := []libparams.GetEnvSetter{
|
||||
libparams.Compulsory(), // to fallback on file reading
|
||||
libparams.CaseSensitiveValue(),
|
||||
libparams.Unset(),
|
||||
libparams.RetroKeys(retroKeys, r.onRetroActive),
|
||||
}
|
||||
value, envErr := r.envParams.GetEnv(envKey, envOptions...)
|
||||
if envErr == nil {
|
||||
return value, nil
|
||||
}
|
||||
|
||||
defaultSecretFile := "/run/secrets/" + strings.ToLower(envKey)
|
||||
filepath, err := r.envParams.GetEnv(envKey+"_SECRETFILE",
|
||||
libparams.CaseSensitiveValue(),
|
||||
libparams.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)
|
||||
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.envParams.GetEnv(strings.ToUpper(secretName)+"_SECRETFILE",
|
||||
libparams.CaseSensitiveValue(),
|
||||
libparams.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
|
||||
}
|
||||
Reference in New Issue
Block a user