Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ $(GOBIN)/golangci-lint: verify $(GOBIN)/eget

$(GOBIN)/hugo: $(GOBIN)/eget
@echo "[*] $@"
"$(GOBIN)/eget" gohugoio/hugo --tag 0.145.0 --upgrade-only --asset=extended_0 --to '$(GOBIN)'
"$(GOBIN)/eget" gohugoio/hugo --tag v0.145.0 --upgrade-only --asset=extended_0 --to '$(GOBIN)'

prepare_build: verify download
@echo "[*] $@"
Expand Down
194 changes: 77 additions & 117 deletions config/profile.go

Large diffs are not rendered by default.

51 changes: 50 additions & 1 deletion config/profile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1393,7 +1393,8 @@ profile:
{"copy", true},
{"prune", true},
{"forget", true},
{"init", false},
{"init", true},
{"other", false},
}

for _, config := range configs {
Expand Down Expand Up @@ -1604,3 +1605,51 @@ func TestGetCopyStructFields(t *testing.T) {
assert.Equal(t, copySection.getInitFlags(profile).GetAll(), profile.GetCopyInitializeFlags().GetAll())
})
}

// make sure all commands are supporting run-before
func TestRunBeforeOnAllCommands(t *testing.T) {
commands := restic.CommandNames()
assert.NotEmpty(t, commands)

for _, command := range commands {
t.Run(command, func(t *testing.T) {
testConfig := `
[profile]
[profile.%[1]s]
run-before = ["echo hello"]
`
profile, err := getProfile("toml", fmt.Sprintf(testConfig, command), "profile", "")
require.NoError(t, err)
assert.NotNil(t, profile)
profileCommands, sectionCommands := profile.GetRunShellCommandsSections(command)
assert.Empty(t, profileCommands)
assert.NotEmpty(t, sectionCommands)
assert.Equal(t, []string{"echo hello"}, sectionCommands.RunBefore)
assert.Empty(t, sectionCommands.RunAfter)
})
}
}

// make sure all commands are supporting send-before
func TestSendBeforeOnAllCommands(t *testing.T) {
commands := restic.CommandNames()
assert.NotEmpty(t, commands)

for _, command := range commands {
t.Run(command, func(t *testing.T) {
testConfig := `
[profile]
[profile.%[1]s]
[[profile.%[1]s.send-before]]
url = "http://example.com"
`
profile, err := getProfile("toml", fmt.Sprintf(testConfig, command), "profile", "")
require.NoError(t, err)
assert.NotNil(t, profile)
monitoring := profile.GetMonitoringSections(command)
assert.NotEmpty(t, monitoring)
assert.Equal(t, 1, len(monitoring.SendBefore))
assert.Empty(t, monitoring.SendAfter)
})
}
}
44 changes: 44 additions & 0 deletions config/send.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package config

// SendMonitoringSections is a group of target to send monitoring information
type SendMonitoringSections struct {
SendBefore []SendMonitoringSection `mapstructure:"send-before" description:"Send HTTP request(s) before a restic command"`
SendAfter []SendMonitoringSection `mapstructure:"send-after" description:"Send HTTP request(s) after a successful restic command"`
SendAfterFail []SendMonitoringSection `mapstructure:"send-after-fail" description:"Send HTTP request(s) after failed restic or shell commands"`
SendFinally []SendMonitoringSection `mapstructure:"send-finally" description:"Send HTTP request(s) always, after all other commands"`
}

func (s *SendMonitoringSections) setRootPath(_ *Profile, rootPath string) {
for _, sections := range s.getAllSendMonitoringSections() {
for index := range sections {
sections[index].BodyTemplate = fixPath(sections[index].BodyTemplate, expandEnv, expandUserHome, absolutePrefix(rootPath))
}
}
}

func (s *SendMonitoringSections) GetSendMonitoring() *SendMonitoringSections { return s }

func (s *SendMonitoringSections) getAllSendMonitoringSections() [][]SendMonitoringSection {
return [][]SendMonitoringSection{
s.SendBefore,
s.SendAfter,
s.SendAfterFail,
s.SendFinally,
}
}

// SendMonitoringSection is used to send monitoring information to third party software
type SendMonitoringSection struct {
Method string `mapstructure:"method" enum:"GET;DELETE;HEAD;OPTIONS;PATCH;POST;PUT;TRACE" default:"GET" description:"HTTP method of the request"`
URL ConfidentialValue `mapstructure:"url" format:"uri" description:"URL of the target to send to"`
Headers []SendMonitoringHeader `mapstructure:"headers" description:"Additional HTTP headers to send with the request"`
Body string `mapstructure:"body" description:"Request body, overrides \"body-template\""`
BodyTemplate string `mapstructure:"body-template" description:"Path to a file containing the request body (go template). See https://creativeprojects.github.io/resticprofile/configuration/http_hooks/#body-template"`
SkipTLS bool `mapstructure:"skip-tls-verification" description:"Enables insecure TLS (without verification), see also \"global.ca-certificates\""`
}

