imagestorage: fix templating of public_url option for webdav (#74885)

* spelling in error message

* imguploader: fix template for webdav url

Since a few years ago, when loading the config file, the  template gets replaced in the expanding
env var phase (see ##25075) and introduced a bug in the webdav public_url config option. This commit
changes the template syntax to be {{file}}. This doesn't get expanded and removed when the config file
is loaded.

* devenv: add a block for a WebDAV server

* Adding alerting as codeowners for webdav

---------

Co-authored-by: Timur Olzhabayev <timur.olzhabayev@grafana.com>
This commit is contained in:
Daniel Lee 2023-09-27 23:35:10 +02:00 committed by GitHub
parent 6cede32535
commit 33a32df47b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 45 additions and 9 deletions

1
.github/CODEOWNERS vendored
View File

@ -209,6 +209,7 @@
/devenv/docker/blocks/tempo/ @grafana/observability-traces-and-profiling
/devenv/docker/blocks/traefik/ @mckn
/devenv/docker/blocks/zipkin/ @grafana/observability-traces-and-profiling
/devenv/docker/blocks/webdav/ @grafana/alerting-backend-product
/devenv/docker/buildcontainer/ @bergquist
/devenv/docker/compose_header.yml @grafana/backend-platform
/devenv/docker/debtest/ @bergquist

View File

@ -0,0 +1,26 @@
# README for the image storage WebDAV docker block
This block is used for testing the [WebDAV](https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#external_image_storagewebdav) option for external image storage which is used in [alert notifications](https://grafana.com/docs/grafana/latest/alerting/manage-notifications/images-in-notifications/). This uses the simplest WebDav server that is still being maintained, a project called [Dufs](https://github.com/sigoden/dufs).
## Using Dufs
Dufs has a web UI that can be accessed at http://localhost:5000 to easily see which files have been uploaded by Grafana. The config has disabled authentication and allows everyone to read and write files.
## Configuring image storage in Grafana to use Dufs
An example config for external image storage with webdav enabled:
```ini
[external_image_storage]
provider = webdav
[external_image_storage.webdav]
url = http://127.0.0.1:5000/images
public_url = http://127.0.0.1:5000/images/{{file}}
; as auth is not configured in Dufs, these are just dummy values
username = test
password = test
```
Note: As everything runs on localhost, the image in an email notification will be broken but the link will work if you click on it and open it in your browser.

View File

@ -0,0 +1,10 @@
webdav:
image: sigoden/dufs
ports:
- "5000:5000"
volumes:
- "webdav-data:/data"
command: "/data -A"
volumes:
webdav-data: {}

View File

@ -1983,7 +1983,7 @@ Basic auth password.
### public_url
Optional URL to send to users in notifications. If the string contains the sequence `${file}`, it is replaced with the uploaded filename. Otherwise, the file name is appended to the path part of the URL, leaving any query string unchanged.
Optional URL to send to users in notifications. If the string contains the sequence `{{file}}`, it is replaced with the uploaded filename. Otherwise, the file name is appended to the path part of the URL, leaving any query string unchanged.
<hr>

View File

@ -37,8 +37,8 @@ var netClient = &http.Client{
}
func (u *WebdavUploader) PublicURL(filename string) string {
if strings.Contains(u.public_url, "${file}") {
return strings.ReplaceAll(u.public_url, "${file}", filename)
if strings.Contains(u.public_url, "{{file}}") {
return strings.ReplaceAll(u.public_url, "{{file}}", filename)
}
publicURL, _ := url.Parse(u.public_url)

View File

@ -2,10 +2,10 @@ package imguploader
import (
"context"
"net/url"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -35,11 +35,10 @@ func TestUploadToWebdav(t *testing.T) {
func TestPublicURL(t *testing.T) {
t.Run("Given a public URL with parameters, and no template", func(t *testing.T) {
webdavUploader, _ := NewWebdavImageUploader("http://localhost:8888/webdav/", "test", "test", "http://cloudycloud.me/s/DOIFDOMV/download?files=")
parsed, _ := url.Parse(webdavUploader.PublicURL("fileyfile.png"))
require.True(t, strings.HasSuffix(parsed.Path, "fileyfile.png"))
assert.Equal(t, "http://cloudycloud.me/s/DOIFDOMV/download/fileyfile.png?files=", webdavUploader.PublicURL("fileyfile.png"))
})
t.Run("Given a public URL with parameters, and a template", func(t *testing.T) {
webdavUploader, _ := NewWebdavImageUploader("http://localhost:8888/webdav/", "test", "test", "http://cloudycloud.me/s/DOIFDOMV/download?files=${file}")
require.True(t, strings.HasSuffix(webdavUploader.PublicURL("fileyfile.png"), "fileyfile.png"))
webdavUploader, _ := NewWebdavImageUploader("http://localhost:8888/webdav/", "test", "test", "http://cloudycloud.me/s/DOIFDOMV/download?files={{file}}")
assert.Equal(t, "http://cloudycloud.me/s/DOIFDOMV/download?files=fileyfile.png", webdavUploader.PublicURL("fileyfile.png"))
})
}

View File

@ -57,7 +57,7 @@ func expandConfig(file *ini.File) error {
for _, expander := range expanders {
err := expander.expander.SetupExpander(file)
if err != nil {
return fmt.Errorf("got error during initilazation of expander '%s': %w", expander.name, err)
return fmt.Errorf("got error during initialization of expander '%s': %w", expander.name, err)
}
for _, section := range file.Sections() {