Compare commits

...

6 Commits

Author SHA1 Message Date
592d1093ac bump version 2024-08-28 17:32:23 +02:00
83481072bb update docs dependencies 2024-08-28 17:28:58 +02:00
Boris Bera
776638e6fe
fix(backend): treat all special chars as _ in env (#382) 2024-08-28 17:25:06 +02:00
Boris Bera
bc74d3f13e
Add option to crash autorestic when key is missing instead of generating a new key (#383)
* feat(backend): add requireKey option to backend

This option will prevent `autorestic` from generating a key and will
cause it to crash instead. This is intended for use cases where you want
to provision the key yourself and don't want `autorestic` to
accidentally generate one for you.

* doc(backend): document requireKey
2024-08-28 17:21:01 +02:00
guest20
dd01e97cf3
install.sh: FreeBSD amd64 (#385) 2024-08-28 17:19:13 +02:00
dependabot[bot]
aabb0989c6
Bump restic/restic from 0.16.4 to 0.17.0 (#386)
Bumps restic/restic from 0.16.4 to 0.17.0.

---
updated-dependencies:
- dependency-name: restic/restic
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-28 17:18:01 +02:00
11 changed files with 2136 additions and 1913 deletions

View File

@ -6,7 +6,7 @@ RUN go mod download
COPY . .
RUN go build
FROM restic/restic:0.16.4
FROM restic/restic:0.17.0
RUN apk add --no-cache rclone bash curl docker-cli
COPY --from=builder /app/autorestic /usr/bin/autorestic
ENTRYPOINT []

View File

@ -1 +1 @@
v20.8.0
v22.7.0

View File

@ -4,11 +4,11 @@
"dev": "NEXT_TELEMETRY_DISABLED=1 next"
},
"dependencies": {
"next": "^13.5.3",
"nextra": "^2.13.1",
"nextra-theme-docs": "^2.13.1",
"react": "^18.2.0",
"react-dom": "^18.2.0"
"next": "^14.2.7",
"nextra": "^2.13.4",
"nextra-theme-docs": "^2.13.4",
"react": "^18.3.1",
"react-dom": "^18.3.1"
},
"packageManager": "pnpm@8.8.0"
"packageManager": "pnpm@9.9.0"
}

View File

@ -16,3 +16,25 @@ backends:
## Types
We restic supports multiple types of backends. See the [full list](/backend/available) for details.
## Avoid Generating Keys
By default, `autorestic` will generate a key for every backend if none is defined. This is done by updating your config file with the key.
In cases where you want to provide the key yourself, you can ensure that `autorestic` doesn't accidentally generate one for you by setting `requireKey: true`.
Example:
```yaml | .autorestic.yml
version: 2
backends:
foo:
type: local
path: /data/my/backups
# Alternatively, you can set the key through the `AUTORESTIC_FOO_RESTIC_PASSWORD` environment variable.
key: ... your key here ...
requireKey: true
```
With this setting, if a key is missing, `autorestic` will crash instead of generating a new key and updating your config file.

3916
docs/pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

5
go.mod
View File

@ -11,9 +11,11 @@ require (
github.com/robfig/cron v1.2.0
github.com/spf13/cobra v1.4.0
github.com/spf13/viper v1.11.0
github.com/stretchr/testify v1.9.0
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fsnotify/fsnotify v1.5.1 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
@ -23,6 +25,7 @@ require (
github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/pelletier/go-toml v1.9.4 // indirect
github.com/pelletier/go-toml/v2 v2.0.0-beta.8 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/afero v1.8.2 // indirect
github.com/spf13/cast v1.4.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
@ -32,5 +35,5 @@ require (
golang.org/x/text v0.3.8 // indirect
gopkg.in/ini.v1 v1.66.4 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

7
go.sum
View File

@ -182,8 +182,9 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@ -487,8 +488,8 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0 h1:hjy8E9ON/egN1tAYqKb61G10WtihqetD4sz2H+8nIeA=
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View File

@ -10,6 +10,8 @@ if [[ $NATIVE_OS == *"linux"* ]]; then
OS=linux
elif [[ $NATIVE_OS == *"darwin"* ]]; then
OS=darwin
elif [[ $NATIVE_OS == *"freebsd"* ]]; then
OS=freebsd
else
echo "Could not determine OS automatically, please check the release page manually: https://github.com/cupcakearmy/autorestic/releases"
exit 1
@ -17,7 +19,7 @@ fi
echo $OS
NATIVE_ARCH=$(uname -m | tr '[:upper:]' '[:lower:]')
if [[ $NATIVE_ARCH == *"x86_64"* ]]; then
if [[ $NATIVE_ARCH == *"x86_64"* || $NATIVE_ARCH == *"amd64"* ]]; then
ARCH=amd64
elif [[ $NATIVE_ARCH == *"arm64"* || $NATIVE_ARCH == *"aarch64"* ]]; then
ARCH=arm64

View File

@ -6,6 +6,7 @@ import (
"fmt"
"net/url"
"os"
"regexp"
"strings"
"github.com/cupcakearmy/autorestic/internal/colors"
@ -22,6 +23,7 @@ type Backend struct {
Type string `mapstructure:"type,omitempty"`
Path string `mapstructure:"path,omitempty"`
Key string `mapstructure:"key,omitempty"`
RequireKey bool `mapstructure:"requireKey,omitempty"`
Env map[string]string `mapstructure:"env,omitempty"`
Rest BackendRest `mapstructure:"rest,omitempty"`
Options Options `mapstructure:"options,omitempty"`
@ -57,6 +59,8 @@ func (b Backend) generateRepo() (string, error) {
}
}
var nonAlphaRegex = regexp.MustCompile("[^A-Za-z0-9]")
func (b Backend) getEnv() (map[string]string, error) {
env := make(map[string]string)
// Key
@ -72,7 +76,9 @@ func (b Backend) getEnv() (map[string]string, error) {
}
// From Envfile and passed as env
var prefix = "AUTORESTIC_" + strings.ToUpper(b.name) + "_"
nameForEnv := strings.ToUpper(b.name)
nameForEnv = nonAlphaRegex.ReplaceAllString(nameForEnv, "_")
var prefix = "AUTORESTIC_" + nameForEnv + "_"
for _, variable := range os.Environ() {
var splitted = strings.SplitN(variable, "=", 2)
if strings.HasPrefix(splitted[0], prefix) {
@ -104,6 +110,9 @@ func (b Backend) validate() error {
// Check if key is set in environment
env, _ := b.getEnv()
if _, found := env["RESTIC_PASSWORD"]; !found {
if b.RequireKey {
return fmt.Errorf("backend %s requires a key but none was provided", b.name)
}
// No key set in config file or env => generate random key and save file
key := generateRandomKey()
b.Key = key

View File

@ -6,6 +6,7 @@ import (
"testing"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
)
func TestGenerateRepo(t *testing.T) {
@ -194,6 +195,33 @@ func TestGetEnv(t *testing.T) {
assertEqual(t, result["B2_ACCOUNT_ID"], "foo123")
assertEqual(t, result["B2_ACCOUNT_KEY"], "foo456")
})
for _, char := range "@-_:/" {
t.Run(fmt.Sprintf("env var with special char (%c)", char), func(t *testing.T) {
// generate env variables
// TODO better way to teardown
defer os.Unsetenv("AUTORESTIC_FOO_BAR_RESTIC_PASSWORD")
defer os.Unsetenv("AUTORESTIC_FOO_BAR_B2_ACCOUNT_ID")
defer os.Unsetenv("AUTORESTIC_FOO_BAR_B2_ACCOUNT_KEY")
os.Setenv("AUTORESTIC_FOO_BAR_RESTIC_PASSWORD", "secret123")
os.Setenv("AUTORESTIC_FOO_BAR_B2_ACCOUNT_ID", "foo123")
os.Setenv("AUTORESTIC_FOO_BAR_B2_ACCOUNT_KEY", "foo456")
b := Backend{
name: fmt.Sprintf("foo%cbar", char),
Type: "local",
Path: "/foo/bar",
}
result, err := b.getEnv()
if err != nil {
t.Errorf("unexpected error %v", err)
}
assertEqual(t, result["RESTIC_REPOSITORY"], "/foo/bar")
assertEqual(t, result["RESTIC_PASSWORD"], "secret123")
assertEqual(t, result["B2_ACCOUNT_ID"], "foo123")
assertEqual(t, result["B2_ACCOUNT_KEY"], "foo456")
})
}
}
func TestValidate(t *testing.T) {
@ -222,4 +250,16 @@ func TestValidate(t *testing.T) {
}
assertEqual(t, err.Error(), "Backend \"foo\" has no \"path\"")
})
t.Run("require key with no key", func(t *testing.T) {
b := Backend{
name: "foo",
Type: "local",
Path: "~/foo/bar",
RequireKey: true,
}
err := b.validate()
fmt.Printf("error: %v\n", err)
assert.EqualError(t, err, "backend foo requires a key but none was provided")
})
}

View File

@ -17,7 +17,7 @@ import (
"github.com/spf13/viper"
)
const VERSION = "1.8.2"
const VERSION = "1.8.3"
type OptionMap map[string][]interface{}
type Options map[string]OptionMap