From f4600a208ffc75ddbe76274257991fc8d09ab5d1 Mon Sep 17 00:00:00 2001 From: Arjen Schwarz Date: Mon, 6 Nov 2017 16:16:58 +1100 Subject: [PATCH] Azure: Keep temporary resource group. Fixes #5045 This changeset will detect if the defined temporary resource group already exists. If it does, it will not destroy it, but clean up every resource required for building that is created by Packer individually, both on success and failure. Unit tests have been fixed, but more tests should be added for the new functionalities. --- builder/azure/arm/azure_client.go | 15 + .../azure/arm/step_create_resource_group.go | 51 +- .../arm/step_create_resource_group_test.go | 46 +- builder/azure/arm/step_delete_os_disk.go | 33 +- builder/azure/arm/step_delete_os_disk_test.go | 9 +- .../azure/arm/step_delete_resource_group.go | 73 +- .../arm/step_delete_resource_group_test.go | 6 +- builder/azure/arm/step_deploy_template.go | 149 +++- builder/azure/common/constants/stateBag.go | 1 + .../Azure/azure-sdk-for-go/arm/disk/client.go | 53 ++ .../Azure/azure-sdk-for-go/arm/disk/disks.go | 728 +++++++++++++++++ .../Azure/azure-sdk-for-go/arm/disk/models.go | 278 +++++++ .../azure-sdk-for-go/arm/disk/snapshots.go | 733 ++++++++++++++++++ .../azure-sdk-for-go/arm/disk/version.go | 29 + vendor/vendor.json | 6 + 15 files changed, 2168 insertions(+), 42 deletions(-) create mode 100755 vendor/github.com/Azure/azure-sdk-for-go/arm/disk/client.go create mode 100755 vendor/github.com/Azure/azure-sdk-for-go/arm/disk/disks.go create mode 100755 vendor/github.com/Azure/azure-sdk-for-go/arm/disk/models.go create mode 100755 vendor/github.com/Azure/azure-sdk-for-go/arm/disk/snapshots.go create mode 100755 vendor/github.com/Azure/azure-sdk-for-go/arm/disk/version.go diff --git a/builder/azure/arm/azure_client.go b/builder/azure/arm/azure_client.go index 3fd58bc34..08dd95eae 100644 --- a/builder/azure/arm/azure_client.go +++ b/builder/azure/arm/azure_client.go @@ -10,6 +10,7 @@ import ( "strconv" "github.com/Azure/azure-sdk-for-go/arm/compute" + "github.com/Azure/azure-sdk-for-go/arm/disk" "github.com/Azure/azure-sdk-for-go/arm/network" "github.com/Azure/azure-sdk-for-go/arm/resources/resources" armStorage "github.com/Azure/azure-sdk-for-go/arm/storage" @@ -32,6 +33,7 @@ var ( type AzureClient struct { storage.BlobStorageClient resources.DeploymentsClient + resources.DeploymentOperationsClient resources.GroupsClient network.PublicIPAddressesClient network.InterfacesClient @@ -41,6 +43,7 @@ type AzureClient struct { compute.VirtualMachinesClient common.VaultClient armStorage.AccountsClient + disk.DisksClient InspectorMaxLength int Template *CaptureTemplate @@ -135,6 +138,18 @@ func NewAzureClient(subscriptionID, resourceGroupName, storageAccountName string azureClient.DeploymentsClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) azureClient.DeploymentsClient.UserAgent += packerUserAgent + azureClient.DeploymentOperationsClient = resources.NewDeploymentOperationsClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) + azureClient.DeploymentOperationsClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) + azureClient.DeploymentOperationsClient.RequestInspector = withInspection(maxlen) + azureClient.DeploymentOperationsClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) + azureClient.DeploymentOperationsClient.UserAgent += packerUserAgent + + azureClient.DisksClient = disk.NewDisksClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) + azureClient.DisksClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) + azureClient.DisksClient.RequestInspector = withInspection(maxlen) + azureClient.DisksClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) + azureClient.DisksClient.UserAgent += packerUserAgent + azureClient.GroupsClient = resources.NewGroupsClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.GroupsClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.GroupsClient.RequestInspector = withInspection(maxlen) diff --git a/builder/azure/arm/step_create_resource_group.go b/builder/azure/arm/step_create_resource_group.go index 079ad5279..745748669 100644 --- a/builder/azure/arm/step_create_resource_group.go +++ b/builder/azure/arm/step_create_resource_group.go @@ -14,6 +14,7 @@ type StepCreateResourceGroup struct { create func(resourceGroupName string, location string, tags *map[string]*string) error say func(message string) error func(e error) + exists func(resourceGroupName string) (bool, error) } func NewStepCreateResourceGroup(client *AzureClient, ui packer.Ui) *StepCreateResourceGroup { @@ -24,6 +25,7 @@ func NewStepCreateResourceGroup(client *AzureClient, ui packer.Ui) *StepCreateRe } step.create = step.createResourceGroup + step.exists = step.doesResourceGroupExist return step } @@ -39,6 +41,15 @@ func (s *StepCreateResourceGroup) createResourceGroup(resourceGroupName string, return err } +func (s *StepCreateResourceGroup) doesResourceGroupExist(resourceGroupName string) (bool, error) { + exists, err := s.client.GroupsClient.CheckExistence(resourceGroupName) + if err != nil { + s.say(s.client.LastError.Error()) + } + + return exists.Response.StatusCode != 404, err +} + func (s *StepCreateResourceGroup) Run(state multistep.StateBag) multistep.StepAction { s.say("Creating resource group ...") @@ -53,8 +64,19 @@ func (s *StepCreateResourceGroup) Run(state multistep.StateBag) multistep.StepAc s.say(fmt.Sprintf(" ->> %s : %s", k, *v)) } - err := s.create(resourceGroupName, location, tags) - if err == nil { + exists, err := s.exists(resourceGroupName) + if err != nil { + s.say(s.client.LastError.Error()) + } + state.Put(constants.ArmIsExistingResourceGroup, exists) + // If the resource group exists, we may not have permissions to update it so we don't. + if !exists { + err = s.create(resourceGroupName, location, tags) + if err == nil { + state.Put(constants.ArmIsResourceGroupCreated, true) + } + } else { + // Mark the resource group as created to deal with later checks state.Put(constants.ArmIsResourceGroupCreated, true) } @@ -68,17 +90,22 @@ func (s *StepCreateResourceGroup) Cleanup(state multistep.StateBag) { } ui := state.Get("ui").(packer.Ui) - ui.Say("\nCleanup requested, deleting resource group ...") + if state.Get(constants.ArmIsExistingResourceGroup).(bool) { + ui.Say("\nThe resource group was not created by Packer, not deleting ...") + return + } else { + ui.Say("\nCleanup requested, deleting resource group ...") - var resourceGroupName = state.Get(constants.ArmResourceGroupName).(string) - _, errChan := s.client.GroupsClient.Delete(resourceGroupName, nil) - err := <-errChan + var resourceGroupName = state.Get(constants.ArmResourceGroupName).(string) + _, errChan := s.client.GroupsClient.Delete(resourceGroupName, nil) + err := <-errChan - if err != nil { - ui.Error(fmt.Sprintf("Error deleting resource group. Please delete it manually.\n\n"+ - "Name: %s\n"+ - "Error: %s", resourceGroupName, err)) - } + if err != nil { + ui.Error(fmt.Sprintf("Error deleting resource group. Please delete it manually.\n\n"+ + "Name: %s\n"+ + "Error: %s", resourceGroupName, err)) + } - ui.Say("Resource group has been deleted.") + ui.Say("Resource group has been deleted.") + } } diff --git a/builder/azure/arm/step_create_resource_group_test.go b/builder/azure/arm/step_create_resource_group_test.go index 4e6b7592f..47a4a01e6 100644 --- a/builder/azure/arm/step_create_resource_group_test.go +++ b/builder/azure/arm/step_create_resource_group_test.go @@ -13,6 +13,7 @@ func TestStepCreateResourceGroupShouldFailIfCreateFails(t *testing.T) { create: func(string, string, *map[string]*string) error { return fmt.Errorf("!! Unit Test FAIL !!") }, say: func(message string) {}, error: func(e error) {}, + exists: func(string) (bool, error) { return false, nil }, } stateBag := createTestStateBagStepCreateResourceGroup() @@ -32,6 +33,7 @@ func TestStepCreateResourceGroupShouldPassIfCreatePasses(t *testing.T) { create: func(string, string, *map[string]*string) error { return nil }, say: func(message string) {}, error: func(e error) {}, + exists: func(string) (bool, error) { return false, nil }, } stateBag := createTestStateBagStepCreateResourceGroup() @@ -58,8 +60,9 @@ func TestStepCreateResourceGroupShouldTakeStepArgumentsFromStateBag(t *testing.T actualTags = tags return nil }, - say: func(message string) {}, - error: func(e error) {}, + say: func(message string) {}, + error: func(e error) {}, + exists: func(string) (bool, error) { return false, nil }, } stateBag := createTestStateBagStepCreateResourceGroup() @@ -91,6 +94,44 @@ func TestStepCreateResourceGroupShouldTakeStepArgumentsFromStateBag(t *testing.T } } +func TestStepCreateResourceGroupMarkAsNonExistingIfDoesntExist(t *testing.T) { + var testSubject = &StepCreateResourceGroup{ + create: func(string, string, *map[string]*string) error { return fmt.Errorf("!! Unit Test FAIL !!") }, + say: func(message string) {}, + error: func(e error) {}, + exists: func(string) (bool, error) { return false, nil }, + } + + stateBag := createTestStateBagStepCreateResourceGroup() + + if _, ok := stateBag.GetOk(constants.ArmIsExistingResourceGroup); ok == true { + t.Fatalf("Expected 'constants.ArmIsExistingResourceGroup' not to be set, but it was") + } + testSubject.Run(stateBag) + if stateBag.Get(constants.ArmIsExistingResourceGroup).(bool) == true { + t.Fatalf("Expected 'constants.ArmIsExistingResourceGroup' to be set to false, but it wasn't.") + } +} + +func TestStepCreateResourceGroupMarkAsExistingIfExists(t *testing.T) { + var testSubject = &StepCreateResourceGroup{ + create: func(string, string, *map[string]*string) error { return fmt.Errorf("!! Unit Test FAIL !!") }, + say: func(message string) {}, + error: func(e error) {}, + exists: func(string) (bool, error) { return true, nil }, + } + + stateBag := createTestStateBagStepCreateResourceGroup() + + if _, ok := stateBag.GetOk(constants.ArmIsExistingResourceGroup); ok == true { + t.Fatalf("Expected 'constants.ArmIsExistingResourceGroup' not to be set, but it was") + } + testSubject.Run(stateBag) + if stateBag.Get(constants.ArmIsExistingResourceGroup).(bool) == false { + t.Fatalf("Expected 'constants.ArmIsExistingResourceGroup' to be set to true, but it wasn't.") + } +} + func createTestStateBagStepCreateResourceGroup() multistep.StateBag { stateBag := new(multistep.BasicStateBag) @@ -103,6 +144,5 @@ func createTestStateBagStepCreateResourceGroup() multistep.StateBag { } stateBag.Put(constants.ArmTags, &tags) - return stateBag } diff --git a/builder/azure/arm/step_delete_os_disk.go b/builder/azure/arm/step_delete_os_disk.go index 1dd28ec85..6c56ac96d 100644 --- a/builder/azure/arm/step_delete_os_disk.go +++ b/builder/azure/arm/step_delete_os_disk.go @@ -12,10 +12,11 @@ import ( ) type StepDeleteOSDisk struct { - client *AzureClient - delete func(string, string) error - say func(message string) - error func(e error) + client *AzureClient + delete func(string, string) error + deleteManaged func(string, string) error + say func(message string) + error func(e error) } func NewStepDeleteOSDisk(client *AzureClient, ui packer.Ui) *StepDeleteOSDisk { @@ -26,6 +27,7 @@ func NewStepDeleteOSDisk(client *AzureClient, ui packer.Ui) *StepDeleteOSDisk { } step.delete = step.deleteBlob + step.deleteManaged = step.deleteManagedDisk return step } @@ -39,19 +41,40 @@ func (s *StepDeleteOSDisk) deleteBlob(storageContainerName string, blobName stri return err } +func (s *StepDeleteOSDisk) deleteManagedDisk(resourceGroupName string, imageName string) error { + s.say("In the deleting part") + xs := strings.Split(imageName, "/") + diskName := xs[len(xs)-1] + _, errChan := s.client.DisksClient.Delete(resourceGroupName, diskName, nil) + err := <-errChan + return err +} + func (s *StepDeleteOSDisk) Run(state multistep.StateBag) multistep.StepAction { s.say("Deleting the temporary OS disk ...") var osDisk = state.Get(constants.ArmOSDiskVhd).(string) var isManagedDisk = state.Get(constants.ArmIsManagedImage).(bool) + var isExistingResourceGroup = state.Get(constants.ArmIsExistingResourceGroup).(bool) + var resourceGroupName = state.Get(constants.ArmResourceGroupName).(string) - if isManagedDisk { + if isManagedDisk && !isExistingResourceGroup { s.say(fmt.Sprintf(" -> OS Disk : skipping, managed disk was used...")) return multistep.ActionContinue } s.say(fmt.Sprintf(" -> OS Disk : '%s'", osDisk)) + var err error + if isManagedDisk { + err = s.deleteManaged(resourceGroupName, osDisk) + if err != nil { + s.say("Failed to delete the managed OS Disk!") + return multistep.ActionHalt + } + s.say("After deleting") + return multistep.ActionContinue + } u, err := url.Parse(osDisk) if err != nil { s.say("Failed to parse the OS Disk's VHD URI!") diff --git a/builder/azure/arm/step_delete_os_disk_test.go b/builder/azure/arm/step_delete_os_disk_test.go index 2724ee611..e19f0e0ba 100644 --- a/builder/azure/arm/step_delete_os_disk_test.go +++ b/builder/azure/arm/step_delete_os_disk_test.go @@ -10,9 +10,10 @@ import ( func TestStepDeleteOSDiskShouldFailIfGetFails(t *testing.T) { var testSubject = &StepDeleteOSDisk{ - delete: func(string, string) error { return fmt.Errorf("!! Unit Test FAIL !!") }, - say: func(message string) {}, - error: func(e error) {}, + delete: func(string, string) error { return fmt.Errorf("!! Unit Test FAIL !!") }, + deleteManaged: func(string, string) error { return nil }, + say: func(message string) {}, + error: func(e error) {}, } stateBag := DeleteTestStateBagStepDeleteOSDisk("http://storage.blob.core.windows.net/images/pkrvm_os.vhd") @@ -106,6 +107,8 @@ func DeleteTestStateBagStepDeleteOSDisk(osDiskVhd string) multistep.StateBag { stateBag := new(multistep.BasicStateBag) stateBag.Put(constants.ArmOSDiskVhd, osDiskVhd) stateBag.Put(constants.ArmIsManagedImage, false) + stateBag.Put(constants.ArmIsExistingResourceGroup, false) + stateBag.Put(constants.ArmResourceGroupName, "testgroup") return stateBag } diff --git a/builder/azure/arm/step_delete_resource_group.go b/builder/azure/arm/step_delete_resource_group.go index 2606b9fc8..28b7c4142 100644 --- a/builder/azure/arm/step_delete_resource_group.go +++ b/builder/azure/arm/step_delete_resource_group.go @@ -3,6 +3,7 @@ package arm import ( "fmt" + "github.com/Azure/go-autorest/autorest" "github.com/hashicorp/packer/builder/azure/common" "github.com/hashicorp/packer/builder/azure/common/constants" "github.com/hashicorp/packer/packer" @@ -11,7 +12,7 @@ import ( type StepDeleteResourceGroup struct { client *AzureClient - delete func(resourceGroupName string, cancelCh <-chan struct{}) error + delete func(state multistep.StateBag, resourceGroupName string, cancelCh <-chan struct{}) error say func(message string) error func(e error) } @@ -27,14 +28,69 @@ func NewStepDeleteResourceGroup(client *AzureClient, ui packer.Ui) *StepDeleteRe return step } -func (s *StepDeleteResourceGroup) deleteResourceGroup(resourceGroupName string, cancelCh <-chan struct{}) error { - _, errChan := s.client.GroupsClient.Delete(resourceGroupName, cancelCh) +func (s *StepDeleteResourceGroup) deleteResourceGroup(state multistep.StateBag, resourceGroupName string, cancelCh <-chan struct{}) error { + var err error + if state.Get(constants.ArmIsExistingResourceGroup).(bool) { + s.say("\nThe resource group was not created by Packer, only deleting individual resources ...") + var deploymentName = state.Get(constants.ArmDeploymentName).(string) + if deploymentName != "" { + maxResources := int32(50) + deploymentOperations, err := s.client.DeploymentOperationsClient.List(resourceGroupName, deploymentName, &maxResources) + if err != nil { + s.say(fmt.Sprintf("Error deleting resources. Please delete them manually.\n\n"+ + "Name: %s\n"+ + "Error: %s", resourceGroupName, err)) + s.error(err) + } + for _, deploymentOperation := range *deploymentOperations.Value { + // Sometimes an empty operation is added to the list by Azure + if deploymentOperation.Properties.TargetResource == nil { + continue + } + s.say(fmt.Sprintf(" -> %s : '%s'", + *deploymentOperation.Properties.TargetResource.ResourceType, + *deploymentOperation.Properties.TargetResource.ResourceName)) + var networkDeleteFunction func(string, string, <-chan struct{}) (<-chan autorest.Response, <-chan error) + switch *deploymentOperation.Properties.TargetResource.ResourceType { + case "Microsoft.Compute/virtualMachines": + _, errChan := s.client.VirtualMachinesClient.Delete(resourceGroupName, *deploymentOperation.Properties.TargetResource.ResourceName, nil) + err := <-errChan + if err != nil { + s.say(fmt.Sprintf("Error deleting resource. Please delete manually.\n\n"+ + "Name: %s\n"+ + "Error: %s", *deploymentOperation.Properties.TargetResource.ResourceName, err.Error())) + s.error(err) + } + case "Microsoft.Network/networkInterfaces": + networkDeleteFunction = s.client.InterfacesClient.Delete + case "Microsoft.Network/virtualNetworks": + networkDeleteFunction = s.client.VirtualNetworksClient.Delete + case "Microsoft.Network/publicIPAddresses": + networkDeleteFunction = s.client.PublicIPAddressesClient.Delete + } + if networkDeleteFunction != nil { + _, errChan := networkDeleteFunction(resourceGroupName, *deploymentOperation.Properties.TargetResource.ResourceName, nil) + err := <-errChan + if err != nil { + s.say(fmt.Sprintf("Error deleting resource. Please delete manually.\n\n"+ + "Name: %s\n"+ + "Error: %s", *deploymentOperation.Properties.TargetResource.ResourceName, err.Error())) + s.error(err) + } + } + } + } + return err + } else { + _, errChan := s.client.GroupsClient.Delete(resourceGroupName, cancelCh) + s.say(state.Get(constants.ArmIsExistingResourceGroup).(string)) + err = <-errChan - err := <-errChan - if err != nil { - s.say(s.client.LastError.Error()) + if err != nil { + s.say(s.client.LastError.Error()) + } + return err } - return err } func (s *StepDeleteResourceGroup) Run(state multistep.StateBag) multistep.StepAction { @@ -45,8 +101,7 @@ func (s *StepDeleteResourceGroup) Run(state multistep.StateBag) multistep.StepAc result := common.StartInterruptibleTask( func() bool { return common.IsStateCancelled(state) }, - func(cancelCh <-chan struct{}) error { return s.delete(resourceGroupName, cancelCh) }) - + func(cancelCh <-chan struct{}) error { return s.delete(state, resourceGroupName, cancelCh) }) stepAction := processInterruptibleResult(result, s.error, state) state.Put(constants.ArmIsResourceGroupCreated, false) diff --git a/builder/azure/arm/step_delete_resource_group_test.go b/builder/azure/arm/step_delete_resource_group_test.go index 25ab14e4d..c9d6e22da 100644 --- a/builder/azure/arm/step_delete_resource_group_test.go +++ b/builder/azure/arm/step_delete_resource_group_test.go @@ -10,7 +10,7 @@ import ( func TestStepDeleteResourceGroupShouldFailIfDeleteFails(t *testing.T) { var testSubject = &StepDeleteResourceGroup{ - delete: func(string, <-chan struct{}) error { return fmt.Errorf("!! Unit Test FAIL !!") }, + delete: func(multistep.StateBag, string, <-chan struct{}) error { return fmt.Errorf("!! Unit Test FAIL !!") }, say: func(message string) {}, error: func(e error) {}, } @@ -29,7 +29,7 @@ func TestStepDeleteResourceGroupShouldFailIfDeleteFails(t *testing.T) { func TestStepDeleteResourceGroupShouldPassIfDeletePasses(t *testing.T) { var testSubject = &StepDeleteResourceGroup{ - delete: func(string, <-chan struct{}) error { return nil }, + delete: func(multistep.StateBag, string, <-chan struct{}) error { return nil }, say: func(message string) {}, error: func(e error) {}, } @@ -48,7 +48,7 @@ func TestStepDeleteResourceGroupShouldPassIfDeletePasses(t *testing.T) { func TestStepDeleteResourceGroupShouldDeleteStateBagArmResourceGroupCreated(t *testing.T) { var testSubject = &StepDeleteResourceGroup{ - delete: func(resourceGroupName string, cancelCh <-chan struct{}) error { + delete: func(s multistep.StateBag, resourceGroupName string, cancelCh <-chan struct{}) error { return nil }, say: func(message string) {}, diff --git a/builder/azure/arm/step_deploy_template.go b/builder/azure/arm/step_deploy_template.go index 8d73402b7..53b639d51 100644 --- a/builder/azure/arm/step_deploy_template.go +++ b/builder/azure/arm/step_deploy_template.go @@ -2,7 +2,10 @@ package arm import ( "fmt" + "net/url" + "strings" + "github.com/Azure/go-autorest/autorest" "github.com/hashicorp/packer/builder/azure/common" "github.com/hashicorp/packer/builder/azure/common/constants" "github.com/hashicorp/packer/packer" @@ -10,12 +13,15 @@ import ( ) type StepDeployTemplate struct { - client *AzureClient - deploy func(resourceGroupName string, deploymentName string, cancelCh <-chan struct{}) error - say func(message string) - error func(e error) - config *Config - factory templateFactoryFunc + client *AzureClient + deploy func(resourceGroupName string, deploymentName string, cancelCh <-chan struct{}) error + delete func(resourceType string, resourceName string, resourceGroupName string) error + disk func(resourceGroupName string, computeName string) (string, string, error) + deleteDisk func(imageType string, imageName string, resourceGroupName string) error + say func(message string) + error func(e error) + config *Config + factory templateFactoryFunc } func NewStepDeployTemplate(client *AzureClient, ui packer.Ui, config *Config, factory templateFactoryFunc) *StepDeployTemplate { @@ -28,6 +34,9 @@ func NewStepDeployTemplate(client *AzureClient, ui packer.Ui, config *Config, fa } step.deploy = step.deployTemplate + step.delete = step.deleteOperationResource + step.disk = step.getImageDetails + step.deleteDisk = step.deleteImage return step } @@ -65,5 +74,131 @@ func (s *StepDeployTemplate) Run(state multistep.StateBag) multistep.StepAction return processInterruptibleResult(result, s.error, state) } -func (*StepDeployTemplate) Cleanup(multistep.StateBag) { +func (s *StepDeployTemplate) getImageDetails(resourceGroupName string, computeName string) (string, string, error) { + //We can't depend on constants.ArmOSDiskVhd being set + var imageName string + var imageType string + vm, err := s.client.VirtualMachinesClient.Get(resourceGroupName, computeName, "") + if err != nil { + return imageName, imageType, err + } else { + if vm.StorageProfile.OsDisk.Vhd != nil { + imageType = "image" + imageName = *vm.StorageProfile.OsDisk.Vhd.URI + } else { + imageType = "Microsoft.Compute/disks" + imageName = *vm.StorageProfile.OsDisk.ManagedDisk.ID + } + } + return imageType, imageName, nil +} + +func (s *StepDeployTemplate) deleteOperationResource(resourceType string, resourceName string, resourceGroupName string) error { + var networkDeleteFunction func(string, string, <-chan struct{}) (<-chan autorest.Response, <-chan error) + switch resourceType { + case "Microsoft.Compute/virtualMachines": + _, errChan := s.client.VirtualMachinesClient.Delete(resourceGroupName, + resourceName, nil) + err := <-errChan + if err != nil { + return err + + } + case "Microsoft.Network/networkInterfaces": + networkDeleteFunction = s.client.InterfacesClient.Delete + case "Microsoft.Network/virtualNetworks": + networkDeleteFunction = s.client.VirtualNetworksClient.Delete + case "Microsoft.Network/publicIPAddresses": + networkDeleteFunction = s.client.PublicIPAddressesClient.Delete + } + if networkDeleteFunction != nil { + _, errChan := networkDeleteFunction(resourceGroupName, resourceName, nil) + err := <-errChan + if err != nil { + return err + } + } + return nil +} + +func (s *StepDeployTemplate) deleteImage(imageType string, imageName string, resourceGroupName string) error { + // Managed disk + if imageType == "Microsoft.Compute/disks" { + xs := strings.Split(imageName, "/") + diskName := xs[len(xs)-1] + _, errChan := s.client.DisksClient.Delete(resourceGroupName, diskName, nil) + err := <-errChan + return err + } + // VHD image + u, err := url.Parse(imageName) + if err != nil { + return err + } + xs := strings.Split(u.Path, "/") + var storageAccountName = xs[1] + var blobName = strings.Join(xs[2:], "/") + + blob := s.client.BlobStorageClient.GetContainerReference(storageAccountName).GetBlobReference(blobName) + err = blob.Delete(nil) + return err + +} + +func (s *StepDeployTemplate) Cleanup(state multistep.StateBag) { + //Only clean up if this was an existing resource group and the resource group + //is marked as created + var existingResourceGroup = state.Get(constants.ArmIsExistingResourceGroup).(bool) + var resourceGroupCreated = state.Get(constants.ArmIsResourceGroupCreated).(bool) + if !existingResourceGroup || !resourceGroupCreated { + return + } + ui := state.Get("ui").(packer.Ui) + ui.Say("\nThe resource group was not created by Packer, deleting individual resources ...") + + var resourceGroupName = state.Get(constants.ArmResourceGroupName).(string) + var computeName = state.Get(constants.ArmComputeName).(string) + var deploymentName = state.Get(constants.ArmDeploymentName).(string) + imageType, imageName, err := s.disk(resourceGroupName, computeName) + if err != nil { + ui.Error("Could not retrieve OS Image details") + } + + ui.Say(" -> Deployment: " + deploymentName) + if deploymentName != "" { + maxResources := int32(50) + deploymentOperations, err := s.client.DeploymentOperationsClient.List(resourceGroupName, deploymentName, &maxResources) + if err != nil { + ui.Error(fmt.Sprintf("Error deleting resources. Please delete them manually.\n\n"+ + "Name: %s\n"+ + "Error: %s", resourceGroupName, err)) + } + for _, deploymentOperation := range *deploymentOperations.Value { + // Sometimes an empty operation is added to the list by Azure + if deploymentOperation.Properties.TargetResource == nil { + continue + } + ui.Say(fmt.Sprintf(" -> %s : '%s'", + *deploymentOperation.Properties.TargetResource.ResourceType, + *deploymentOperation.Properties.TargetResource.ResourceName)) + err = s.delete(*deploymentOperation.Properties.TargetResource.ResourceType, + *deploymentOperation.Properties.TargetResource.ResourceName, + resourceGroupName) + if err != nil { + ui.Error(fmt.Sprintf("Error deleting resource. Please delete manually.\n\n"+ + "Name: %s\n"+ + "Error: %s", *deploymentOperation.Properties.TargetResource.ResourceName, err)) + } + } + + // The disk is not defined as an operation in the template so has to be + // deleted separately + ui.Say(fmt.Sprintf(" -> %s : '%s'", imageType, imageName)) + err = s.deleteDisk(imageType, imageName, resourceGroupName) + if err != nil { + ui.Error(fmt.Sprintf("Error deleting resource. Please delete manually.\n\n"+ + "Name: %s\n"+ + "Error: %s", imageName, err)) + } + } } diff --git a/builder/azure/common/constants/stateBag.go b/builder/azure/common/constants/stateBag.go index a6eef5bd4..1df94a8f0 100644 --- a/builder/azure/common/constants/stateBag.go +++ b/builder/azure/common/constants/stateBag.go @@ -26,6 +26,7 @@ const ( ArmStorageAccountName string = "arm.StorageAccountName" ArmTags string = "arm.Tags" ArmVirtualMachineCaptureParameters string = "arm.VirtualMachineCaptureParameters" + ArmIsExistingResourceGroup string = "arm.IsExistingResourceGroup" ArmIsManagedImage string = "arm.IsManagedImage" ArmManagedImageResourceGroupName string = "arm.ManagedImageResourceGroupName" diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/client.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/client.go new file mode 100755 index 000000000..8bab7acc1 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/client.go @@ -0,0 +1,53 @@ +// Package disk implements the Azure ARM Disk service API version +// 2016-04-30-preview. +// +// The Disk Resource Provider Client. +package disk + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" +) + +const ( + // DefaultBaseURI is the default URI used for the service Disk + DefaultBaseURI = "https://management.azure.com" +) + +// ManagementClient is the base client for Disk. +type ManagementClient struct { + autorest.Client + BaseURI string + SubscriptionID string +} + +// New creates an instance of the ManagementClient client. +func New(subscriptionID string) ManagementClient { + return NewWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewWithBaseURI creates an instance of the ManagementClient client. +func NewWithBaseURI(baseURI string, subscriptionID string) ManagementClient { + return ManagementClient{ + Client: autorest.NewClientWithUserAgent(UserAgent()), + BaseURI: baseURI, + SubscriptionID: subscriptionID, + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/disks.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/disks.go new file mode 100755 index 000000000..4f7fce74f --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/disks.go @@ -0,0 +1,728 @@ +package disk + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// DisksClient is the the Disk Resource Provider Client. +type DisksClient struct { + ManagementClient +} + +// NewDisksClient creates an instance of the DisksClient client. +func NewDisksClient(subscriptionID string) DisksClient { + return NewDisksClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewDisksClientWithBaseURI creates an instance of the DisksClient client. +func NewDisksClientWithBaseURI(baseURI string, subscriptionID string) DisksClient { + return DisksClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate creates or updates a disk. This method may poll for +// completion. Polling can be canceled by passing the cancel channel argument. +// The channel will be used to cancel polling and any outstanding HTTP +// requests. +// +// resourceGroupName is the name of the resource group. diskName is the name of +// the disk within the given subscription and resource group. diskParameter is +// disk object supplied in the body of the Put disk operation. +func (client DisksClient) CreateOrUpdate(resourceGroupName string, diskName string, diskParameter Model, cancel <-chan struct{}) (<-chan Model, <-chan error) { + resultChan := make(chan Model, 1) + errChan := make(chan error, 1) + if err := validation.Validate([]validation.Validation{ + {TargetValue: diskParameter, + Constraints: []validation.Constraint{{Target: "diskParameter.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "diskParameter.Properties.CreationData", Name: validation.Null, Rule: true, + Chain: []validation.Constraint{{Target: "diskParameter.Properties.CreationData.ImageReference", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "diskParameter.Properties.CreationData.ImageReference.ID", Name: validation.Null, Rule: true, Chain: nil}}}, + }}, + {Target: "diskParameter.Properties.EncryptionSettings", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "diskParameter.Properties.EncryptionSettings.DiskEncryptionKey", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "diskParameter.Properties.EncryptionSettings.DiskEncryptionKey.SourceVault", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "diskParameter.Properties.EncryptionSettings.DiskEncryptionKey.SecretURL", Name: validation.Null, Rule: true, Chain: nil}, + }}, + {Target: "diskParameter.Properties.EncryptionSettings.KeyEncryptionKey", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "diskParameter.Properties.EncryptionSettings.KeyEncryptionKey.SourceVault", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "diskParameter.Properties.EncryptionSettings.KeyEncryptionKey.KeyURL", Name: validation.Null, Rule: true, Chain: nil}, + }}, + }}, + }}}}}); err != nil { + errChan <- validation.NewErrorWithValidationError(err, "disk.DisksClient", "CreateOrUpdate") + close(errChan) + close(resultChan) + return resultChan, errChan + } + + go func() { + var err error + var result Model + defer func() { + resultChan <- result + errChan <- err + close(resultChan) + close(errChan) + }() + req, err := client.CreateOrUpdatePreparer(resourceGroupName, diskName, diskParameter, cancel) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "CreateOrUpdate", nil, "Failure preparing request") + return + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.DisksClient", "CreateOrUpdate", resp, "Failure sending request") + return + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "CreateOrUpdate", resp, "Failure responding to request") + } + }() + return resultChan, errChan +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client DisksClient) CreateOrUpdatePreparer(resourceGroupName string, diskName string, diskParameter Model, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "diskName": autorest.Encode("path", diskName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/disks/{diskName}", pathParameters), + autorest.WithJSON(diskParameter), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client DisksClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client DisksClient) CreateOrUpdateResponder(resp *http.Response) (result Model, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete deletes a disk. This method may poll for completion. Polling can be +// canceled by passing the cancel channel argument. The channel will be used to +// cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. diskName is the name of +// the disk within the given subscription and resource group. +func (client DisksClient) Delete(resourceGroupName string, diskName string, cancel <-chan struct{}) (<-chan OperationStatusResponse, <-chan error) { + resultChan := make(chan OperationStatusResponse, 1) + errChan := make(chan error, 1) + go func() { + var err error + var result OperationStatusResponse + defer func() { + resultChan <- result + errChan <- err + close(resultChan) + close(errChan) + }() + req, err := client.DeletePreparer(resourceGroupName, diskName, cancel) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "Delete", nil, "Failure preparing request") + return + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.DisksClient", "Delete", resp, "Failure sending request") + return + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "Delete", resp, "Failure responding to request") + } + }() + return resultChan, errChan +} + +// DeletePreparer prepares the Delete request. +func (client DisksClient) DeletePreparer(resourceGroupName string, diskName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "diskName": autorest.Encode("path", diskName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/disks/{diskName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client DisksClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client DisksClient) DeleteResponder(resp *http.Response) (result OperationStatusResponse, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Get gets information about a disk. +// +// resourceGroupName is the name of the resource group. diskName is the name of +// the disk within the given subscription and resource group. +func (client DisksClient) Get(resourceGroupName string, diskName string) (result Model, err error) { + req, err := client.GetPreparer(resourceGroupName, diskName) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "Get", nil, "Failure preparing request") + return + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.DisksClient", "Get", resp, "Failure sending request") + return + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client DisksClient) GetPreparer(resourceGroupName string, diskName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "diskName": autorest.Encode("path", diskName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/disks/{diskName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client DisksClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client DisksClient) GetResponder(resp *http.Response) (result Model, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GrantAccess grants access to a disk. This method may poll for completion. +// Polling can be canceled by passing the cancel channel argument. The channel +// will be used to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. diskName is the name of +// the disk within the given subscription and resource group. grantAccessData +// is access data object supplied in the body of the get disk access operation. +func (client DisksClient) GrantAccess(resourceGroupName string, diskName string, grantAccessData GrantAccessData, cancel <-chan struct{}) (<-chan AccessURI, <-chan error) { + resultChan := make(chan AccessURI, 1) + errChan := make(chan error, 1) + if err := validation.Validate([]validation.Validation{ + {TargetValue: grantAccessData, + Constraints: []validation.Constraint{{Target: "grantAccessData.DurationInSeconds", Name: validation.Null, Rule: true, Chain: nil}}}}); err != nil { + errChan <- validation.NewErrorWithValidationError(err, "disk.DisksClient", "GrantAccess") + close(errChan) + close(resultChan) + return resultChan, errChan + } + + go func() { + var err error + var result AccessURI + defer func() { + resultChan <- result + errChan <- err + close(resultChan) + close(errChan) + }() + req, err := client.GrantAccessPreparer(resourceGroupName, diskName, grantAccessData, cancel) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "GrantAccess", nil, "Failure preparing request") + return + } + + resp, err := client.GrantAccessSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.DisksClient", "GrantAccess", resp, "Failure sending request") + return + } + + result, err = client.GrantAccessResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "GrantAccess", resp, "Failure responding to request") + } + }() + return resultChan, errChan +} + +// GrantAccessPreparer prepares the GrantAccess request. +func (client DisksClient) GrantAccessPreparer(resourceGroupName string, diskName string, grantAccessData GrantAccessData, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "diskName": autorest.Encode("path", diskName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/disks/{diskName}/beginGetAccess", pathParameters), + autorest.WithJSON(grantAccessData), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// GrantAccessSender sends the GrantAccess request. The method will close the +// http.Response Body if it receives an error. +func (client DisksClient) GrantAccessSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// GrantAccessResponder handles the response to the GrantAccess request. The method always +// closes the http.Response Body. +func (client DisksClient) GrantAccessResponder(resp *http.Response) (result AccessURI, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List lists all the disks under a subscription. +func (client DisksClient) List() (result ListType, err error) { + req, err := client.ListPreparer() + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.DisksClient", "List", resp, "Failure sending request") + return + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client DisksClient) ListPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Compute/disks", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client DisksClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client DisksClient) ListResponder(resp *http.Response) (result ListType, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client DisksClient) ListNextResults(lastResults ListType) (result ListType, err error) { + req, err := lastResults.ListTypePreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "List", resp, "Failure responding to next results request") + } + + return +} + +// ListByResourceGroup lists all the disks under a resource group. +// +// resourceGroupName is the name of the resource group. +func (client DisksClient) ListByResourceGroup(resourceGroupName string) (result ListType, err error) { + req, err := client.ListByResourceGroupPreparer(resourceGroupName) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "ListByResourceGroup", nil, "Failure preparing request") + return + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.DisksClient", "ListByResourceGroup", resp, "Failure sending request") + return + } + + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "ListByResourceGroup", resp, "Failure responding to request") + } + + return +} + +// ListByResourceGroupPreparer prepares the ListByResourceGroup request. +func (client DisksClient) ListByResourceGroupPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/disks", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListByResourceGroupSender sends the ListByResourceGroup request. The method will close the +// http.Response Body if it receives an error. +func (client DisksClient) ListByResourceGroupSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListByResourceGroupResponder handles the response to the ListByResourceGroup request. The method always +// closes the http.Response Body. +func (client DisksClient) ListByResourceGroupResponder(resp *http.Response) (result ListType, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListByResourceGroupNextResults retrieves the next set of results, if any. +func (client DisksClient) ListByResourceGroupNextResults(lastResults ListType) (result ListType, err error) { + req, err := lastResults.ListTypePreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "ListByResourceGroup", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "ListByResourceGroup", resp, "Failure sending next results request") + } + + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "ListByResourceGroup", resp, "Failure responding to next results request") + } + + return +} + +// RevokeAccess revokes access to a disk. This method may poll for completion. +// Polling can be canceled by passing the cancel channel argument. The channel +// will be used to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. diskName is the name of +// the disk within the given subscription and resource group. +func (client DisksClient) RevokeAccess(resourceGroupName string, diskName string, cancel <-chan struct{}) (<-chan OperationStatusResponse, <-chan error) { + resultChan := make(chan OperationStatusResponse, 1) + errChan := make(chan error, 1) + go func() { + var err error + var result OperationStatusResponse + defer func() { + resultChan <- result + errChan <- err + close(resultChan) + close(errChan) + }() + req, err := client.RevokeAccessPreparer(resourceGroupName, diskName, cancel) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "RevokeAccess", nil, "Failure preparing request") + return + } + + resp, err := client.RevokeAccessSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.DisksClient", "RevokeAccess", resp, "Failure sending request") + return + } + + result, err = client.RevokeAccessResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "RevokeAccess", resp, "Failure responding to request") + } + }() + return resultChan, errChan +} + +// RevokeAccessPreparer prepares the RevokeAccess request. +func (client DisksClient) RevokeAccessPreparer(resourceGroupName string, diskName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "diskName": autorest.Encode("path", diskName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/disks/{diskName}/endGetAccess", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// RevokeAccessSender sends the RevokeAccess request. The method will close the +// http.Response Body if it receives an error. +func (client DisksClient) RevokeAccessSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// RevokeAccessResponder handles the response to the RevokeAccess request. The method always +// closes the http.Response Body. +func (client DisksClient) RevokeAccessResponder(resp *http.Response) (result OperationStatusResponse, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Update updates (patches) a disk. This method may poll for completion. +// Polling can be canceled by passing the cancel channel argument. The channel +// will be used to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. diskName is the name of +// the disk within the given subscription and resource group. diskParameter is +// disk object supplied in the body of the Patch disk operation. +func (client DisksClient) Update(resourceGroupName string, diskName string, diskParameter UpdateType, cancel <-chan struct{}) (<-chan Model, <-chan error) { + resultChan := make(chan Model, 1) + errChan := make(chan error, 1) + go func() { + var err error + var result Model + defer func() { + resultChan <- result + errChan <- err + close(resultChan) + close(errChan) + }() + req, err := client.UpdatePreparer(resourceGroupName, diskName, diskParameter, cancel) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "Update", nil, "Failure preparing request") + return + } + + resp, err := client.UpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.DisksClient", "Update", resp, "Failure sending request") + return + } + + result, err = client.UpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "Update", resp, "Failure responding to request") + } + }() + return resultChan, errChan +} + +// UpdatePreparer prepares the Update request. +func (client DisksClient) UpdatePreparer(resourceGroupName string, diskName string, diskParameter UpdateType, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "diskName": autorest.Encode("path", diskName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/disks/{diskName}", pathParameters), + autorest.WithJSON(diskParameter), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// UpdateSender sends the Update request. The method will close the +// http.Response Body if it receives an error. +func (client DisksClient) UpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// UpdateResponder handles the response to the Update request. The method always +// closes the http.Response Body. +func (client DisksClient) UpdateResponder(resp *http.Response) (result Model, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/models.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/models.go new file mode 100755 index 000000000..e8118696a --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/models.go @@ -0,0 +1,278 @@ +package disk + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/date" + "github.com/Azure/go-autorest/autorest/to" + "net/http" +) + +// AccessLevel enumerates the values for access level. +type AccessLevel string + +const ( + // None specifies the none state for access level. + None AccessLevel = "None" + // Read specifies the read state for access level. + Read AccessLevel = "Read" +) + +// CreateOption enumerates the values for create option. +type CreateOption string + +const ( + // Attach specifies the attach state for create option. + Attach CreateOption = "Attach" + // Copy specifies the copy state for create option. + Copy CreateOption = "Copy" + // Empty specifies the empty state for create option. + Empty CreateOption = "Empty" + // FromImage specifies the from image state for create option. + FromImage CreateOption = "FromImage" + // Import specifies the import state for create option. + Import CreateOption = "Import" + // Restore specifies the restore state for create option. + Restore CreateOption = "Restore" +) + +// OperatingSystemTypes enumerates the values for operating system types. +type OperatingSystemTypes string + +const ( + // Linux specifies the linux state for operating system types. + Linux OperatingSystemTypes = "Linux" + // Windows specifies the windows state for operating system types. + Windows OperatingSystemTypes = "Windows" +) + +// StorageAccountTypes enumerates the values for storage account types. +type StorageAccountTypes string + +const ( + // PremiumLRS specifies the premium lrs state for storage account types. + PremiumLRS StorageAccountTypes = "Premium_LRS" + // StandardLRS specifies the standard lrs state for storage account types. + StandardLRS StorageAccountTypes = "Standard_LRS" +) + +// AccessURI is a disk access SAS uri. +type AccessURI struct { + autorest.Response `json:"-"` + *AccessURIOutput `json:"properties,omitempty"` +} + +// AccessURIOutput is azure properties, including output. +type AccessURIOutput struct { + *AccessURIRaw `json:"output,omitempty"` +} + +// AccessURIRaw is this object gets 'bubbled up' through flattening. +type AccessURIRaw struct { + AccessSAS *string `json:"accessSAS,omitempty"` +} + +// APIError is api error. +type APIError struct { + Details *[]APIErrorBase `json:"details,omitempty"` + Innererror *InnerError `json:"innererror,omitempty"` + Code *string `json:"code,omitempty"` + Target *string `json:"target,omitempty"` + Message *string `json:"message,omitempty"` +} + +// APIErrorBase is api error base. +type APIErrorBase struct { + Code *string `json:"code,omitempty"` + Target *string `json:"target,omitempty"` + Message *string `json:"message,omitempty"` +} + +// CreationData is data used when creating a disk. +type CreationData struct { + CreateOption CreateOption `json:"createOption,omitempty"` + StorageAccountID *string `json:"storageAccountId,omitempty"` + ImageReference *ImageDiskReference `json:"imageReference,omitempty"` + SourceURI *string `json:"sourceUri,omitempty"` + SourceResourceID *string `json:"sourceResourceId,omitempty"` +} + +// EncryptionSettings is encryption settings for disk or snapshot +type EncryptionSettings struct { + Enabled *bool `json:"enabled,omitempty"` + DiskEncryptionKey *KeyVaultAndSecretReference `json:"diskEncryptionKey,omitempty"` + KeyEncryptionKey *KeyVaultAndKeyReference `json:"keyEncryptionKey,omitempty"` +} + +// GrantAccessData is data used for requesting a SAS. +type GrantAccessData struct { + Access AccessLevel `json:"access,omitempty"` + DurationInSeconds *int32 `json:"durationInSeconds,omitempty"` +} + +// ImageDiskReference is the source image used for creating the disk. +type ImageDiskReference struct { + ID *string `json:"id,omitempty"` + Lun *int32 `json:"lun,omitempty"` +} + +// InnerError is inner error details. +type InnerError struct { + Exceptiontype *string `json:"exceptiontype,omitempty"` + Errordetail *string `json:"errordetail,omitempty"` +} + +// KeyVaultAndKeyReference is key Vault Key Url and vault id of KeK, KeK is +// optional and when provided is used to unwrap the encryptionKey +type KeyVaultAndKeyReference struct { + SourceVault *SourceVault `json:"sourceVault,omitempty"` + KeyURL *string `json:"keyUrl,omitempty"` +} + +// KeyVaultAndSecretReference is key Vault Secret Url and vault id of the +// encryption key +type KeyVaultAndSecretReference struct { + SourceVault *SourceVault `json:"sourceVault,omitempty"` + SecretURL *string `json:"secretUrl,omitempty"` +} + +// ListType is the List Disks operation response. +type ListType struct { + autorest.Response `json:"-"` + Value *[]Model `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// ListTypePreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client ListType) ListTypePreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// Model is disk resource. +type Model struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + *Properties `json:"properties,omitempty"` +} + +// OperationStatusResponse is operation status response +type OperationStatusResponse struct { + autorest.Response `json:"-"` + Name *string `json:"name,omitempty"` + Status *string `json:"status,omitempty"` + StartTime *date.Time `json:"startTime,omitempty"` + EndTime *date.Time `json:"endTime,omitempty"` + Error *APIError `json:"error,omitempty"` +} + +// Properties is disk resource properties. +type Properties struct { + AccountType StorageAccountTypes `json:"accountType,omitempty"` + TimeCreated *date.Time `json:"timeCreated,omitempty"` + OsType OperatingSystemTypes `json:"osType,omitempty"` + CreationData *CreationData `json:"creationData,omitempty"` + DiskSizeGB *int32 `json:"diskSizeGB,omitempty"` + EncryptionSettings *EncryptionSettings `json:"encryptionSettings,omitempty"` + OwnerID *string `json:"ownerId,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// Resource is the Resource model definition. +type Resource struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` +} + +// ResourceUpdate is the Resource model definition. +type ResourceUpdate struct { + Tags *map[string]*string `json:"tags,omitempty"` +} + +// Snapshot is snapshot resource. +type Snapshot struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + *Properties `json:"properties,omitempty"` +} + +// SnapshotList is the List Snapshots operation response. +type SnapshotList struct { + autorest.Response `json:"-"` + Value *[]Snapshot `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// SnapshotListPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client SnapshotList) SnapshotListPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// SnapshotUpdate is snapshot update resource. +type SnapshotUpdate struct { + Tags *map[string]*string `json:"tags,omitempty"` + *UpdateProperties `json:"properties,omitempty"` +} + +// SourceVault is the vault id is an Azure Resource Manager Resoure id in the +// form +// /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.KeyVault/vaults/{vaultName} +type SourceVault struct { + ID *string `json:"id,omitempty"` +} + +// UpdateProperties is disk resource update properties. +type UpdateProperties struct { + AccountType StorageAccountTypes `json:"accountType,omitempty"` + OsType OperatingSystemTypes `json:"osType,omitempty"` + CreationData *CreationData `json:"creationData,omitempty"` + DiskSizeGB *int32 `json:"diskSizeGB,omitempty"` + EncryptionSettings *EncryptionSettings `json:"encryptionSettings,omitempty"` +} + +// UpdateType is disk update resource. +type UpdateType struct { + Tags *map[string]*string `json:"tags,omitempty"` + *UpdateProperties `json:"properties,omitempty"` +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/snapshots.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/snapshots.go new file mode 100755 index 000000000..f4e5579d0 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/snapshots.go @@ -0,0 +1,733 @@ +package disk + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// SnapshotsClient is the the Disk Resource Provider Client. +type SnapshotsClient struct { + ManagementClient +} + +// NewSnapshotsClient creates an instance of the SnapshotsClient client. +func NewSnapshotsClient(subscriptionID string) SnapshotsClient { + return NewSnapshotsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewSnapshotsClientWithBaseURI creates an instance of the SnapshotsClient +// client. +func NewSnapshotsClientWithBaseURI(baseURI string, subscriptionID string) SnapshotsClient { + return SnapshotsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate creates or updates a snapshot. This method may poll for +// completion. Polling can be canceled by passing the cancel channel argument. +// The channel will be used to cancel polling and any outstanding HTTP +// requests. +// +// resourceGroupName is the name of the resource group. snapshotName is the +// name of the snapshot within the given subscription and resource group. +// snapshot is snapshot object supplied in the body of the Put disk operation. +func (client SnapshotsClient) CreateOrUpdate(resourceGroupName string, snapshotName string, snapshot Snapshot, cancel <-chan struct{}) (<-chan Snapshot, <-chan error) { + resultChan := make(chan Snapshot, 1) + errChan := make(chan error, 1) + if err := validation.Validate([]validation.Validation{ + {TargetValue: snapshot, + Constraints: []validation.Constraint{{Target: "snapshot.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "snapshot.Properties.CreationData", Name: validation.Null, Rule: true, + Chain: []validation.Constraint{{Target: "snapshot.Properties.CreationData.ImageReference", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "snapshot.Properties.CreationData.ImageReference.ID", Name: validation.Null, Rule: true, Chain: nil}}}, + }}, + {Target: "snapshot.Properties.EncryptionSettings", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "snapshot.Properties.EncryptionSettings.DiskEncryptionKey", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "snapshot.Properties.EncryptionSettings.DiskEncryptionKey.SourceVault", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "snapshot.Properties.EncryptionSettings.DiskEncryptionKey.SecretURL", Name: validation.Null, Rule: true, Chain: nil}, + }}, + {Target: "snapshot.Properties.EncryptionSettings.KeyEncryptionKey", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "snapshot.Properties.EncryptionSettings.KeyEncryptionKey.SourceVault", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "snapshot.Properties.EncryptionSettings.KeyEncryptionKey.KeyURL", Name: validation.Null, Rule: true, Chain: nil}, + }}, + }}, + }}}}}); err != nil { + errChan <- validation.NewErrorWithValidationError(err, "disk.SnapshotsClient", "CreateOrUpdate") + close(errChan) + close(resultChan) + return resultChan, errChan + } + + go func() { + var err error + var result Snapshot + defer func() { + resultChan <- result + errChan <- err + close(resultChan) + close(errChan) + }() + req, err := client.CreateOrUpdatePreparer(resourceGroupName, snapshotName, snapshot, cancel) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "CreateOrUpdate", nil, "Failure preparing request") + return + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "CreateOrUpdate", resp, "Failure sending request") + return + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "CreateOrUpdate", resp, "Failure responding to request") + } + }() + return resultChan, errChan +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client SnapshotsClient) CreateOrUpdatePreparer(resourceGroupName string, snapshotName string, snapshot Snapshot, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "snapshotName": autorest.Encode("path", snapshotName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/snapshots/{snapshotName}", pathParameters), + autorest.WithJSON(snapshot), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client SnapshotsClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client SnapshotsClient) CreateOrUpdateResponder(resp *http.Response) (result Snapshot, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete deletes a snapshot. This method may poll for completion. Polling can +// be canceled by passing the cancel channel argument. The channel will be used +// to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. snapshotName is the +// name of the snapshot within the given subscription and resource group. +func (client SnapshotsClient) Delete(resourceGroupName string, snapshotName string, cancel <-chan struct{}) (<-chan OperationStatusResponse, <-chan error) { + resultChan := make(chan OperationStatusResponse, 1) + errChan := make(chan error, 1) + go func() { + var err error + var result OperationStatusResponse + defer func() { + resultChan <- result + errChan <- err + close(resultChan) + close(errChan) + }() + req, err := client.DeletePreparer(resourceGroupName, snapshotName, cancel) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "Delete", nil, "Failure preparing request") + return + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "Delete", resp, "Failure sending request") + return + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "Delete", resp, "Failure responding to request") + } + }() + return resultChan, errChan +} + +// DeletePreparer prepares the Delete request. +func (client SnapshotsClient) DeletePreparer(resourceGroupName string, snapshotName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "snapshotName": autorest.Encode("path", snapshotName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/snapshots/{snapshotName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client SnapshotsClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client SnapshotsClient) DeleteResponder(resp *http.Response) (result OperationStatusResponse, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Get gets information about a snapshot. +// +// resourceGroupName is the name of the resource group. snapshotName is the +// name of the snapshot within the given subscription and resource group. +func (client SnapshotsClient) Get(resourceGroupName string, snapshotName string) (result Snapshot, err error) { + req, err := client.GetPreparer(resourceGroupName, snapshotName) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "Get", nil, "Failure preparing request") + return + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "Get", resp, "Failure sending request") + return + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client SnapshotsClient) GetPreparer(resourceGroupName string, snapshotName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "snapshotName": autorest.Encode("path", snapshotName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/snapshots/{snapshotName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client SnapshotsClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client SnapshotsClient) GetResponder(resp *http.Response) (result Snapshot, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GrantAccess grants access to a snapshot. This method may poll for +// completion. Polling can be canceled by passing the cancel channel argument. +// The channel will be used to cancel polling and any outstanding HTTP +// requests. +// +// resourceGroupName is the name of the resource group. snapshotName is the +// name of the snapshot within the given subscription and resource group. +// grantAccessData is access data object supplied in the body of the get +// snapshot access operation. +func (client SnapshotsClient) GrantAccess(resourceGroupName string, snapshotName string, grantAccessData GrantAccessData, cancel <-chan struct{}) (<-chan AccessURI, <-chan error) { + resultChan := make(chan AccessURI, 1) + errChan := make(chan error, 1) + if err := validation.Validate([]validation.Validation{ + {TargetValue: grantAccessData, + Constraints: []validation.Constraint{{Target: "grantAccessData.DurationInSeconds", Name: validation.Null, Rule: true, Chain: nil}}}}); err != nil { + errChan <- validation.NewErrorWithValidationError(err, "disk.SnapshotsClient", "GrantAccess") + close(errChan) + close(resultChan) + return resultChan, errChan + } + + go func() { + var err error + var result AccessURI + defer func() { + resultChan <- result + errChan <- err + close(resultChan) + close(errChan) + }() + req, err := client.GrantAccessPreparer(resourceGroupName, snapshotName, grantAccessData, cancel) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "GrantAccess", nil, "Failure preparing request") + return + } + + resp, err := client.GrantAccessSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "GrantAccess", resp, "Failure sending request") + return + } + + result, err = client.GrantAccessResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "GrantAccess", resp, "Failure responding to request") + } + }() + return resultChan, errChan +} + +// GrantAccessPreparer prepares the GrantAccess request. +func (client SnapshotsClient) GrantAccessPreparer(resourceGroupName string, snapshotName string, grantAccessData GrantAccessData, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "snapshotName": autorest.Encode("path", snapshotName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/snapshots/{snapshotName}/beginGetAccess", pathParameters), + autorest.WithJSON(grantAccessData), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// GrantAccessSender sends the GrantAccess request. The method will close the +// http.Response Body if it receives an error. +func (client SnapshotsClient) GrantAccessSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// GrantAccessResponder handles the response to the GrantAccess request. The method always +// closes the http.Response Body. +func (client SnapshotsClient) GrantAccessResponder(resp *http.Response) (result AccessURI, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List lists snapshots under a subscription. +func (client SnapshotsClient) List() (result SnapshotList, err error) { + req, err := client.ListPreparer() + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "List", resp, "Failure sending request") + return + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client SnapshotsClient) ListPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Compute/snapshots", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client SnapshotsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client SnapshotsClient) ListResponder(resp *http.Response) (result SnapshotList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client SnapshotsClient) ListNextResults(lastResults SnapshotList) (result SnapshotList, err error) { + req, err := lastResults.SnapshotListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "List", resp, "Failure responding to next results request") + } + + return +} + +// ListByResourceGroup lists snapshots under a resource group. +// +// resourceGroupName is the name of the resource group. +func (client SnapshotsClient) ListByResourceGroup(resourceGroupName string) (result SnapshotList, err error) { + req, err := client.ListByResourceGroupPreparer(resourceGroupName) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "ListByResourceGroup", nil, "Failure preparing request") + return + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "ListByResourceGroup", resp, "Failure sending request") + return + } + + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "ListByResourceGroup", resp, "Failure responding to request") + } + + return +} + +// ListByResourceGroupPreparer prepares the ListByResourceGroup request. +func (client SnapshotsClient) ListByResourceGroupPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/snapshots", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListByResourceGroupSender sends the ListByResourceGroup request. The method will close the +// http.Response Body if it receives an error. +func (client SnapshotsClient) ListByResourceGroupSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListByResourceGroupResponder handles the response to the ListByResourceGroup request. The method always +// closes the http.Response Body. +func (client SnapshotsClient) ListByResourceGroupResponder(resp *http.Response) (result SnapshotList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListByResourceGroupNextResults retrieves the next set of results, if any. +func (client SnapshotsClient) ListByResourceGroupNextResults(lastResults SnapshotList) (result SnapshotList, err error) { + req, err := lastResults.SnapshotListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "ListByResourceGroup", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "ListByResourceGroup", resp, "Failure sending next results request") + } + + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "ListByResourceGroup", resp, "Failure responding to next results request") + } + + return +} + +// RevokeAccess revokes access to a snapshot. This method may poll for +// completion. Polling can be canceled by passing the cancel channel argument. +// The channel will be used to cancel polling and any outstanding HTTP +// requests. +// +// resourceGroupName is the name of the resource group. snapshotName is the +// name of the snapshot within the given subscription and resource group. +func (client SnapshotsClient) RevokeAccess(resourceGroupName string, snapshotName string, cancel <-chan struct{}) (<-chan OperationStatusResponse, <-chan error) { + resultChan := make(chan OperationStatusResponse, 1) + errChan := make(chan error, 1) + go func() { + var err error + var result OperationStatusResponse + defer func() { + resultChan <- result + errChan <- err + close(resultChan) + close(errChan) + }() + req, err := client.RevokeAccessPreparer(resourceGroupName, snapshotName, cancel) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "RevokeAccess", nil, "Failure preparing request") + return + } + + resp, err := client.RevokeAccessSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "RevokeAccess", resp, "Failure sending request") + return + } + + result, err = client.RevokeAccessResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "RevokeAccess", resp, "Failure responding to request") + } + }() + return resultChan, errChan +} + +// RevokeAccessPreparer prepares the RevokeAccess request. +func (client SnapshotsClient) RevokeAccessPreparer(resourceGroupName string, snapshotName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "snapshotName": autorest.Encode("path", snapshotName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/snapshots/{snapshotName}/endGetAccess", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// RevokeAccessSender sends the RevokeAccess request. The method will close the +// http.Response Body if it receives an error. +func (client SnapshotsClient) RevokeAccessSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// RevokeAccessResponder handles the response to the RevokeAccess request. The method always +// closes the http.Response Body. +func (client SnapshotsClient) RevokeAccessResponder(resp *http.Response) (result OperationStatusResponse, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Update updates (patches) a snapshot. This method may poll for completion. +// Polling can be canceled by passing the cancel channel argument. The channel +// will be used to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. snapshotName is the +// name of the snapshot within the given subscription and resource group. +// snapshot is snapshot object supplied in the body of the Patch snapshot +// operation. +func (client SnapshotsClient) Update(resourceGroupName string, snapshotName string, snapshot SnapshotUpdate, cancel <-chan struct{}) (<-chan Snapshot, <-chan error) { + resultChan := make(chan Snapshot, 1) + errChan := make(chan error, 1) + go func() { + var err error + var result Snapshot + defer func() { + resultChan <- result + errChan <- err + close(resultChan) + close(errChan) + }() + req, err := client.UpdatePreparer(resourceGroupName, snapshotName, snapshot, cancel) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "Update", nil, "Failure preparing request") + return + } + + resp, err := client.UpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "Update", resp, "Failure sending request") + return + } + + result, err = client.UpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "Update", resp, "Failure responding to request") + } + }() + return resultChan, errChan +} + +// UpdatePreparer prepares the Update request. +func (client SnapshotsClient) UpdatePreparer(resourceGroupName string, snapshotName string, snapshot SnapshotUpdate, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "snapshotName": autorest.Encode("path", snapshotName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/snapshots/{snapshotName}", pathParameters), + autorest.WithJSON(snapshot), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// UpdateSender sends the Update request. The method will close the +// http.Response Body if it receives an error. +func (client SnapshotsClient) UpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// UpdateResponder handles the response to the Update request. The method always +// closes the http.Response Body. +func (client SnapshotsClient) UpdateResponder(resp *http.Response) (result Snapshot, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/version.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/version.go new file mode 100755 index 000000000..a78b351a0 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/version.go @@ -0,0 +1,29 @@ +package disk + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +// UserAgent returns the UserAgent string to use when sending http.Requests. +func UserAgent() string { + return "Azure-SDK-For-Go/v10.0.2-beta arm-disk/2016-04-30-preview" +} + +// Version returns the semantic version (see http://semver.org) of the client. +func Version() string { + return "v10.0.2-beta" +} diff --git a/vendor/vendor.json b/vendor/vendor.json index 0a06ac4b1..503290446 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -17,6 +17,12 @@ "version": "v10.0.3-beta", "versionExact": "v10.0.3-beta" }, + { + "checksumSHA1": "Kr6/gY3LrNiOxMfDBCfBvBvenYw=", + "path": "github.com/Azure/azure-sdk-for-go/arm/disk", + "revision": "26132835cbefa2669a306b777f34b929b56aa0a2", + "revisionTime": "2017-05-18T20:34:07Z" + }, { "checksumSHA1": "HMu0WrEHVs+wqyjsTzXxRsEJimI=", "comment": "v3.1.0-beta",