func Await(client management.Client, async asyncFunc) error { requestID, err := async() if err != nil { return err } return client.WaitForOperation(requestID, nil) }
// ExecuteAsyncOperation blocks until the provided asyncOperation is // no longer in the InProgress state. Any known retryiable transient // errors are retried and additional retry rules can be specified. // If the operation was successful, nothing is returned, otherwise // an error is returned. func ExecuteAsyncOperation(client management.Client, asyncOperation func() (management.OperationID, error), extraRules ...RetryRule) error { if asyncOperation == nil { return fmt.Errorf("Parameter not specified: %s", "asyncOperation") } retryPolicy := append(newDefaultRetryPolicy(), extraRules...) for { // retry loop for azure errors, call continue for retryable errors operationId, err := asyncOperation() if err == nil && operationId != "" { log.Printf("Waiting for operation: %s", operationId) err = client.WaitForOperation(operationId, nil) } if err != nil { log.Printf("Caught error (%T) during retryable operation: %v", err, err) // need to remove the pointer receiver in Azure SDK to make these *'s go away if azureError, ok := err.(management.AzureError); ok { log.Printf("Error is Azure error, checking if we should retry...") if shouldRetry, backoff := retryPolicy.ShouldRetry(azureError); shouldRetry { log.Printf("Error needs to be retried, sleeping %v", backoff) time.Sleep(backoff) continue // retry asyncOperation } } } return err } }
// ExecuteAsyncOperation blocks until the provided asyncOperation is // no longer in the InProgress state. Any known retryiable transient // errors are retried and additional retry rules can be specified. // If the operation was successful, nothing is returned, otherwise // an error is returned. func ExecuteAsyncOperation(client management.Client, asyncOperation func() (management.OperationID, error), extraRules ...RetryRule) error { if asyncOperation == nil { return fmt.Errorf("Parameter not specified: %s", "asyncOperation") } retryPolicy := append(newDefaultRetryPolicy(), extraRules...) for { // retry loop for azure errors, call continue for retryable errors operationId, err := asyncOperation() if err == nil { err = client.WaitForOperation(operationId, nil) } if err != nil { // need to remove the pointer receiver in Azure SDK to make these *'s go away if azureError, ok := err.(*management.AzureError); ok { if shouldRetry, backoff := retryPolicy.ShouldRetry(*azureError); shouldRetry { time.Sleep(backoff) continue // retry asyncOperation } } } return err } }
func getAffinityGroupLocation(client management.Client, affinityGroup string) (string, error) { const getAffinityGroupProperties = "affinitygroups/%s" d, err := client.SendAzureGetRequest(fmt.Sprintf(getAffinityGroupProperties, affinityGroup)) if err != nil { return "", err } var afGroup struct { Location string } err = xml.Unmarshal(d, &afGroup) return afGroup.Location, err }
func checkVirtualNetworkConfiguration(client management.Client, vnetname, subnetname, location string) error { const getVNetConfig = "services/networking/media" d, err := client.SendAzureGetRequest(getVNetConfig) if err != nil { return err } var vnetConfig struct { VNets []struct { Name string `xml:"name,attr"` AffinityGroup string `xml:",attr"` Location string `xml:",attr"` Subnets []struct { Name string `xml:"name,attr"` AddressPrefix string } `xml:"Subnets>Subnet"` } `xml:"VirtualNetworkConfiguration>VirtualNetworkSites>VirtualNetworkSite"` } err = xml.Unmarshal(d, &vnetConfig) if err != nil { return err } for _, vnet := range vnetConfig.VNets { if vnet.Name == vnetname { if vnet.AffinityGroup != "" { vnet.Location, err = getAffinityGroupLocation(client, vnet.AffinityGroup) if err != nil { return err } } if vnet.Location != location { return fmt.Errorf("VNet %q is not in location %q, but in %q", vnet.Name, location, vnet.Location) } for _, sn := range vnet.Subnets { if sn.Name == subnetname { return nil } } } } return fmt.Errorf("Could not find vnet %q and subnet %q in network configuration: %v", vnetname, subnetname, vnetConfig) }
func GetTestStorageAccount(t *testing.T, client management.Client) storage.StorageServiceResponse { t.Log("Retrieving storage account") sc := storage.NewClient(client) var sa storage.StorageServiceResponse ssl, err := sc.ListStorageServices() if err != nil { t.Fatal(err) } rnd := rand.New(rand.NewSource(time.Now().UnixNano())) if len(ssl.StorageServices) == 0 { t.Log("No storage accounts found, creating a new one") lc := location.NewClient(client) ll, err := lc.ListLocations() if err != nil { t.Fatal(err) } loc := ll.Locations[rnd.Intn(len(ll.Locations))].Name t.Logf("Location for new storage account: %s", loc) name := GenerateName() op, err := sc.CreateStorageService(storage.StorageAccountCreateParameters{ ServiceName: name, Label: base64.StdEncoding.EncodeToString([]byte(name)), Location: loc, AccountType: storage.AccountTypeStandardLRS}) if err != nil { t.Fatal(err) } if err := client.WaitForOperation(op, nil); err != nil { t.Fatal(err) } sa, err = sc.GetStorageService(name) } else { sa = ssl.StorageServices[rnd.Intn(len(ssl.StorageServices))] } t.Logf("Selected storage account '%s' in location '%s'", sa.ServiceName, sa.StorageServiceProperties.Location) return sa }