From 246e6fc0d807e966512ccdf81ee0e923ab66f115 Mon Sep 17 00:00:00 2001 From: cupcakearmy Date: Sat, 30 Oct 2021 13:48:44 +0200 Subject: [PATCH] enable generic env variables --- docs/markdown/backend/available.md | 2 ++ docs/markdown/backend/env.md | 55 +++++++++++++++++++++++------- internal/backend.go | 35 +++++++++---------- 3 files changed, 61 insertions(+), 31 deletions(-) diff --git a/docs/markdown/backend/available.md b/docs/markdown/backend/available.md index 88bccf0..cf692c4 100644 --- a/docs/markdown/backend/available.md +++ b/docs/markdown/backend/available.md @@ -4,6 +4,8 @@ In theory [all the restic backends](https://restic.readthedocs.io/en/stable/030_ Those tested are the following: +> ℹ️ You can also [specify the `env` variables in a config file](/backend/env) to separate them from the config file. + ## Local ```yaml diff --git a/docs/markdown/backend/env.md b/docs/markdown/backend/env.md index 4831c13..f66784e 100644 --- a/docs/markdown/backend/env.md +++ b/docs/markdown/backend/env.md @@ -1,36 +1,67 @@ # Environment -> ⚠ Available since version `v1.3.0` +> ⚠ Available since version `v1.4.0` Sometimes it's favorable not having the encryption keys in the config files. -For that `autorestic` allows passing the backend keys as `ENV` variables, or through an env file. +For that `autorestic` allows passing the env variables to backend password as `ENV` variables, or through an env file. +You can also pass whatever `env` variable to restic by prefixing it with `AUTORESTIC_[BACKEND NAME]_`. -The syntax for the `ENV` variables is as follows: `AUTORESTIC_[BACKEND NAME]_KEY`. +> ℹ️ Env variables and file overwrite the config file in the following order: +> +> Env Variables > Env File (`.autorestic.env`) > Config file (`.autorestic.yaml`) + +## Env file + +Alternatively `autorestic` can load an env file, located next to `.autorestic.yml` called `.autorestic.env`. + +``` +AUTORESTIC_FOO_RESTIC_PASSWORD=secret123 +``` + +### Example with repository password + +The syntax for the `ENV` variables is as follows: `AUTORESTIC_[BACKEND NAME]_RESTIC_PASSWORD`. ```yaml | autorestic.yaml backend: foo: type: ... path: ... - key: secret123 # => AUTORESTIC_FOO_KEY=secret123 + key: secret123 # => AUTORESTIC_FOO_RESTIC_PASSWORD=secret123 ``` -## Example - This means we could remove `key: secret123` from `.autorestic.yaml` and execute as follows: ```bash -AUTORESTIC_FOO_KEY=secret123 autorestic backup ... +AUTORESTIC_FOO_RESTIC_PASSWORD=secret123 autorestic backup ... ``` -## Env file +### Example with Backblaze B2 + +```yaml | autorestic.yaml +backends: + bb: + type: b2 + path: myBucket + key: myPassword + env: + B2_ACCOUNT_ID: 123 + B2_ACCOUNT_KEY: 456 +``` -Alternatively `autorestic` can load an env file, located next to `autorestic.yml` called `.autorestic.env`. +You could create an `.autorestic.env` or pass the following `ENV` variables to autorestic: -```| .autorestic.env -AUTORESTIC_FOO_KEY=secret123 +``` +AUTORESTIC_BB_RESTIC_PASSWORD=myPassword +AUTORESTIC_BB_B2_ACCOUNT_ID=123 +AUTORESTIC_BB_B2_ACCOUNT_KEY=456 ``` -after that you can simply use `autorestic` as your are used to. +```yaml | autorestic.yaml +backends: + bb: + type: b2 + path: myBucket +``` > :ToCPrevNext diff --git a/internal/backend.go b/internal/backend.go index 8116d44..e60c709 100644 --- a/internal/backend.go +++ b/internal/backend.go @@ -58,20 +58,27 @@ func (b Backend) generateRepo() (string, error) { func (b Backend) getEnv() (map[string]string, error) { env := make(map[string]string) + // Key if b.Key != "" { env["RESTIC_PASSWORD"] = b.Key - } else { - key, err := b.getKey() - if err != nil { - return nil, err - } - env["RESTIC_PASSWORD"] = key } + + // From config file repo, err := b.generateRepo() env["RESTIC_REPOSITORY"] = repo for key, value := range b.Env { env[strings.ToUpper(key)] = value } + + // From Envfile and passed as env + var prefix = "AUTORESTIC_" + strings.ToUpper(b.name) + "_" + for _, variable := range os.Environ() { + var splitted = strings.SplitN(variable, "=", 2) + if strings.HasPrefix(splitted[0], prefix) { + env[strings.TrimPrefix(splitted[0], prefix)] = splitted[1] + } + } + return env, err } @@ -85,17 +92,6 @@ func generateRandomKey() string { return key } -func (b Backend) getKey() (string, error) { - if b.Key != "" { - return b.Key, nil - } - keyName := "AUTORESTIC_" + strings.ToUpper(b.name) + "_KEY" - if key, found := os.LookupEnv(keyName); found { - return key, nil - } - return "", fmt.Errorf("no key found for backend \"%s\"", b.name) -} - func (b Backend) validate() error { if b.Type == "" { return fmt.Errorf(`Backend "%s" has no "type"`, b.name) @@ -105,8 +101,9 @@ func (b Backend) validate() error { } if b.Key == "" { // Check if key is set in environment - if _, err := b.getKey(); err != nil { - // If not generate a new one + env, _ := b.getEnv() + if _, found := env["RESTIC_PASSWORD"]; !found { + // No key set in config file or env => generate random key and save file key := generateRandomKey() b.Key = key c := GetConfig()