harness-drone/store/logs/azureblob.go
2019-08-14 09:59:59 -07:00

100 lines
2.7 KiB
Go

// Copyright 2019 Drone.IO Inc. All rights reserved.
// Use of this source code is governed by the Drone Non-Commercial License
// that can be found in the LICENSE file.
// +build !oss
package logs
import (
"context"
"fmt"
"io"
"net/url"
"github.com/Azure/azure-storage-blob-go/azblob"
"github.com/drone/drone/core"
)
// NewAzureBlobEnv returns a new Azure blob log store.
func NewAzureBlobEnv(containerName, storageAccountName, storageAccessKey string) core.LogStore {
return &azureBlobStore{
containerName: containerName,
storageAccountName: storageAccountName,
storageAccessKey: storageAccessKey,
containerURL: nil,
}
}
type azureBlobStore struct {
containerName string
storageAccountName string
storageAccessKey string
containerURL *azblob.ContainerURL
}
func (az *azureBlobStore) Find(ctx context.Context, step int64) (io.ReadCloser, error) {
err := az.getContainerURL()
if err != nil {
return nil, err
}
blobURL := az.containerURL.NewBlockBlobURL(fmt.Sprintf("%d", step))
out, err := blobURL.Download(ctx, 0, azblob.CountToEnd, azblob.BlobAccessConditions{}, false)
if err != nil {
return nil, err
}
return out.Body(azblob.RetryReaderOptions{}), nil
}
func (az *azureBlobStore) Create(ctx context.Context, step int64, r io.Reader) error {
err := az.getContainerURL()
if err != nil {
return err
}
opts := &azblob.UploadStreamToBlockBlobOptions{
BufferSize: 4 * 1024 * 1024,
MaxBuffers: 5,
}
blobURL := az.containerURL.NewBlockBlobURL(fmt.Sprintf("%d", step))
_, err = azblob.UploadStreamToBlockBlob(ctx, r, blobURL, *opts)
return err
}
func (az *azureBlobStore) Update(ctx context.Context, step int64, r io.Reader) error {
return az.Create(ctx, step, r)
}
func (az *azureBlobStore) Delete(ctx context.Context, step int64) error {
err := az.getContainerURL()
if err != nil {
return err
}
blobURL := az.containerURL.NewBlockBlobURL(fmt.Sprintf("%d", step))
_, err = blobURL.Delete(ctx, azblob.DeleteSnapshotsOptionInclude, azblob.BlobAccessConditions{})
return err
}
func (az *azureBlobStore) getContainerURL() error {
if az.containerURL != nil {
return nil
}
if len(az.storageAccountName) == 0 || len(az.storageAccessKey) == 0 {
return fmt.Errorf("Either the storage account or storage access key environment variable is not set")
}
credential, err := azblob.NewSharedKeyCredential(az.storageAccountName, az.storageAccessKey)
if err != nil {
return err
}
p := azblob.NewPipeline(credential, azblob.PipelineOptions{})
URL, err := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net/%s", az.storageAccountName, az.containerName))
if err != nil {
return err
}
containerURL := azblob.NewContainerURL(*URL, p)
az.containerURL = &containerURL
return nil
}