The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/pkg/infra/filestorage/api.go

109 lines
2.5 KiB

package filestorage
import (
"context"
"errors"
"regexp"
"strings"
"time"
)
type Operation string
const (
OperationGet Operation = "get"
OperationDelete Operation = "delete"
OperationUpsert Operation = "upsert"
OperationListFiles Operation = "listFiles"
OperationListFolders Operation = "listFolders"
OperationCreateFolder Operation = "createFolder"
OperationDeleteFolder Operation = "deleteFolder"
)
var (
ErrRelativePath = errors.New("path cant be relative")
ErrNonCanonicalPath = errors.New("path must be canonical")
ErrPathTooLong = errors.New("path is too long")
ErrPathInvalid = errors.New("path is invalid")
ErrPathEndsWithDelimiter = errors.New("path can not end with delimiter")
ErrOperationNotSupported = errors.New("operation not supported")
Delimiter = "/"
multipleDelimiters = regexp.MustCompile(`/+`)
)
func Join(parts ...string) string {
joinedPath := Delimiter + strings.Join(parts, Delimiter)
// makes the API more forgiving for clients without compromising safety
return multipleDelimiters.ReplaceAllString(joinedPath, Delimiter)
}
type File struct {
Contents []byte
FileMetadata
}
type FileMetadata struct {
Name string
FullPath string
MimeType string
Modified time.Time
Created time.Time
Size int64
Properties map[string]string
}
type ListFilesResponse struct {
Files []FileMetadata
HasMore bool
LastPath string
}
type Paging struct {
After string
First int
}
type UpsertFileCommand struct {
Path string
MimeType string
Contents *[]byte
Properties map[string]string
}
type PathFilters struct {
allowedPrefixes []string
}
func (f *PathFilters) isAllowed(path string) bool {
if f == nil || f.allowedPrefixes == nil {
return true
}
for i := range f.allowedPrefixes {
if strings.HasPrefix(path, strings.ToLower(f.allowedPrefixes[i])) {
return true
}
}
return false
}
type ListOptions struct {
Recursive bool
PathFilters
}
type FileStorage interface {
Get(ctx context.Context, path string) (*File, error)
Delete(ctx context.Context, path string) error
Upsert(ctx context.Context, command *UpsertFileCommand) error
ListFiles(ctx context.Context, folderPath string, paging *Paging, options *ListOptions) (*ListFilesResponse, error)
ListFolders(ctx context.Context, folderPath string, options *ListOptions) ([]FileMetadata, error)
CreateFolder(ctx context.Context, path string) error
DeleteFolder(ctx context.Context, path string) error
close() error
}