diff --git a/go.sum b/go.sum index bf9e74a..7b34760 100644 --- a/go.sum +++ b/go.sum @@ -340,7 +340,6 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4 h1:b0LrWgu8+q7z4J+0Y3Umo5q1dL7NXBkKBWkaVkAq17E= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -408,7 +407,6 @@ golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750 h1:ZBu6861dZq7xBnG1bn5SRU0vA8nx42at4+kP07FMTog= golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -419,7 +417,6 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= diff --git a/tfstate/remote_azurerm.go b/tfstate/remote_azurerm.go index fdcd82b..6737ec5 100644 --- a/tfstate/remote_azurerm.go +++ b/tfstate/remote_azurerm.go @@ -3,15 +3,16 @@ package tfstate import ( "context" "fmt" - "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2021-04-01/storage" - "github.com/Azure/azure-storage-blob-go/azblob" - "github.com/Azure/go-autorest/autorest/azure/auth" - "github.com/Azure/go-autorest/autorest/azure/cli" "io" - "log" "net/url" "os" "path" + + "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2021-04-01/storage" + "github.com/Azure/azure-storage-blob-go/azblob" + "github.com/Azure/go-autorest/autorest/azure/auth" + "github.com/Azure/go-autorest/autorest/azure/cli" + "github.com/pkg/errors" ) type azureRMOption struct { @@ -35,71 +36,80 @@ func readAzureRMState(config map[string]interface{}, ws string) (io.ReadCloser, } func readAzureRM(resourceGroupName string, accountName string, containerName string, key string, opt azureRMOption) (io.ReadCloser, error) { - var err error ctx := context.Background() - URL, _ := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net/%s", accountName, containerName)) + u, _ := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net/%s", accountName, containerName)) //get blob access key - accountKey := getDefaultAccessKey(ctx, resourceGroupName, accountName) - if len(os.Getenv("AZURE_STORAGE_ACCESS_KEY")) == 0 && len(opt.accessKey) == 0 && len(accountKey) == 0 { - log.Fatal("Blob access key not found in ENV, terraform config and can't be fetched from current Azure Profile") + var accountKey string + for _, gen := range []func() (string, error){ + func() (string, error) { return opt.accessKey, nil }, + func() (string, error) { return os.Getenv("AZURE_STORAGE_ACCESS_KEY"), nil }, + func() (string, error) { return getDefaultAccessKey(ctx, resourceGroupName, accountName) }, + } { + key, err := gen() + if err != nil { + return nil, err + } else if key != "" { + accountKey = key + break + } } - if len(opt.accessKey) != 0 { - accountKey = opt.accessKey - } else if len(os.Getenv("AZURE_STORAGE_ACCESS_KEY")) != 0 { - accountKey = os.Getenv("AZURE_STORAGE_ACCESS_KEY") + if accountKey == "" { + return nil, errors.New("Blob access key not found in ENV, terraform config and can't be fetched from current Azure Profile") } - //Authenticate - credential, err := azblob.NewSharedKeyCredential(accountName, accountKey) - //set up client - p := azblob.NewPipeline(credential, azblob.PipelineOptions{}) - containerURL := azblob.NewContainerURL(*URL, p) - blobURL := containerURL.NewBlockBlobURL(key) + // Authenticate + credential, err := azblob.NewSharedKeyCredential(accountName, accountKey) if err != nil { - return nil, err + return nil, errors.Wrap(err, "failed to create credential") } - //fetch data + // set up client + p := azblob.NewPipeline(credential, azblob.PipelineOptions{}) + containerURL := azblob.NewContainerURL(*u, p) + blobURL := containerURL.NewBlockBlobURL(key) + + // fetch data response, err := blobURL.Download(ctx, 0, azblob.CountToEnd, azblob.BlobAccessConditions{}, false, azblob.ClientProvidedKeyOptions{}) if err != nil { return nil, err } defer response.Response().Body.Close() r := response.Body(azblob.RetryReaderOptions{MaxRetryRequests: 20}) - return r, nil } -func getDefaultSubscription() string { - profilePath, err := cli.ProfilePath() + +func getDefaultSubscription() (string, error) { + profilePath, _ := cli.ProfilePath() profile, err := cli.LoadProfile(profilePath) if err != nil { - log.Printf("Failed to load profile: %v", err) + return "", errors.Wrap(err, "failed to load profile") } subscriptionID := "" - if len(profile.Subscriptions) != 0 { - for _, x := range profile.Subscriptions { - if x.IsDefault != true { - continue - } - subscriptionID = x.ID + for _, x := range profile.Subscriptions { + if !x.IsDefault { + continue } + subscriptionID = x.ID } - return subscriptionID + return subscriptionID, nil } -func getDefaultAccessKey(ctx context.Context, resourceGroupName string, accountName string) string { + +func getDefaultAccessKey(ctx context.Context, resourceGroupName string, accountName string) (string, error) { storageAuthorizer, err := auth.NewAuthorizerFromCLI() if err != nil { - log.Printf("Failed to authorize: %v", err) + return "", errors.Wrap(err, "failed to authorize") + } + subscriptionID, err := getDefaultSubscription() + if err != nil { + return "", errors.Wrap(err, "failed to get default subscription") } - subscriptionID := getDefaultSubscription() client := storage.NewAccountsClient(subscriptionID) client.Authorizer = storageAuthorizer client.AddToUserAgent("tfstate-lookup") accountKeys, err := client.ListKeys(ctx, resourceGroupName, accountName, storage.ListKeyExpandKerb) if err != nil { - log.Printf("failed to list keys: %v", err) - return "" + return "", errors.Wrap(err, "failed to list keys") } - return *(((*accountKeys.Keys)[0]).Value) + return *(((*accountKeys.Keys)[0]).Value), nil }