Alerting: Linking external images securely - Azure Blob (#1) (#56598)

This commit is contained in:
Petr Stupka
2022-11-01 13:02:17 +01:00
committed by GitHub
parent 3188af9be3
commit e99f75f0ca
8 changed files with 75 additions and 15 deletions
@@ -19,23 +19,26 @@ import (
"strings"
"time"
"github.com/Azure/azure-storage-blob-go/azblob"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/util"
)
type AzureBlobUploader struct {
account_name string
account_key string
container_name string
log log.Logger
account_name string
account_key string
container_name string
sas_token_expiration_days int
log log.Logger
}
func NewAzureBlobUploader(account_name string, account_key string, container_name string) *AzureBlobUploader {
func NewAzureBlobUploader(account_name string, account_key string, container_name string, sas_token_expiration_days int) *AzureBlobUploader {
return &AzureBlobUploader{
account_name: account_name,
account_key: account_key,
container_name: container_name,
log: log.New("azureBlobUploader"),
account_name: account_name,
account_key: account_key,
container_name: container_name,
sas_token_expiration_days: sas_token_expiration_days,
log: log.New("azureBlobUploader"),
}
}
@@ -91,9 +94,49 @@ func (az *AzureBlobUploader) Upload(ctx context.Context, imageDiskPath string) (
}
url := fmt.Sprintf("https://%s.blob.core.windows.net/%s/%s", az.account_name, az.container_name, randomFileName)
if az.sas_token_expiration_days > 0 {
url, err = blob.GetBlobSasUrl(ctx, az.container_name, randomFileName, az.sas_token_expiration_days)
if err != nil {
return "", err
}
}
return url, nil
}
// SignWithSharedKey uses an account's SharedKeyCredential to sign this signature values to produce the proper SAS query parameters.
func (c *StorageClient) GetBlobSasUrl(ctx context.Context, containerName, blobName string, sasTokenExpiration int) (string, error) {
if c.Auth == nil {
return "", fmt.Errorf("cannot sign SAS query without Shared Key Credential")
}
// create source blob SAS url
credential, err := azblob.NewSharedKeyCredential(c.Auth.Account, c.Auth.Key)
if err != nil {
return "", err
}
// Set the desired SAS signature values and sign them with the shared key credentials to get the SAS query parameters.
sasQueryParams, err := azblob.BlobSASSignatureValues{
Protocol: azblob.SASProtocolHTTPS, // Users MUST use HTTPS (not HTTP)
ExpiryTime: time.Now().UTC().AddDate(0, 0, sasTokenExpiration), // Expiration time
ContainerName: containerName,
BlobName: blobName,
Permissions: azblob.BlobSASPermissions{Add: false, Read: true, Write: false}.String(), // Read only permissions
}.NewSASQueryParameters(credential)
if err != nil {
return "", err
}
// Create the URL of the resource you wish to access and append the SAS query parameters.
// Since this is a blob SAS, the URL is to the Azure storage blob.
qp := sasQueryParams.Encode()
blobSasUrl := fmt.Sprintf("https://%s.blob.core.windows.net/%s/%s?%s", c.Auth.Account, containerName, blobName, qp)
// Return Blob SAS token URL
return blobSasUrl, nil
}
// --- AZURE LIBRARY
type Error struct {
Code int
+3 -1
View File
@@ -110,8 +110,10 @@ func NewImageUploader() (ImageUploader, error) {
account_name := azureBlobSec.Key("account_name").MustString("")
account_key := azureBlobSec.Key("account_key").MustString("")
container_name := azureBlobSec.Key("container_name").MustString("")
sas_token_expiration_days := azureBlobSec.Key("sas_token_expiration_days").MustInt(-1)
return NewAzureBlobUploader(account_name, account_key, container_name, sas_token_expiration_days), nil
return NewAzureBlobUploader(account_name, account_key, container_name), nil
case "local":
return NewLocalImageUploader()
}
@@ -154,6 +154,8 @@ func TestImageUploaderFactory(t *testing.T) {
require.NoError(t, err)
_, err = azureBlobSec.NewKey("container_name", "container_name")
require.NoError(t, err)
_, err = azureBlobSec.NewKey("sas_token_expiration_days", "sas_token_expiration_days")
require.NoError(t, err)
uploader, err := NewImageUploader()
require.NoError(t, err)
@@ -163,6 +165,7 @@ func TestImageUploaderFactory(t *testing.T) {
require.Equal(t, "account_name", original.account_name)
require.Equal(t, "account_key", original.account_key)
require.Equal(t, "container_name", original.container_name)
require.Equal(t, -1, original.sas_token_expiration_days)
})
})