// SendMonitoringHeader is used to send HTTP headers
type SendMonitoringHeader struct {
Name string `mapstructure:"name" regex:"^\\w([\\w-]+)\\w$" examples:"\"Authorization\";\"Cache-Control\";\"Content-Disposition\";\"Content-Type\"" description:"Name of the HTTP header"`
Value ConfidentialValue `mapstructure:"value" examples:"\"Bearer ...\";\"Basic ...\";\"no-cache\";\"attachment;; filename=stats.txt\";\"application/json\";\"text/plain\";\"text/xml\"" description:"Value of the header"`
}
2 changes: 2 additions & 0 deletions contrib/templates/reference.gomd
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ archetype: "chapter"
pre: "<b>6. </b>"
linkTitle: Reference
slug: reference
aliases:
- /configuration/reference
{{ if .Env.META_TITLE -}}
title: {{ .Env.META_TITLE }}
{{- else -}}
Expand Down
2 changes: 1 addition & 1 deletion docs/version.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[params]
version = "v0.30.0"
version = "v0.31.0"
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/creativeprojects/resticprofile

go 1.24.2
go 1.24.3

require (
github.com/Masterminds/semver/v3 v3.3.1
Expand Down
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (

// These fields are populated by the goreleaser build
var (
version = "0.30.0-dev"
version = "0.31.0-dev"
commit = ""
date = ""
builtBy = ""
Expand Down
28 changes: 16 additions & 12 deletions monitor/hook/sender_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,11 +252,13 @@ func TestConfidentialURL(t *testing.T) {

profile := &config.Profile{
Backup: &config.BackupSection{
SectionWithScheduleAndMonitoring: config.SectionWithScheduleAndMonitoring{
SendMonitoringSections: config.SendMonitoringSections{
SendBefore: []config.SendMonitoringSection{
{
URL: config.NewConfidentialValue(serverURL),
GenericSectionWithSchedule: config.GenericSectionWithSchedule{
GenericSection: config.GenericSection{
SendMonitoringSections: config.SendMonitoringSections{
SendBefore: []config.SendMonitoringSection{
{
URL: config.NewConfidentialValue(serverURL),
},
},
},
},
Expand Down Expand Up @@ -286,13 +288,15 @@ func TestConfidentialHeader(t *testing.T) {

profile := &config.Profile{
Backup: &config.BackupSection{
SectionWithScheduleAndMonitoring: config.SectionWithScheduleAndMonitoring{
SendMonitoringSections: config.SendMonitoringSections{
SendBefore: []config.SendMonitoringSection{
{
URL: config.NewConfidentialValue(server.URL),
Headers: []config.SendMonitoringHeader{
{Name: headerKey, Value: config.NewConfidentialValue(headerValue)},
GenericSectionWithSchedule: config.GenericSectionWithSchedule{
GenericSection: config.GenericSection{
SendMonitoringSections: config.SendMonitoringSections{
SendBefore: []config.SendMonitoringSection{
{
URL: config.NewConfidentialValue(server.URL),
Headers: []config.SendMonitoringHeader{
{Name: headerKey, Value: config.NewConfidentialValue(headerValue)},
},
},
},
},
Expand Down
2 changes: 1 addition & 1 deletion sonar-project.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
sonar.organization=creativeprojects
sonar.projectKey=creativeprojects_resticprofile
sonar.projectName=resticprofile
sonar.projectVersion=0.30.0
sonar.projectVersion=0.31.0

sonar.sources=.
sonar.exclusions=**/*_test.go,/docs/**
Expand Down
6 changes: 3 additions & 3 deletions wrapper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1024,11 +1024,11 @@ func TestRunShellCommands(t *testing.T) {

profile := config.NewProfile(&config.Config{}, "name")
profile.Backup = &config.BackupSection{}
profile.Check = &config.SectionWithScheduleAndMonitoring{}
profile.Check = &config.GenericSectionWithSchedule{}
profile.Copy = &config.CopySection{}
profile.Forget = &config.SectionWithScheduleAndMonitoring{}
profile.Forget = &config.GenericSectionWithSchedule{}
profile.Init = &config.InitSection{}
profile.Prune = &config.SectionWithScheduleAndMonitoring{}
profile.Prune = &config.GenericSectionWithSchedule{}
for name := range profile.OtherSections {
profile.OtherSections[name] = new(config.GenericSection)
}
Expand Down