github.com/aigarnetwork/aigar@v0.0.0-20191115204914-d59a6eb70f8e/internal/build/azure.go (about)

     1  //  Copyright 2018 The go-ethereum Authors
     2  //  Copyright 2019 The go-aigar Authors
     3  //  This file is part of the go-aigar library.
     4  //
     5  //  The go-aigar library is free software: you can redistribute it and/or modify
     6  //  it under the terms of the GNU Lesser General Public License as published by
     7  //  the Free Software Foundation, either version 3 of the License, or
     8  //  (at your option) any later version.
     9  //
    10  //  The go-aigar library is distributed in the hope that it will be useful,
    11  //  but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  //  GNU Lesser General Public License for more details.
    14  //
    15  //  You should have received a copy of the GNU Lesser General Public License
    16  //  along with the go-aigar library. If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package build
    19  
    20  import (
    21  	"context"
    22  	"fmt"
    23  	"net/url"
    24  	"os"
    25  
    26  	"github.com/Azure/azure-storage-blob-go/azblob"
    27  )
    28  
    29  // AzureBlobstoreConfig is an authentication and configuration struct containing
    30  // the data needed by the Azure SDK to interact with a speicifc container in the
    31  // blobstore.
    32  type AzureBlobstoreConfig struct {
    33  	Account   string // Account name to authorize API requests with
    34  	Token     string // Access token for the above account
    35  	Container string // Blob container to upload files into
    36  }
    37  
    38  // AzureBlobstoreUpload uploads a local file to the Azure Blob Storage. Note, this
    39  // method assumes a max file size of 64MB (Azure limitation). Larger files will
    40  // need a multi API call approach implemented.
    41  //
    42  // See: https://msdn.microsoft.com/en-us/library/azure/dd179451.aspx#Anchor_3
    43  func AzureBlobstoreUpload(path string, name string, config AzureBlobstoreConfig) error {
    44  	if *DryRunFlag {
    45  		fmt.Printf("would upload %q to %s/%s/%s\n", path, config.Account, config.Container, name)
    46  		return nil
    47  	}
    48  	// Create an authenticated client against the Azure cloud
    49  	credential, err := azblob.NewSharedKeyCredential(config.Account, config.Token)
    50  	if err != nil {
    51  		return err
    52  	}
    53  
    54  	pipeline := azblob.NewPipeline(credential, azblob.PipelineOptions{})
    55  
    56  	u, _ := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net", config.Account))
    57  	service := azblob.NewServiceURL(*u, pipeline)
    58  
    59  	container := service.NewContainerURL(config.Container)
    60  	blockblob := container.NewBlockBlobURL(name)
    61  
    62  	// Stream the file to upload into the designated blobstore container
    63  	in, err := os.Open(path)
    64  	if err != nil {
    65  		return err
    66  	}
    67  	defer in.Close()
    68  
    69  	_, err = blockblob.Upload(context.Background(), in, azblob.BlobHTTPHeaders{}, azblob.Metadata{}, azblob.BlobAccessConditions{})
    70  	return err
    71  }
    72  
    73  // AzureBlobstoreList lists all the files contained within an azure blobstore.
    74  func AzureBlobstoreList(config AzureBlobstoreConfig) ([]azblob.BlobItem, error) {
    75  	credential, err := azblob.NewSharedKeyCredential(config.Account, config.Token)
    76  	if err != nil {
    77  		return nil, err
    78  	}
    79  
    80  	pipeline := azblob.NewPipeline(credential, azblob.PipelineOptions{})
    81  
    82  	u, _ := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net", config.Account))
    83  	service := azblob.NewServiceURL(*u, pipeline)
    84  
    85  	// List all the blobs from the container and return them
    86  	container := service.NewContainerURL(config.Container)
    87  
    88  	res, err := container.ListBlobsFlatSegment(context.Background(), azblob.Marker{}, azblob.ListBlobsSegmentOptions{
    89  		MaxResults: 1024 * 1024 * 1024, // Yes, fetch all of them
    90  	})
    91  	if err != nil {
    92  		return nil, err
    93  	}
    94  	return res.Segment.BlobItems, nil
    95  }
    96  
    97  // AzureBlobstoreDelete iterates over a list of files to delete and removes them
    98  // from the blobstore.
    99  func AzureBlobstoreDelete(config AzureBlobstoreConfig, blobs []azblob.BlobItem) error {
   100  	if *DryRunFlag {
   101  		for _, blob := range blobs {
   102  			fmt.Printf("would delete %s (%s) from %s/%s\n", blob.Name, blob.Properties.LastModified, config.Account, config.Container)
   103  		}
   104  		return nil
   105  	}
   106  	// Create an authenticated client against the Azure cloud
   107  	credential, err := azblob.NewSharedKeyCredential(config.Account, config.Token)
   108  	if err != nil {
   109  		return err
   110  	}
   111  
   112  	pipeline := azblob.NewPipeline(credential, azblob.PipelineOptions{})
   113  
   114  	u, _ := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net", config.Account))
   115  	service := azblob.NewServiceURL(*u, pipeline)
   116  
   117  	container := service.NewContainerURL(config.Container)
   118  
   119  	// Iterate over the blobs and delete them
   120  	for _, blob := range blobs {
   121  		blockblob := container.NewBlockBlobURL(blob.Name)
   122  		if _, err := blockblob.Delete(context.Background(), azblob.DeleteSnapshotsOptionInclude, azblob.BlobAccessConditions{}); err != nil {
   123  			return err
   124  		}
   125  	}
   126  	return nil
   127  }