From 4023b618b4ad6c60fbb9ba1f55464ba47768db55 Mon Sep 17 00:00:00 2001 From: bugbuilder Date: Sun, 23 Jul 2017 01:31:46 -0400 Subject: [PATCH 001/220] Verify remote cache for ESXi --- builder/vmware/iso/builder.go | 19 ++++--- builder/vmware/iso/step_download.go | 72 ++++++++++++++++++++++++ builder/vmware/iso/step_remote_upload.go | 26 +++++---- 3 files changed, 98 insertions(+), 19 deletions(-) create mode 100644 builder/vmware/iso/step_download.go diff --git a/builder/vmware/iso/builder.go b/builder/vmware/iso/builder.go index 42038b96a..5dba8de4e 100644 --- a/builder/vmware/iso/builder.go +++ b/builder/vmware/iso/builder.go @@ -220,15 +220,16 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe RemoteType: b.config.RemoteType, ToolsUploadFlavor: b.config.ToolsUploadFlavor, }, - &common.StepDownload{ - Checksum: b.config.ISOChecksum, - ChecksumType: b.config.ISOChecksumType, - Description: "ISO", - Extension: b.config.TargetExtension, - ResultKey: "iso_path", - TargetPath: b.config.TargetPath, - Url: b.config.ISOUrls, - }, + &stepDownload{ + step: &common.StepDownload{ + Checksum: b.config.ISOChecksum, + ChecksumType: b.config.ISOChecksumType, + Description: "ISO", + Extension: b.config.TargetExtension, + ResultKey: "iso_path", + TargetPath: b.config.TargetPath, + Url: b.config.ISOUrls, + }}, &vmwcommon.StepOutputDir{ Force: b.config.PackerForce, }, diff --git a/builder/vmware/iso/step_download.go b/builder/vmware/iso/step_download.go new file mode 100644 index 000000000..874a2a26e --- /dev/null +++ b/builder/vmware/iso/step_download.go @@ -0,0 +1,72 @@ +package iso + +import ( + "crypto/sha1" + "encoding/hex" + "fmt" + neturl "net/url" + + vmwcommon "github.com/hashicorp/packer/builder/vmware/common" + "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" + "runtime" +) + +type stepDownload struct { + step *common.StepDownload +} + +func (s *stepDownload) Run(state multistep.StateBag) multistep.StepAction { + cache := state.Get("cache").(packer.Cache) + driver := state.Get("driver").(vmwcommon.Driver) + ui := state.Get("ui").(packer.Ui) + + if esx5, ok := driver.(*ESX5Driver); ok { + ui.Say("Verifying remote cache") + + targetPath := "" + for _, url := range s.step.Url { + targetPath = s.step.TargetPath + + if targetPath == "" { + if u, err := neturl.Parse(url); err == nil { + + if u.Scheme == "file" { + + if u.Path != "" { + targetPath = u.Path + } else if u.Opaque != "" { + targetPath = u.Opaque + } + + if runtime.GOOS == "windows" && len(targetPath) > 0 && targetPath[0] == '/' { + targetPath = targetPath[1:] + } + } + } + + if targetPath == "" { + hash := sha1.Sum([]byte(url)) + cacheKey := fmt.Sprintf("%s.%s", hex.EncodeToString(hash[:]), s.step.Extension) + targetPath = cache.Lock(cacheKey) + cache.Unlock(cacheKey) + } + } + + remotePath := esx5.cachePath(targetPath) + ui.Message(remotePath) + if esx5.verifyChecksum(s.step.ChecksumType, s.step.Checksum, remotePath) { + state.Put(s.step.ResultKey, "skip_upload:"+remotePath) + ui.Message("Remote cache verified, skipping download step") + return multistep.ActionContinue + } + + ui.Message("Remote cache couldn't be verified") + } + } + + return s.step.Run(state) +} + +func (s *stepDownload) Cleanup(multistep.StateBag) {} diff --git a/builder/vmware/iso/step_remote_upload.go b/builder/vmware/iso/step_remote_upload.go index 6ef27bce6..852369627 100644 --- a/builder/vmware/iso/step_remote_upload.go +++ b/builder/vmware/iso/step_remote_upload.go @@ -2,10 +2,12 @@ package iso import ( "fmt" + "log" + "strings" + vmwcommon "github.com/hashicorp/packer/builder/vmware/common" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "log" ) // stepRemoteUpload uploads some thing from the state bag to a remote driver @@ -33,17 +35,21 @@ func (s *stepRemoteUpload) Run(state multistep.StateBag) multistep.StepAction { checksum := config.ISOChecksum checksumType := config.ISOChecksumType - ui.Say(s.Message) - log.Printf("Remote uploading: %s", path) - newPath, err := remote.UploadISO(path, checksum, checksumType) - if err != nil { - err := fmt.Errorf("Error uploading file: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt + if !strings.HasPrefix(path, "skip_upload:") { + log.Printf("Remote uploading: %s", path) + newPath, err := remote.UploadISO(path, checksum, checksumType) + + if err != nil { + err := fmt.Errorf("Error uploading file: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + state.Put(s.Key, newPath) + } else { + state.Put(s.Key, strings.Split("skip_upload:", path)[0]) } - state.Put(s.Key, newPath) return multistep.ActionContinue } From 84ad413e23186f9ecfbb74d0e0a52a844c8a7628 Mon Sep 17 00:00:00 2001 From: bugbuilder Date: Sun, 23 Jul 2017 03:20:06 -0400 Subject: [PATCH 002/220] Set remote iso path --- builder/vmware/iso/step_remote_upload.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/vmware/iso/step_remote_upload.go b/builder/vmware/iso/step_remote_upload.go index 852369627..2cb5003f5 100644 --- a/builder/vmware/iso/step_remote_upload.go +++ b/builder/vmware/iso/step_remote_upload.go @@ -36,9 +36,9 @@ func (s *stepRemoteUpload) Run(state multistep.StateBag) multistep.StepAction { checksumType := config.ISOChecksumType if !strings.HasPrefix(path, "skip_upload:") { + ui.Say(s.Message) log.Printf("Remote uploading: %s", path) newPath, err := remote.UploadISO(path, checksum, checksumType) - if err != nil { err := fmt.Errorf("Error uploading file: %s", err) state.Put("error", err) @@ -47,7 +47,7 @@ func (s *stepRemoteUpload) Run(state multistep.StateBag) multistep.StepAction { } state.Put(s.Key, newPath) } else { - state.Put(s.Key, strings.Split("skip_upload:", path)[0]) + state.Put(s.Key, strings.Split(path, "skip_upload:")[1]) } return multistep.ActionContinue From 22aa89db274245621fda6b155f2622f57a2dd184 Mon Sep 17 00:00:00 2001 From: bugbuilder Date: Sun, 23 Jul 2017 14:11:48 -0400 Subject: [PATCH 003/220] file scheme has prioriry as remote targetPath --- builder/vmware/iso/step_download.go | 32 ++++++++++++++--------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/builder/vmware/iso/step_download.go b/builder/vmware/iso/step_download.go index 874a2a26e..7228fc8dd 100644 --- a/builder/vmware/iso/step_download.go +++ b/builder/vmware/iso/step_download.go @@ -29,29 +29,27 @@ func (s *stepDownload) Run(state multistep.StateBag) multistep.StepAction { for _, url := range s.step.Url { targetPath = s.step.TargetPath - if targetPath == "" { - if u, err := neturl.Parse(url); err == nil { + if u, err := neturl.Parse(url); err == nil { - if u.Scheme == "file" { + if u.Scheme == "file" { - if u.Path != "" { - targetPath = u.Path - } else if u.Opaque != "" { - targetPath = u.Opaque - } + if u.Path != "" { + targetPath = u.Path + } else if u.Opaque != "" { + targetPath = u.Opaque + } - if runtime.GOOS == "windows" && len(targetPath) > 0 && targetPath[0] == '/' { - targetPath = targetPath[1:] - } + if runtime.GOOS == "windows" && len(targetPath) > 0 && targetPath[0] == '/' { + targetPath = targetPath[1:] } } + } - if targetPath == "" { - hash := sha1.Sum([]byte(url)) - cacheKey := fmt.Sprintf("%s.%s", hex.EncodeToString(hash[:]), s.step.Extension) - targetPath = cache.Lock(cacheKey) - cache.Unlock(cacheKey) - } + if targetPath == "" { + hash := sha1.Sum([]byte(url)) + cacheKey := fmt.Sprintf("%s.%s", hex.EncodeToString(hash[:]), s.step.Extension) + targetPath = cache.Lock(cacheKey) + cache.Unlock(cacheKey) } remotePath := esx5.cachePath(targetPath) From d4e0847a74766e60acc61bfb4c2fa9214341eb5d Mon Sep 17 00:00:00 2001 From: bugbuilder Date: Sun, 23 Jul 2017 14:16:03 -0400 Subject: [PATCH 004/220] remove unnecessary initialization --- builder/vmware/iso/step_download.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/builder/vmware/iso/step_download.go b/builder/vmware/iso/step_download.go index 7228fc8dd..d9a26fc17 100644 --- a/builder/vmware/iso/step_download.go +++ b/builder/vmware/iso/step_download.go @@ -25,12 +25,10 @@ func (s *stepDownload) Run(state multistep.StateBag) multistep.StepAction { if esx5, ok := driver.(*ESX5Driver); ok { ui.Say("Verifying remote cache") - targetPath := "" for _, url := range s.step.Url { - targetPath = s.step.TargetPath + targetPath := s.step.TargetPath if u, err := neturl.Parse(url); err == nil { - if u.Scheme == "file" { if u.Path != "" { From b50e279d8abfec34350ccd86e55a99973a53610c Mon Sep 17 00:00:00 2001 From: bugbuilder Date: Mon, 24 Jul 2017 00:11:30 -0400 Subject: [PATCH 005/220] Making visible verify cache step --- builder/vmware/iso/builder.go | 34 +++++++++++-------- builder/vmware/iso/step_register.go | 2 +- builder/vmware/iso/step_remote_upload.go | 34 ++++++++++--------- ...{step_download.go => step_verify_cache.go} | 28 ++++++++------- 4 files changed, 54 insertions(+), 44 deletions(-) rename builder/vmware/iso/{step_download.go => step_verify_cache.go} (63%) diff --git a/builder/vmware/iso/builder.go b/builder/vmware/iso/builder.go index 5dba8de4e..7d3d6074e 100644 --- a/builder/vmware/iso/builder.go +++ b/builder/vmware/iso/builder.go @@ -215,21 +215,28 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe state.Put("hook", hook) state.Put("ui", ui) + stepVerifyCache := &stepVerifyCache{ + download: &common.StepDownload{ + Checksum: b.config.ISOChecksum, + ChecksumType: b.config.ISOChecksumType, + Description: "ISO", + Extension: b.config.TargetExtension, + ResultKey: "iso_path", + TargetPath: b.config.TargetPath, + Url: b.config.ISOUrls, + }, + remoteUpload: &stepRemoteUpload{ + Key: "iso_path", + Message: "Uploading ISO to remoteUpload machine...", + }, + } + steps := []multistep.Step{ &vmwcommon.StepPrepareTools{ RemoteType: b.config.RemoteType, ToolsUploadFlavor: b.config.ToolsUploadFlavor, }, - &stepDownload{ - step: &common.StepDownload{ - Checksum: b.config.ISOChecksum, - ChecksumType: b.config.ISOChecksumType, - Description: "ISO", - Extension: b.config.TargetExtension, - ResultKey: "iso_path", - TargetPath: b.config.TargetPath, - Url: b.config.ISOUrls, - }}, + stepVerifyCache, &vmwcommon.StepOutputDir{ Force: b.config.PackerForce, }, @@ -239,12 +246,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, &stepRemoteUpload{ Key: "floppy_path", - Message: "Uploading Floppy to remote machine...", - }, - &stepRemoteUpload{ - Key: "iso_path", - Message: "Uploading ISO to remote machine...", + Message: "Uploading Floppy to remoteUpload machine...", }, + stepVerifyCache.remoteUpload, &stepCreateDisk{}, &stepCreateVMX{}, &vmwcommon.StepConfigureVMX{ diff --git a/builder/vmware/iso/step_register.go b/builder/vmware/iso/step_register.go index a90de5fa2..524e3006d 100644 --- a/builder/vmware/iso/step_register.go +++ b/builder/vmware/iso/step_register.go @@ -20,7 +20,7 @@ func (s *StepRegister) Run(state multistep.StateBag) multistep.StepAction { vmxPath := state.Get("vmx_path").(string) if remoteDriver, ok := driver.(RemoteDriver); ok { - ui.Say("Registering remote VM...") + ui.Say("Registering remoteUpload VM...") if err := remoteDriver.Register(vmxPath); err != nil { err := fmt.Errorf("Error registering VM: %s", err) state.Put("error", err) diff --git a/builder/vmware/iso/step_remote_upload.go b/builder/vmware/iso/step_remote_upload.go index 2cb5003f5..56e1d0e58 100644 --- a/builder/vmware/iso/step_remote_upload.go +++ b/builder/vmware/iso/step_remote_upload.go @@ -3,24 +3,30 @@ package iso import ( "fmt" "log" - "strings" vmwcommon "github.com/hashicorp/packer/builder/vmware/common" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" ) -// stepRemoteUpload uploads some thing from the state bag to a remote driver -// (if it can) and stores that new remote path into the state bag. +// stepRemoteUpload uploads some thing from the state bag to a remoteUpload driver +// (if it can) and stores that new remoteUpload path into the state bag. type stepRemoteUpload struct { Key string Message string + + // Set this to true for skip + Skip bool } func (s *stepRemoteUpload) Run(state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(vmwcommon.Driver) ui := state.Get("ui").(packer.Ui) + if s.Skip { + return multistep.ActionContinue + } + remote, ok := driver.(RemoteDriver) if !ok { return multistep.ActionContinue @@ -35,20 +41,16 @@ func (s *stepRemoteUpload) Run(state multistep.StateBag) multistep.StepAction { checksum := config.ISOChecksum checksumType := config.ISOChecksumType - if !strings.HasPrefix(path, "skip_upload:") { - ui.Say(s.Message) - log.Printf("Remote uploading: %s", path) - newPath, err := remote.UploadISO(path, checksum, checksumType) - if err != nil { - err := fmt.Errorf("Error uploading file: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - state.Put(s.Key, newPath) - } else { - state.Put(s.Key, strings.Split(path, "skip_upload:")[1]) + ui.Say(s.Message) + log.Printf("Remote uploading: %s", path) + newPath, err := remote.UploadISO(path, checksum, checksumType) + if err != nil { + err := fmt.Errorf("Error uploading file: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt } + state.Put(s.Key, newPath) return multistep.ActionContinue } diff --git a/builder/vmware/iso/step_download.go b/builder/vmware/iso/step_verify_cache.go similarity index 63% rename from builder/vmware/iso/step_download.go rename to builder/vmware/iso/step_verify_cache.go index d9a26fc17..01e90bbbf 100644 --- a/builder/vmware/iso/step_download.go +++ b/builder/vmware/iso/step_verify_cache.go @@ -13,20 +13,21 @@ import ( "runtime" ) -type stepDownload struct { - step *common.StepDownload +type stepVerifyCache struct { + download *common.StepDownload + remoteUpload *stepRemoteUpload } -func (s *stepDownload) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepVerifyCache) Run(state multistep.StateBag) multistep.StepAction { cache := state.Get("cache").(packer.Cache) driver := state.Get("driver").(vmwcommon.Driver) ui := state.Get("ui").(packer.Ui) if esx5, ok := driver.(*ESX5Driver); ok { - ui.Say("Verifying remote cache") + ui.Say("Verifying remoteUpload cache") - for _, url := range s.step.Url { - targetPath := s.step.TargetPath + for _, url := range s.download.Url { + targetPath := s.download.TargetPath if u, err := neturl.Parse(url); err == nil { if u.Scheme == "file" { @@ -45,16 +46,19 @@ func (s *stepDownload) Run(state multistep.StateBag) multistep.StepAction { if targetPath == "" { hash := sha1.Sum([]byte(url)) - cacheKey := fmt.Sprintf("%s.%s", hex.EncodeToString(hash[:]), s.step.Extension) + cacheKey := fmt.Sprintf("%s.%s", hex.EncodeToString(hash[:]), s.download.Extension) targetPath = cache.Lock(cacheKey) cache.Unlock(cacheKey) } remotePath := esx5.cachePath(targetPath) ui.Message(remotePath) - if esx5.verifyChecksum(s.step.ChecksumType, s.step.Checksum, remotePath) { - state.Put(s.step.ResultKey, "skip_upload:"+remotePath) - ui.Message("Remote cache verified, skipping download step") + + if esx5.verifyChecksum(s.download.ChecksumType, s.download.Checksum, remotePath) { + ui.Message("Remote cache verified, skipping download/upload step") + + s.remoteUpload.Skip = true + state.Put(s.download.ResultKey, remotePath) return multistep.ActionContinue } @@ -62,7 +66,7 @@ func (s *stepDownload) Run(state multistep.StateBag) multistep.StepAction { } } - return s.step.Run(state) + return s.download.Run(state) } -func (s *stepDownload) Cleanup(multistep.StateBag) {} +func (s *stepVerifyCache) Cleanup(multistep.StateBag) {} From f31f1542377710471b2aad5d245dad035c6bac93 Mon Sep 17 00:00:00 2001 From: bugbuilder Date: Mon, 24 Jul 2017 00:17:18 -0400 Subject: [PATCH 006/220] Cleaning refactoring name errors --- builder/vmware/iso/step_register.go | 2 +- builder/vmware/iso/step_remote_upload.go | 4 ++-- builder/vmware/iso/step_verify_cache.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/builder/vmware/iso/step_register.go b/builder/vmware/iso/step_register.go index 524e3006d..a90de5fa2 100644 --- a/builder/vmware/iso/step_register.go +++ b/builder/vmware/iso/step_register.go @@ -20,7 +20,7 @@ func (s *StepRegister) Run(state multistep.StateBag) multistep.StepAction { vmxPath := state.Get("vmx_path").(string) if remoteDriver, ok := driver.(RemoteDriver); ok { - ui.Say("Registering remoteUpload VM...") + ui.Say("Registering remote VM...") if err := remoteDriver.Register(vmxPath); err != nil { err := fmt.Errorf("Error registering VM: %s", err) state.Put("error", err) diff --git a/builder/vmware/iso/step_remote_upload.go b/builder/vmware/iso/step_remote_upload.go index 56e1d0e58..691ebcb84 100644 --- a/builder/vmware/iso/step_remote_upload.go +++ b/builder/vmware/iso/step_remote_upload.go @@ -9,8 +9,8 @@ import ( "github.com/mitchellh/multistep" ) -// stepRemoteUpload uploads some thing from the state bag to a remoteUpload driver -// (if it can) and stores that new remoteUpload path into the state bag. +// stepRemoteUpload uploads some thing from the state bag to a remote driver +// (if it can) and stores that new remote path into the state bag. type stepRemoteUpload struct { Key string Message string diff --git a/builder/vmware/iso/step_verify_cache.go b/builder/vmware/iso/step_verify_cache.go index 01e90bbbf..7aefa128c 100644 --- a/builder/vmware/iso/step_verify_cache.go +++ b/builder/vmware/iso/step_verify_cache.go @@ -24,7 +24,7 @@ func (s *stepVerifyCache) Run(state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) if esx5, ok := driver.(*ESX5Driver); ok { - ui.Say("Verifying remoteUpload cache") + ui.Say("Verifying remote cache") for _, url := range s.download.Url { targetPath := s.download.TargetPath From 15eb33859603b4b0d603310957d4b60943bed21a Mon Sep 17 00:00:00 2001 From: bugbuilder Date: Mon, 24 Jul 2017 00:30:55 -0400 Subject: [PATCH 007/220] Cleaning refactoring name errors x2 --- builder/vmware/iso/builder.go | 4 ++-- builder/vmware/iso/step_verify_cache.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/builder/vmware/iso/builder.go b/builder/vmware/iso/builder.go index 7d3d6074e..75c37f875 100644 --- a/builder/vmware/iso/builder.go +++ b/builder/vmware/iso/builder.go @@ -227,7 +227,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, remoteUpload: &stepRemoteUpload{ Key: "iso_path", - Message: "Uploading ISO to remoteUpload machine...", + Message: "Uploading ISO to remote machine...", }, } @@ -246,7 +246,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, &stepRemoteUpload{ Key: "floppy_path", - Message: "Uploading Floppy to remoteUpload machine...", + Message: "Uploading Floppy to remote machine...", }, stepVerifyCache.remoteUpload, &stepCreateDisk{}, diff --git a/builder/vmware/iso/step_verify_cache.go b/builder/vmware/iso/step_verify_cache.go index 7aefa128c..f6f7d8b0d 100644 --- a/builder/vmware/iso/step_verify_cache.go +++ b/builder/vmware/iso/step_verify_cache.go @@ -55,7 +55,7 @@ func (s *stepVerifyCache) Run(state multistep.StateBag) multistep.StepAction { ui.Message(remotePath) if esx5.verifyChecksum(s.download.ChecksumType, s.download.Checksum, remotePath) { - ui.Message("Remote cache verified, skipping download/upload step") + ui.Message("Remote cache verified, skipping download/upload steps") s.remoteUpload.Skip = true state.Put(s.download.ResultKey, remotePath) From be2afccb85b0d7ad020ef69bb6f6b5f10f1b5a6e Mon Sep 17 00:00:00 2001 From: bugbuilder Date: Fri, 10 Nov 2017 23:55:26 -0300 Subject: [PATCH 008/220] Revamped the process to verify remote cache. --- builder/vmware/iso/builder.go | 25 ++++---- builder/vmware/iso/step_remote_upload.go | 11 ++++ builder/vmware/iso/step_verify_cache.go | 72 ------------------------ 3 files changed, 21 insertions(+), 87 deletions(-) delete mode 100644 builder/vmware/iso/step_verify_cache.go diff --git a/builder/vmware/iso/builder.go b/builder/vmware/iso/builder.go index 73a6a1c04..5fa15317f 100644 --- a/builder/vmware/iso/builder.go +++ b/builder/vmware/iso/builder.go @@ -225,8 +225,12 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe state.Put("hook", hook) state.Put("ui", ui) - stepVerifyCache := &stepVerifyCache{ - download: &common.StepDownload{ + steps := []multistep.Step{ + &vmwcommon.StepPrepareTools{ + RemoteType: b.config.RemoteType, + ToolsUploadFlavor: b.config.ToolsUploadFlavor, + }, + &common.StepDownload{ Checksum: b.config.ISOChecksum, ChecksumType: b.config.ISOChecksumType, Description: "ISO", @@ -235,18 +239,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe TargetPath: b.config.TargetPath, Url: b.config.ISOUrls, }, - remoteUpload: &stepRemoteUpload{ - Key: "iso_path", - Message: "Uploading ISO to remote machine...", - }, - } - - steps := []multistep.Step{ - &vmwcommon.StepPrepareTools{ - RemoteType: b.config.RemoteType, - ToolsUploadFlavor: b.config.ToolsUploadFlavor, - }, - stepVerifyCache, &vmwcommon.StepOutputDir{ Force: b.config.PackerForce, }, @@ -258,7 +250,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Key: "floppy_path", Message: "Uploading Floppy to remote machine...", }, - stepVerifyCache.remoteUpload, + &stepRemoteUpload{ + Key: "iso_path", + Message: "Uploading ISO to remote machine...", + }, &stepCreateDisk{}, &stepCreateVMX{}, &vmwcommon.StepConfigureVMX{ diff --git a/builder/vmware/iso/step_remote_upload.go b/builder/vmware/iso/step_remote_upload.go index 691ebcb84..6aa963055 100644 --- a/builder/vmware/iso/step_remote_upload.go +++ b/builder/vmware/iso/step_remote_upload.go @@ -41,6 +41,17 @@ func (s *stepRemoteUpload) Run(state multistep.StateBag) multistep.StepAction { checksum := config.ISOChecksum checksumType := config.ISOChecksumType + if esx5, ok := remote.(*ESX5Driver); ok { + remotePath := esx5.cachePath(path) + + if esx5.verifyChecksum(checksumType, checksum, remotePath) { + ui.Say("Remote cache was verified skipping remote upload...") + state.Put(s.Key, remotePath) + return multistep.ActionContinue + } + + } + ui.Say(s.Message) log.Printf("Remote uploading: %s", path) newPath, err := remote.UploadISO(path, checksum, checksumType) diff --git a/builder/vmware/iso/step_verify_cache.go b/builder/vmware/iso/step_verify_cache.go deleted file mode 100644 index f6f7d8b0d..000000000 --- a/builder/vmware/iso/step_verify_cache.go +++ /dev/null @@ -1,72 +0,0 @@ -package iso - -import ( - "crypto/sha1" - "encoding/hex" - "fmt" - neturl "net/url" - - vmwcommon "github.com/hashicorp/packer/builder/vmware/common" - "github.com/hashicorp/packer/common" - "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" - "runtime" -) - -type stepVerifyCache struct { - download *common.StepDownload - remoteUpload *stepRemoteUpload -} - -func (s *stepVerifyCache) Run(state multistep.StateBag) multistep.StepAction { - cache := state.Get("cache").(packer.Cache) - driver := state.Get("driver").(vmwcommon.Driver) - ui := state.Get("ui").(packer.Ui) - - if esx5, ok := driver.(*ESX5Driver); ok { - ui.Say("Verifying remote cache") - - for _, url := range s.download.Url { - targetPath := s.download.TargetPath - - if u, err := neturl.Parse(url); err == nil { - if u.Scheme == "file" { - - if u.Path != "" { - targetPath = u.Path - } else if u.Opaque != "" { - targetPath = u.Opaque - } - - if runtime.GOOS == "windows" && len(targetPath) > 0 && targetPath[0] == '/' { - targetPath = targetPath[1:] - } - } - } - - if targetPath == "" { - hash := sha1.Sum([]byte(url)) - cacheKey := fmt.Sprintf("%s.%s", hex.EncodeToString(hash[:]), s.download.Extension) - targetPath = cache.Lock(cacheKey) - cache.Unlock(cacheKey) - } - - remotePath := esx5.cachePath(targetPath) - ui.Message(remotePath) - - if esx5.verifyChecksum(s.download.ChecksumType, s.download.Checksum, remotePath) { - ui.Message("Remote cache verified, skipping download/upload steps") - - s.remoteUpload.Skip = true - state.Put(s.download.ResultKey, remotePath) - return multistep.ActionContinue - } - - ui.Message("Remote cache couldn't be verified") - } - } - - return s.download.Run(state) -} - -func (s *stepVerifyCache) Cleanup(multistep.StateBag) {} From f7b45312f115b588395b2d0da8a3e4eb2988b7a3 Mon Sep 17 00:00:00 2001 From: bugbuilder Date: Fri, 10 Nov 2017 23:58:24 -0300 Subject: [PATCH 009/220] Removing skip attribute --- builder/vmware/iso/step_remote_upload.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/builder/vmware/iso/step_remote_upload.go b/builder/vmware/iso/step_remote_upload.go index 6aa963055..a9f6ecc80 100644 --- a/builder/vmware/iso/step_remote_upload.go +++ b/builder/vmware/iso/step_remote_upload.go @@ -14,19 +14,12 @@ import ( type stepRemoteUpload struct { Key string Message string - - // Set this to true for skip - Skip bool } func (s *stepRemoteUpload) Run(state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(vmwcommon.Driver) ui := state.Get("ui").(packer.Ui) - if s.Skip { - return multistep.ActionContinue - } - remote, ok := driver.(RemoteDriver) if !ok { return multistep.ActionContinue From 3192f5e0da7752d0ac6a3cb06f28202335d3e75a Mon Sep 17 00:00:00 2001 From: Matt Coleman Date: Wed, 2 May 2018 00:56:13 -0400 Subject: [PATCH 010/220] qemu builder: add the 'use_backing_file' setting for QCOW2 images --- builder/qemu/builder.go | 6 +++ builder/qemu/builder_test.go | 43 +++++++++++++++++++ builder/qemu/step_copy_disk.go | 2 +- builder/qemu/step_create_disk.go | 14 ++++-- website/source/docs/builders/qemu.html.md.erb | 11 ++++- 5 files changed, 70 insertions(+), 6 deletions(-) diff --git a/builder/qemu/builder.go b/builder/qemu/builder.go index d664dade9..fa2f1f9d9 100644 --- a/builder/qemu/builder.go +++ b/builder/qemu/builder.go @@ -99,6 +99,7 @@ type Config struct { Format string `mapstructure:"format"` Headless bool `mapstructure:"headless"` DiskImage bool `mapstructure:"disk_image"` + UseBackingFile bool `mapstructure:"use_backing_file"` MachineType string `mapstructure:"machine_type"` NetDevice string `mapstructure:"net_device"` OutputDir string `mapstructure:"output_directory"` @@ -255,6 +256,11 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { b.config.DiskCompression = false } + if b.config.UseBackingFile && !(b.config.DiskImage && b.config.Format == "qcow2") { + errs = packer.MultiErrorAppend( + errs, errors.New("use_backing_file can only be enabled for QCOW2 images and when disk_image is true")) + } + if _, ok := accels[b.config.Accelerator]; !ok { errs = packer.MultiErrorAppend( errs, errors.New("invalid accelerator, only 'kvm', 'tcg', 'xen', 'hax', 'hvf', or 'none' are allowed")) diff --git a/builder/qemu/builder_test.go b/builder/qemu/builder_test.go index 4ddfa1560..d0d403666 100644 --- a/builder/qemu/builder_test.go +++ b/builder/qemu/builder_test.go @@ -224,6 +224,49 @@ func TestBuilderPrepare_Format(t *testing.T) { } } +func TestBuilderPrepare_UseBackingFile(t *testing.T) { + var b Builder + config := testConfig() + + config["use_backing_file"] = true + + // Bad: iso_url is not a disk_image + config["disk_image"] = false + config["format"] = "qcow2" + b = Builder{} + warns, err := b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err == nil { + t.Fatal("should have error") + } + + // Bad: format is not 'qcow2' + config["disk_image"] = true + config["format"] = "raw" + b = Builder{} + warns, err = b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err == nil { + t.Fatal("should have error") + } + + // Good: iso_url is a disk image and format is 'qcow2' + config["disk_image"] = true + config["format"] = "qcow2" + b = Builder{} + warns, err = b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } +} + func TestBuilderPrepare_FloppyFiles(t *testing.T) { var b Builder config := testConfig() diff --git a/builder/qemu/step_copy_disk.go b/builder/qemu/step_copy_disk.go index 51ca47a1d..3f1c33ffb 100644 --- a/builder/qemu/step_copy_disk.go +++ b/builder/qemu/step_copy_disk.go @@ -28,7 +28,7 @@ func (s *stepCopyDisk) Run(_ context.Context, state multistep.StateBag) multiste path, } - if config.DiskImage == false { + if !config.DiskImage || config.UseBackingFile { return multistep.ActionContinue } diff --git a/builder/qemu/step_create_disk.go b/builder/qemu/step_create_disk.go index 4472903f1..0a18a3c18 100644 --- a/builder/qemu/step_create_disk.go +++ b/builder/qemu/step_create_disk.go @@ -23,11 +23,19 @@ func (s *stepCreateDisk) Run(_ context.Context, state multistep.StateBag) multis command := []string{ "create", "-f", config.Format, - path, - fmt.Sprintf("%vM", config.DiskSize), } - if config.DiskImage == true { + if config.UseBackingFile { + isoPath := state.Get("iso_path").(string) + command = append(command, "-b", isoPath) + } + + command = append(command, + path, + fmt.Sprintf("%vM", config.DiskSize), + ) + + if config.DiskImage && !config.UseBackingFile { return multistep.ActionContinue } diff --git a/website/source/docs/builders/qemu.html.md.erb b/website/source/docs/builders/qemu.html.md.erb index 5d6de7e45..df7b08af2 100644 --- a/website/source/docs/builders/qemu.html.md.erb +++ b/website/source/docs/builders/qemu.html.md.erb @@ -152,8 +152,9 @@ Linux server and have not enabled X11 forwarding (`ssh -X`). - `disk_image` (boolean) - Packer defaults to building from an ISO file, this parameter controls whether the ISO URL supplied is actually a bootable - QEMU image. When this value is set to true, the machine will clone the - source, resize it according to `disk_size` and boot the image. + QEMU image. When this value is set to `true`, the machine will either clone + the source or use it as a backing file (if `use_backing_file` is `true`); + then, it will resize the image according to `disk_size` and boot it. - `disk_interface` (string) - The interface to use for the disk. Allowed values include any of `ide`, `scsi`, `virtio` or `virtio-scsi`^\*. Note @@ -319,6 +320,12 @@ will bind to their own SSH port as determined by each process. This will also work with WinRM, just change the port forward in `qemuargs` to map to WinRM's default port of `5985` or whatever value you have the service set to listen on. +- `use_backing_file` (boolean) - Only applicable when `disk_image` is `true` + and `format` is `qcow2`, set this option to `true` to create a new QCOW2 + file that uses the file located at `iso_url` as a backing file. The new file + will only contain blocks that have changed compared to the backing file, so + enabling this option can significantly reduce disk usage. + - `use_default_display` (boolean) - If true, do not pass a `-display` option to qemu, allowing it to choose the default. This may be needed when running under macOS, and getting errors about `sdl` not being available. From f793d219b2d081325454e8a0ddf887728d117cb9 Mon Sep 17 00:00:00 2001 From: David Tesar Date: Wed, 16 May 2018 15:29:54 -0400 Subject: [PATCH 011/220] Only show Windows Sysprep code with validation The first example completes successfully, but will not let you know that the image is not actually able to be deployed to a VM. --- website/source/docs/builders/azure.html.md | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/website/source/docs/builders/azure.html.md b/website/source/docs/builders/azure.html.md index 976268232..6af8986cd 100644 --- a/website/source/docs/builders/azure.html.md +++ b/website/source/docs/builders/azure.html.md @@ -260,23 +260,7 @@ Please refer to the Azure [examples](https://github.com/hashicorp/packer/tree/ma ### Windows -The following provisioner snippet shows how to sysprep a Windows VM. Deprovision should be the last operation executed by a build. - -``` json -{ - "provisioners": [ - { - "type": "powershell", - "inline": [ - "if( Test-Path $Env:SystemRoot\\windows\\system32\\Sysprep\\unattend.xml ){ rm $Env:SystemRoot\\windows\\system32\\Sysprep\\unattend.xml -Force}", - "& $Env:SystemRoot\\System32\\Sysprep\\Sysprep.exe /oobe /generalize /shutdown /quiet" - ] - } - ] -} -``` - -In some circumstances the above isn't enough to reliably know that the sysprep is actually finished generalizing the image, the code below will wait for sysprep to write the image status in the registry and will exit after that. The possible states, in case you want to wait for another state, [are documented here](https://technet.microsoft.com/en-us/library/hh824815.aspx) +The following provisioner snippet shows how to sysprep a Windows VM. The code below will wait for sysprep to write the image status in the registry and will exit after that. The possible states, in case you want to wait for another state, [are documented here](https://technet.microsoft.com/en-us/library/hh824815.aspx) ``` json { @@ -290,8 +274,6 @@ In some circumstances the above isn't enough to reliably know that the sysprep i } ] } - - ``` ### Linux From f81492ef9d8f563ba6257834fe4317b9b99b3d88 Mon Sep 17 00:00:00 2001 From: David Tesar Date: Wed, 16 May 2018 15:35:14 -0400 Subject: [PATCH 012/220] Add back last step comment --- website/source/docs/builders/azure.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/builders/azure.html.md b/website/source/docs/builders/azure.html.md index 6af8986cd..e3a4100d1 100644 --- a/website/source/docs/builders/azure.html.md +++ b/website/source/docs/builders/azure.html.md @@ -260,7 +260,7 @@ Please refer to the Azure [examples](https://github.com/hashicorp/packer/tree/ma ### Windows -The following provisioner snippet shows how to sysprep a Windows VM. The code below will wait for sysprep to write the image status in the registry and will exit after that. The possible states, in case you want to wait for another state, [are documented here](https://technet.microsoft.com/en-us/library/hh824815.aspx) +The following provisioner snippet shows how to sysprep a Windows VM. Deprovision should be the last operation executed by a build. The code below will wait for sysprep to write the image status in the registry and will exit after that. The possible states, in case you want to wait for another state, [are documented here](https://technet.microsoft.com/en-us/library/hh824815.aspx) ``` json { From c925a02f82473415b456651e35c1c47c8d13bafe Mon Sep 17 00:00:00 2001 From: Chris Lundquist Date: Wed, 16 May 2018 21:40:22 +0000 Subject: [PATCH 013/220] don't chown to close the security issue --- builder/lxc/command.go | 26 +++++++++++++++++++++++++ builder/lxc/step_export.go | 33 ++------------------------------ builder/lxc/step_lxc_create.go | 35 +++++----------------------------- 3 files changed, 33 insertions(+), 61 deletions(-) diff --git a/builder/lxc/command.go b/builder/lxc/command.go index af81cff83..4afa56844 100644 --- a/builder/lxc/command.go +++ b/builder/lxc/command.go @@ -1,7 +1,11 @@ package lxc import ( + "bytes" + "fmt" + "log" "os/exec" + "strings" ) // CommandWrapper is a type that given a command, will possibly modify that @@ -13,3 +17,25 @@ type CommandWrapper func(string) (string, error) func ShellCommand(command string) *exec.Cmd { return exec.Command("/bin/sh", "-c", command) } + +func RunCommand(args ...string) error { + var stdout, stderr bytes.Buffer + + log.Printf("Executing args: %#v", args) + cmd := exec.Command(args[0], args[1:]...) + cmd.Stdout = &stdout + cmd.Stderr = &stderr + err := cmd.Run() + + stdoutString := strings.TrimSpace(stdout.String()) + stderrString := strings.TrimSpace(stderr.String()) + + if _, ok := err.(*exec.ExitError); ok { + err = fmt.Errorf("Command error: %s", stderrString) + } + + log.Printf("stdout: %s", stdoutString) + log.Printf("stderr: %s", stderrString) + + return err +} diff --git a/builder/lxc/step_export.go b/builder/lxc/step_export.go index f01b30074..ddfa85048 100644 --- a/builder/lxc/step_export.go +++ b/builder/lxc/step_export.go @@ -1,15 +1,11 @@ package lxc import ( - "bytes" "context" "fmt" "io" - "log" "os" - "os/exec" "path/filepath" - "strings" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" @@ -47,7 +43,7 @@ func (s *stepExport) Run(_ context.Context, state multistep.StateBag) multistep. _, err = io.Copy(configFile, originalConfigFile) - commands := make([][]string, 4) + commands := make([][]string, 3) commands[0] = []string{ "lxc-stop", "--name", name, } @@ -57,13 +53,10 @@ func (s *stepExport) Run(_ context.Context, state multistep.StateBag) multistep. commands[2] = []string{ "chmod", "+x", configFilePath, } - commands[3] = []string{ - "sh", "-c", "chown $USER:`id -gn` " + filepath.Join(config.OutputDir, "*"), - } ui.Say("Exporting container...") for _, command := range commands { - err := s.SudoCommand(command...) + err := RunCommand(command...) if err != nil { err := fmt.Errorf("Error exporting container: %s", err) state.Put("error", err) @@ -76,25 +69,3 @@ func (s *stepExport) Run(_ context.Context, state multistep.StateBag) multistep. } func (s *stepExport) Cleanup(state multistep.StateBag) {} - -func (s *stepExport) SudoCommand(args ...string) error { - var stdout, stderr bytes.Buffer - - log.Printf("Executing sudo command: %#v", args) - cmd := exec.Command("sudo", args...) - cmd.Stdout = &stdout - cmd.Stderr = &stderr - err := cmd.Run() - - stdoutString := strings.TrimSpace(stdout.String()) - stderrString := strings.TrimSpace(stderr.String()) - - if _, ok := err.(*exec.ExitError); ok { - err = fmt.Errorf("Sudo command error: %s", stderrString) - } - - log.Printf("stdout: %s", stdoutString) - log.Printf("stderr: %s", stderrString) - - return err -} diff --git a/builder/lxc/step_lxc_create.go b/builder/lxc/step_lxc_create.go index 98dce3a7c..0c89ce190 100644 --- a/builder/lxc/step_lxc_create.go +++ b/builder/lxc/step_lxc_create.go @@ -1,13 +1,9 @@ package lxc import ( - "bytes" "context" "fmt" - "log" - "os/exec" "path/filepath" - "strings" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" @@ -30,7 +26,9 @@ func (s *stepLxcCreate) Run(_ context.Context, state multistep.StateBag) multist } commands := make([][]string, 3) - commands[0] = append(config.EnvVars, "lxc-create") + commands[0] = append(commands[0], "env") + commands[0] = append(commands[0], config.EnvVars...) + commands[0] = append(commands[0], "lxc-create") commands[0] = append(commands[0], config.CreateOptions...) commands[0] = append(commands[0], []string{"-n", name, "-t", config.Name, "--"}...) commands[0] = append(commands[0], config.Parameters...) @@ -42,8 +40,7 @@ func (s *stepLxcCreate) Run(_ context.Context, state multistep.StateBag) multist ui.Say("Creating container...") for _, command := range commands { - log.Printf("Executing sudo command: %#v", command) - err := s.SudoCommand(command...) + err := RunCommand(command...) if err != nil { err := fmt.Errorf("Error creating container: %s", err) state.Put("error", err) @@ -66,29 +63,7 @@ func (s *stepLxcCreate) Cleanup(state multistep.StateBag) { } ui.Say("Unregistering and deleting virtual machine...") - if err := s.SudoCommand(command...); err != nil { + if err := RunCommand(command...); err != nil { ui.Error(fmt.Sprintf("Error deleting virtual machine: %s", err)) } } - -func (s *stepLxcCreate) SudoCommand(args ...string) error { - var stdout, stderr bytes.Buffer - - log.Printf("Executing sudo command: %#v", args) - cmd := exec.Command("sudo", args...) - cmd.Stdout = &stdout - cmd.Stderr = &stderr - err := cmd.Run() - - stdoutString := strings.TrimSpace(stdout.String()) - stderrString := strings.TrimSpace(stderr.String()) - - if _, ok := err.(*exec.ExitError); ok { - err = fmt.Errorf("Sudo command error: %s", stderrString) - } - - log.Printf("stdout: %s", stdoutString) - log.Printf("stderr: %s", stderrString) - - return err -} From d142055ab191ae5da063ad1b0cc6687a2ba0cc10 Mon Sep 17 00:00:00 2001 From: James Nugent Date: Tue, 22 May 2018 11:16:25 +0400 Subject: [PATCH 014/220] build: Remove old versions of Go on Travis CI There is no real value in continuing to build against versions of Go which are not the latest (1.10.2 right now). This can easily be expressed in the `.travis.yml` file as `1.x`, to mean the latest version in the Go 1 series, which is (presumably) what is being used for releases. Keeping older versions around is causing spurious CI failures, and increases the cycle time to feedback for pull requests: see hashicorp/packer#6265 for an example of this. --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2bac499b3..51d686c0a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,11 +6,8 @@ sudo: false language: go go: - - 1.8.x - - 1.9.x - 1.x - install: - make deps From 9b30c9aed0fc7aaed71b5197ce9422b8b8e3d18f Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago Date: Mon, 11 Jun 2018 17:53:54 -0500 Subject: [PATCH 015/220] Allow StepAttachIso in the VirtualBox builder to resolve symbolic links when processing the IsoPath. This just closes out a really old issue (#3437) by using `filepath.EvalSymLinks` to resolve the symbolic link that the user specifies for the IsoPath. --- builder/virtualbox/iso/step_attach_iso.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/builder/virtualbox/iso/step_attach_iso.go b/builder/virtualbox/iso/step_attach_iso.go index 619d61afd..928a76761 100644 --- a/builder/virtualbox/iso/step_attach_iso.go +++ b/builder/virtualbox/iso/step_attach_iso.go @@ -34,6 +34,16 @@ func (s *stepAttachISO) Run(_ context.Context, state multistep.StateBag) multist device = "0" } + // If it's a symlink, resolve it to it's target. + resolvedIsoPath, err := filepath.EvalSymlinks(isoPath) + if err != nil { + err := fmt.Errorf("Error resolving symlink for ISO: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + isoPath = resolvedIsoPath + // Attach the disk to the controller command := []string{ "storageattach", vmName, From 963932699ec96335d54cf26eedb0bb723863958e Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago Date: Mon, 11 Jun 2018 18:02:52 -0500 Subject: [PATCH 016/220] Remove a stray tab that resulted from poor usage of Github's file editor. That's what I get for not making a proper branch... --- builder/virtualbox/iso/step_attach_iso.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/virtualbox/iso/step_attach_iso.go b/builder/virtualbox/iso/step_attach_iso.go index 928a76761..94bdc7a2f 100644 --- a/builder/virtualbox/iso/step_attach_iso.go +++ b/builder/virtualbox/iso/step_attach_iso.go @@ -43,7 +43,7 @@ func (s *stepAttachISO) Run(_ context.Context, state multistep.StateBag) multist return multistep.ActionHalt } isoPath = resolvedIsoPath - + // Attach the disk to the controller command := []string{ "storageattach", vmName, From 47a3315fdef09e1ab0b5a4f577c9e1c37cf107f4 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago Date: Mon, 11 Jun 2018 18:07:43 -0500 Subject: [PATCH 017/220] Added a missing reference to the "path/filepath" module. Lol. Dammit. --- builder/virtualbox/iso/step_attach_iso.go | 1 + 1 file changed, 1 insertion(+) diff --git a/builder/virtualbox/iso/step_attach_iso.go b/builder/virtualbox/iso/step_attach_iso.go index 94bdc7a2f..624696482 100644 --- a/builder/virtualbox/iso/step_attach_iso.go +++ b/builder/virtualbox/iso/step_attach_iso.go @@ -3,6 +3,7 @@ package iso import ( "context" "fmt" + "path/filepath" vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" "github.com/hashicorp/packer/helper/multistep" From d05a601d00b9dc3301562d4c1f60c4362d034b07 Mon Sep 17 00:00:00 2001 From: Conrad Jones Date: Sun, 17 Jun 2018 01:38:42 +0100 Subject: [PATCH 018/220] Add support to vmware-vmx builder for linked clones. --- builder/qemu/step_run.go | 4 ++++ builder/vmware/common/driver.go | 2 +- builder/vmware/common/driver_fusion5.go | 2 +- builder/vmware/common/driver_fusion6.go | 2 +- builder/vmware/common/driver_mock.go | 4 +++- builder/vmware/common/driver_player5.go | 2 +- builder/vmware/common/driver_player6.go | 2 +- builder/vmware/common/driver_workstation10.go | 12 ++++++++++-- builder/vmware/common/driver_workstation9.go | 2 +- builder/vmware/iso/driver_esx5.go | 2 +- builder/vmware/vmx/builder.go | 1 + builder/vmware/vmx/config.go | 1 + builder/vmware/vmx/step_clone_vmx.go | 3 ++- website/source/docs/builders/vmware-vmx.html.md.erb | 3 +++ 14 files changed, 31 insertions(+), 11 deletions(-) diff --git a/builder/qemu/step_run.go b/builder/qemu/step_run.go index c524d5514..9769e7cd7 100644 --- a/builder/qemu/step_run.go +++ b/builder/qemu/step_run.go @@ -41,6 +41,7 @@ func (s *stepRun) Run(_ context.Context, state multistep.StateBag) multistep.Ste return multistep.ActionHalt } + ui.Message(fmt.Sprintf("command:=%s", command)) if err := driver.Qemu(command...); err != nil { err := fmt.Errorf("Error launching VM: %s", err) ui.Error(err.Error()) @@ -104,6 +105,9 @@ func getCommandArgs(bootDrive string, state multistep.StateBag) ([]string, error } else { driveArgs = append(driveArgs, fmt.Sprintf("file=%s,if=%s,cache=%s,format=%s", imgPath, config.DiskInterface, config.DiskCache, config.Format)) } + + ui.Message(fmt.Sprintf("config.NetDevice:=%s", config.NetDevice)) + deviceArgs = append(deviceArgs, fmt.Sprintf("%s,netdev=user.0", config.NetDevice)) if config.Headless == true { diff --git a/builder/vmware/common/driver.go b/builder/vmware/common/driver.go index 8ceb393ff..98b75faf5 100644 --- a/builder/vmware/common/driver.go +++ b/builder/vmware/common/driver.go @@ -23,7 +23,7 @@ type Driver interface { // Clone clones the VMX and the disk to the destination path. The // destination is a path to the VMX file. The disk will be copied // to that same directory. - Clone(dst string, src string) error + Clone(dst string, src string, cloneType bool) error // CompactDisk compacts a virtual disk. CompactDisk(string) error diff --git a/builder/vmware/common/driver_fusion5.go b/builder/vmware/common/driver_fusion5.go index 63211f99a..2599604b9 100644 --- a/builder/vmware/common/driver_fusion5.go +++ b/builder/vmware/common/driver_fusion5.go @@ -24,7 +24,7 @@ type Fusion5Driver struct { SSHConfig *SSHConfig } -func (d *Fusion5Driver) Clone(dst, src string) error { +func (d *Fusion5Driver) Clone(dst, src string, linked bool) error { return errors.New("Cloning is not supported with Fusion 5. Please use Fusion 6+.") } diff --git a/builder/vmware/common/driver_fusion6.go b/builder/vmware/common/driver_fusion6.go index 002d4227a..9e84ce3db 100644 --- a/builder/vmware/common/driver_fusion6.go +++ b/builder/vmware/common/driver_fusion6.go @@ -18,7 +18,7 @@ type Fusion6Driver struct { Fusion5Driver } -func (d *Fusion6Driver) Clone(dst, src string) error { +func (d *Fusion6Driver) Clone(dst, src string, linked bool) error { cmd := exec.Command(d.vmrunPath(), "-T", "fusion", "clone", src, dst, diff --git a/builder/vmware/common/driver_mock.go b/builder/vmware/common/driver_mock.go index 8c540913e..019b688fc 100644 --- a/builder/vmware/common/driver_mock.go +++ b/builder/vmware/common/driver_mock.go @@ -13,6 +13,7 @@ type DriverMock struct { CloneCalled bool CloneDst string CloneSrc string + Linked bool CloneErr error CompactDiskCalled bool @@ -107,10 +108,11 @@ func (m NetworkMapperMock) DeviceIntoName(device string) (string, error) { return "", nil } -func (d *DriverMock) Clone(dst string, src string) error { +func (d *DriverMock) Clone(dst string, src string, linked bool) error { d.CloneCalled = true d.CloneDst = dst d.CloneSrc = src + d.Linked = linked return d.CloneErr } diff --git a/builder/vmware/common/driver_player5.go b/builder/vmware/common/driver_player5.go index 5f492e6be..ccb1de2c2 100644 --- a/builder/vmware/common/driver_player5.go +++ b/builder/vmware/common/driver_player5.go @@ -25,7 +25,7 @@ type Player5Driver struct { SSHConfig *SSHConfig } -func (d *Player5Driver) Clone(dst, src string) error { +func (d *Player5Driver) Clone(dst, src string, linked bool) error { return errors.New("Cloning is not supported with VMWare Player version 5. Please use VMWare Player version 6, or greater.") } diff --git a/builder/vmware/common/driver_player6.go b/builder/vmware/common/driver_player6.go index 1ccb84b85..f0d57e51d 100644 --- a/builder/vmware/common/driver_player6.go +++ b/builder/vmware/common/driver_player6.go @@ -13,7 +13,7 @@ type Player6Driver struct { Player5Driver } -func (d *Player6Driver) Clone(dst, src string) error { +func (d *Player6Driver) Clone(dst, src string, linked bool) error { // TODO(rasa) check if running player+, not just player cmd := exec.Command(d.Player5Driver.VmrunPath, diff --git a/builder/vmware/common/driver_workstation10.go b/builder/vmware/common/driver_workstation10.go index 471fce37d..070df50c2 100644 --- a/builder/vmware/common/driver_workstation10.go +++ b/builder/vmware/common/driver_workstation10.go @@ -13,11 +13,19 @@ type Workstation10Driver struct { Workstation9Driver } -func (d *Workstation10Driver) Clone(dst, src string) error { +func (d *Workstation10Driver) Clone(dst, src string, linked bool) error { + + var cloneType string + if linked { + cloneType = "linked" + } else { + cloneType = "full" + } + cmd := exec.Command(d.Workstation9Driver.VmrunPath, "-T", "ws", "clone", src, dst, - "full") + cloneType) if _, _, err := runAndLog(cmd); err != nil { return err diff --git a/builder/vmware/common/driver_workstation9.go b/builder/vmware/common/driver_workstation9.go index 8186ac83f..50bf77f34 100644 --- a/builder/vmware/common/driver_workstation9.go +++ b/builder/vmware/common/driver_workstation9.go @@ -24,7 +24,7 @@ type Workstation9Driver struct { SSHConfig *SSHConfig } -func (d *Workstation9Driver) Clone(dst, src string) error { +func (d *Workstation9Driver) Clone(dst, src string, linked bool) error { return errors.New("Cloning is not supported with VMware WS version 9. Please use VMware WS version 10, or greater.") } diff --git a/builder/vmware/iso/driver_esx5.go b/builder/vmware/iso/driver_esx5.go index c31d8da95..b3eb8c078 100644 --- a/builder/vmware/iso/driver_esx5.go +++ b/builder/vmware/iso/driver_esx5.go @@ -41,7 +41,7 @@ type ESX5Driver struct { vmId string } -func (d *ESX5Driver) Clone(dst, src string) error { +func (d *ESX5Driver) Clone(dst, src string, linked bool) error { return errors.New("Cloning is not supported with the ESX driver.") } diff --git a/builder/vmware/vmx/builder.go b/builder/vmware/vmx/builder.go index 130c533d7..dbb74b7a1 100644 --- a/builder/vmware/vmx/builder.go +++ b/builder/vmware/vmx/builder.go @@ -69,6 +69,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe OutputDir: b.config.OutputDir, Path: b.config.SourcePath, VMName: b.config.VMName, + Linked: b.config.Linked, }, &vmwcommon.StepConfigureVMX{ CustomData: b.config.VMXData, diff --git a/builder/vmware/vmx/config.go b/builder/vmware/vmx/config.go index 0fb9993aa..1e32ac7b7 100644 --- a/builder/vmware/vmx/config.go +++ b/builder/vmware/vmx/config.go @@ -26,6 +26,7 @@ type Config struct { vmwcommon.ToolsConfig `mapstructure:",squash"` vmwcommon.VMXConfig `mapstructure:",squash"` + Linked bool `mapstructure:"linked"` RemoteType string `mapstructure:"remote_type"` SkipCompaction bool `mapstructure:"skip_compaction"` SourcePath string `mapstructure:"source_path"` diff --git a/builder/vmware/vmx/step_clone_vmx.go b/builder/vmware/vmx/step_clone_vmx.go index 9eebc0096..55c24d2a7 100644 --- a/builder/vmware/vmx/step_clone_vmx.go +++ b/builder/vmware/vmx/step_clone_vmx.go @@ -17,6 +17,7 @@ type StepCloneVMX struct { OutputDir string Path string VMName string + Linked bool } type vmxAdapter struct { @@ -64,7 +65,7 @@ func (s *StepCloneVMX) Run(_ context.Context, state multistep.StateBag) multiste ui.Say("Cloning source VM...") log.Printf("Cloning from: %s", s.Path) log.Printf("Cloning to: %s", vmxPath) - if err := driver.Clone(vmxPath, s.Path); err != nil { + if err := driver.Clone(vmxPath, s.Path, s.Linked); err != nil { state.Put("error", err) return multistep.ActionHalt } diff --git a/website/source/docs/builders/vmware-vmx.html.md.erb b/website/source/docs/builders/vmware-vmx.html.md.erb index 90880cb54..03c144de9 100644 --- a/website/source/docs/builders/vmware-vmx.html.md.erb +++ b/website/source/docs/builders/vmware-vmx.html.md.erb @@ -137,6 +137,9 @@ builder. doesn't shut down in this time, it is an error. By default, the timeout is `5m` or five minutes. +- `linked` (boolean) - Virtual machine is created a linked clone. + Defaults to `false`. + - `skip_compaction` (boolean) - VMware-created disks are defragmented and compacted at the end of the build process using `vmware-vdiskmanager`. In certain rare cases, this might actually end up making the resulting disks From abfb9f24d6cccb62087b4fe5dd9d9f61284fdbd4 Mon Sep 17 00:00:00 2001 From: Conrad Jones Date: Sun, 17 Jun 2018 01:45:26 +0100 Subject: [PATCH 019/220] revert accidental debugging change --- builder/qemu/step_run.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/builder/qemu/step_run.go b/builder/qemu/step_run.go index 9769e7cd7..c524d5514 100644 --- a/builder/qemu/step_run.go +++ b/builder/qemu/step_run.go @@ -41,7 +41,6 @@ func (s *stepRun) Run(_ context.Context, state multistep.StateBag) multistep.Ste return multistep.ActionHalt } - ui.Message(fmt.Sprintf("command:=%s", command)) if err := driver.Qemu(command...); err != nil { err := fmt.Errorf("Error launching VM: %s", err) ui.Error(err.Error()) @@ -105,9 +104,6 @@ func getCommandArgs(bootDrive string, state multistep.StateBag) ([]string, error } else { driveArgs = append(driveArgs, fmt.Sprintf("file=%s,if=%s,cache=%s,format=%s", imgPath, config.DiskInterface, config.DiskCache, config.Format)) } - - ui.Message(fmt.Sprintf("config.NetDevice:=%s", config.NetDevice)) - deviceArgs = append(deviceArgs, fmt.Sprintf("%s,netdev=user.0", config.NetDevice)) if config.Headless == true { From ec8747a04242d60349e74a8b98784342ad856ae4 Mon Sep 17 00:00:00 2001 From: Alexander Georgievskiy Date: Fri, 22 Jun 2018 00:45:20 +0300 Subject: [PATCH 020/220] They finally added https on download.virtualbox.org Because downloading SHA256SUMS via http is a fun joke --- builder/virtualbox/common/step_download_guest_additions.go | 4 ++-- .../guides/packer-on-cicd/build-virtualbox-image.html.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/builder/virtualbox/common/step_download_guest_additions.go b/builder/virtualbox/common/step_download_guest_additions.go index 706d5f466..da413e994 100644 --- a/builder/virtualbox/common/step_download_guest_additions.go +++ b/builder/virtualbox/common/step_download_guest_additions.go @@ -94,7 +94,7 @@ func (s *StepDownloadGuestAdditions) Run(ctx context.Context, state multistep.St } else { ui.Error(err.Error()) url = fmt.Sprintf( - "http://download.virtualbox.org/virtualbox/%s/%s", + "https://download.virtualbox.org/virtualbox/%s/%s", version, additionsName) } @@ -150,7 +150,7 @@ func (s *StepDownloadGuestAdditions) downloadAdditionsSHA256(ctx context.Context // First things first, we get the list of checksums for the files available // for this version. checksumsUrl := fmt.Sprintf( - "http://download.virtualbox.org/virtualbox/%s/SHA256SUMS", + "https://download.virtualbox.org/virtualbox/%s/SHA256SUMS", additionsVersion) checksumsFile, err := ioutil.TempFile("", "packer") diff --git a/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md b/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md index 33582a910..479ab8614 100644 --- a/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md +++ b/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md @@ -68,7 +68,7 @@ apt-get install -y zip linux-headers-generic linux-headers-4.13.0-16-generic bui **Install VirtualBox** ``` -curl -OL "http://download.virtualbox.org/virtualbox/5.2.2/virtualbox-5.2_5.2.2-119230~Ubuntu~xenial_amd64.deb" +curl -OL "https://download.virtualbox.org/virtualbox/5.2.2/virtualbox-5.2_5.2.2-119230~Ubuntu~xenial_amd64.deb" dpkg -i virtualbox-5.2_5.2.2-119230~Ubuntu~xenial_amd64.deb ``` From f79381c3d59679f2adc28133bf71484146d899c3 Mon Sep 17 00:00:00 2001 From: Matthew Hooker Date: Fri, 22 Jun 2018 11:04:19 -0700 Subject: [PATCH 021/220] update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c37764f7..49cf377a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,8 @@ * provisoner/shell-local: New options have been added to create feature parity with the shell-local post-processor. This feature now works on Windows hosts. [GH-5956] +* builder/virtualbox: Use HTTPS to download guest editions, now that it's + available. [GH-6406] ## 1.2.3 (April 25, 2018) From 4a7953f93a6c135f5c990c0a0deed62a18c336d0 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Fri, 22 Jun 2018 13:49:39 -0700 Subject: [PATCH 022/220] found a config validation bug where packer crashes instead of throwing a validation error if a windows-style path is provided to a provisioner on linux --- common/shell-local/config.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/common/shell-local/config.go b/common/shell-local/config.go index 82a41a192..ba2508120 100644 --- a/common/shell-local/config.go +++ b/common/shell-local/config.go @@ -215,6 +215,13 @@ func ConvertToLinuxPath(winAbsPath string) (string, error) { // get absolute path of script, and morph it into the bash path winAbsPath = strings.Replace(winAbsPath, "\\", "/", -1) splitPath := strings.SplitN(winAbsPath, ":/", 2) - winBashPath := fmt.Sprintf("/mnt/%s/%s", strings.ToLower(splitPath[0]), splitPath[1]) - return winBashPath, nil + if len(splitPath) == 2 { + winBashPath := fmt.Sprintf("/mnt/%s/%s", strings.ToLower(splitPath[0]), splitPath[1]) + return winBashPath, nil + } else { + err := fmt.Errorf("There was an error splitting your absolute path; expected "+ + "to find a drive following the format ':/' but did not: absolute "+ + "path: %s", winAbsPath) + return "", err + } } From 896ceee9021bc2259232dfa828ee91a65c39234f Mon Sep 17 00:00:00 2001 From: Fotios Lindiakos <30440247+thefotios-enigma@users.noreply.github.com> Date: Fri, 22 Jun 2018 18:55:50 -0400 Subject: [PATCH 023/220] Update list of required IAM permissions The `ec2:DescribeSpotPriceHistory` is required when the `spot_price` parameter is set to `auto`. --- website/source/docs/builders/amazon.html.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/website/source/docs/builders/amazon.html.md b/website/source/docs/builders/amazon.html.md index d54a28cef..3b1a177a9 100644 --- a/website/source/docs/builders/amazon.html.md +++ b/website/source/docs/builders/amazon.html.md @@ -184,7 +184,13 @@ Note that if you'd like to create a spot instance, you must also add: ec2:RequestSpotInstances, ec2:CancelSpotInstanceRequests, ec2:DescribeSpotInstanceRequests -``` +``` + +If you have the `spot_price` parameter set to `auto`, you must also add: + +``` json +ec2:DescribeSpotPriceHistory +``` ## Troubleshooting From 591bfe3dfa1527e90d6e29aa214e67a0e282d905 Mon Sep 17 00:00:00 2001 From: Bob Brumfield Date: Fri, 22 Jun 2018 18:09:27 -0700 Subject: [PATCH 024/220] Continue searching for leases even if one of the files cannot be read. --- builder/vmware/common/driver.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/builder/vmware/common/driver.go b/builder/vmware/common/driver.go index 8ceb393ff..553d307ba 100644 --- a/builder/vmware/common/driver.go +++ b/builder/vmware/common/driver.go @@ -358,7 +358,8 @@ func (d *VmwareDriver) GuestIP(state multistep.StateBag) (string, error) { // open up the lease and read its contents fh, err := os.Open(dhcpLeasesPath) if err != nil { - return "", err + log.Printf("Unable to open lease path, skipping: %s", dhcpLeasesPath) + continue } defer fh.Close() From f511c706c9af478b91ee0df8ad105a76776144c7 Mon Sep 17 00:00:00 2001 From: willmao Date: Sat, 23 Jun 2018 16:34:45 +0800 Subject: [PATCH 025/220] fix alicloud builder eip allocating issue --- builder/alicloud/ecs/builder.go | 1 + builder/alicloud/ecs/step_config_eip.go | 2 ++ 2 files changed, 3 insertions(+) diff --git a/builder/alicloud/ecs/builder.go b/builder/alicloud/ecs/builder.go index 892910c3d..99d759dc2 100644 --- a/builder/alicloud/ecs/builder.go +++ b/builder/alicloud/ecs/builder.go @@ -140,6 +140,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe AssociatePublicIpAddress: b.config.AssociatePublicIpAddress, RegionId: b.config.AlicloudRegion, InternetChargeType: b.config.InternetChargeType, + InternetMaxBandwidthOut: b.config.InternetMaxBandwidthOut, }) } else { steps = append(steps, &stepConfigAlicloudPublicIP{ diff --git a/builder/alicloud/ecs/step_config_eip.go b/builder/alicloud/ecs/step_config_eip.go index 397d8fd0a..f747068f2 100644 --- a/builder/alicloud/ecs/step_config_eip.go +++ b/builder/alicloud/ecs/step_config_eip.go @@ -14,6 +14,7 @@ type stepConfigAlicloudEIP struct { AssociatePublicIpAddress bool RegionId string InternetChargeType string + InternetMaxBandwidthOut int allocatedId string } @@ -24,6 +25,7 @@ func (s *stepConfigAlicloudEIP) Run(_ context.Context, state multistep.StateBag) ui.Say("Allocating eip") ipaddress, allocateId, err := client.AllocateEipAddress(&ecs.AllocateEipAddressArgs{ RegionId: common.Region(s.RegionId), InternetChargeType: common.InternetChargeType(s.InternetChargeType), + Bandwidth: s.InternetMaxBandwidthOut, }) if err != nil { state.Put("error", err) From b45d8c49c5b707b48dae77a6c72e1b803879a955 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolae=20Vl=C4=83descu?= Date: Sat, 23 Jun 2018 16:45:15 +0300 Subject: [PATCH 026/220] Fix typo --- website/source/docs/provisioners/shell-local.html.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/source/docs/provisioners/shell-local.html.md b/website/source/docs/provisioners/shell-local.html.md index 6a04272ad..d64e19fac 100644 --- a/website/source/docs/provisioners/shell-local.html.md +++ b/website/source/docs/provisioners/shell-local.html.md @@ -1,7 +1,7 @@ --- description: | shell-local will run a shell script of your choosing on the machine where Packer - is being run - in other words, it shell-local will run the shell script on your + is being run - in other words, shell-local will run the shell script on your build server, or your desktop, etc., rather than the remote/guest machine being provisioned by Packer. layout: docs @@ -14,7 +14,7 @@ sidebar_current: 'docs-provisioners-shell-local' Type: `shell-local` shell-local will run a shell script of your choosing on the machine where Packer -is being run - in other words, it shell-local will run the shell script on your +is being run - in other words, shell-local will run the shell script on your build server, or your desktop, etc., rather than the remote/guest machine being provisioned by Packer. From 7bab499b73a33bbcd358a2e3577b8e9aad7d97b8 Mon Sep 17 00:00:00 2001 From: willmao Date: Sun, 24 Jun 2018 12:23:35 +0800 Subject: [PATCH 027/220] fix vpc clean up issue --- builder/alicloud/ecs/step_config_vpc.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/builder/alicloud/ecs/step_config_vpc.go b/builder/alicloud/ecs/step_config_vpc.go index 36d52838f..8ce5663ed 100644 --- a/builder/alicloud/ecs/step_config_vpc.go +++ b/builder/alicloud/ecs/step_config_vpc.go @@ -85,7 +85,8 @@ func (s *stepConfigAlicloudVPC) Cleanup(state multistep.StateBag) { e, _ := err.(*common.Error) if (e.Code == "DependencyViolation.Instance" || e.Code == "DependencyViolation.RouteEntry" || e.Code == "DependencyViolation.VSwitch" || - e.Code == "DependencyViolation.SecurityGroup") && time.Now().Before(timeoutPoint) { + e.Code == "DependencyViolation.SecurityGroup" || + e.Code == "Forbbiden") && time.Now().Before(timeoutPoint) { time.Sleep(1 * time.Second) continue } From a69e2ac78e5efb5aab6a7d27ee072d2597cc7408 Mon Sep 17 00:00:00 2001 From: Harvey Lowndes Date: Fri, 22 Jun 2018 12:38:25 +0100 Subject: [PATCH 028/220] Support instance display name configuration --- builder/oracle/oci/config.go | 4 ++++ builder/oracle/oci/driver_oci.go | 11 +++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/builder/oracle/oci/config.go b/builder/oracle/oci/config.go index 75fea183b..c82246762 100644 --- a/builder/oracle/oci/config.go +++ b/builder/oracle/oci/config.go @@ -44,6 +44,10 @@ type Config struct { BaseImageID string `mapstructure:"base_image_ocid"` Shape string `mapstructure:"shape"` ImageName string `mapstructure:"image_name"` + + // Instance + InstanceName string `mapstructure:"instance_name"` + // UserData and UserDataFile file are both optional and mutually exclusive. UserData string `mapstructure:"user_data"` UserDataFile string `mapstructure:"user_data_file"` diff --git a/builder/oracle/oci/driver_oci.go b/builder/oracle/oci/driver_oci.go index ffb3732c1..43b2d5c88 100644 --- a/builder/oracle/oci/driver_oci.go +++ b/builder/oracle/oci/driver_oci.go @@ -45,14 +45,21 @@ func (d *driverOCI) CreateInstance(publicKey string) (string, error) { metadata["user_data"] = d.cfg.UserData } - instance, err := d.computeClient.LaunchInstance(context.TODO(), core.LaunchInstanceRequest{LaunchInstanceDetails: core.LaunchInstanceDetails{ + instanceDetails := core.LaunchInstanceDetails{ AvailabilityDomain: &d.cfg.AvailabilityDomain, CompartmentId: &d.cfg.CompartmentID, ImageId: &d.cfg.BaseImageID, Shape: &d.cfg.Shape, SubnetId: &d.cfg.SubnetID, Metadata: metadata, - }}) + } + + // When empty, the default display name is used. + if d.cfg.InstanceName != "" { + instanceDetails.DisplayName = &d.cfg.InstanceName + } + + instance, err := d.computeClient.LaunchInstance(context.TODO(), core.LaunchInstanceRequest{LaunchInstanceDetails: instanceDetails}) if err != nil { return "", err From 475e79a2510196e967cf739549537b3e53ea6ea6 Mon Sep 17 00:00:00 2001 From: Simon Hulme Date: Mon, 25 Jun 2018 14:13:43 +0100 Subject: [PATCH 029/220] Fixed SecureBootTemplate not being passed through to PS cmdlet Added check for SecureBootTemplate parameter for Server 2012 and below Corrected enableSecureBootString usage --- common/powershell/hyperv/hyperv.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index 392984e3f..5b6501abe 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -518,8 +518,13 @@ Hyper-V\Set-VMNetworkAdapter -VMName $vmName -MacAddressSpoofing $enableMacSpoof func SetVirtualMachineSecureBoot(vmName string, enableSecureBoot bool, templateName string) error { var script = ` -param([string]$vmName, $enableSecureBoot) -Hyper-V\Set-VMFirmware -VMName $vmName -EnableSecureBoot $enableSecureBoot +param([string]$vmName, [string]$enableSecureBootString, [string]$templateName) +$cmdletParameterExists = Get-Help SetVMFirmware -Parameter SecureBootTemplate -ErrorAction SilentlyContinue +if ($cmdletParameterExists) { + Hyper-V\Set-VMFirmware -VMName $vmName -EnableSecureBoot $enableSecureBootString -SecureBootTemplate $templateName +} else { + Hyper-V\Set-VMFirmware -VMName $vmName -EnableSecureBoot $enableSecureBootString +} ` var ps powershell.PowerShellCmd From 04ff0761e6ffa749da817bcb1c819eaa864f6e49 Mon Sep 17 00:00:00 2001 From: Bob Brumfield Date: Mon, 25 Jun 2018 08:28:32 -0700 Subject: [PATCH 030/220] Notify that we are skipping file, but retain error message --- builder/vmware/common/driver.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/vmware/common/driver.go b/builder/vmware/common/driver.go index 553d307ba..1a945d19b 100644 --- a/builder/vmware/common/driver.go +++ b/builder/vmware/common/driver.go @@ -358,7 +358,7 @@ func (d *VmwareDriver) GuestIP(state multistep.StateBag) (string, error) { // open up the lease and read its contents fh, err := os.Open(dhcpLeasesPath) if err != nil { - log.Printf("Unable to open lease path, skipping: %s", dhcpLeasesPath) + log.Printf("Error while reading DHCP lease path file %s: %s", dhcpLeasesPath, err.Error()) continue } defer fh.Close() From 297f6b85ec59ef3f64b206d28923e7d57f47adc7 Mon Sep 17 00:00:00 2001 From: DanHam Date: Mon, 25 Jun 2018 23:51:27 +0100 Subject: [PATCH 031/220] Use Get-Command over Get-Help to check for SecureBootTemplate parameter --- common/powershell/hyperv/hyperv.go | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index 5b6501abe..343e02776 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -267,7 +267,7 @@ if ($harddrivePath){ func DisableAutomaticCheckpoints(vmName string) error { var script = ` param([string]$vmName) -if ((Get-Command Hyper-V\Set-Vm).Parameters["AutomaticCheckpointsEnabled"]) { +if ((Get-Command Hyper-V\Set-Vm).Parameters["AutomaticCheckpointsEnabled"]) { Hyper-V\Set-Vm -Name $vmName -AutomaticCheckpointsEnabled $false } ` var ps powershell.PowerShellCmd @@ -279,7 +279,7 @@ func ExportVmxcVirtualMachine(exportPath string, vmName string, snapshotName str var script = ` param([string]$exportPath, [string]$vmName, [string]$snapshotName, [string]$allSnapshotsString) -$WorkingPath = Join-Path $exportPath $vmName +$WorkingPath = Join-Path $exportPath $vmName if (Test-Path $WorkingPath) { throw "Export path working directory: $WorkingPath already exists!" @@ -297,7 +297,7 @@ if ($snapshotName) { } else { $snapshot = $null } - + if (!$snapshot) { #No snapshot clone Hyper-V\Export-VM -Name $vmName -Path $exportPath -ErrorAction Stop @@ -328,7 +328,7 @@ param([string]$exportPath, [string]$cloneFromVmxcPath) if (!(Test-Path $cloneFromVmxcPath)){ throw "Clone from vmxc directory: $cloneFromVmxcPath does not exist!" } - + if (!(Test-Path $exportPath)){ New-Item -ItemType Directory -Force -Path $exportPath } @@ -390,12 +390,12 @@ if ($vhdPath){ $existingFirstHarddrive | Hyper-V\Set-VMHardDiskDrive -Path $vhdPath } else { Hyper-V\Add-VMHardDiskDrive -VM $compatibilityReport.VM -Path $vhdPath - } + } } Hyper-V\Set-VMMemory -VM $compatibilityReport.VM -StartupBytes $memoryStartupBytes $networkAdaptor = $compatibilityReport.VM.NetworkAdapters | Select -First 1 Hyper-V\Disconnect-VMNetworkAdapter -VMNetworkAdapter $networkAdaptor -Hyper-V\Connect-VMNetworkAdapter -VMNetworkAdapter $networkAdaptor -SwitchName $switchName +Hyper-V\Connect-VMNetworkAdapter -VMNetworkAdapter $networkAdaptor -SwitchName $switchName $vm = Hyper-V\Import-VM -CompatibilityReport $compatibilityReport if ($vm) { @@ -519,8 +519,9 @@ Hyper-V\Set-VMNetworkAdapter -VMName $vmName -MacAddressSpoofing $enableMacSpoof func SetVirtualMachineSecureBoot(vmName string, enableSecureBoot bool, templateName string) error { var script = ` param([string]$vmName, [string]$enableSecureBootString, [string]$templateName) -$cmdletParameterExists = Get-Help SetVMFirmware -Parameter SecureBootTemplate -ErrorAction SilentlyContinue -if ($cmdletParameterExists) { +$cmdlet = Get-Command Hyper-V\Set-VMFirmware +# The SecureBootTemplate parameter is only available in later versions +if ($cmdlet.Parameters.SecureBootTemplate) { Hyper-V\Set-VMFirmware -VMName $vmName -EnableSecureBoot $enableSecureBootString -SecureBootTemplate $templateName } else { Hyper-V\Set-VMFirmware -VMName $vmName -EnableSecureBoot $enableSecureBootString From a5e29e68da651e557eefc9d97e28fb291c52191e Mon Sep 17 00:00:00 2001 From: Matthew Hooker Date: Mon, 25 Jun 2018 15:03:09 -0700 Subject: [PATCH 032/220] cmd/validate: notify user if config is "fixable" --- command/validate.go | 45 +- vendor/github.com/google/go-cmp/LICENSE | 27 + .../github.com/google/go-cmp/cmp/compare.go | 599 ++++++++++++++++++ .../go-cmp/cmp/internal/diff/debug_disable.go | 17 + .../go-cmp/cmp/internal/diff/debug_enable.go | 122 ++++ .../google/go-cmp/cmp/internal/diff/diff.go | 363 +++++++++++ .../go-cmp/cmp/internal/function/func.go | 49 ++ .../go-cmp/cmp/internal/value/format.go | 280 ++++++++ .../cmp/internal/value/pointer_purego.go | 23 + .../cmp/internal/value/pointer_unsafe.go | 26 + .../google/go-cmp/cmp/internal/value/sort.go | 111 ++++ .../github.com/google/go-cmp/cmp/options.go | 456 +++++++++++++ vendor/github.com/google/go-cmp/cmp/path.go | 309 +++++++++ .../github.com/google/go-cmp/cmp/reporter.go | 53 ++ .../google/go-cmp/cmp/unsafe_reflect.go | 23 + vendor/vendor.json | 24 + 16 files changed, 2526 insertions(+), 1 deletion(-) create mode 100644 vendor/github.com/google/go-cmp/LICENSE create mode 100644 vendor/github.com/google/go-cmp/cmp/compare.go create mode 100644 vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go create mode 100644 vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go create mode 100644 vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go create mode 100644 vendor/github.com/google/go-cmp/cmp/internal/function/func.go create mode 100644 vendor/github.com/google/go-cmp/cmp/internal/value/format.go create mode 100644 vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go create mode 100644 vendor/github.com/google/go-cmp/cmp/internal/value/pointer_unsafe.go create mode 100644 vendor/github.com/google/go-cmp/cmp/internal/value/sort.go create mode 100644 vendor/github.com/google/go-cmp/cmp/options.go create mode 100644 vendor/github.com/google/go-cmp/cmp/path.go create mode 100644 vendor/github.com/google/go-cmp/cmp/reporter.go create mode 100644 vendor/github.com/google/go-cmp/cmp/unsafe_reflect.go diff --git a/command/validate.go b/command/validate.go index 05c29dc2c..8c0bef8e4 100644 --- a/command/validate.go +++ b/command/validate.go @@ -1,13 +1,16 @@ package command import ( + "encoding/json" "fmt" "log" "strings" + "github.com/hashicorp/packer/fix" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template" + "github.com/google/go-cmp/cmp" "github.com/posener/complete" ) @@ -80,6 +83,47 @@ func (c *ValidateCommand) Run(args []string) int { } } + // Check if any of the configuration is fixable + var templateData map[string]interface{} + json.Unmarshal(tpl.RawContents, &templateData) + input := make(map[string]interface{}) + for k, v := range templateData { + input[k] = v + } + for _, name := range fix.FixerOrder { + var err error + fixer, ok := fix.Fixers[name] + if !ok { + panic("fixer not found: " + name) + } + input, err = fixer.Fix(input) + if err != nil { + c.Ui.Error(fmt.Sprintf("Error fixing: %s", err)) + return 1 + } + } + // delete empty top-level keys since the fixers seem to add them + // willy-nilly + for k := range input { + ml, ok := input[k].([]map[string]interface{}) + if !ok { + continue + } + if len(ml) == 0 { + delete(input, k) + } + } + // Guaranteed to be valid json, so we can ignore errors + var fixedData map[string]interface{} + j, _ := json.Marshal(input) + json.Unmarshal(j, &fixedData) + if diff := cmp.Diff(templateData, fixedData); diff != "" { + c.Ui.Say("[warning] Fixable configuration found.") + c.Ui.Say("You may need to run `packer fix` to get your build to run") + c.Ui.Say("correctly. See debug log for more information.\n") + log.Printf("Fixable config differences:\n%s", diff) + } + if len(errs) > 0 { c.Ui.Error("Template validation failed. Errors are shown below.\n") for i, err := range errs { @@ -89,7 +133,6 @@ func (c *ValidateCommand) Run(args []string) int { c.Ui.Error("") } } - return 1 } diff --git a/vendor/github.com/google/go-cmp/LICENSE b/vendor/github.com/google/go-cmp/LICENSE new file mode 100644 index 000000000..32017f8fa --- /dev/null +++ b/vendor/github.com/google/go-cmp/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2017 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/google/go-cmp/cmp/compare.go b/vendor/github.com/google/go-cmp/cmp/compare.go new file mode 100644 index 000000000..b56d63447 --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/compare.go @@ -0,0 +1,599 @@ +// Copyright 2017, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +// Package cmp determines equality of values. +// +// This package is intended to be a more powerful and safer alternative to +// reflect.DeepEqual for comparing whether two values are semantically equal. +// +// The primary features of cmp are: +// +// • When the default behavior of equality does not suit the needs of the test, +// custom equality functions can override the equality operation. +// For example, an equality function may report floats as equal so long as they +// are within some tolerance of each other. +// +// • Types that have an Equal method may use that method to determine equality. +// This allows package authors to determine the equality operation for the types +// that they define. +// +// • If no custom equality functions are used and no Equal method is defined, +// equality is determined by recursively comparing the primitive kinds on both +// values, much like reflect.DeepEqual. Unlike reflect.DeepEqual, unexported +// fields are not compared by default; they result in panics unless suppressed +// by using an Ignore option (see cmpopts.IgnoreUnexported) or explicitly compared +// using the AllowUnexported option. +package cmp + +import ( + "fmt" + "reflect" + "strings" + + "github.com/google/go-cmp/cmp/internal/diff" + "github.com/google/go-cmp/cmp/internal/function" + "github.com/google/go-cmp/cmp/internal/value" +) + +// BUG(dsnet): Maps with keys containing NaN values cannot be properly compared due to +// the reflection package's inability to retrieve such entries. Equal will panic +// anytime it comes across a NaN key, but this behavior may change. +// +// See https://golang.org/issue/11104 for more details. + +var nothing = reflect.Value{} + +// Equal reports whether x and y are equal by recursively applying the +// following rules in the given order to x and y and all of their sub-values: +// +// • If two values are not of the same type, then they are never equal +// and the overall result is false. +// +// • Let S be the set of all Ignore, Transformer, and Comparer options that +// remain after applying all path filters, value filters, and type filters. +// If at least one Ignore exists in S, then the comparison is ignored. +// If the number of Transformer and Comparer options in S is greater than one, +// then Equal panics because it is ambiguous which option to use. +// If S contains a single Transformer, then use that to transform the current +// values and recursively call Equal on the output values. +// If S contains a single Comparer, then use that to compare the current values. +// Otherwise, evaluation proceeds to the next rule. +// +// • If the values have an Equal method of the form "(T) Equal(T) bool" or +// "(T) Equal(I) bool" where T is assignable to I, then use the result of +// x.Equal(y) even if x or y is nil. +// Otherwise, no such method exists and evaluation proceeds to the next rule. +// +// • Lastly, try to compare x and y based on their basic kinds. +// Simple kinds like booleans, integers, floats, complex numbers, strings, and +// channels are compared using the equivalent of the == operator in Go. +// Functions are only equal if they are both nil, otherwise they are unequal. +// Pointers are equal if the underlying values they point to are also equal. +// Interfaces are equal if their underlying concrete values are also equal. +// +// Structs are equal if all of their fields are equal. If a struct contains +// unexported fields, Equal panics unless the AllowUnexported option is used or +// an Ignore option (e.g., cmpopts.IgnoreUnexported) ignores that field. +// +// Arrays, slices, and maps are equal if they are both nil or both non-nil +// with the same length and the elements at each index or key are equal. +// Note that a non-nil empty slice and a nil slice are not equal. +// To equate empty slices and maps, consider using cmpopts.EquateEmpty. +// Map keys are equal according to the == operator. +// To use custom comparisons for map keys, consider using cmpopts.SortMaps. +func Equal(x, y interface{}, opts ...Option) bool { + s := newState(opts) + s.compareAny(reflect.ValueOf(x), reflect.ValueOf(y)) + return s.result.Equal() +} + +// Diff returns a human-readable report of the differences between two values. +// It returns an empty string if and only if Equal returns true for the same +// input values and options. The output string will use the "-" symbol to +// indicate elements removed from x, and the "+" symbol to indicate elements +// added to y. +// +// Do not depend on this output being stable. +func Diff(x, y interface{}, opts ...Option) string { + r := new(defaultReporter) + opts = Options{Options(opts), r} + eq := Equal(x, y, opts...) + d := r.String() + if (d == "") != eq { + panic("inconsistent difference and equality results") + } + return d +} + +type state struct { + // These fields represent the "comparison state". + // Calling statelessCompare must not result in observable changes to these. + result diff.Result // The current result of comparison + curPath Path // The current path in the value tree + reporter reporter // Optional reporter used for difference formatting + + // recChecker checks for infinite cycles applying the same set of + // transformers upon the output of itself. + recChecker recChecker + + // dynChecker triggers pseudo-random checks for option correctness. + // It is safe for statelessCompare to mutate this value. + dynChecker dynChecker + + // These fields, once set by processOption, will not change. + exporters map[reflect.Type]bool // Set of structs with unexported field visibility + opts Options // List of all fundamental and filter options +} + +func newState(opts []Option) *state { + s := new(state) + for _, opt := range opts { + s.processOption(opt) + } + return s +} + +func (s *state) processOption(opt Option) { + switch opt := opt.(type) { + case nil: + case Options: + for _, o := range opt { + s.processOption(o) + } + case coreOption: + type filtered interface { + isFiltered() bool + } + if fopt, ok := opt.(filtered); ok && !fopt.isFiltered() { + panic(fmt.Sprintf("cannot use an unfiltered option: %v", opt)) + } + s.opts = append(s.opts, opt) + case visibleStructs: + if s.exporters == nil { + s.exporters = make(map[reflect.Type]bool) + } + for t := range opt { + s.exporters[t] = true + } + case reporter: + if s.reporter != nil { + panic("difference reporter already registered") + } + s.reporter = opt + default: + panic(fmt.Sprintf("unknown option %T", opt)) + } +} + +// statelessCompare compares two values and returns the result. +// This function is stateless in that it does not alter the current result, +// or output to any registered reporters. +func (s *state) statelessCompare(vx, vy reflect.Value) diff.Result { + // We do not save and restore the curPath because all of the compareX + // methods should properly push and pop from the path. + // It is an implementation bug if the contents of curPath differs from + // when calling this function to when returning from it. + + oldResult, oldReporter := s.result, s.reporter + s.result = diff.Result{} // Reset result + s.reporter = nil // Remove reporter to avoid spurious printouts + s.compareAny(vx, vy) + res := s.result + s.result, s.reporter = oldResult, oldReporter + return res +} + +func (s *state) compareAny(vx, vy reflect.Value) { + // TODO: Support cyclic data structures. + s.recChecker.Check(s.curPath) + + // Rule 0: Differing types are never equal. + if !vx.IsValid() || !vy.IsValid() { + s.report(vx.IsValid() == vy.IsValid(), vx, vy) + return + } + if vx.Type() != vy.Type() { + s.report(false, vx, vy) // Possible for path to be empty + return + } + t := vx.Type() + if len(s.curPath) == 0 { + s.curPath.push(&pathStep{typ: t}) + defer s.curPath.pop() + } + vx, vy = s.tryExporting(vx, vy) + + // Rule 1: Check whether an option applies on this node in the value tree. + if s.tryOptions(vx, vy, t) { + return + } + + // Rule 2: Check whether the type has a valid Equal method. + if s.tryMethod(vx, vy, t) { + return + } + + // Rule 3: Recursively descend into each value's underlying kind. + switch t.Kind() { + case reflect.Bool: + s.report(vx.Bool() == vy.Bool(), vx, vy) + return + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + s.report(vx.Int() == vy.Int(), vx, vy) + return + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + s.report(vx.Uint() == vy.Uint(), vx, vy) + return + case reflect.Float32, reflect.Float64: + s.report(vx.Float() == vy.Float(), vx, vy) + return + case reflect.Complex64, reflect.Complex128: + s.report(vx.Complex() == vy.Complex(), vx, vy) + return + case reflect.String: + s.report(vx.String() == vy.String(), vx, vy) + return + case reflect.Chan, reflect.UnsafePointer: + s.report(vx.Pointer() == vy.Pointer(), vx, vy) + return + case reflect.Func: + s.report(vx.IsNil() && vy.IsNil(), vx, vy) + return + case reflect.Ptr: + if vx.IsNil() || vy.IsNil() { + s.report(vx.IsNil() && vy.IsNil(), vx, vy) + return + } + s.curPath.push(&indirect{pathStep{t.Elem()}}) + defer s.curPath.pop() + s.compareAny(vx.Elem(), vy.Elem()) + return + case reflect.Interface: + if vx.IsNil() || vy.IsNil() { + s.report(vx.IsNil() && vy.IsNil(), vx, vy) + return + } + if vx.Elem().Type() != vy.Elem().Type() { + s.report(false, vx.Elem(), vy.Elem()) + return + } + s.curPath.push(&typeAssertion{pathStep{vx.Elem().Type()}}) + defer s.curPath.pop() + s.compareAny(vx.Elem(), vy.Elem()) + return + case reflect.Slice: + if vx.IsNil() || vy.IsNil() { + s.report(vx.IsNil() && vy.IsNil(), vx, vy) + return + } + fallthrough + case reflect.Array: + s.compareArray(vx, vy, t) + return + case reflect.Map: + s.compareMap(vx, vy, t) + return + case reflect.Struct: + s.compareStruct(vx, vy, t) + return + default: + panic(fmt.Sprintf("%v kind not handled", t.Kind())) + } +} + +func (s *state) tryExporting(vx, vy reflect.Value) (reflect.Value, reflect.Value) { + if sf, ok := s.curPath[len(s.curPath)-1].(*structField); ok && sf.unexported { + if sf.force { + // Use unsafe pointer arithmetic to get read-write access to an + // unexported field in the struct. + vx = unsafeRetrieveField(sf.pvx, sf.field) + vy = unsafeRetrieveField(sf.pvy, sf.field) + } else { + // We are not allowed to export the value, so invalidate them + // so that tryOptions can panic later if not explicitly ignored. + vx = nothing + vy = nothing + } + } + return vx, vy +} + +func (s *state) tryOptions(vx, vy reflect.Value, t reflect.Type) bool { + // If there were no FilterValues, we will not detect invalid inputs, + // so manually check for them and append invalid if necessary. + // We still evaluate the options since an ignore can override invalid. + opts := s.opts + if !vx.IsValid() || !vy.IsValid() { + opts = Options{opts, invalid{}} + } + + // Evaluate all filters and apply the remaining options. + if opt := opts.filter(s, vx, vy, t); opt != nil { + opt.apply(s, vx, vy) + return true + } + return false +} + +func (s *state) tryMethod(vx, vy reflect.Value, t reflect.Type) bool { + // Check if this type even has an Equal method. + m, ok := t.MethodByName("Equal") + if !ok || !function.IsType(m.Type, function.EqualAssignable) { + return false + } + + eq := s.callTTBFunc(m.Func, vx, vy) + s.report(eq, vx, vy) + return true +} + +func (s *state) callTRFunc(f, v reflect.Value) reflect.Value { + v = sanitizeValue(v, f.Type().In(0)) + if !s.dynChecker.Next() { + return f.Call([]reflect.Value{v})[0] + } + + // Run the function twice and ensure that we get the same results back. + // We run in goroutines so that the race detector (if enabled) can detect + // unsafe mutations to the input. + c := make(chan reflect.Value) + go detectRaces(c, f, v) + want := f.Call([]reflect.Value{v})[0] + if got := <-c; !s.statelessCompare(got, want).Equal() { + // To avoid false-positives with non-reflexive equality operations, + // we sanity check whether a value is equal to itself. + if !s.statelessCompare(want, want).Equal() { + return want + } + fn := getFuncName(f.Pointer()) + panic(fmt.Sprintf("non-deterministic function detected: %s", fn)) + } + return want +} + +func (s *state) callTTBFunc(f, x, y reflect.Value) bool { + x = sanitizeValue(x, f.Type().In(0)) + y = sanitizeValue(y, f.Type().In(1)) + if !s.dynChecker.Next() { + return f.Call([]reflect.Value{x, y})[0].Bool() + } + + // Swapping the input arguments is sufficient to check that + // f is symmetric and deterministic. + // We run in goroutines so that the race detector (if enabled) can detect + // unsafe mutations to the input. + c := make(chan reflect.Value) + go detectRaces(c, f, y, x) + want := f.Call([]reflect.Value{x, y})[0].Bool() + if got := <-c; !got.IsValid() || got.Bool() != want { + fn := getFuncName(f.Pointer()) + panic(fmt.Sprintf("non-deterministic or non-symmetric function detected: %s", fn)) + } + return want +} + +func detectRaces(c chan<- reflect.Value, f reflect.Value, vs ...reflect.Value) { + var ret reflect.Value + defer func() { + recover() // Ignore panics, let the other call to f panic instead + c <- ret + }() + ret = f.Call(vs)[0] +} + +// sanitizeValue converts nil interfaces of type T to those of type R, +// assuming that T is assignable to R. +// Otherwise, it returns the input value as is. +func sanitizeValue(v reflect.Value, t reflect.Type) reflect.Value { + // TODO(dsnet): Workaround for reflect bug (https://golang.org/issue/22143). + // The upstream fix landed in Go1.10, so we can remove this when drop support + // for Go1.9 and below. + if v.Kind() == reflect.Interface && v.IsNil() && v.Type() != t { + return reflect.New(t).Elem() + } + return v +} + +func (s *state) compareArray(vx, vy reflect.Value, t reflect.Type) { + step := &sliceIndex{pathStep{t.Elem()}, 0, 0} + s.curPath.push(step) + + // Compute an edit-script for slices vx and vy. + es := diff.Difference(vx.Len(), vy.Len(), func(ix, iy int) diff.Result { + step.xkey, step.ykey = ix, iy + return s.statelessCompare(vx.Index(ix), vy.Index(iy)) + }) + + // Report the entire slice as is if the arrays are of primitive kind, + // and the arrays are different enough. + isPrimitive := false + switch t.Elem().Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, + reflect.Bool, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128: + isPrimitive = true + } + if isPrimitive && es.Dist() > (vx.Len()+vy.Len())/4 { + s.curPath.pop() // Pop first since we are reporting the whole slice + s.report(false, vx, vy) + return + } + + // Replay the edit-script. + var ix, iy int + for _, e := range es { + switch e { + case diff.UniqueX: + step.xkey, step.ykey = ix, -1 + s.report(false, vx.Index(ix), nothing) + ix++ + case diff.UniqueY: + step.xkey, step.ykey = -1, iy + s.report(false, nothing, vy.Index(iy)) + iy++ + default: + step.xkey, step.ykey = ix, iy + if e == diff.Identity { + s.report(true, vx.Index(ix), vy.Index(iy)) + } else { + s.compareAny(vx.Index(ix), vy.Index(iy)) + } + ix++ + iy++ + } + } + s.curPath.pop() + return +} + +func (s *state) compareMap(vx, vy reflect.Value, t reflect.Type) { + if vx.IsNil() || vy.IsNil() { + s.report(vx.IsNil() && vy.IsNil(), vx, vy) + return + } + + // We combine and sort the two map keys so that we can perform the + // comparisons in a deterministic order. + step := &mapIndex{pathStep: pathStep{t.Elem()}} + s.curPath.push(step) + defer s.curPath.pop() + for _, k := range value.SortKeys(append(vx.MapKeys(), vy.MapKeys()...)) { + step.key = k + vvx := vx.MapIndex(k) + vvy := vy.MapIndex(k) + switch { + case vvx.IsValid() && vvy.IsValid(): + s.compareAny(vvx, vvy) + case vvx.IsValid() && !vvy.IsValid(): + s.report(false, vvx, nothing) + case !vvx.IsValid() && vvy.IsValid(): + s.report(false, nothing, vvy) + default: + // It is possible for both vvx and vvy to be invalid if the + // key contained a NaN value in it. There is no way in + // reflection to be able to retrieve these values. + // See https://golang.org/issue/11104 + panic(fmt.Sprintf("%#v has map key with NaNs", s.curPath)) + } + } +} + +func (s *state) compareStruct(vx, vy reflect.Value, t reflect.Type) { + var vax, vay reflect.Value // Addressable versions of vx and vy + + step := &structField{} + s.curPath.push(step) + defer s.curPath.pop() + for i := 0; i < t.NumField(); i++ { + vvx := vx.Field(i) + vvy := vy.Field(i) + step.typ = t.Field(i).Type + step.name = t.Field(i).Name + step.idx = i + step.unexported = !isExported(step.name) + if step.unexported { + // Defer checking of unexported fields until later to give an + // Ignore a chance to ignore the field. + if !vax.IsValid() || !vay.IsValid() { + // For unsafeRetrieveField to work, the parent struct must + // be addressable. Create a new copy of the values if + // necessary to make them addressable. + vax = makeAddressable(vx) + vay = makeAddressable(vy) + } + step.force = s.exporters[t] + step.pvx = vax + step.pvy = vay + step.field = t.Field(i) + } + s.compareAny(vvx, vvy) + } +} + +// report records the result of a single comparison. +// It also calls Report if any reporter is registered. +func (s *state) report(eq bool, vx, vy reflect.Value) { + if eq { + s.result.NSame++ + } else { + s.result.NDiff++ + } + if s.reporter != nil { + s.reporter.Report(vx, vy, eq, s.curPath) + } +} + +// recChecker tracks the state needed to periodically perform checks that +// user provided transformers are not stuck in an infinitely recursive cycle. +type recChecker struct{ next int } + +// Check scans the Path for any recursive transformers and panics when any +// recursive transformers are detected. Note that the presence of a +// recursive Transformer does not necessarily imply an infinite cycle. +// As such, this check only activates after some minimal number of path steps. +func (rc *recChecker) Check(p Path) { + const minLen = 1 << 16 + if rc.next == 0 { + rc.next = minLen + } + if len(p) < rc.next { + return + } + rc.next <<= 1 + + // Check whether the same transformer has appeared at least twice. + var ss []string + m := map[Option]int{} + for _, ps := range p { + if t, ok := ps.(Transform); ok { + t := t.Option() + if m[t] == 1 { // Transformer was used exactly once before + tf := t.(*transformer).fnc.Type() + ss = append(ss, fmt.Sprintf("%v: %v => %v", t, tf.In(0), tf.Out(0))) + } + m[t]++ + } + } + if len(ss) > 0 { + const warning = "recursive set of Transformers detected" + const help = "consider using cmpopts.AcyclicTransformer" + set := strings.Join(ss, "\n\t") + panic(fmt.Sprintf("%s:\n\t%s\n%s", warning, set, help)) + } +} + +// dynChecker tracks the state needed to periodically perform checks that +// user provided functions are symmetric and deterministic. +// The zero value is safe for immediate use. +type dynChecker struct{ curr, next int } + +// Next increments the state and reports whether a check should be performed. +// +// Checks occur every Nth function call, where N is a triangular number: +// 0 1 3 6 10 15 21 28 36 45 55 66 78 91 105 120 136 153 171 190 ... +// See https://en.wikipedia.org/wiki/Triangular_number +// +// This sequence ensures that the cost of checks drops significantly as +// the number of functions calls grows larger. +func (dc *dynChecker) Next() bool { + ok := dc.curr == dc.next + if ok { + dc.curr = 0 + dc.next++ + } + dc.curr++ + return ok +} + +// makeAddressable returns a value that is always addressable. +// It returns the input verbatim if it is already addressable, +// otherwise it creates a new value and returns an addressable copy. +func makeAddressable(v reflect.Value) reflect.Value { + if v.CanAddr() { + return v + } + vc := reflect.New(v.Type()).Elem() + vc.Set(v) + return vc +} diff --git a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go b/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go new file mode 100644 index 000000000..42afa4960 --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go @@ -0,0 +1,17 @@ +// Copyright 2017, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +// +build !debug + +package diff + +var debug debugger + +type debugger struct{} + +func (debugger) Begin(_, _ int, f EqualFunc, _, _ *EditScript) EqualFunc { + return f +} +func (debugger) Update() {} +func (debugger) Finish() {} diff --git a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go b/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go new file mode 100644 index 000000000..fd9f7f177 --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go @@ -0,0 +1,122 @@ +// Copyright 2017, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +// +build debug + +package diff + +import ( + "fmt" + "strings" + "sync" + "time" +) + +// The algorithm can be seen running in real-time by enabling debugging: +// go test -tags=debug -v +// +// Example output: +// === RUN TestDifference/#34 +// ┌───────────────────────────────┐ +// │ \ · · · · · · · · · · · · · · │ +// │ · # · · · · · · · · · · · · · │ +// │ · \ · · · · · · · · · · · · · │ +// │ · · \ · · · · · · · · · · · · │ +// │ · · · X # · · · · · · · · · · │ +// │ · · · # \ · · · · · · · · · · │ +// │ · · · · · # # · · · · · · · · │ +// │ · · · · · # \ · · · · · · · · │ +// │ · · · · · · · \ · · · · · · · │ +// │ · · · · · · · · \ · · · · · · │ +// │ · · · · · · · · · \ · · · · · │ +// │ · · · · · · · · · · \ · · # · │ +// │ · · · · · · · · · · · \ # # · │ +// │ · · · · · · · · · · · # # # · │ +// │ · · · · · · · · · · # # # # · │ +// │ · · · · · · · · · # # # # # · │ +// │ · · · · · · · · · · · · · · \ │ +// └───────────────────────────────┘ +// [.Y..M.XY......YXYXY.|] +// +// The grid represents the edit-graph where the horizontal axis represents +// list X and the vertical axis represents list Y. The start of the two lists +// is the top-left, while the ends are the bottom-right. The '·' represents +// an unexplored node in the graph. The '\' indicates that the two symbols +// from list X and Y are equal. The 'X' indicates that two symbols are similar +// (but not exactly equal) to each other. The '#' indicates that the two symbols +// are different (and not similar). The algorithm traverses this graph trying to +// make the paths starting in the top-left and the bottom-right connect. +// +// The series of '.', 'X', 'Y', and 'M' characters at the bottom represents +// the currently established path from the forward and reverse searches, +// separated by a '|' character. + +const ( + updateDelay = 100 * time.Millisecond + finishDelay = 500 * time.Millisecond + ansiTerminal = true // ANSI escape codes used to move terminal cursor +) + +var debug debugger + +type debugger struct { + sync.Mutex + p1, p2 EditScript + fwdPath, revPath *EditScript + grid []byte + lines int +} + +func (dbg *debugger) Begin(nx, ny int, f EqualFunc, p1, p2 *EditScript) EqualFunc { + dbg.Lock() + dbg.fwdPath, dbg.revPath = p1, p2 + top := "┌─" + strings.Repeat("──", nx) + "┐\n" + row := "│ " + strings.Repeat("· ", nx) + "│\n" + btm := "└─" + strings.Repeat("──", nx) + "┘\n" + dbg.grid = []byte(top + strings.Repeat(row, ny) + btm) + dbg.lines = strings.Count(dbg.String(), "\n") + fmt.Print(dbg) + + // Wrap the EqualFunc so that we can intercept each result. + return func(ix, iy int) (r Result) { + cell := dbg.grid[len(top)+iy*len(row):][len("│ ")+len("· ")*ix:][:len("·")] + for i := range cell { + cell[i] = 0 // Zero out the multiple bytes of UTF-8 middle-dot + } + switch r = f(ix, iy); { + case r.Equal(): + cell[0] = '\\' + case r.Similar(): + cell[0] = 'X' + default: + cell[0] = '#' + } + return + } +} + +func (dbg *debugger) Update() { + dbg.print(updateDelay) +} + +func (dbg *debugger) Finish() { + dbg.print(finishDelay) + dbg.Unlock() +} + +func (dbg *debugger) String() string { + dbg.p1, dbg.p2 = *dbg.fwdPath, dbg.p2[:0] + for i := len(*dbg.revPath) - 1; i >= 0; i-- { + dbg.p2 = append(dbg.p2, (*dbg.revPath)[i]) + } + return fmt.Sprintf("%s[%v|%v]\n\n", dbg.grid, dbg.p1, dbg.p2) +} + +func (dbg *debugger) print(d time.Duration) { + if ansiTerminal { + fmt.Printf("\x1b[%dA", dbg.lines) // Reset terminal cursor + } + fmt.Print(dbg) + time.Sleep(d) +} diff --git a/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go b/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go new file mode 100644 index 000000000..260befea2 --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go @@ -0,0 +1,363 @@ +// Copyright 2017, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +// Package diff implements an algorithm for producing edit-scripts. +// The edit-script is a sequence of operations needed to transform one list +// of symbols into another (or vice-versa). The edits allowed are insertions, +// deletions, and modifications. The summation of all edits is called the +// Levenshtein distance as this problem is well-known in computer science. +// +// This package prioritizes performance over accuracy. That is, the run time +// is more important than obtaining a minimal Levenshtein distance. +package diff + +// EditType represents a single operation within an edit-script. +type EditType uint8 + +const ( + // Identity indicates that a symbol pair is identical in both list X and Y. + Identity EditType = iota + // UniqueX indicates that a symbol only exists in X and not Y. + UniqueX + // UniqueY indicates that a symbol only exists in Y and not X. + UniqueY + // Modified indicates that a symbol pair is a modification of each other. + Modified +) + +// EditScript represents the series of differences between two lists. +type EditScript []EditType + +// String returns a human-readable string representing the edit-script where +// Identity, UniqueX, UniqueY, and Modified are represented by the +// '.', 'X', 'Y', and 'M' characters, respectively. +func (es EditScript) String() string { + b := make([]byte, len(es)) + for i, e := range es { + switch e { + case Identity: + b[i] = '.' + case UniqueX: + b[i] = 'X' + case UniqueY: + b[i] = 'Y' + case Modified: + b[i] = 'M' + default: + panic("invalid edit-type") + } + } + return string(b) +} + +// stats returns a histogram of the number of each type of edit operation. +func (es EditScript) stats() (s struct{ NI, NX, NY, NM int }) { + for _, e := range es { + switch e { + case Identity: + s.NI++ + case UniqueX: + s.NX++ + case UniqueY: + s.NY++ + case Modified: + s.NM++ + default: + panic("invalid edit-type") + } + } + return +} + +// Dist is the Levenshtein distance and is guaranteed to be 0 if and only if +// lists X and Y are equal. +func (es EditScript) Dist() int { return len(es) - es.stats().NI } + +// LenX is the length of the X list. +func (es EditScript) LenX() int { return len(es) - es.stats().NY } + +// LenY is the length of the Y list. +func (es EditScript) LenY() int { return len(es) - es.stats().NX } + +// EqualFunc reports whether the symbols at indexes ix and iy are equal. +// When called by Difference, the index is guaranteed to be within nx and ny. +type EqualFunc func(ix int, iy int) Result + +// Result is the result of comparison. +// NSame is the number of sub-elements that are equal. +// NDiff is the number of sub-elements that are not equal. +type Result struct{ NSame, NDiff int } + +// Equal indicates whether the symbols are equal. Two symbols are equal +// if and only if NDiff == 0. If Equal, then they are also Similar. +func (r Result) Equal() bool { return r.NDiff == 0 } + +// Similar indicates whether two symbols are similar and may be represented +// by using the Modified type. As a special case, we consider binary comparisons +// (i.e., those that return Result{1, 0} or Result{0, 1}) to be similar. +// +// The exact ratio of NSame to NDiff to determine similarity may change. +func (r Result) Similar() bool { + // Use NSame+1 to offset NSame so that binary comparisons are similar. + return r.NSame+1 >= r.NDiff +} + +// Difference reports whether two lists of lengths nx and ny are equal +// given the definition of equality provided as f. +// +// This function returns an edit-script, which is a sequence of operations +// needed to convert one list into the other. The following invariants for +// the edit-script are maintained: +// • eq == (es.Dist()==0) +// • nx == es.LenX() +// • ny == es.LenY() +// +// This algorithm is not guaranteed to be an optimal solution (i.e., one that +// produces an edit-script with a minimal Levenshtein distance). This algorithm +// favors performance over optimality. The exact output is not guaranteed to +// be stable and may change over time. +func Difference(nx, ny int, f EqualFunc) (es EditScript) { + // This algorithm is based on traversing what is known as an "edit-graph". + // See Figure 1 from "An O(ND) Difference Algorithm and Its Variations" + // by Eugene W. Myers. Since D can be as large as N itself, this is + // effectively O(N^2). Unlike the algorithm from that paper, we are not + // interested in the optimal path, but at least some "decent" path. + // + // For example, let X and Y be lists of symbols: + // X = [A B C A B B A] + // Y = [C B A B A C] + // + // The edit-graph can be drawn as the following: + // A B C A B B A + // ┌─────────────┐ + // C │_|_|\|_|_|_|_│ 0 + // B │_|\|_|_|\|\|_│ 1 + // A │\|_|_|\|_|_|\│ 2 + // B │_|\|_|_|\|\|_│ 3 + // A │\|_|_|\|_|_|\│ 4 + // C │ | |\| | | | │ 5 + // └─────────────┘ 6 + // 0 1 2 3 4 5 6 7 + // + // List X is written along the horizontal axis, while list Y is written + // along the vertical axis. At any point on this grid, if the symbol in + // list X matches the corresponding symbol in list Y, then a '\' is drawn. + // The goal of any minimal edit-script algorithm is to find a path from the + // top-left corner to the bottom-right corner, while traveling through the + // fewest horizontal or vertical edges. + // A horizontal edge is equivalent to inserting a symbol from list X. + // A vertical edge is equivalent to inserting a symbol from list Y. + // A diagonal edge is equivalent to a matching symbol between both X and Y. + + // Invariants: + // • 0 ≤ fwdPath.X ≤ (fwdFrontier.X, revFrontier.X) ≤ revPath.X ≤ nx + // • 0 ≤ fwdPath.Y ≤ (fwdFrontier.Y, revFrontier.Y) ≤ revPath.Y ≤ ny + // + // In general: + // • fwdFrontier.X < revFrontier.X + // • fwdFrontier.Y < revFrontier.Y + // Unless, it is time for the algorithm to terminate. + fwdPath := path{+1, point{0, 0}, make(EditScript, 0, (nx+ny)/2)} + revPath := path{-1, point{nx, ny}, make(EditScript, 0)} + fwdFrontier := fwdPath.point // Forward search frontier + revFrontier := revPath.point // Reverse search frontier + + // Search budget bounds the cost of searching for better paths. + // The longest sequence of non-matching symbols that can be tolerated is + // approximately the square-root of the search budget. + searchBudget := 4 * (nx + ny) // O(n) + + // The algorithm below is a greedy, meet-in-the-middle algorithm for + // computing sub-optimal edit-scripts between two lists. + // + // The algorithm is approximately as follows: + // • Searching for differences switches back-and-forth between + // a search that starts at the beginning (the top-left corner), and + // a search that starts at the end (the bottom-right corner). The goal of + // the search is connect with the search from the opposite corner. + // • As we search, we build a path in a greedy manner, where the first + // match seen is added to the path (this is sub-optimal, but provides a + // decent result in practice). When matches are found, we try the next pair + // of symbols in the lists and follow all matches as far as possible. + // • When searching for matches, we search along a diagonal going through + // through the "frontier" point. If no matches are found, we advance the + // frontier towards the opposite corner. + // • This algorithm terminates when either the X coordinates or the + // Y coordinates of the forward and reverse frontier points ever intersect. + // + // This algorithm is correct even if searching only in the forward direction + // or in the reverse direction. We do both because it is commonly observed + // that two lists commonly differ because elements were added to the front + // or end of the other list. + // + // Running the tests with the "debug" build tag prints a visualization of + // the algorithm running in real-time. This is educational for understanding + // how the algorithm works. See debug_enable.go. + f = debug.Begin(nx, ny, f, &fwdPath.es, &revPath.es) + for { + // Forward search from the beginning. + if fwdFrontier.X >= revFrontier.X || fwdFrontier.Y >= revFrontier.Y || searchBudget == 0 { + break + } + for stop1, stop2, i := false, false, 0; !(stop1 && stop2) && searchBudget > 0; i++ { + // Search in a diagonal pattern for a match. + z := zigzag(i) + p := point{fwdFrontier.X + z, fwdFrontier.Y - z} + switch { + case p.X >= revPath.X || p.Y < fwdPath.Y: + stop1 = true // Hit top-right corner + case p.Y >= revPath.Y || p.X < fwdPath.X: + stop2 = true // Hit bottom-left corner + case f(p.X, p.Y).Equal(): + // Match found, so connect the path to this point. + fwdPath.connect(p, f) + fwdPath.append(Identity) + // Follow sequence of matches as far as possible. + for fwdPath.X < revPath.X && fwdPath.Y < revPath.Y { + if !f(fwdPath.X, fwdPath.Y).Equal() { + break + } + fwdPath.append(Identity) + } + fwdFrontier = fwdPath.point + stop1, stop2 = true, true + default: + searchBudget-- // Match not found + } + debug.Update() + } + // Advance the frontier towards reverse point. + if revPath.X-fwdFrontier.X >= revPath.Y-fwdFrontier.Y { + fwdFrontier.X++ + } else { + fwdFrontier.Y++ + } + + // Reverse search from the end. + if fwdFrontier.X >= revFrontier.X || fwdFrontier.Y >= revFrontier.Y || searchBudget == 0 { + break + } + for stop1, stop2, i := false, false, 0; !(stop1 && stop2) && searchBudget > 0; i++ { + // Search in a diagonal pattern for a match. + z := zigzag(i) + p := point{revFrontier.X - z, revFrontier.Y + z} + switch { + case fwdPath.X >= p.X || revPath.Y < p.Y: + stop1 = true // Hit bottom-left corner + case fwdPath.Y >= p.Y || revPath.X < p.X: + stop2 = true // Hit top-right corner + case f(p.X-1, p.Y-1).Equal(): + // Match found, so connect the path to this point. + revPath.connect(p, f) + revPath.append(Identity) + // Follow sequence of matches as far as possible. + for fwdPath.X < revPath.X && fwdPath.Y < revPath.Y { + if !f(revPath.X-1, revPath.Y-1).Equal() { + break + } + revPath.append(Identity) + } + revFrontier = revPath.point + stop1, stop2 = true, true + default: + searchBudget-- // Match not found + } + debug.Update() + } + // Advance the frontier towards forward point. + if revFrontier.X-fwdPath.X >= revFrontier.Y-fwdPath.Y { + revFrontier.X-- + } else { + revFrontier.Y-- + } + } + + // Join the forward and reverse paths and then append the reverse path. + fwdPath.connect(revPath.point, f) + for i := len(revPath.es) - 1; i >= 0; i-- { + t := revPath.es[i] + revPath.es = revPath.es[:i] + fwdPath.append(t) + } + debug.Finish() + return fwdPath.es +} + +type path struct { + dir int // +1 if forward, -1 if reverse + point // Leading point of the EditScript path + es EditScript +} + +// connect appends any necessary Identity, Modified, UniqueX, or UniqueY types +// to the edit-script to connect p.point to dst. +func (p *path) connect(dst point, f EqualFunc) { + if p.dir > 0 { + // Connect in forward direction. + for dst.X > p.X && dst.Y > p.Y { + switch r := f(p.X, p.Y); { + case r.Equal(): + p.append(Identity) + case r.Similar(): + p.append(Modified) + case dst.X-p.X >= dst.Y-p.Y: + p.append(UniqueX) + default: + p.append(UniqueY) + } + } + for dst.X > p.X { + p.append(UniqueX) + } + for dst.Y > p.Y { + p.append(UniqueY) + } + } else { + // Connect in reverse direction. + for p.X > dst.X && p.Y > dst.Y { + switch r := f(p.X-1, p.Y-1); { + case r.Equal(): + p.append(Identity) + case r.Similar(): + p.append(Modified) + case p.Y-dst.Y >= p.X-dst.X: + p.append(UniqueY) + default: + p.append(UniqueX) + } + } + for p.X > dst.X { + p.append(UniqueX) + } + for p.Y > dst.Y { + p.append(UniqueY) + } + } +} + +func (p *path) append(t EditType) { + p.es = append(p.es, t) + switch t { + case Identity, Modified: + p.add(p.dir, p.dir) + case UniqueX: + p.add(p.dir, 0) + case UniqueY: + p.add(0, p.dir) + } + debug.Update() +} + +type point struct{ X, Y int } + +func (p *point) add(dx, dy int) { p.X += dx; p.Y += dy } + +// zigzag maps a consecutive sequence of integers to a zig-zag sequence. +// [0 1 2 3 4 5 ...] => [0 -1 +1 -2 +2 ...] +func zigzag(x int) int { + if x&1 != 0 { + x = ^x + } + return x >> 1 +} diff --git a/vendor/github.com/google/go-cmp/cmp/internal/function/func.go b/vendor/github.com/google/go-cmp/cmp/internal/function/func.go new file mode 100644 index 000000000..4c35ff11e --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/internal/function/func.go @@ -0,0 +1,49 @@ +// Copyright 2017, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +// Package function identifies function types. +package function + +import "reflect" + +type funcType int + +const ( + _ funcType = iota + + ttbFunc // func(T, T) bool + tibFunc // func(T, I) bool + trFunc // func(T) R + + Equal = ttbFunc // func(T, T) bool + EqualAssignable = tibFunc // func(T, I) bool; encapsulates func(T, T) bool + Transformer = trFunc // func(T) R + ValueFilter = ttbFunc // func(T, T) bool + Less = ttbFunc // func(T, T) bool +) + +var boolType = reflect.TypeOf(true) + +// IsType reports whether the reflect.Type is of the specified function type. +func IsType(t reflect.Type, ft funcType) bool { + if t == nil || t.Kind() != reflect.Func || t.IsVariadic() { + return false + } + ni, no := t.NumIn(), t.NumOut() + switch ft { + case ttbFunc: // func(T, T) bool + if ni == 2 && no == 1 && t.In(0) == t.In(1) && t.Out(0) == boolType { + return true + } + case tibFunc: // func(T, I) bool + if ni == 2 && no == 1 && t.In(0).AssignableTo(t.In(1)) && t.Out(0) == boolType { + return true + } + case trFunc: // func(T) R + if ni == 1 && no == 1 { + return true + } + } + return false +} diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/format.go b/vendor/github.com/google/go-cmp/cmp/internal/value/format.go new file mode 100644 index 000000000..bafb2d121 --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/internal/value/format.go @@ -0,0 +1,280 @@ +// Copyright 2017, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +// Package value provides functionality for reflect.Value types. +package value + +import ( + "fmt" + "reflect" + "strconv" + "strings" + "unicode" +) + +var stringerIface = reflect.TypeOf((*fmt.Stringer)(nil)).Elem() + +// Format formats the value v as a string. +// +// This is similar to fmt.Sprintf("%+v", v) except this: +// * Prints the type unless it can be elided +// * Avoids printing struct fields that are zero +// * Prints a nil-slice as being nil, not empty +// * Prints map entries in deterministic order +func Format(v reflect.Value, conf FormatConfig) string { + conf.printType = true + conf.followPointers = true + conf.realPointers = true + return formatAny(v, conf, visited{}) +} + +type FormatConfig struct { + UseStringer bool // Should the String method be used if available? + printType bool // Should we print the type before the value? + PrintPrimitiveType bool // Should we print the type of primitives? + followPointers bool // Should we recursively follow pointers? + realPointers bool // Should we print the real address of pointers? +} + +func formatAny(v reflect.Value, conf FormatConfig, m visited) string { + // TODO: Should this be a multi-line printout in certain situations? + + if !v.IsValid() { + return "" + } + if conf.UseStringer && v.Type().Implements(stringerIface) && v.CanInterface() { + if (v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface) && v.IsNil() { + return "" + } + + const stringerPrefix = "s" // Indicates that the String method was used + s := v.Interface().(fmt.Stringer).String() + return stringerPrefix + formatString(s) + } + + switch v.Kind() { + case reflect.Bool: + return formatPrimitive(v.Type(), v.Bool(), conf) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return formatPrimitive(v.Type(), v.Int(), conf) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + if v.Type().PkgPath() == "" || v.Kind() == reflect.Uintptr { + // Unnamed uints are usually bytes or words, so use hexadecimal. + return formatPrimitive(v.Type(), formatHex(v.Uint()), conf) + } + return formatPrimitive(v.Type(), v.Uint(), conf) + case reflect.Float32, reflect.Float64: + return formatPrimitive(v.Type(), v.Float(), conf) + case reflect.Complex64, reflect.Complex128: + return formatPrimitive(v.Type(), v.Complex(), conf) + case reflect.String: + return formatPrimitive(v.Type(), formatString(v.String()), conf) + case reflect.UnsafePointer, reflect.Chan, reflect.Func: + return formatPointer(v, conf) + case reflect.Ptr: + if v.IsNil() { + if conf.printType { + return fmt.Sprintf("(%v)(nil)", v.Type()) + } + return "" + } + if m.Visit(v) || !conf.followPointers { + return formatPointer(v, conf) + } + return "&" + formatAny(v.Elem(), conf, m) + case reflect.Interface: + if v.IsNil() { + if conf.printType { + return fmt.Sprintf("%v(nil)", v.Type()) + } + return "" + } + return formatAny(v.Elem(), conf, m) + case reflect.Slice: + if v.IsNil() { + if conf.printType { + return fmt.Sprintf("%v(nil)", v.Type()) + } + return "" + } + fallthrough + case reflect.Array: + var ss []string + subConf := conf + subConf.printType = v.Type().Elem().Kind() == reflect.Interface + for i := 0; i < v.Len(); i++ { + vi := v.Index(i) + if vi.CanAddr() { // Check for recursive elements + p := vi.Addr() + if m.Visit(p) { + subConf := conf + subConf.printType = true + ss = append(ss, "*"+formatPointer(p, subConf)) + continue + } + } + ss = append(ss, formatAny(vi, subConf, m)) + } + s := fmt.Sprintf("{%s}", strings.Join(ss, ", ")) + if conf.printType { + return v.Type().String() + s + } + return s + case reflect.Map: + if v.IsNil() { + if conf.printType { + return fmt.Sprintf("%v(nil)", v.Type()) + } + return "" + } + if m.Visit(v) { + return formatPointer(v, conf) + } + + var ss []string + keyConf, valConf := conf, conf + keyConf.printType = v.Type().Key().Kind() == reflect.Interface + keyConf.followPointers = false + valConf.printType = v.Type().Elem().Kind() == reflect.Interface + for _, k := range SortKeys(v.MapKeys()) { + sk := formatAny(k, keyConf, m) + sv := formatAny(v.MapIndex(k), valConf, m) + ss = append(ss, fmt.Sprintf("%s: %s", sk, sv)) + } + s := fmt.Sprintf("{%s}", strings.Join(ss, ", ")) + if conf.printType { + return v.Type().String() + s + } + return s + case reflect.Struct: + var ss []string + subConf := conf + subConf.printType = true + for i := 0; i < v.NumField(); i++ { + vv := v.Field(i) + if isZero(vv) { + continue // Elide zero value fields + } + name := v.Type().Field(i).Name + subConf.UseStringer = conf.UseStringer + s := formatAny(vv, subConf, m) + ss = append(ss, fmt.Sprintf("%s: %s", name, s)) + } + s := fmt.Sprintf("{%s}", strings.Join(ss, ", ")) + if conf.printType { + return v.Type().String() + s + } + return s + default: + panic(fmt.Sprintf("%v kind not handled", v.Kind())) + } +} + +func formatString(s string) string { + // Use quoted string if it the same length as a raw string literal. + // Otherwise, attempt to use the raw string form. + qs := strconv.Quote(s) + if len(qs) == 1+len(s)+1 { + return qs + } + + // Disallow newlines to ensure output is a single line. + // Only allow printable runes for readability purposes. + rawInvalid := func(r rune) bool { + return r == '`' || r == '\n' || !unicode.IsPrint(r) + } + if strings.IndexFunc(s, rawInvalid) < 0 { + return "`" + s + "`" + } + return qs +} + +func formatPrimitive(t reflect.Type, v interface{}, conf FormatConfig) string { + if conf.printType && (conf.PrintPrimitiveType || t.PkgPath() != "") { + return fmt.Sprintf("%v(%v)", t, v) + } + return fmt.Sprintf("%v", v) +} + +func formatPointer(v reflect.Value, conf FormatConfig) string { + p := v.Pointer() + if !conf.realPointers { + p = 0 // For deterministic printing purposes + } + s := formatHex(uint64(p)) + if conf.printType { + return fmt.Sprintf("(%v)(%s)", v.Type(), s) + } + return s +} + +func formatHex(u uint64) string { + var f string + switch { + case u <= 0xff: + f = "0x%02x" + case u <= 0xffff: + f = "0x%04x" + case u <= 0xffffff: + f = "0x%06x" + case u <= 0xffffffff: + f = "0x%08x" + case u <= 0xffffffffff: + f = "0x%010x" + case u <= 0xffffffffffff: + f = "0x%012x" + case u <= 0xffffffffffffff: + f = "0x%014x" + case u <= 0xffffffffffffffff: + f = "0x%016x" + } + return fmt.Sprintf(f, u) +} + +// isZero reports whether v is the zero value. +// This does not rely on Interface and so can be used on unexported fields. +func isZero(v reflect.Value) bool { + switch v.Kind() { + case reflect.Bool: + return v.Bool() == false + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.Complex64, reflect.Complex128: + return v.Complex() == 0 + case reflect.String: + return v.String() == "" + case reflect.UnsafePointer: + return v.Pointer() == 0 + case reflect.Chan, reflect.Func, reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice: + return v.IsNil() + case reflect.Array: + for i := 0; i < v.Len(); i++ { + if !isZero(v.Index(i)) { + return false + } + } + return true + case reflect.Struct: + for i := 0; i < v.NumField(); i++ { + if !isZero(v.Field(i)) { + return false + } + } + return true + } + return false +} + +type visited map[Pointer]bool + +func (m visited) Visit(v reflect.Value) bool { + p := PointerOf(v) + visited := m[p] + m[p] = true + return visited +} diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go b/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go new file mode 100644 index 000000000..0a01c4796 --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go @@ -0,0 +1,23 @@ +// Copyright 2018, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +// +build purego + +package value + +import "reflect" + +// Pointer is an opaque typed pointer and is guaranteed to be comparable. +type Pointer struct { + p uintptr + t reflect.Type +} + +// PointerOf returns a Pointer from v, which must be a +// reflect.Ptr, reflect.Slice, or reflect.Map. +func PointerOf(v reflect.Value) Pointer { + // NOTE: Storing a pointer as an uintptr is technically incorrect as it + // assumes that the GC implementation does not use a moving collector. + return Pointer{v.Pointer(), v.Type()} +} diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_unsafe.go b/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_unsafe.go new file mode 100644 index 000000000..da134ae2a --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_unsafe.go @@ -0,0 +1,26 @@ +// Copyright 2018, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +// +build !purego + +package value + +import ( + "reflect" + "unsafe" +) + +// Pointer is an opaque typed pointer and is guaranteed to be comparable. +type Pointer struct { + p unsafe.Pointer + t reflect.Type +} + +// PointerOf returns a Pointer from v, which must be a +// reflect.Ptr, reflect.Slice, or reflect.Map. +func PointerOf(v reflect.Value) Pointer { + // The proper representation of a pointer is unsafe.Pointer, + // which is necessary if the GC ever uses a moving collector. + return Pointer{unsafe.Pointer(v.Pointer()), v.Type()} +} diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/sort.go b/vendor/github.com/google/go-cmp/cmp/internal/value/sort.go new file mode 100644 index 000000000..fe8aa27a0 --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/internal/value/sort.go @@ -0,0 +1,111 @@ +// Copyright 2017, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +package value + +import ( + "fmt" + "math" + "reflect" + "sort" +) + +// SortKeys sorts a list of map keys, deduplicating keys if necessary. +// The type of each value must be comparable. +func SortKeys(vs []reflect.Value) []reflect.Value { + if len(vs) == 0 { + return vs + } + + // Sort the map keys. + sort.Sort(valueSorter(vs)) + + // Deduplicate keys (fails for NaNs). + vs2 := vs[:1] + for _, v := range vs[1:] { + if isLess(vs2[len(vs2)-1], v) { + vs2 = append(vs2, v) + } + } + return vs2 +} + +// TODO: Use sort.Slice once Google AppEngine is on Go1.8 or above. +type valueSorter []reflect.Value + +func (vs valueSorter) Len() int { return len(vs) } +func (vs valueSorter) Less(i, j int) bool { return isLess(vs[i], vs[j]) } +func (vs valueSorter) Swap(i, j int) { vs[i], vs[j] = vs[j], vs[i] } + +// isLess is a generic function for sorting arbitrary map keys. +// The inputs must be of the same type and must be comparable. +func isLess(x, y reflect.Value) bool { + switch x.Type().Kind() { + case reflect.Bool: + return !x.Bool() && y.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return x.Int() < y.Int() + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return x.Uint() < y.Uint() + case reflect.Float32, reflect.Float64: + fx, fy := x.Float(), y.Float() + return fx < fy || math.IsNaN(fx) && !math.IsNaN(fy) + case reflect.Complex64, reflect.Complex128: + cx, cy := x.Complex(), y.Complex() + rx, ix, ry, iy := real(cx), imag(cx), real(cy), imag(cy) + if rx == ry || (math.IsNaN(rx) && math.IsNaN(ry)) { + return ix < iy || math.IsNaN(ix) && !math.IsNaN(iy) + } + return rx < ry || math.IsNaN(rx) && !math.IsNaN(ry) + case reflect.Ptr, reflect.UnsafePointer, reflect.Chan: + return x.Pointer() < y.Pointer() + case reflect.String: + return x.String() < y.String() + case reflect.Array: + for i := 0; i < x.Len(); i++ { + if isLess(x.Index(i), y.Index(i)) { + return true + } + if isLess(y.Index(i), x.Index(i)) { + return false + } + } + return false + case reflect.Struct: + for i := 0; i < x.NumField(); i++ { + if isLess(x.Field(i), y.Field(i)) { + return true + } + if isLess(y.Field(i), x.Field(i)) { + return false + } + } + return false + case reflect.Interface: + vx, vy := x.Elem(), y.Elem() + if !vx.IsValid() || !vy.IsValid() { + return !vx.IsValid() && vy.IsValid() + } + tx, ty := vx.Type(), vy.Type() + if tx == ty { + return isLess(x.Elem(), y.Elem()) + } + if tx.Kind() != ty.Kind() { + return vx.Kind() < vy.Kind() + } + if tx.String() != ty.String() { + return tx.String() < ty.String() + } + if tx.PkgPath() != ty.PkgPath() { + return tx.PkgPath() < ty.PkgPath() + } + // This can happen in rare situations, so we fallback to just comparing + // the unique pointer for a reflect.Type. This guarantees deterministic + // ordering within a program, but it is obviously not stable. + return reflect.ValueOf(vx.Type()).Pointer() < reflect.ValueOf(vy.Type()).Pointer() + default: + // Must be Func, Map, or Slice; which are not comparable. + panic(fmt.Sprintf("%T is not comparable", x.Type())) + } +} diff --git a/vendor/github.com/google/go-cmp/cmp/options.go b/vendor/github.com/google/go-cmp/cmp/options.go new file mode 100644 index 000000000..cc3a4b9e7 --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/options.go @@ -0,0 +1,456 @@ +// Copyright 2017, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +package cmp + +import ( + "fmt" + "reflect" + "runtime" + "strings" + + "github.com/google/go-cmp/cmp/internal/function" +) + +// Option configures for specific behavior of Equal and Diff. In particular, +// the fundamental Option functions (Ignore, Transformer, and Comparer), +// configure how equality is determined. +// +// The fundamental options may be composed with filters (FilterPath and +// FilterValues) to control the scope over which they are applied. +// +// The cmp/cmpopts package provides helper functions for creating options that +// may be used with Equal and Diff. +type Option interface { + // filter applies all filters and returns the option that remains. + // Each option may only read s.curPath and call s.callTTBFunc. + // + // An Options is returned only if multiple comparers or transformers + // can apply simultaneously and will only contain values of those types + // or sub-Options containing values of those types. + filter(s *state, vx, vy reflect.Value, t reflect.Type) applicableOption +} + +// applicableOption represents the following types: +// Fundamental: ignore | invalid | *comparer | *transformer +// Grouping: Options +type applicableOption interface { + Option + + // apply executes the option, which may mutate s or panic. + apply(s *state, vx, vy reflect.Value) +} + +// coreOption represents the following types: +// Fundamental: ignore | invalid | *comparer | *transformer +// Filters: *pathFilter | *valuesFilter +type coreOption interface { + Option + isCore() +} + +type core struct{} + +func (core) isCore() {} + +// Options is a list of Option values that also satisfies the Option interface. +// Helper comparison packages may return an Options value when packing multiple +// Option values into a single Option. When this package processes an Options, +// it will be implicitly expanded into a flat list. +// +// Applying a filter on an Options is equivalent to applying that same filter +// on all individual options held within. +type Options []Option + +func (opts Options) filter(s *state, vx, vy reflect.Value, t reflect.Type) (out applicableOption) { + for _, opt := range opts { + switch opt := opt.filter(s, vx, vy, t); opt.(type) { + case ignore: + return ignore{} // Only ignore can short-circuit evaluation + case invalid: + out = invalid{} // Takes precedence over comparer or transformer + case *comparer, *transformer, Options: + switch out.(type) { + case nil: + out = opt + case invalid: + // Keep invalid + case *comparer, *transformer, Options: + out = Options{out, opt} // Conflicting comparers or transformers + } + } + } + return out +} + +func (opts Options) apply(s *state, _, _ reflect.Value) { + const warning = "ambiguous set of applicable options" + const help = "consider using filters to ensure at most one Comparer or Transformer may apply" + var ss []string + for _, opt := range flattenOptions(nil, opts) { + ss = append(ss, fmt.Sprint(opt)) + } + set := strings.Join(ss, "\n\t") + panic(fmt.Sprintf("%s at %#v:\n\t%s\n%s", warning, s.curPath, set, help)) +} + +func (opts Options) String() string { + var ss []string + for _, opt := range opts { + ss = append(ss, fmt.Sprint(opt)) + } + return fmt.Sprintf("Options{%s}", strings.Join(ss, ", ")) +} + +// FilterPath returns a new Option where opt is only evaluated if filter f +// returns true for the current Path in the value tree. +// +// The option passed in may be an Ignore, Transformer, Comparer, Options, or +// a previously filtered Option. +func FilterPath(f func(Path) bool, opt Option) Option { + if f == nil { + panic("invalid path filter function") + } + if opt := normalizeOption(opt); opt != nil { + return &pathFilter{fnc: f, opt: opt} + } + return nil +} + +type pathFilter struct { + core + fnc func(Path) bool + opt Option +} + +func (f pathFilter) filter(s *state, vx, vy reflect.Value, t reflect.Type) applicableOption { + if f.fnc(s.curPath) { + return f.opt.filter(s, vx, vy, t) + } + return nil +} + +func (f pathFilter) String() string { + fn := getFuncName(reflect.ValueOf(f.fnc).Pointer()) + return fmt.Sprintf("FilterPath(%s, %v)", fn, f.opt) +} + +// FilterValues returns a new Option where opt is only evaluated if filter f, +// which is a function of the form "func(T, T) bool", returns true for the +// current pair of values being compared. If the type of the values is not +// assignable to T, then this filter implicitly returns false. +// +// The filter function must be +// symmetric (i.e., agnostic to the order of the inputs) and +// deterministic (i.e., produces the same result when given the same inputs). +// If T is an interface, it is possible that f is called with two values with +// different concrete types that both implement T. +// +// The option passed in may be an Ignore, Transformer, Comparer, Options, or +// a previously filtered Option. +func FilterValues(f interface{}, opt Option) Option { + v := reflect.ValueOf(f) + if !function.IsType(v.Type(), function.ValueFilter) || v.IsNil() { + panic(fmt.Sprintf("invalid values filter function: %T", f)) + } + if opt := normalizeOption(opt); opt != nil { + vf := &valuesFilter{fnc: v, opt: opt} + if ti := v.Type().In(0); ti.Kind() != reflect.Interface || ti.NumMethod() > 0 { + vf.typ = ti + } + return vf + } + return nil +} + +type valuesFilter struct { + core + typ reflect.Type // T + fnc reflect.Value // func(T, T) bool + opt Option +} + +func (f valuesFilter) filter(s *state, vx, vy reflect.Value, t reflect.Type) applicableOption { + if !vx.IsValid() || !vy.IsValid() { + return invalid{} + } + if (f.typ == nil || t.AssignableTo(f.typ)) && s.callTTBFunc(f.fnc, vx, vy) { + return f.opt.filter(s, vx, vy, t) + } + return nil +} + +func (f valuesFilter) String() string { + fn := getFuncName(f.fnc.Pointer()) + return fmt.Sprintf("FilterValues(%s, %v)", fn, f.opt) +} + +// Ignore is an Option that causes all comparisons to be ignored. +// This value is intended to be combined with FilterPath or FilterValues. +// It is an error to pass an unfiltered Ignore option to Equal. +func Ignore() Option { return ignore{} } + +type ignore struct{ core } + +func (ignore) isFiltered() bool { return false } +func (ignore) filter(_ *state, _, _ reflect.Value, _ reflect.Type) applicableOption { return ignore{} } +func (ignore) apply(_ *state, _, _ reflect.Value) { return } +func (ignore) String() string { return "Ignore()" } + +// invalid is a sentinel Option type to indicate that some options could not +// be evaluated due to unexported fields. +type invalid struct{ core } + +func (invalid) filter(_ *state, _, _ reflect.Value, _ reflect.Type) applicableOption { return invalid{} } +func (invalid) apply(s *state, _, _ reflect.Value) { + const help = "consider using AllowUnexported or cmpopts.IgnoreUnexported" + panic(fmt.Sprintf("cannot handle unexported field: %#v\n%s", s.curPath, help)) +} + +// Transformer returns an Option that applies a transformation function that +// converts values of a certain type into that of another. +// +// The transformer f must be a function "func(T) R" that converts values of +// type T to those of type R and is implicitly filtered to input values +// assignable to T. The transformer must not mutate T in any way. +// +// To help prevent some cases of infinite recursive cycles applying the +// same transform to the output of itself (e.g., in the case where the +// input and output types are the same), an implicit filter is added such that +// a transformer is applicable only if that exact transformer is not already +// in the tail of the Path since the last non-Transform step. +// For situations where the implicit filter is still insufficient, +// consider using cmpopts.AcyclicTransformer, which adds a filter +// to prevent the transformer from being recursively applied upon itself. +// +// The name is a user provided label that is used as the Transform.Name in the +// transformation PathStep. If empty, an arbitrary name is used. +func Transformer(name string, f interface{}) Option { + v := reflect.ValueOf(f) + if !function.IsType(v.Type(), function.Transformer) || v.IsNil() { + panic(fmt.Sprintf("invalid transformer function: %T", f)) + } + if name == "" { + name = "λ" // Lambda-symbol as place-holder for anonymous transformer + } + if !isValid(name) { + panic(fmt.Sprintf("invalid name: %q", name)) + } + tr := &transformer{name: name, fnc: reflect.ValueOf(f)} + if ti := v.Type().In(0); ti.Kind() != reflect.Interface || ti.NumMethod() > 0 { + tr.typ = ti + } + return tr +} + +type transformer struct { + core + name string + typ reflect.Type // T + fnc reflect.Value // func(T) R +} + +func (tr *transformer) isFiltered() bool { return tr.typ != nil } + +func (tr *transformer) filter(s *state, _, _ reflect.Value, t reflect.Type) applicableOption { + for i := len(s.curPath) - 1; i >= 0; i-- { + if t, ok := s.curPath[i].(*transform); !ok { + break // Hit most recent non-Transform step + } else if tr == t.trans { + return nil // Cannot directly use same Transform + } + } + if tr.typ == nil || t.AssignableTo(tr.typ) { + return tr + } + return nil +} + +func (tr *transformer) apply(s *state, vx, vy reflect.Value) { + // Update path before calling the Transformer so that dynamic checks + // will use the updated path. + s.curPath.push(&transform{pathStep{tr.fnc.Type().Out(0)}, tr}) + defer s.curPath.pop() + + vx = s.callTRFunc(tr.fnc, vx) + vy = s.callTRFunc(tr.fnc, vy) + s.compareAny(vx, vy) +} + +func (tr transformer) String() string { + return fmt.Sprintf("Transformer(%s, %s)", tr.name, getFuncName(tr.fnc.Pointer())) +} + +// Comparer returns an Option that determines whether two values are equal +// to each other. +// +// The comparer f must be a function "func(T, T) bool" and is implicitly +// filtered to input values assignable to T. If T is an interface, it is +// possible that f is called with two values of different concrete types that +// both implement T. +// +// The equality function must be: +// • Symmetric: equal(x, y) == equal(y, x) +// • Deterministic: equal(x, y) == equal(x, y) +// • Pure: equal(x, y) does not modify x or y +func Comparer(f interface{}) Option { + v := reflect.ValueOf(f) + if !function.IsType(v.Type(), function.Equal) || v.IsNil() { + panic(fmt.Sprintf("invalid comparer function: %T", f)) + } + cm := &comparer{fnc: v} + if ti := v.Type().In(0); ti.Kind() != reflect.Interface || ti.NumMethod() > 0 { + cm.typ = ti + } + return cm +} + +type comparer struct { + core + typ reflect.Type // T + fnc reflect.Value // func(T, T) bool +} + +func (cm *comparer) isFiltered() bool { return cm.typ != nil } + +func (cm *comparer) filter(_ *state, _, _ reflect.Value, t reflect.Type) applicableOption { + if cm.typ == nil || t.AssignableTo(cm.typ) { + return cm + } + return nil +} + +func (cm *comparer) apply(s *state, vx, vy reflect.Value) { + eq := s.callTTBFunc(cm.fnc, vx, vy) + s.report(eq, vx, vy) +} + +func (cm comparer) String() string { + return fmt.Sprintf("Comparer(%s)", getFuncName(cm.fnc.Pointer())) +} + +// AllowUnexported returns an Option that forcibly allows operations on +// unexported fields in certain structs, which are specified by passing in a +// value of each struct type. +// +// Users of this option must understand that comparing on unexported fields +// from external packages is not safe since changes in the internal +// implementation of some external package may cause the result of Equal +// to unexpectedly change. However, it may be valid to use this option on types +// defined in an internal package where the semantic meaning of an unexported +// field is in the control of the user. +// +// For some cases, a custom Comparer should be used instead that defines +// equality as a function of the public API of a type rather than the underlying +// unexported implementation. +// +// For example, the reflect.Type documentation defines equality to be determined +// by the == operator on the interface (essentially performing a shallow pointer +// comparison) and most attempts to compare *regexp.Regexp types are interested +// in only checking that the regular expression strings are equal. +// Both of these are accomplished using Comparers: +// +// Comparer(func(x, y reflect.Type) bool { return x == y }) +// Comparer(func(x, y *regexp.Regexp) bool { return x.String() == y.String() }) +// +// In other cases, the cmpopts.IgnoreUnexported option can be used to ignore +// all unexported fields on specified struct types. +func AllowUnexported(types ...interface{}) Option { + if !supportAllowUnexported { + panic("AllowUnexported is not supported on purego builds, Google App Engine Standard, or GopherJS") + } + m := make(map[reflect.Type]bool) + for _, typ := range types { + t := reflect.TypeOf(typ) + if t.Kind() != reflect.Struct { + panic(fmt.Sprintf("invalid struct type: %T", typ)) + } + m[t] = true + } + return visibleStructs(m) +} + +type visibleStructs map[reflect.Type]bool + +func (visibleStructs) filter(_ *state, _, _ reflect.Value, _ reflect.Type) applicableOption { + panic("not implemented") +} + +// reporter is an Option that configures how differences are reported. +type reporter interface { + // TODO: Not exported yet. + // + // Perhaps add PushStep and PopStep and change Report to only accept + // a PathStep instead of the full-path? Adding a PushStep and PopStep makes + // it clear that we are traversing the value tree in a depth-first-search + // manner, which has an effect on how values are printed. + + Option + + // Report is called for every comparison made and will be provided with + // the two values being compared, the equality result, and the + // current path in the value tree. It is possible for x or y to be an + // invalid reflect.Value if one of the values is non-existent; + // which is possible with maps and slices. + Report(x, y reflect.Value, eq bool, p Path) +} + +// normalizeOption normalizes the input options such that all Options groups +// are flattened and groups with a single element are reduced to that element. +// Only coreOptions and Options containing coreOptions are allowed. +func normalizeOption(src Option) Option { + switch opts := flattenOptions(nil, Options{src}); len(opts) { + case 0: + return nil + case 1: + return opts[0] + default: + return opts + } +} + +// flattenOptions copies all options in src to dst as a flat list. +// Only coreOptions and Options containing coreOptions are allowed. +func flattenOptions(dst, src Options) Options { + for _, opt := range src { + switch opt := opt.(type) { + case nil: + continue + case Options: + dst = flattenOptions(dst, opt) + case coreOption: + dst = append(dst, opt) + default: + panic(fmt.Sprintf("invalid option type: %T", opt)) + } + } + return dst +} + +// getFuncName returns a short function name from the pointer. +// The string parsing logic works up until Go1.9. +func getFuncName(p uintptr) string { + fnc := runtime.FuncForPC(p) + if fnc == nil { + return "" + } + name := fnc.Name() // E.g., "long/path/name/mypkg.(mytype).(long/path/name/mypkg.myfunc)-fm" + if strings.HasSuffix(name, ")-fm") || strings.HasSuffix(name, ")·fm") { + // Strip the package name from method name. + name = strings.TrimSuffix(name, ")-fm") + name = strings.TrimSuffix(name, ")·fm") + if i := strings.LastIndexByte(name, '('); i >= 0 { + methodName := name[i+1:] // E.g., "long/path/name/mypkg.myfunc" + if j := strings.LastIndexByte(methodName, '.'); j >= 0 { + methodName = methodName[j+1:] // E.g., "myfunc" + } + name = name[:i] + methodName // E.g., "long/path/name/mypkg.(mytype)." + "myfunc" + } + } + if i := strings.LastIndexByte(name, '/'); i >= 0 { + // Strip the package name. + name = name[i+1:] // E.g., "mypkg.(mytype).myfunc" + } + return name +} diff --git a/vendor/github.com/google/go-cmp/cmp/path.go b/vendor/github.com/google/go-cmp/cmp/path.go new file mode 100644 index 000000000..c08a3cf80 --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/path.go @@ -0,0 +1,309 @@ +// Copyright 2017, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +package cmp + +import ( + "fmt" + "reflect" + "strings" + "unicode" + "unicode/utf8" +) + +type ( + // Path is a list of PathSteps describing the sequence of operations to get + // from some root type to the current position in the value tree. + // The first Path element is always an operation-less PathStep that exists + // simply to identify the initial type. + // + // When traversing structs with embedded structs, the embedded struct will + // always be accessed as a field before traversing the fields of the + // embedded struct themselves. That is, an exported field from the + // embedded struct will never be accessed directly from the parent struct. + Path []PathStep + + // PathStep is a union-type for specific operations to traverse + // a value's tree structure. Users of this package never need to implement + // these types as values of this type will be returned by this package. + PathStep interface { + String() string + Type() reflect.Type // Resulting type after performing the path step + isPathStep() + } + + // SliceIndex is an index operation on a slice or array at some index Key. + SliceIndex interface { + PathStep + Key() int // May return -1 if in a split state + + // SplitKeys returns the indexes for indexing into slices in the + // x and y values, respectively. These indexes may differ due to the + // insertion or removal of an element in one of the slices, causing + // all of the indexes to be shifted. If an index is -1, then that + // indicates that the element does not exist in the associated slice. + // + // Key is guaranteed to return -1 if and only if the indexes returned + // by SplitKeys are not the same. SplitKeys will never return -1 for + // both indexes. + SplitKeys() (x int, y int) + + isSliceIndex() + } + // MapIndex is an index operation on a map at some index Key. + MapIndex interface { + PathStep + Key() reflect.Value + isMapIndex() + } + // TypeAssertion represents a type assertion on an interface. + TypeAssertion interface { + PathStep + isTypeAssertion() + } + // StructField represents a struct field access on a field called Name. + StructField interface { + PathStep + Name() string + Index() int + isStructField() + } + // Indirect represents pointer indirection on the parent type. + Indirect interface { + PathStep + isIndirect() + } + // Transform is a transformation from the parent type to the current type. + Transform interface { + PathStep + Name() string + Func() reflect.Value + + // Option returns the originally constructed Transformer option. + // The == operator can be used to detect the exact option used. + Option() Option + + isTransform() + } +) + +func (pa *Path) push(s PathStep) { + *pa = append(*pa, s) +} + +func (pa *Path) pop() { + *pa = (*pa)[:len(*pa)-1] +} + +// Last returns the last PathStep in the Path. +// If the path is empty, this returns a non-nil PathStep that reports a nil Type. +func (pa Path) Last() PathStep { + return pa.Index(-1) +} + +// Index returns the ith step in the Path and supports negative indexing. +// A negative index starts counting from the tail of the Path such that -1 +// refers to the last step, -2 refers to the second-to-last step, and so on. +// If index is invalid, this returns a non-nil PathStep that reports a nil Type. +func (pa Path) Index(i int) PathStep { + if i < 0 { + i = len(pa) + i + } + if i < 0 || i >= len(pa) { + return pathStep{} + } + return pa[i] +} + +// String returns the simplified path to a node. +// The simplified path only contains struct field accesses. +// +// For example: +// MyMap.MySlices.MyField +func (pa Path) String() string { + var ss []string + for _, s := range pa { + if _, ok := s.(*structField); ok { + ss = append(ss, s.String()) + } + } + return strings.TrimPrefix(strings.Join(ss, ""), ".") +} + +// GoString returns the path to a specific node using Go syntax. +// +// For example: +// (*root.MyMap["key"].(*mypkg.MyStruct).MySlices)[2][3].MyField +func (pa Path) GoString() string { + var ssPre, ssPost []string + var numIndirect int + for i, s := range pa { + var nextStep PathStep + if i+1 < len(pa) { + nextStep = pa[i+1] + } + switch s := s.(type) { + case *indirect: + numIndirect++ + pPre, pPost := "(", ")" + switch nextStep.(type) { + case *indirect: + continue // Next step is indirection, so let them batch up + case *structField: + numIndirect-- // Automatic indirection on struct fields + case nil: + pPre, pPost = "", "" // Last step; no need for parenthesis + } + if numIndirect > 0 { + ssPre = append(ssPre, pPre+strings.Repeat("*", numIndirect)) + ssPost = append(ssPost, pPost) + } + numIndirect = 0 + continue + case *transform: + ssPre = append(ssPre, s.trans.name+"(") + ssPost = append(ssPost, ")") + continue + case *typeAssertion: + // As a special-case, elide type assertions on anonymous types + // since they are typically generated dynamically and can be very + // verbose. For example, some transforms return interface{} because + // of Go's lack of generics, but typically take in and return the + // exact same concrete type. + if s.Type().PkgPath() == "" { + continue + } + } + ssPost = append(ssPost, s.String()) + } + for i, j := 0, len(ssPre)-1; i < j; i, j = i+1, j-1 { + ssPre[i], ssPre[j] = ssPre[j], ssPre[i] + } + return strings.Join(ssPre, "") + strings.Join(ssPost, "") +} + +type ( + pathStep struct { + typ reflect.Type + } + + sliceIndex struct { + pathStep + xkey, ykey int + } + mapIndex struct { + pathStep + key reflect.Value + } + typeAssertion struct { + pathStep + } + structField struct { + pathStep + name string + idx int + + // These fields are used for forcibly accessing an unexported field. + // pvx, pvy, and field are only valid if unexported is true. + unexported bool + force bool // Forcibly allow visibility + pvx, pvy reflect.Value // Parent values + field reflect.StructField // Field information + } + indirect struct { + pathStep + } + transform struct { + pathStep + trans *transformer + } +) + +func (ps pathStep) Type() reflect.Type { return ps.typ } +func (ps pathStep) String() string { + if ps.typ == nil { + return "" + } + s := ps.typ.String() + if s == "" || strings.ContainsAny(s, "{}\n") { + return "root" // Type too simple or complex to print + } + return fmt.Sprintf("{%s}", s) +} + +func (si sliceIndex) String() string { + switch { + case si.xkey == si.ykey: + return fmt.Sprintf("[%d]", si.xkey) + case si.ykey == -1: + // [5->?] means "I don't know where X[5] went" + return fmt.Sprintf("[%d->?]", si.xkey) + case si.xkey == -1: + // [?->3] means "I don't know where Y[3] came from" + return fmt.Sprintf("[?->%d]", si.ykey) + default: + // [5->3] means "X[5] moved to Y[3]" + return fmt.Sprintf("[%d->%d]", si.xkey, si.ykey) + } +} +func (mi mapIndex) String() string { return fmt.Sprintf("[%#v]", mi.key) } +func (ta typeAssertion) String() string { return fmt.Sprintf(".(%v)", ta.typ) } +func (sf structField) String() string { return fmt.Sprintf(".%s", sf.name) } +func (in indirect) String() string { return "*" } +func (tf transform) String() string { return fmt.Sprintf("%s()", tf.trans.name) } + +func (si sliceIndex) Key() int { + if si.xkey != si.ykey { + return -1 + } + return si.xkey +} +func (si sliceIndex) SplitKeys() (x, y int) { return si.xkey, si.ykey } +func (mi mapIndex) Key() reflect.Value { return mi.key } +func (sf structField) Name() string { return sf.name } +func (sf structField) Index() int { return sf.idx } +func (tf transform) Name() string { return tf.trans.name } +func (tf transform) Func() reflect.Value { return tf.trans.fnc } +func (tf transform) Option() Option { return tf.trans } + +func (pathStep) isPathStep() {} +func (sliceIndex) isSliceIndex() {} +func (mapIndex) isMapIndex() {} +func (typeAssertion) isTypeAssertion() {} +func (structField) isStructField() {} +func (indirect) isIndirect() {} +func (transform) isTransform() {} + +var ( + _ SliceIndex = sliceIndex{} + _ MapIndex = mapIndex{} + _ TypeAssertion = typeAssertion{} + _ StructField = structField{} + _ Indirect = indirect{} + _ Transform = transform{} + + _ PathStep = sliceIndex{} + _ PathStep = mapIndex{} + _ PathStep = typeAssertion{} + _ PathStep = structField{} + _ PathStep = indirect{} + _ PathStep = transform{} +) + +// isExported reports whether the identifier is exported. +func isExported(id string) bool { + r, _ := utf8.DecodeRuneInString(id) + return unicode.IsUpper(r) +} + +// isValid reports whether the identifier is valid. +// Empty and underscore-only strings are not valid. +func isValid(id string) bool { + ok := id != "" && id != "_" + for j, c := range id { + ok = ok && (j > 0 || !unicode.IsDigit(c)) + ok = ok && (c == '_' || unicode.IsLetter(c) || unicode.IsDigit(c)) + } + return ok +} diff --git a/vendor/github.com/google/go-cmp/cmp/reporter.go b/vendor/github.com/google/go-cmp/cmp/reporter.go new file mode 100644 index 000000000..20e9f18e0 --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/reporter.go @@ -0,0 +1,53 @@ +// Copyright 2017, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +package cmp + +import ( + "fmt" + "reflect" + "strings" + + "github.com/google/go-cmp/cmp/internal/value" +) + +type defaultReporter struct { + Option + diffs []string // List of differences, possibly truncated + ndiffs int // Total number of differences + nbytes int // Number of bytes in diffs + nlines int // Number of lines in diffs +} + +var _ reporter = (*defaultReporter)(nil) + +func (r *defaultReporter) Report(x, y reflect.Value, eq bool, p Path) { + if eq { + return // Ignore equal results + } + const maxBytes = 4096 + const maxLines = 256 + r.ndiffs++ + if r.nbytes < maxBytes && r.nlines < maxLines { + sx := value.Format(x, value.FormatConfig{UseStringer: true}) + sy := value.Format(y, value.FormatConfig{UseStringer: true}) + if sx == sy { + // Unhelpful output, so use more exact formatting. + sx = value.Format(x, value.FormatConfig{PrintPrimitiveType: true}) + sy = value.Format(y, value.FormatConfig{PrintPrimitiveType: true}) + } + s := fmt.Sprintf("%#v:\n\t-: %s\n\t+: %s\n", p, sx, sy) + r.diffs = append(r.diffs, s) + r.nbytes += len(s) + r.nlines += strings.Count(s, "\n") + } +} + +func (r *defaultReporter) String() string { + s := strings.Join(r.diffs, "") + if r.ndiffs == len(r.diffs) { + return s + } + return fmt.Sprintf("%s... %d more differences ...", s, r.ndiffs-len(r.diffs)) +} diff --git a/vendor/github.com/google/go-cmp/cmp/unsafe_reflect.go b/vendor/github.com/google/go-cmp/cmp/unsafe_reflect.go new file mode 100644 index 000000000..579b65507 --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/unsafe_reflect.go @@ -0,0 +1,23 @@ +// Copyright 2017, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +// +build !purego,!appengine,!js + +package cmp + +import ( + "reflect" + "unsafe" +) + +const supportAllowUnexported = true + +// unsafeRetrieveField uses unsafe to forcibly retrieve any field from a struct +// such that the value has read-write permissions. +// +// The parent struct, v, must be addressable, while f must be a StructField +// describing the field to retrieve. +func unsafeRetrieveField(v reflect.Value, f reflect.StructField) reflect.Value { + return reflect.NewAt(f.Type, unsafe.Pointer(v.UnsafeAddr()+f.Offset)).Elem() +} diff --git a/vendor/vendor.json b/vendor/vendor.json index 3f2ba9413..255242b25 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -682,6 +682,30 @@ "path": "github.com/golang/protobuf/proto", "revision": "b982704f8bb716bb608144408cff30e15fbde841" }, + { + "checksumSHA1": "sOd6u/eTkieb8AgKxnXZ/C9/FhI=", + "path": "github.com/google/go-cmp/cmp", + "revision": "5411ab924f9ffa6566244a9e504bc347edacffd3", + "revisionTime": "2018-03-28T20:15:12Z" + }, + { + "checksumSHA1": "oLBV7th4sxzxzmf1b91NVVbdOfI=", + "path": "github.com/google/go-cmp/cmp/internal/diff", + "revision": "5411ab924f9ffa6566244a9e504bc347edacffd3", + "revisionTime": "2018-03-28T20:15:12Z" + }, + { + "checksumSHA1": "kYtvRhMjM0X4bvEjR3pqEHLw1qo=", + "path": "github.com/google/go-cmp/cmp/internal/function", + "revision": "5411ab924f9ffa6566244a9e504bc347edacffd3", + "revisionTime": "2018-03-28T20:15:12Z" + }, + { + "checksumSHA1": "OQQ56f38ikfmG2Zd3lUlk4LUBIw=", + "path": "github.com/google/go-cmp/cmp/internal/value", + "revision": "5411ab924f9ffa6566244a9e504bc347edacffd3", + "revisionTime": "2018-03-28T20:15:12Z" + }, { "checksumSHA1": "Evpv9y6iPdy+8FeAVDmKrqV1sqo=", "path": "github.com/google/go-querystring/query", From b600be009d7024513d6d0a409e5985d67b1f1f5c Mon Sep 17 00:00:00 2001 From: Owain Lewis Date: Tue, 26 Jun 2018 10:05:56 +0100 Subject: [PATCH 033/220] Pass context into OCI client --- builder/oracle/oci/artifact.go | 4 ++- builder/oracle/oci/driver.go | 20 ++++++----- builder/oracle/oci/driver_mock.go | 20 ++++++----- builder/oracle/oci/driver_oci.go | 33 ++++++++++--------- builder/oracle/oci/step_create_instance.go | 10 +++--- .../oci/step_get_default_credentials.go | 4 +-- builder/oracle/oci/step_image.go | 6 ++-- builder/oracle/oci/step_instance_info.go | 4 +-- 8 files changed, 56 insertions(+), 45 deletions(-) diff --git a/builder/oracle/oci/artifact.go b/builder/oracle/oci/artifact.go index a454ff7c7..703cd062d 100644 --- a/builder/oracle/oci/artifact.go +++ b/builder/oracle/oci/artifact.go @@ -1,6 +1,7 @@ package oci import ( + "context" "fmt" "github.com/oracle/oci-go-sdk/core" @@ -41,11 +42,12 @@ func (a *Artifact) String() string { ) } +// State ... func (a *Artifact) State(name string) interface{} { return nil } // Destroy deletes the custom image associated with the artifact. func (a *Artifact) Destroy() error { - return a.driver.DeleteImage(*a.Image.Id) + return a.driver.DeleteImage(context.TODO(), *a.Image.Id) } diff --git a/builder/oracle/oci/driver.go b/builder/oracle/oci/driver.go index 704b2f2a9..4e6013bbd 100644 --- a/builder/oracle/oci/driver.go +++ b/builder/oracle/oci/driver.go @@ -1,14 +1,18 @@ package oci -import "github.com/oracle/oci-go-sdk/core" +import ( + "context" + + "github.com/oracle/oci-go-sdk/core" +) // Driver interfaces between the builder steps and the OCI SDK. type Driver interface { - CreateInstance(publicKey string) (string, error) - CreateImage(id string) (core.Image, error) - DeleteImage(id string) error - GetInstanceIP(id string) (string, error) - TerminateInstance(id string) error - WaitForImageCreation(id string) error - WaitForInstanceState(id string, waitStates []string, terminalState string) error + CreateInstance(ctx context.Context, publicKey string) (string, error) + CreateImage(ctx context.Context, id string) (core.Image, error) + DeleteImage(ctx context.Context, id string) error + GetInstanceIP(ctx context.Context, id string) (string, error) + TerminateInstance(ctx context.Context, id string) error + WaitForImageCreation(ctx context.Context, id string) error + WaitForInstanceState(ctx context.Context, id string, waitStates []string, terminalState string) error } diff --git a/builder/oracle/oci/driver_mock.go b/builder/oracle/oci/driver_mock.go index 1f2e7ec2b..df478998c 100644 --- a/builder/oracle/oci/driver_mock.go +++ b/builder/oracle/oci/driver_mock.go @@ -1,6 +1,10 @@ package oci -import "github.com/oracle/oci-go-sdk/core" +import ( + "context" + + "github.com/oracle/oci-go-sdk/core" +) // driverMock implements the Driver interface and communicates with Oracle // OCI. @@ -27,7 +31,7 @@ type driverMock struct { } // CreateInstance creates a new compute instance. -func (d *driverMock) CreateInstance(publicKey string) (string, error) { +func (d *driverMock) CreateInstance(ctx context.Context, publicKey string) (string, error) { if d.CreateInstanceErr != nil { return "", d.CreateInstanceErr } @@ -38,7 +42,7 @@ func (d *driverMock) CreateInstance(publicKey string) (string, error) { } // CreateImage creates a new custom image. -func (d *driverMock) CreateImage(id string) (core.Image, error) { +func (d *driverMock) CreateImage(ctx context.Context, id string) (core.Image, error) { if d.CreateImageErr != nil { return core.Image{}, d.CreateImageErr } @@ -47,7 +51,7 @@ func (d *driverMock) CreateImage(id string) (core.Image, error) { } // DeleteImage mocks deleting a custom image. -func (d *driverMock) DeleteImage(id string) error { +func (d *driverMock) DeleteImage(ctx context.Context, id string) error { if d.DeleteImageErr != nil { return d.DeleteImageErr } @@ -58,7 +62,7 @@ func (d *driverMock) DeleteImage(id string) error { } // GetInstanceIP returns the public or private IP corresponding to the given instance id. -func (d *driverMock) GetInstanceIP(id string) (string, error) { +func (d *driverMock) GetInstanceIP(ctx context.Context, id string) (string, error) { if d.GetInstanceIPErr != nil { return "", d.GetInstanceIPErr } @@ -69,7 +73,7 @@ func (d *driverMock) GetInstanceIP(id string) (string, error) { } // TerminateInstance terminates a compute instance. -func (d *driverMock) TerminateInstance(id string) error { +func (d *driverMock) TerminateInstance(ctx context.Context, id string) error { if d.TerminateInstanceErr != nil { return d.TerminateInstanceErr } @@ -81,12 +85,12 @@ func (d *driverMock) TerminateInstance(id string) error { // WaitForImageCreation waits for a provisioning custom image to reach the // "AVAILABLE" state. -func (d *driverMock) WaitForImageCreation(id string) error { +func (d *driverMock) WaitForImageCreation(ctx context.Context, id string) error { return d.WaitForImageCreationErr } // WaitForInstanceState waits for an instance to reach the a given terminal // state. -func (d *driverMock) WaitForInstanceState(id string, waitStates []string, terminalState string) error { +func (d *driverMock) WaitForInstanceState(ctx context.Context, id string, waitStates []string, terminalState string) error { return d.WaitForInstanceStateErr } diff --git a/builder/oracle/oci/driver_oci.go b/builder/oracle/oci/driver_oci.go index 43b2d5c88..4a752c0a2 100644 --- a/builder/oracle/oci/driver_oci.go +++ b/builder/oracle/oci/driver_oci.go @@ -15,6 +15,7 @@ type driverOCI struct { computeClient core.ComputeClient vcnClient core.VirtualNetworkClient cfg *Config + context context.Context } // NewDriverOCI Creates a new driverOCI with a connected compute client and a connected vcn client. @@ -37,7 +38,7 @@ func NewDriverOCI(cfg *Config) (Driver, error) { } // CreateInstance creates a new compute instance. -func (d *driverOCI) CreateInstance(publicKey string) (string, error) { +func (d *driverOCI) CreateInstance(ctx context.Context, publicKey string) (string, error) { metadata := map[string]string{ "ssh_authorized_keys": publicKey, } @@ -69,8 +70,8 @@ func (d *driverOCI) CreateInstance(publicKey string) (string, error) { } // CreateImage creates a new custom image. -func (d *driverOCI) CreateImage(id string) (core.Image, error) { - res, err := d.computeClient.CreateImage(context.TODO(), core.CreateImageRequest{CreateImageDetails: core.CreateImageDetails{ +func (d *driverOCI) CreateImage(ctx context.Context, id string) (core.Image, error) { + res, err := d.computeClient.CreateImage(ctx, core.CreateImageRequest{CreateImageDetails: core.CreateImageDetails{ CompartmentId: &d.cfg.CompartmentID, InstanceId: &id, DisplayName: &d.cfg.ImageName, @@ -84,14 +85,14 @@ func (d *driverOCI) CreateImage(id string) (core.Image, error) { } // DeleteImage deletes a custom image. -func (d *driverOCI) DeleteImage(id string) error { - _, err := d.computeClient.DeleteImage(context.TODO(), core.DeleteImageRequest{ImageId: &id}) +func (d *driverOCI) DeleteImage(ctx context.Context, id string) error { + _, err := d.computeClient.DeleteImage(ctx, core.DeleteImageRequest{ImageId: &id}) return err } // GetInstanceIP returns the public or private IP corresponding to the given instance id. -func (d *driverOCI) GetInstanceIP(id string) (string, error) { - vnics, err := d.computeClient.ListVnicAttachments(context.TODO(), core.ListVnicAttachmentsRequest{ +func (d *driverOCI) GetInstanceIP(ctx context.Context, id string) (string, error) { + vnics, err := d.computeClient.ListVnicAttachments(ctx, core.ListVnicAttachmentsRequest{ InstanceId: &id, CompartmentId: &d.cfg.CompartmentID, }) @@ -103,7 +104,7 @@ func (d *driverOCI) GetInstanceIP(id string) (string, error) { return "", errors.New("instance has zero VNICs") } - vnic, err := d.vcnClient.GetVnic(context.TODO(), core.GetVnicRequest{VnicId: vnics.Items[0].VnicId}) + vnic, err := d.vcnClient.GetVnic(ctx, core.GetVnicRequest{VnicId: vnics.Items[0].VnicId}) if err != nil { return "", fmt.Errorf("Error getting VNIC details: %s", err) } @@ -119,8 +120,8 @@ func (d *driverOCI) GetInstanceIP(id string) (string, error) { return *vnic.PublicIp, nil } -func (d *driverOCI) GetInstanceInitialCredentials(id string) (string, string, error) { - credentials, err := d.computeClient.GetWindowsInstanceInitialCredentials(context.TODO(), core.GetWindowsInstanceInitialCredentialsRequest{ +func (d *driverOCI) GetInstanceInitialCredentials(ctx context.Context, id string) (string, string, error) { + credentials, err := d.computeClient.GetWindowsInstanceInitialCredentials(ctx, core.GetWindowsInstanceInitialCredentialsRequest{ InstanceId: &id, }) if err != nil { @@ -131,8 +132,8 @@ func (d *driverOCI) GetInstanceInitialCredentials(id string) (string, string, er } // TerminateInstance terminates a compute instance. -func (d *driverOCI) TerminateInstance(id string) error { - _, err := d.computeClient.TerminateInstance(context.TODO(), core.TerminateInstanceRequest{ +func (d *driverOCI) TerminateInstance(ctx context.Context, id string) error { + _, err := d.computeClient.TerminateInstance(ctx, core.TerminateInstanceRequest{ InstanceId: &id, }) return err @@ -140,10 +141,10 @@ func (d *driverOCI) TerminateInstance(id string) error { // WaitForImageCreation waits for a provisioning custom image to reach the // "AVAILABLE" state. -func (d *driverOCI) WaitForImageCreation(id string) error { +func (d *driverOCI) WaitForImageCreation(ctx context.Context, id string) error { return waitForResourceToReachState( func(string) (string, error) { - image, err := d.computeClient.GetImage(context.TODO(), core.GetImageRequest{ImageId: &id}) + image, err := d.computeClient.GetImage(ctx, core.GetImageRequest{ImageId: &id}) if err != nil { return "", err } @@ -159,10 +160,10 @@ func (d *driverOCI) WaitForImageCreation(id string) error { // WaitForInstanceState waits for an instance to reach the a given terminal // state. -func (d *driverOCI) WaitForInstanceState(id string, waitStates []string, terminalState string) error { +func (d *driverOCI) WaitForInstanceState(ctx context.Context, id string, waitStates []string, terminalState string) error { return waitForResourceToReachState( func(string) (string, error) { - instance, err := d.computeClient.GetInstance(context.TODO(), core.GetInstanceRequest{InstanceId: &id}) + instance, err := d.computeClient.GetInstance(ctx, core.GetInstanceRequest{InstanceId: &id}) if err != nil { return "", err } diff --git a/builder/oracle/oci/step_create_instance.go b/builder/oracle/oci/step_create_instance.go index 375b92b1b..7ca52bf32 100644 --- a/builder/oracle/oci/step_create_instance.go +++ b/builder/oracle/oci/step_create_instance.go @@ -10,7 +10,7 @@ import ( type stepCreateInstance struct{} -func (s *stepCreateInstance) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *stepCreateInstance) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { var ( driver = state.Get("driver").(Driver) ui = state.Get("ui").(packer.Ui) @@ -19,7 +19,7 @@ func (s *stepCreateInstance) Run(_ context.Context, state multistep.StateBag) mu ui.Say("Creating instance...") - instanceID, err := driver.CreateInstance(publicKey) + instanceID, err := driver.CreateInstance(ctx, publicKey) if err != nil { err = fmt.Errorf("Problem creating instance: %s", err) ui.Error(err.Error()) @@ -33,7 +33,7 @@ func (s *stepCreateInstance) Run(_ context.Context, state multistep.StateBag) mu ui.Say("Waiting for instance to enter 'RUNNING' state...") - if err = driver.WaitForInstanceState(instanceID, []string{"STARTING", "PROVISIONING"}, "RUNNING"); err != nil { + if err = driver.WaitForInstanceState(ctx, instanceID, []string{"STARTING", "PROVISIONING"}, "RUNNING"); err != nil { err = fmt.Errorf("Error waiting for instance to start: %s", err) ui.Error(err.Error()) state.Put("error", err) @@ -57,14 +57,14 @@ func (s *stepCreateInstance) Cleanup(state multistep.StateBag) { ui.Say(fmt.Sprintf("Terminating instance (%s)...", id)) - if err := driver.TerminateInstance(id); err != nil { + if err := driver.TerminateInstance(context.TODO(), id); err != nil { err = fmt.Errorf("Error terminating instance. Please terminate manually: %s", err) ui.Error(err.Error()) state.Put("error", err) return } - err := driver.WaitForInstanceState(id, []string{"TERMINATING"}, "TERMINATED") + err := driver.WaitForInstanceState(context.TODO(), id, []string{"TERMINATING"}, "TERMINATED") if err != nil { err = fmt.Errorf("Error terminating instance. Please terminate manually: %s", err) ui.Error(err.Error()) diff --git a/builder/oracle/oci/step_get_default_credentials.go b/builder/oracle/oci/step_get_default_credentials.go index 7503b853c..b7f6f71e9 100644 --- a/builder/oracle/oci/step_get_default_credentials.go +++ b/builder/oracle/oci/step_get_default_credentials.go @@ -17,7 +17,7 @@ type stepGetDefaultCredentials struct { BuildName string } -func (s *stepGetDefaultCredentials) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *stepGetDefaultCredentials) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { var ( driver = state.Get("driver").(*driverOCI) ui = state.Get("ui").(packer.Ui) @@ -36,7 +36,7 @@ func (s *stepGetDefaultCredentials) Run(_ context.Context, state multistep.State return multistep.ActionContinue } - username, password, err := driver.GetInstanceInitialCredentials(id) + username, password, err := driver.GetInstanceInitialCredentials(ctx, id) if err != nil { err = fmt.Errorf("Error getting instance's credentials: %s", err) ui.Error(err.Error()) diff --git a/builder/oracle/oci/step_image.go b/builder/oracle/oci/step_image.go index 9589594c8..b3d37da0a 100644 --- a/builder/oracle/oci/step_image.go +++ b/builder/oracle/oci/step_image.go @@ -10,7 +10,7 @@ import ( type stepImage struct{} -func (s *stepImage) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *stepImage) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { var ( driver = state.Get("driver").(Driver) ui = state.Get("ui").(packer.Ui) @@ -19,7 +19,7 @@ func (s *stepImage) Run(_ context.Context, state multistep.StateBag) multistep.S ui.Say("Creating image from instance...") - image, err := driver.CreateImage(instanceID) + image, err := driver.CreateImage(ctx, instanceID) if err != nil { err = fmt.Errorf("Error creating image from instance: %s", err) ui.Error(err.Error()) @@ -27,7 +27,7 @@ func (s *stepImage) Run(_ context.Context, state multistep.StateBag) multistep.S return multistep.ActionHalt } - err = driver.WaitForImageCreation(*image.Id) + err = driver.WaitForImageCreation(ctx, *image.Id) if err != nil { err = fmt.Errorf("Error waiting for image creation to finish: %s", err) ui.Error(err.Error()) diff --git a/builder/oracle/oci/step_instance_info.go b/builder/oracle/oci/step_instance_info.go index 891a261cd..63b9120c1 100644 --- a/builder/oracle/oci/step_instance_info.go +++ b/builder/oracle/oci/step_instance_info.go @@ -10,14 +10,14 @@ import ( type stepInstanceInfo struct{} -func (s *stepInstanceInfo) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *stepInstanceInfo) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { var ( driver = state.Get("driver").(Driver) ui = state.Get("ui").(packer.Ui) id = state.Get("instance_id").(string) ) - ip, err := driver.GetInstanceIP(id) + ip, err := driver.GetInstanceIP(ctx, id) if err != nil { err = fmt.Errorf("Error getting instance's IP: %s", err) ui.Error(err.Error()) From b2e456c340871982a513510b106eee8978bdfff5 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Tue, 26 Jun 2018 11:35:04 -0700 Subject: [PATCH 034/220] docs needed clarifying on what Packer would do. Document this feature in ebs-volume. --- .../source/docs/builders/amazon-ebs.html.md | 11 ++++++++-- .../docs/builders/amazon-ebssurrogate.html.md | 11 ++++++++-- .../docs/builders/amazon-ebsvolume.html.md | 21 +++++++++++++++++++ 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/website/source/docs/builders/amazon-ebs.html.md b/website/source/docs/builders/amazon-ebs.html.md index 2901bd249..f8d75ebd0 100644 --- a/website/source/docs/builders/amazon-ebs.html.md +++ b/website/source/docs/builders/amazon-ebs.html.md @@ -150,8 +150,15 @@ builder. after all provisioners have run. For Windows instances, it is sometimes desirable to [run Sysprep](http://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ami-create-standard.html) which will stop the instance for you. If this is set to true, Packer *will not* - stop the instance and will wait for you to stop it manually. You can do this - with a [windows-shell provisioner](https://www.packer.io/docs/provisioners/windows-shell.html). + stop the instance but will assume that you will send the stop signal + yourself through your final provisioner. You can do this with a + [windows-shell provisioner](https://www.packer.io/docs/provisioners/windows-shell.html). + + Note that Packer will still wait for the instance to be stopped, and failing + to send the stop signal yourself, when you have set this flag to `true`, + will cause a timeout. + + Example of a valid shutdown command: ``` json { diff --git a/website/source/docs/builders/amazon-ebssurrogate.html.md b/website/source/docs/builders/amazon-ebssurrogate.html.md index 720521536..eb21c1525 100644 --- a/website/source/docs/builders/amazon-ebssurrogate.html.md +++ b/website/source/docs/builders/amazon-ebssurrogate.html.md @@ -143,8 +143,15 @@ builder. after all provisioners have run. For Windows instances, it is sometimes desirable to [run Sysprep](http://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ami-create-standard.html) which will stop the instance for you. If this is set to true, Packer *will not* - stop the instance and will wait for you to stop it manually. You can do this - with a [windows-shell provisioner](https://www.packer.io/docs/provisioners/windows-shell.html). + stop the instance but will assume that you will send the stop signal + yourself through your final provisioner. You can do this with a + [windows-shell provisioner](https://www.packer.io/docs/provisioners/windows-shell.html). + + Note that Packer will still wait for the instance to be stopped, and failing + to send the stop signal yourself, when you have set this flag to `true`, + will cause a timeout. + + Example of a valid shutdown command: ``` json { diff --git a/website/source/docs/builders/amazon-ebsvolume.html.md b/website/source/docs/builders/amazon-ebsvolume.html.md index 1bab5eb62..acfa33e84 100644 --- a/website/source/docs/builders/amazon-ebsvolume.html.md +++ b/website/source/docs/builders/amazon-ebsvolume.html.md @@ -111,6 +111,27 @@ builder. provider whose API is compatible with aws EC2. Specify another endpoint like this `https://ec2.custom.endpoint.com`. +- `disable_stop_instance` (boolean) - Packer normally stops the build instance + after all provisioners have run. For Windows instances, it is sometimes + desirable to [run Sysprep](http://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ami-create-standard.html) + which will stop the instance for you. If this is set to true, Packer *will not* + stop the instance but will assume that you will send the stop signal + yourself through your final provisioner. You can do this with a + [windows-shell provisioner](https://www.packer.io/docs/provisioners/windows-shell.html). + + Note that Packer will still wait for the instance to be stopped, and failing + to send the stop signal yourself, when you have set this flag to `true`, + will cause a timeout. + + Example of a valid shutdown command: + + ``` json + { + "type": "windows-shell", + "inline": ["\"c:\\Program Files\\Amazon\\Ec2ConfigService\\ec2config.exe\" -sysprep"] + } + ``` + - `ebs_optimized` (boolean) - Mark instance as [EBS Optimized](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSOptimized.html). Default `false`. From ce40e9cc860d574ebb7ead6f7bfda4af9e95feb6 Mon Sep 17 00:00:00 2001 From: Matthew Hooker Date: Tue, 26 Jun 2018 16:18:20 -0700 Subject: [PATCH 035/220] only test on .10.x --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2bac499b3..02f936309 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ language: go go: - 1.8.x - 1.9.x - - 1.x + - 1.10.x install: From e21981e58190641cf62fae5cbcb395a9bd710a22 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Tue, 26 Jun 2018 15:17:59 -0700 Subject: [PATCH 036/220] fix vendor commit for go-oracle-terraform --- .../go-oracle-terraform/compute/image_list.go | 4 ++-- .../compute/machine_images.go | 4 ++-- .../compute/orchestration.go | 23 ++++++++++++++++--- .../compute/security_lists.go | 8 +++---- .../go-oracle-terraform/compute/snapshots.go | 8 +++---- .../go-oracle-terraform/compute/ssh_keys.go | 4 ++-- .../compute/storage_volume_attachments.go | 1 + vendor/vendor.json | 20 ++++++---------- 8 files changed, 42 insertions(+), 30 deletions(-) diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/image_list.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/image_list.go index 0d4ca06ba..1d908987c 100644 --- a/vendor/github.com/hashicorp/go-oracle-terraform/compute/image_list.go +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/image_list.go @@ -89,7 +89,7 @@ func (c *ImageListClient) CreateImageList(createInput *CreateImageListInput) (*I // DeleteKeyInput describes the image list to delete type DeleteImageListInput struct { // The name of the Image List - Name string `json:name` + Name string `json:"name"` } // DeleteImageList deletes the Image List with the given name. @@ -101,7 +101,7 @@ func (c *ImageListClient) DeleteImageList(deleteInput *DeleteImageListInput) err // GetImageListInput describes the image list to get type GetImageListInput struct { // The name of the Image List - Name string `json:name` + Name string `json:"name"` } // GetImageList retrieves the Image List with the given name. diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/machine_images.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/machine_images.go index bf7736a63..f2c4b4a15 100644 --- a/vendor/github.com/hashicorp/go-oracle-terraform/compute/machine_images.go +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/machine_images.go @@ -109,7 +109,7 @@ func (c *MachineImagesClient) CreateMachineImage(createInput *CreateMachineImage // DeleteMachineImageInput describes the MachineImage to delete type DeleteMachineImageInput struct { // The name of the MachineImage - Name string `json:name` + Name string `json:"name"` } // DeleteMachineImage deletes the MachineImage with the given name. @@ -122,7 +122,7 @@ type GetMachineImageInput struct { // account of the associated Object Storage Classic instance Account string `json:"account"` // The name of the Machine Image - Name string `json:name` + Name string `json:"name"` } // GetMachineImage retrieves the MachineImage with the given name. diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/orchestration.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/orchestration.go index 684e0d45f..93d9e2342 100644 --- a/vendor/github.com/hashicorp/go-oracle-terraform/compute/orchestration.go +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/orchestration.go @@ -60,6 +60,12 @@ const ( OrchestrationTypeInstance OrchestrationType = "Instance" ) +type OrchestrationRelationshipType string + +const ( + OrchestrationRelationshipTypeDepends OrchestrationRelationshipType = "depends" +) + // OrchestrationInfo describes an existing Orchestration. type Orchestration struct { // The default Oracle Compute Cloud Service account, such as /Compute-acme/default. @@ -162,7 +168,7 @@ type Object struct { // Note that when recovering from a failure, the orchestration doesn't consider object relationships. // Orchestrations v2 use object references to recover interdependent objects to a healthy state. SeeObject // References and Relationships in Using Oracle Compute Cloud Service (IaaS). - Relationship []Object `json:"relationships,omitempty"` + Relationships []Relationship `json:"relationships,omitempty"` // The template attribute defines the properties or characteristics of the Oracle Compute Cloud Service object // that you want to create, as specified by the type attribute. // The fields in the template section vary depending on the specified type. See Orchestration v2 Attributes @@ -193,6 +199,16 @@ type Health struct { Error string `json:"error,omitempty"` } +type Relationship struct { + // The type of Relationship + // The only type is depends + // Required + Type OrchestrationRelationshipType `json:"type"` + // What objects the relationship depends on + // Required + Targets []string `json:"targets"` +} + // CreateOrchestration creates a new Orchestration with the given name, key and enabled flag. func (c *OrchestrationsClient) CreateOrchestration(input *CreateOrchestrationInput) (*Orchestration, error) { var createdOrchestration Orchestration @@ -222,6 +238,7 @@ func (c *OrchestrationsClient) CreateOrchestration(input *CreateOrchestrationInp instanceInput.Storage = qualifiedStorageAttachments instanceInput.Networking = instanceClient.qualifyNetworking(instanceInput.Networking) + } } @@ -258,7 +275,7 @@ func (c *OrchestrationsClient) CreateOrchestration(input *CreateOrchestrationInp // GetOrchestrationInput describes the Orchestration to get type GetOrchestrationInput struct { // The three-part name of the Orchestration (/Compute-identity_domain/user/object). - Name string `json:name` + Name string `json:"name"` } // GetOrchestration retrieves the Orchestration with the given name. @@ -341,7 +358,7 @@ func (c *OrchestrationsClient) UpdateOrchestration(input *UpdateOrchestrationInp type DeleteOrchestrationInput struct { // The three-part name of the Orchestration (/Compute-identity_domain/user/object). // Required - Name string `json:name` + Name string `json:"name"` // Timeout for delete request Timeout time.Duration `json:"-"` } diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/security_lists.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/security_lists.go index 3c6d87364..dec906e8c 100644 --- a/vendor/github.com/hashicorp/go-oracle-terraform/compute/security_lists.go +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/security_lists.go @@ -30,7 +30,7 @@ type SecurityListInfo struct { // Shows the default account for your identity domain. Account string `json:"account"` // A description of the security list. - Description string `json:description` + Description string `json:"description"` // The three-part name of the security list (/Compute-identity_domain/user/object). Name string `json:"name"` // The policy for outbound traffic from the security list. @@ -73,7 +73,7 @@ func (c *SecurityListsClient) CreateSecurityList(createInput *CreateSecurityList type GetSecurityListInput struct { // The three-part name of the Security List (/Compute-identity_domain/user/object). // Required - Name string `json:name` + Name string `json:"name"` } // GetSecurityList retrieves the security list with the given name. @@ -90,7 +90,7 @@ func (c *SecurityListsClient) GetSecurityList(getInput *GetSecurityListInput) (* type UpdateSecurityListInput struct { // A description of the security list. // Optional - Description string `json:description` + Description string `json:"description"` // The three-part name of the Security List (/Compute-identity_domain/user/object). // Required Name string `json:"name"` @@ -117,7 +117,7 @@ func (c *SecurityListsClient) UpdateSecurityList(updateInput *UpdateSecurityList type DeleteSecurityListInput struct { // The three-part name of the Security List (/Compute-identity_domain/user/object). // Required - Name string `json:name` + Name string `json:"name"` } // DeleteSecurityList deletes the security list with the given name. diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/snapshots.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/snapshots.go index 370fd0c97..98a24ac9d 100644 --- a/vendor/github.com/hashicorp/go-oracle-terraform/compute/snapshots.go +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/snapshots.go @@ -120,7 +120,7 @@ func (c *SnapshotsClient) CreateSnapshot(input *CreateSnapshotInput) (*Snapshot, type GetSnapshotInput struct { // The name of the Snapshot // Required - Name string `json:name` + Name string `json:"name"` } // GetSnapshot retrieves the Snapshot with the given name. @@ -176,9 +176,9 @@ func (c *SnapshotsClient) DeleteSnapshot(machineImagesClient *MachineImagesClien return nil } -// DeleteSnapshot deletes the Snapshot with the given name. -// A machine image gets created with the associated snapshot is not deleted -// by this method. +// DeleteSnapshotResourceOnly deletes the Snapshot with the given name. +// The machine image that gets created with the associated snapshot is not +// deleted by this method. func (c *SnapshotsClient) DeleteSnapshotResourceOnly(input *DeleteSnapshotInput) error { // Wait for snapshot complete in case delay is active and the corresponding // instance needs to be deleted first diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/ssh_keys.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/ssh_keys.go index 7e8be20ed..821fd2216 100644 --- a/vendor/github.com/hashicorp/go-oracle-terraform/compute/ssh_keys.go +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/ssh_keys.go @@ -70,7 +70,7 @@ func (c *SSHKeysClient) CreateSSHKey(createInput *CreateSSHKeyInput) (*SSHKey, e // GetSSHKeyInput describes the ssh key to get type GetSSHKeyInput struct { // The three-part name of the SSH Key (/Compute-identity_domain/user/object). - Name string `json:name` + Name string `json:"name"` } // GetSSHKey retrieves the SSH key with the given name. @@ -110,7 +110,7 @@ func (c *SSHKeysClient) UpdateSSHKey(updateInput *UpdateSSHKeyInput) (*SSHKey, e // DeleteKeyInput describes the ssh key to delete type DeleteSSHKeyInput struct { // The three-part name of the SSH Key (/Compute-identity_domain/user/object). - Name string `json:name` + Name string `json:"name"` } // DeleteSSHKey deletes the SSH key with the given name. diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/storage_volume_attachments.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/storage_volume_attachments.go index 51e18af47..7fe9a13ef 100644 --- a/vendor/github.com/hashicorp/go-oracle-terraform/compute/storage_volume_attachments.go +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/storage_volume_attachments.go @@ -81,6 +81,7 @@ type CreateStorageAttachmentInput struct { // CreateStorageAttachment creates a storage attachment attaching the given volume to the given instance at the given index. func (c *StorageAttachmentsClient) CreateStorageAttachment(input *CreateStorageAttachmentInput) (*StorageAttachmentInfo, error) { input.InstanceName = c.getQualifiedName(input.InstanceName) + input.StorageVolumeName = c.getQualifiedName(input.StorageVolumeName) var attachmentInfo *StorageAttachmentInfo if err := c.createResource(&input, &attachmentInfo); err != nil { diff --git a/vendor/vendor.json b/vendor/vendor.json index 3f2ba9413..7f7d5ae68 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -836,29 +836,23 @@ "path": "github.com/hashicorp/go-multierror", "revision": "d30f09973e19c1dfcd120b2d9c4f168e68d6b5d5" }, - { - "checksumSHA1": "Nf2Gdn9M1KlUS3sovKfymO1VJF4=", - "path": "github.com/hashicorp/go-oracle-terraform", - "revision": "5a9a298c54339d2296d2f1135eae55a3a8f5e8c2", - "revisionTime": "2018-01-11T20:31:13Z" - }, { "checksumSHA1": "hjQfXn32Tvuu6IJACOTsMzm+AbA=", "path": "github.com/hashicorp/go-oracle-terraform/client", - "revision": "5a9a298c54339d2296d2f1135eae55a3a8f5e8c2", - "revisionTime": "2018-01-11T20:31:13Z" + "revision": "62e2241f9c4154d5603a3678adc912991a47a468", + "revisionTime": "2018-01-31T23:42:02Z" }, { - "checksumSHA1": "wce86V0j11J6xRSvJEanprjK7so=", + "checksumSHA1": "yoA7SyeQNJ8XxwC7IcXdJ2kOTqg=", "path": "github.com/hashicorp/go-oracle-terraform/compute", - "revision": "5a9a298c54339d2296d2f1135eae55a3a8f5e8c2", - "revisionTime": "2018-01-11T20:31:13Z" + "revision": "62e2241f9c4154d5603a3678adc912991a47a468", + "revisionTime": "2018-01-31T23:42:02Z" }, { "checksumSHA1": "NuObCk0/ybL3w++EnltgrB1GQRc=", "path": "github.com/hashicorp/go-oracle-terraform/opc", - "revision": "5a9a298c54339d2296d2f1135eae55a3a8f5e8c2", - "revisionTime": "2018-01-11T20:31:13Z" + "revision": "62e2241f9c4154d5603a3678adc912991a47a468", + "revisionTime": "2018-01-31T23:42:02Z" }, { "checksumSHA1": "ErJHGU6AVPZM9yoY/xV11TwSjQs=", From 3622a669dcfa304ae16ff3bd5f9657d117e36585 Mon Sep 17 00:00:00 2001 From: Sean Malloy Date: Thu, 29 Mar 2018 22:50:58 -0500 Subject: [PATCH 037/220] Add new post processor googlecompute-import --- command/plugin.go | 2 + post-processor/compress/notes.txt | 3 + post-processor/compress/post-processor.go | 3 + post-processor/compress/tar_fix.go | 9 + post-processor/compress/tar_fix_go110.go | 11 + .../googlecompute-import/artifact.go | 37 + .../googlecompute-import/artifact_test.go | 15 + .../googlecompute-import/post-processor.go | 235 + .../google.golang.org/api/gensupport/go18.go | 17 + .../google.golang.org/api/gensupport/media.go | 166 +- .../api/gensupport/not_go18.go | 14 + .../google.golang.org/api/gensupport/send.go | 16 + .../api/storage/v1/storage-api.json | 3784 ++++++ .../api/storage/v1/storage-gen.go | 11171 ++++++++++++++++ vendor/vendor.json | 12 +- .../googlecompute-import.html.md | 145 + 16 files changed, 15620 insertions(+), 20 deletions(-) create mode 100644 post-processor/compress/notes.txt create mode 100644 post-processor/compress/tar_fix.go create mode 100644 post-processor/compress/tar_fix_go110.go create mode 100644 post-processor/googlecompute-import/artifact.go create mode 100644 post-processor/googlecompute-import/artifact_test.go create mode 100644 post-processor/googlecompute-import/post-processor.go create mode 100644 vendor/google.golang.org/api/gensupport/go18.go create mode 100644 vendor/google.golang.org/api/gensupport/not_go18.go create mode 100644 vendor/google.golang.org/api/storage/v1/storage-api.json create mode 100644 vendor/google.golang.org/api/storage/v1/storage-gen.go create mode 100644 website/source/docs/post-processors/googlecompute-import.html.md diff --git a/command/plugin.go b/command/plugin.go index 60651332d..34062a11e 100644 --- a/command/plugin.go +++ b/command/plugin.go @@ -56,6 +56,7 @@ import ( dockersavepostprocessor "github.com/hashicorp/packer/post-processor/docker-save" dockertagpostprocessor "github.com/hashicorp/packer/post-processor/docker-tag" googlecomputeexportpostprocessor "github.com/hashicorp/packer/post-processor/googlecompute-export" + googlecomputeimportpostprocessor "github.com/hashicorp/packer/post-processor/googlecompute-import" manifestpostprocessor "github.com/hashicorp/packer/post-processor/manifest" shelllocalpostprocessor "github.com/hashicorp/packer/post-processor/shell-local" vagrantpostprocessor "github.com/hashicorp/packer/post-processor/vagrant" @@ -146,6 +147,7 @@ var PostProcessors = map[string]packer.PostProcessor{ "docker-save": new(dockersavepostprocessor.PostProcessor), "docker-tag": new(dockertagpostprocessor.PostProcessor), "googlecompute-export": new(googlecomputeexportpostprocessor.PostProcessor), + "googlecompute-import": new(googlecomputeimportpostprocessor.PostProcessor), "manifest": new(manifestpostprocessor.PostProcessor), "shell-local": new(shelllocalpostprocessor.PostProcessor), "vagrant": new(vagrantpostprocessor.PostProcessor), diff --git a/post-processor/compress/notes.txt b/post-processor/compress/notes.txt new file mode 100644 index 000000000..51f9f7f0b --- /dev/null +++ b/post-processor/compress/notes.txt @@ -0,0 +1,3 @@ +* 1.9.6 => GNU tar format +* 1.10.3 w/ patch => GNU tar format +* 1.10.3 w/o patch => Posix tar format diff --git a/post-processor/compress/post-processor.go b/post-processor/compress/post-processor.go index d1bf89f1a..3e089f867 100644 --- a/post-processor/compress/post-processor.go +++ b/post-processor/compress/post-processor.go @@ -303,6 +303,9 @@ func createTarArchive(files []string, output io.WriteCloser) error { return fmt.Errorf("Failed to create tar header for %s: %s", path, err) } + // workaround for archive format on go >=1.10 + setHeaderFormat(header) + if err := archive.WriteHeader(header); err != nil { return fmt.Errorf("Failed to write tar header for %s: %s", path, err) } diff --git a/post-processor/compress/tar_fix.go b/post-processor/compress/tar_fix.go new file mode 100644 index 000000000..af60a2fff --- /dev/null +++ b/post-processor/compress/tar_fix.go @@ -0,0 +1,9 @@ +// +build !go1.10 + +package compress + +import "archive/tar" + +func setHeaderFormat(header *tar.Header) { + // no-op +} diff --git a/post-processor/compress/tar_fix_go110.go b/post-processor/compress/tar_fix_go110.go new file mode 100644 index 000000000..016b6b656 --- /dev/null +++ b/post-processor/compress/tar_fix_go110.go @@ -0,0 +1,11 @@ +// +build go1.10 + +package compress + +import "archive/tar" + +func setHeaderFormat(header *tar.Header) { + // We have to set the Format explicitly for the googlecompute-import + // post-processor. Google Cloud only allows importing GNU tar format. + header.Format = tar.FormatGNU +} diff --git a/post-processor/googlecompute-import/artifact.go b/post-processor/googlecompute-import/artifact.go new file mode 100644 index 000000000..1a43d7c50 --- /dev/null +++ b/post-processor/googlecompute-import/artifact.go @@ -0,0 +1,37 @@ +package googlecomputeimport + +import ( + "fmt" +) + +const BuilderId = "packer.post-processor.googlecompute-import" + +type Artifact struct { + paths []string +} + +func (*Artifact) BuilderId() string { + return BuilderId +} + +func (*Artifact) Id() string { + return "" +} + +func (a *Artifact) Files() []string { + pathsCopy := make([]string, len(a.paths)) + copy(pathsCopy, a.paths) + return pathsCopy +} + +func (a *Artifact) String() string { + return fmt.Sprintf("Exported artifacts in: %s", a.paths) +} + +func (*Artifact) State(name string) interface{} { + return nil +} + +func (a *Artifact) Destroy() error { + return nil +} diff --git a/post-processor/googlecompute-import/artifact_test.go b/post-processor/googlecompute-import/artifact_test.go new file mode 100644 index 000000000..9d53c0b07 --- /dev/null +++ b/post-processor/googlecompute-import/artifact_test.go @@ -0,0 +1,15 @@ +package googlecomputeimport + +import ( + "testing" + + "github.com/hashicorp/packer/packer" +) + +func TestArtifact_ImplementsArtifact(t *testing.T) { + var raw interface{} + raw = &Artifact{} + if _, ok := raw.(packer.Artifact); !ok { + t.Fatalf("Artifact should be a Artifact") + } +} diff --git a/post-processor/googlecompute-import/post-processor.go b/post-processor/googlecompute-import/post-processor.go new file mode 100644 index 000000000..a043a8ade --- /dev/null +++ b/post-processor/googlecompute-import/post-processor.go @@ -0,0 +1,235 @@ +package googlecomputeimport + +import ( + "fmt" + "net/http" + "os" + "strings" + "time" + + "google.golang.org/api/compute/v1" + "google.golang.org/api/storage/v1" + + "github.com/hashicorp/packer/builder/googlecompute" + "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/config" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/hashicorp/packer/post-processor/compress" + "github.com/hashicorp/packer/template/interpolate" + + "golang.org/x/oauth2" + "golang.org/x/oauth2/jwt" +) + +type Config struct { + common.PackerConfig `mapstructure:",squash"` + + Bucket string `mapstructure:"bucket"` + GCSObjectName string `mapstructure:"gcs_object_name"` + ImageDescription string `mapstructure:"image_description"` + ImageFamily string `mapstructure:"image_family"` + ImageLabels map[string]string `mapstructure:"image_labels"` + ImageName string `mapstructure:"image_name"` + ProjectId string `mapstructure:"project_id"` + AccountFile string `mapstructure:"account_file"` + KeepOriginalImage bool `mapstructure:"keep_input_artifact"` + + ctx interpolate.Context +} + +type PostProcessor struct { + config Config + runner multistep.Runner +} + +func (p *PostProcessor) Configure(raws ...interface{}) error { + err := config.Decode(&p.config, &config.DecodeOpts{ + Interpolate: true, + InterpolateContext: &p.config.ctx, + InterpolateFilter: &interpolate.RenderFilter{ + Exclude: []string{ + "gcs_object_name", + }, + }, + }, raws...) + if err != nil { + return err + } + + // Set defaults + if p.config.GCSObjectName == "" { + p.config.GCSObjectName = "packer-import-{{timestamp}}.tar.gz" + } + + errs := new(packer.MultiError) + + // Check and render gcs_object_name + if err = interpolate.Validate(p.config.GCSObjectName, &p.config.ctx); err != nil { + errs = packer.MultiErrorAppend( + errs, fmt.Errorf("Error parsing gcs_object_name template: %s", err)) + } + + templates := map[string]*string{ + "bucket": &p.config.Bucket, + "image_name": &p.config.ImageName, + "project_id": &p.config.ProjectId, + "account_file": &p.config.AccountFile, + } + for key, ptr := range templates { + if *ptr == "" { + errs = packer.MultiErrorAppend( + errs, fmt.Errorf("%s must be set", key)) + } + } + + if len(errs.Errors) > 0 { + return errs + } + + return nil +} + +func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) { + var err error + + if artifact.BuilderId() != compress.BuilderId { + err = fmt.Errorf( + "incompatible artifact type: %s\nCan only import from Compress post-processor artifacts", + artifact.BuilderId()) + return nil, false, err + } + + p.config.GCSObjectName, err = interpolate.Render(p.config.GCSObjectName, &p.config.ctx) + if err != nil { + return nil, false, fmt.Errorf("Error rendering gcs_object_name template: %s", err) + } + + rawImageGcsPath, err := UploadToBucket(p.config.AccountFile, ui, artifact, p.config.Bucket, p.config.GCSObjectName) + if err != nil { + return nil, p.config.KeepOriginalImage, err + } + + gceImageArtifact, err := CreateGceImage(p.config.AccountFile, ui, p.config.ProjectId, rawImageGcsPath, p.config.ImageName, p.config.ImageDescription, p.config.ImageFamily, p.config.ImageLabels) + if err != nil { + return nil, p.config.KeepOriginalImage, err + } + + return gceImageArtifact, p.config.KeepOriginalImage, nil +} + +func UploadToBucket(accountFile string, ui packer.Ui, artifact packer.Artifact, bucket string, gcsObjectName string) (string, error) { + var client *http.Client + var account googlecompute.AccountFile + + err := googlecompute.ProcessAccountFile(&account, accountFile) + if err != nil { + return "", err + } + + var DriverScopes = []string{"https://www.googleapis.com/auth/devstorage.full_control"} + conf := jwt.Config{ + Email: account.ClientEmail, + PrivateKey: []byte(account.PrivateKey), + Scopes: DriverScopes, + TokenURL: "https://accounts.google.com/o/oauth2/token", + } + + client = conf.Client(oauth2.NoContext) + service, err := storage.New(client) + if err != nil { + return "", err + } + + ui.Say("Looking for tar.gz file in list of artifacts...") + source := "" + for _, path := range artifact.Files() { + ui.Say(fmt.Sprintf("Found artifact %v...", path)) + if strings.HasSuffix(path, ".tar.gz") { + source = path + break + } + } + + if source == "" { + return "", fmt.Errorf("No tar.gz file found in list of articats") + } + + artifactFile, err := os.Open(source) + if err != nil { + err := fmt.Errorf("error opening %v", source) + return "", err + } + + ui.Say(fmt.Sprintf("Uploading file %v to GCS bucket %v/%v...", source, bucket, gcsObjectName)) + storageObject, err := service.Objects.Insert(bucket, &storage.Object{Name: gcsObjectName}).Media(artifactFile).Do() + if err != nil { + ui.Say(fmt.Sprintf("Failed to upload: %v", storageObject)) + return "", err + } + + return "https://storage.googleapis.com/" + bucket + "/" + gcsObjectName, nil +} + +func CreateGceImage(accountFile string, ui packer.Ui, project string, rawImageURL string, imageName string, imageDescription string, imageFamily string, imageLabels map[string]string) (packer.Artifact, error) { + var client *http.Client + var account googlecompute.AccountFile + + err := googlecompute.ProcessAccountFile(&account, accountFile) + if err != nil { + return nil, err + } + + var DriverScopes = []string{"https://www.googleapis.com/auth/compute", "https://www.googleapis.com/auth/devstorage.full_control"} + conf := jwt.Config{ + Email: account.ClientEmail, + PrivateKey: []byte(account.PrivateKey), + Scopes: DriverScopes, + TokenURL: "https://accounts.google.com/o/oauth2/token", + } + + client = conf.Client(oauth2.NoContext) + + service, err := compute.New(client) + if err != nil { + return nil, err + } + + gceImage := &compute.Image{ + Name: imageName, + Description: imageDescription, + Family: imageFamily, + Labels: imageLabels, + RawDisk: &compute.ImageRawDisk{Source: rawImageURL}, + SourceType: "RAW", + } + + ui.Say(fmt.Sprintf("Creating GCE image %v...", imageName)) + op, err := service.Images.Insert(project, gceImage).Do() + if err != nil { + ui.Say("Error creating GCE image") + return nil, err + } + + ui.Say("Waiting for GCE image creation operation to complete...") + for op.Status != "DONE" { + op, err = service.GlobalOperations.Get(project, op.Name).Do() + if err != nil { + return nil, err + } + + time.Sleep(5 * time.Second) + } + + // fail if image creation operation has an error + if op.Error != nil { + var imageError string + for _, error := range op.Error.Errors { + imageError += error.Message + } + err = fmt.Errorf("failed to create GCE image %s: %s", imageName, imageError) + return nil, err + } + + return &Artifact{paths: []string{op.TargetLink}}, nil +} diff --git a/vendor/google.golang.org/api/gensupport/go18.go b/vendor/google.golang.org/api/gensupport/go18.go new file mode 100644 index 000000000..c76cb8f20 --- /dev/null +++ b/vendor/google.golang.org/api/gensupport/go18.go @@ -0,0 +1,17 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.8 + +package gensupport + +import ( + "io" + "net/http" +) + +// SetGetBody sets the GetBody field of req to f. +func SetGetBody(req *http.Request, f func() (io.ReadCloser, error)) { + req.GetBody = f +} diff --git a/vendor/google.golang.org/api/gensupport/media.go b/vendor/google.golang.org/api/gensupport/media.go index c6410e89a..5a2674104 100644 --- a/vendor/google.golang.org/api/gensupport/media.go +++ b/vendor/google.golang.org/api/gensupport/media.go @@ -5,12 +5,14 @@ package gensupport import ( + "bytes" "fmt" "io" "io/ioutil" "mime/multipart" "net/http" "net/textproto" + "strings" "google.golang.org/api/googleapi" ) @@ -174,26 +176,156 @@ func typeHeader(contentType string) textproto.MIMEHeader { // PrepareUpload determines whether the data in the supplied reader should be // uploaded in a single request, or in sequential chunks. // chunkSize is the size of the chunk that media should be split into. -// If chunkSize is non-zero and the contents of media do not fit in a single -// chunk (or there is an error reading media), then media will be returned as a -// MediaBuffer. Otherwise, media will be returned as a Reader. +// +// If chunkSize is zero, media is returned as the first value, and the other +// two return values are nil, true. +// +// Otherwise, a MediaBuffer is returned, along with a bool indicating whether the +// contents of media fit in a single chunk. // // After PrepareUpload has been called, media should no longer be used: the // media content should be accessed via one of the return values. -func PrepareUpload(media io.Reader, chunkSize int) (io.Reader, *MediaBuffer) { +func PrepareUpload(media io.Reader, chunkSize int) (r io.Reader, mb *MediaBuffer, singleChunk bool) { if chunkSize == 0 { // do not chunk - return media, nil + return media, nil, true + } + mb = NewMediaBuffer(media, chunkSize) + _, _, _, err := mb.Chunk() + // If err is io.EOF, we can upload this in a single request. Otherwise, err is + // either nil or a non-EOF error. If it is the latter, then the next call to + // mb.Chunk will return the same error. Returning a MediaBuffer ensures that this + // error will be handled at some point. + return nil, mb, err == io.EOF +} + +// MediaInfo holds information for media uploads. It is intended for use by generated +// code only. +type MediaInfo struct { + // At most one of Media and MediaBuffer will be set. + media io.Reader + buffer *MediaBuffer + singleChunk bool + mType string + size int64 // mediaSize, if known. Used only for calls to progressUpdater_. + progressUpdater googleapi.ProgressUpdater +} + +// NewInfoFromMedia should be invoked from the Media method of a call. It returns a +// MediaInfo populated with chunk size and content type, and a reader or MediaBuffer +// if needed. +func NewInfoFromMedia(r io.Reader, options []googleapi.MediaOption) *MediaInfo { + mi := &MediaInfo{} + opts := googleapi.ProcessMediaOptions(options) + if !opts.ForceEmptyContentType { + r, mi.mType = DetermineContentType(r, opts.ContentType) + } + mi.media, mi.buffer, mi.singleChunk = PrepareUpload(r, opts.ChunkSize) + return mi +} + +// NewInfoFromResumableMedia should be invoked from the ResumableMedia method of a +// call. It returns a MediaInfo using the given reader, size and media type. +func NewInfoFromResumableMedia(r io.ReaderAt, size int64, mediaType string) *MediaInfo { + rdr := ReaderAtToReader(r, size) + rdr, mType := DetermineContentType(rdr, mediaType) + return &MediaInfo{ + size: size, + mType: mType, + buffer: NewMediaBuffer(rdr, googleapi.DefaultUploadChunkSize), + media: nil, + singleChunk: false, + } +} + +func (mi *MediaInfo) SetProgressUpdater(pu googleapi.ProgressUpdater) { + if mi != nil { + mi.progressUpdater = pu + } +} + +// UploadType determines the type of upload: a single request, or a resumable +// series of requests. +func (mi *MediaInfo) UploadType() string { + if mi.singleChunk { + return "multipart" + } + return "resumable" +} + +// UploadRequest sets up an HTTP request for media upload. It adds headers +// as necessary, and returns a replacement for the body and a function for http.Request.GetBody. +func (mi *MediaInfo) UploadRequest(reqHeaders http.Header, body io.Reader) (newBody io.Reader, getBody func() (io.ReadCloser, error), cleanup func()) { + cleanup = func() {} + if mi == nil { + return body, nil, cleanup + } + var media io.Reader + if mi.media != nil { + // This only happens when the caller has turned off chunking. In that + // case, we write all of media in a single non-retryable request. + media = mi.media + } else if mi.singleChunk { + // The data fits in a single chunk, which has now been read into the MediaBuffer. + // We obtain that chunk so we can write it in a single request. The request can + // be retried because the data is stored in the MediaBuffer. + media, _, _, _ = mi.buffer.Chunk() + } + if media != nil { + fb := readerFunc(body) + fm := readerFunc(media) + combined, ctype := CombineBodyMedia(body, "application/json", media, mi.mType) + if fb != nil && fm != nil { + getBody = func() (io.ReadCloser, error) { + rb := ioutil.NopCloser(fb()) + rm := ioutil.NopCloser(fm()) + r, _ := CombineBodyMedia(rb, "application/json", rm, mi.mType) + return r, nil + } + } + cleanup = func() { combined.Close() } + reqHeaders.Set("Content-Type", ctype) + body = combined + } + if mi.buffer != nil && mi.mType != "" && !mi.singleChunk { + reqHeaders.Set("X-Upload-Content-Type", mi.mType) + } + return body, getBody, cleanup +} + +// readerFunc returns a function that always returns an io.Reader that has the same +// contents as r, provided that can be done without consuming r. Otherwise, it +// returns nil. +// See http.NewRequest (in net/http/request.go). +func readerFunc(r io.Reader) func() io.Reader { + switch r := r.(type) { + case *bytes.Buffer: + buf := r.Bytes() + return func() io.Reader { return bytes.NewReader(buf) } + case *bytes.Reader: + snapshot := *r + return func() io.Reader { r := snapshot; return &r } + case *strings.Reader: + snapshot := *r + return func() io.Reader { r := snapshot; return &r } + default: + return nil + } +} + +// ResumableUpload returns an appropriately configured ResumableUpload value if the +// upload is resumable, or nil otherwise. +func (mi *MediaInfo) ResumableUpload(locURI string) *ResumableUpload { + if mi == nil || mi.singleChunk { + return nil + } + return &ResumableUpload{ + URI: locURI, + Media: mi.buffer, + MediaType: mi.mType, + Callback: func(curr int64) { + if mi.progressUpdater != nil { + mi.progressUpdater(curr, mi.size) + } + }, } - - mb := NewMediaBuffer(media, chunkSize) - rdr, _, _, err := mb.Chunk() - - if err == io.EOF { // we can upload this in a single request - return rdr, nil - } - // err might be a non-EOF error. If it is, the next call to mb.Chunk will - // return the same error. Returning a MediaBuffer ensures that this error - // will be handled at some point. - - return nil, mb } diff --git a/vendor/google.golang.org/api/gensupport/not_go18.go b/vendor/google.golang.org/api/gensupport/not_go18.go new file mode 100644 index 000000000..2536501ce --- /dev/null +++ b/vendor/google.golang.org/api/gensupport/not_go18.go @@ -0,0 +1,14 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.8 + +package gensupport + +import ( + "io" + "net/http" +) + +func SetGetBody(req *http.Request, f func() (io.ReadCloser, error)) {} diff --git a/vendor/google.golang.org/api/gensupport/send.go b/vendor/google.golang.org/api/gensupport/send.go index 3d22f638f..0f75aa867 100644 --- a/vendor/google.golang.org/api/gensupport/send.go +++ b/vendor/google.golang.org/api/gensupport/send.go @@ -5,6 +5,8 @@ package gensupport import ( + "encoding/json" + "errors" "net/http" "golang.org/x/net/context" @@ -32,6 +34,11 @@ func RegisterHook(h Hook) { // If ctx is non-nil, it calls all hooks, then sends the request with // ctxhttp.Do, then calls any functions returned by the hooks in reverse order. func SendRequest(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) { + // Disallow Accept-Encoding because it interferes with the automatic gzip handling + // done by the default http.Transport. See https://github.com/google/google-api-go-client/issues/219. + if _, ok := req.Header["Accept-Encoding"]; ok { + return nil, errors.New("google api: custom Accept-Encoding headers not allowed") + } if ctx == nil { return client.Do(req) } @@ -53,3 +60,12 @@ func SendRequest(ctx context.Context, client *http.Client, req *http.Request) (* } return resp, err } + +// DecodeResponse decodes the body of res into target. If there is no body, +// target is unchanged. +func DecodeResponse(target interface{}, res *http.Response) error { + if res.StatusCode == http.StatusNoContent { + return nil + } + return json.NewDecoder(res.Body).Decode(target) +} diff --git a/vendor/google.golang.org/api/storage/v1/storage-api.json b/vendor/google.golang.org/api/storage/v1/storage-api.json new file mode 100644 index 000000000..2d23f028b --- /dev/null +++ b/vendor/google.golang.org/api/storage/v1/storage-api.json @@ -0,0 +1,3784 @@ +{ + "auth": { + "oauth2": { + "scopes": { + "https://www.googleapis.com/auth/cloud-platform": { + "description": "View and manage your data across Google Cloud Platform services" + }, + "https://www.googleapis.com/auth/cloud-platform.read-only": { + "description": "View your data across Google Cloud Platform services" + }, + "https://www.googleapis.com/auth/devstorage.full_control": { + "description": "Manage your data and permissions in Google Cloud Storage" + }, + "https://www.googleapis.com/auth/devstorage.read_only": { + "description": "View your data in Google Cloud Storage" + }, + "https://www.googleapis.com/auth/devstorage.read_write": { + "description": "Manage your data in Google Cloud Storage" + } + } + } + }, + "basePath": "/storage/v1/", + "baseUrl": "https://www.googleapis.com/storage/v1/", + "batchPath": "batch/storage/v1", + "description": "Stores and retrieves potentially large, immutable data objects.", + "discoveryVersion": "v1", + "documentationLink": "https://developers.google.com/storage/docs/json_api/", + "etag": "\"-iA1DTNe4s-I6JZXPt1t1Ypy8IU/nD7tyZqYOGFELa4QRBOZJ8raFKA\"", + "icons": { + "x16": "https://www.google.com/images/icons/product/cloud_storage-16.png", + "x32": "https://www.google.com/images/icons/product/cloud_storage-32.png" + }, + "id": "storage:v1", + "kind": "discovery#restDescription", + "labels": [ + "labs" + ], + "name": "storage", + "ownerDomain": "google.com", + "ownerName": "Google", + "parameters": { + "alt": { + "default": "json", + "description": "Data format for the response.", + "enum": [ + "json" + ], + "enumDescriptions": [ + "Responses with Content-Type of application/json" + ], + "location": "query", + "type": "string" + }, + "fields": { + "description": "Selector specifying which fields to include in a partial response.", + "location": "query", + "type": "string" + }, + "key": { + "description": "API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token.", + "location": "query", + "type": "string" + }, + "oauth_token": { + "description": "OAuth 2.0 token for the current user.", + "location": "query", + "type": "string" + }, + "prettyPrint": { + "default": "true", + "description": "Returns response with indentations and line breaks.", + "location": "query", + "type": "boolean" + }, + "quotaUser": { + "description": "Available to use for quota purposes for server-side applications. Can be any arbitrary string assigned to a user, but should not exceed 40 characters. Overrides userIp if both are provided.", + "location": "query", + "type": "string" + }, + "userIp": { + "description": "IP address of the site where the request originates. Use this if you want to enforce per-user limits.", + "location": "query", + "type": "string" + } + }, + "protocol": "rest", + "resources": { + "bucketAccessControls": { + "methods": { + "delete": { + "description": "Permanently deletes the ACL entry for the specified entity on the specified bucket.", + "httpMethod": "DELETE", + "id": "storage.bucketAccessControls.delete", + "parameterOrder": [ + "bucket", + "entity" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "entity": { + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/acl/{entity}", + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "get": { + "description": "Returns the ACL entry for the specified entity on the specified bucket.", + "httpMethod": "GET", + "id": "storage.bucketAccessControls.get", + "parameterOrder": [ + "bucket", + "entity" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "entity": { + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/acl/{entity}", + "response": { + "$ref": "BucketAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "insert": { + "description": "Creates a new ACL entry on the specified bucket.", + "httpMethod": "POST", + "id": "storage.bucketAccessControls.insert", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/acl", + "request": { + "$ref": "BucketAccessControl" + }, + "response": { + "$ref": "BucketAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "list": { + "description": "Retrieves ACL entries on the specified bucket.", + "httpMethod": "GET", + "id": "storage.bucketAccessControls.list", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/acl", + "response": { + "$ref": "BucketAccessControls" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "patch": { + "description": "Patches an ACL entry on the specified bucket.", + "httpMethod": "PATCH", + "id": "storage.bucketAccessControls.patch", + "parameterOrder": [ + "bucket", + "entity" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "entity": { + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/acl/{entity}", + "request": { + "$ref": "BucketAccessControl" + }, + "response": { + "$ref": "BucketAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "update": { + "description": "Updates an ACL entry on the specified bucket.", + "httpMethod": "PUT", + "id": "storage.bucketAccessControls.update", + "parameterOrder": [ + "bucket", + "entity" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "entity": { + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/acl/{entity}", + "request": { + "$ref": "BucketAccessControl" + }, + "response": { + "$ref": "BucketAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + } + } + }, + "buckets": { + "methods": { + "delete": { + "description": "Permanently deletes an empty bucket.", + "httpMethod": "DELETE", + "id": "storage.buckets.delete", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "If set, only deletes the bucket if its metageneration matches this value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationNotMatch": { + "description": "If set, only deletes the bucket if its metageneration does not match this value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}", + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "get": { + "description": "Returns metadata for the specified bucket.", + "httpMethod": "GET", + "id": "storage.buckets.get", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationNotMatch": { + "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "projection": { + "description": "Set of properties to return. Defaults to noAcl.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit owner, acl and defaultObjectAcl properties." + ], + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}", + "response": { + "$ref": "Bucket" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "getIamPolicy": { + "description": "Returns an IAM policy for the specified bucket.", + "httpMethod": "GET", + "id": "storage.buckets.getIamPolicy", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/iam", + "response": { + "$ref": "Policy" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "insert": { + "description": "Creates a new bucket.", + "httpMethod": "POST", + "id": "storage.buckets.insert", + "parameterOrder": [ + "project" + ], + "parameters": { + "predefinedAcl": { + "description": "Apply a predefined set of access controls to this bucket.", + "enum": [ + "authenticatedRead", + "private", + "projectPrivate", + "publicRead", + "publicReadWrite" + ], + "enumDescriptions": [ + "Project team owners get OWNER access, and allAuthenticatedUsers get READER access.", + "Project team owners get OWNER access.", + "Project team members get access according to their roles.", + "Project team owners get OWNER access, and allUsers get READER access.", + "Project team owners get OWNER access, and allUsers get WRITER access." + ], + "location": "query", + "type": "string" + }, + "predefinedDefaultObjectAcl": { + "description": "Apply a predefined set of default object access controls to this bucket.", + "enum": [ + "authenticatedRead", + "bucketOwnerFullControl", + "bucketOwnerRead", + "private", + "projectPrivate", + "publicRead" + ], + "enumDescriptions": [ + "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + "Object owner gets OWNER access, and project team owners get OWNER access.", + "Object owner gets OWNER access, and project team owners get READER access.", + "Object owner gets OWNER access.", + "Object owner gets OWNER access, and project team members get access according to their roles.", + "Object owner gets OWNER access, and allUsers get READER access." + ], + "location": "query", + "type": "string" + }, + "project": { + "description": "A valid API project identifier.", + "location": "query", + "required": true, + "type": "string" + }, + "projection": { + "description": "Set of properties to return. Defaults to noAcl, unless the bucket resource specifies acl or defaultObjectAcl properties, when it defaults to full.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit owner, acl and defaultObjectAcl properties." + ], + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request.", + "location": "query", + "type": "string" + } + }, + "path": "b", + "request": { + "$ref": "Bucket" + }, + "response": { + "$ref": "Bucket" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "list": { + "description": "Retrieves a list of buckets for a given project.", + "httpMethod": "GET", + "id": "storage.buckets.list", + "parameterOrder": [ + "project" + ], + "parameters": { + "maxResults": { + "default": "1000", + "description": "Maximum number of buckets to return in a single response. The service will use this parameter or 1,000 items, whichever is smaller.", + "format": "uint32", + "location": "query", + "minimum": "0", + "type": "integer" + }, + "pageToken": { + "description": "A previously-returned page token representing part of the larger set of results to view.", + "location": "query", + "type": "string" + }, + "prefix": { + "description": "Filter results to buckets whose names begin with this prefix.", + "location": "query", + "type": "string" + }, + "project": { + "description": "A valid API project identifier.", + "location": "query", + "required": true, + "type": "string" + }, + "projection": { + "description": "Set of properties to return. Defaults to noAcl.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit owner, acl and defaultObjectAcl properties." + ], + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request.", + "location": "query", + "type": "string" + } + }, + "path": "b", + "response": { + "$ref": "Buckets" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "lockRetentionPolicy": { + "description": "Locks retention policy on a bucket.", + "httpMethod": "POST", + "id": "storage.buckets.lockRetentionPolicy", + "parameterOrder": [ + "bucket", + "ifMetagenerationMatch" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "Makes the operation conditional on whether bucket's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/lockRetentionPolicy", + "response": { + "$ref": "Bucket" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "patch": { + "description": "Updates a bucket. Changes to the bucket will be readable immediately after writing, but configuration changes may take time to propagate. This method supports patch semantics.", + "httpMethod": "PATCH", + "id": "storage.buckets.patch", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationNotMatch": { + "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "predefinedAcl": { + "description": "Apply a predefined set of access controls to this bucket.", + "enum": [ + "authenticatedRead", + "private", + "projectPrivate", + "publicRead", + "publicReadWrite" + ], + "enumDescriptions": [ + "Project team owners get OWNER access, and allAuthenticatedUsers get READER access.", + "Project team owners get OWNER access.", + "Project team members get access according to their roles.", + "Project team owners get OWNER access, and allUsers get READER access.", + "Project team owners get OWNER access, and allUsers get WRITER access." + ], + "location": "query", + "type": "string" + }, + "predefinedDefaultObjectAcl": { + "description": "Apply a predefined set of default object access controls to this bucket.", + "enum": [ + "authenticatedRead", + "bucketOwnerFullControl", + "bucketOwnerRead", + "private", + "projectPrivate", + "publicRead" + ], + "enumDescriptions": [ + "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + "Object owner gets OWNER access, and project team owners get OWNER access.", + "Object owner gets OWNER access, and project team owners get READER access.", + "Object owner gets OWNER access.", + "Object owner gets OWNER access, and project team members get access according to their roles.", + "Object owner gets OWNER access, and allUsers get READER access." + ], + "location": "query", + "type": "string" + }, + "projection": { + "description": "Set of properties to return. Defaults to full.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit owner, acl and defaultObjectAcl properties." + ], + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}", + "request": { + "$ref": "Bucket" + }, + "response": { + "$ref": "Bucket" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "setIamPolicy": { + "description": "Updates an IAM policy for the specified bucket.", + "httpMethod": "PUT", + "id": "storage.buckets.setIamPolicy", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/iam", + "request": { + "$ref": "Policy" + }, + "response": { + "$ref": "Policy" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "testIamPermissions": { + "description": "Tests a set of permissions on the given bucket to see which, if any, are held by the caller.", + "httpMethod": "GET", + "id": "storage.buckets.testIamPermissions", + "parameterOrder": [ + "bucket", + "permissions" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "permissions": { + "description": "Permissions to test.", + "location": "query", + "repeated": true, + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/iam/testPermissions", + "response": { + "$ref": "TestIamPermissionsResponse" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "update": { + "description": "Updates a bucket. Changes to the bucket will be readable immediately after writing, but configuration changes may take time to propagate.", + "httpMethod": "PUT", + "id": "storage.buckets.update", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationNotMatch": { + "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "predefinedAcl": { + "description": "Apply a predefined set of access controls to this bucket.", + "enum": [ + "authenticatedRead", + "private", + "projectPrivate", + "publicRead", + "publicReadWrite" + ], + "enumDescriptions": [ + "Project team owners get OWNER access, and allAuthenticatedUsers get READER access.", + "Project team owners get OWNER access.", + "Project team members get access according to their roles.", + "Project team owners get OWNER access, and allUsers get READER access.", + "Project team owners get OWNER access, and allUsers get WRITER access." + ], + "location": "query", + "type": "string" + }, + "predefinedDefaultObjectAcl": { + "description": "Apply a predefined set of default object access controls to this bucket.", + "enum": [ + "authenticatedRead", + "bucketOwnerFullControl", + "bucketOwnerRead", + "private", + "projectPrivate", + "publicRead" + ], + "enumDescriptions": [ + "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + "Object owner gets OWNER access, and project team owners get OWNER access.", + "Object owner gets OWNER access, and project team owners get READER access.", + "Object owner gets OWNER access.", + "Object owner gets OWNER access, and project team members get access according to their roles.", + "Object owner gets OWNER access, and allUsers get READER access." + ], + "location": "query", + "type": "string" + }, + "projection": { + "description": "Set of properties to return. Defaults to full.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit owner, acl and defaultObjectAcl properties." + ], + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}", + "request": { + "$ref": "Bucket" + }, + "response": { + "$ref": "Bucket" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + } + } + }, + "channels": { + "methods": { + "stop": { + "description": "Stop watching resources through this channel", + "httpMethod": "POST", + "id": "storage.channels.stop", + "path": "channels/stop", + "request": { + "$ref": "Channel", + "parameterName": "resource" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + } + } + }, + "defaultObjectAccessControls": { + "methods": { + "delete": { + "description": "Permanently deletes the default object ACL entry for the specified entity on the specified bucket.", + "httpMethod": "DELETE", + "id": "storage.defaultObjectAccessControls.delete", + "parameterOrder": [ + "bucket", + "entity" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "entity": { + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/defaultObjectAcl/{entity}", + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "get": { + "description": "Returns the default object ACL entry for the specified entity on the specified bucket.", + "httpMethod": "GET", + "id": "storage.defaultObjectAccessControls.get", + "parameterOrder": [ + "bucket", + "entity" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "entity": { + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/defaultObjectAcl/{entity}", + "response": { + "$ref": "ObjectAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "insert": { + "description": "Creates a new default object ACL entry on the specified bucket.", + "httpMethod": "POST", + "id": "storage.defaultObjectAccessControls.insert", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/defaultObjectAcl", + "request": { + "$ref": "ObjectAccessControl" + }, + "response": { + "$ref": "ObjectAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "list": { + "description": "Retrieves default object ACL entries on the specified bucket.", + "httpMethod": "GET", + "id": "storage.defaultObjectAccessControls.list", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "If present, only return default ACL listing if the bucket's current metageneration matches this value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationNotMatch": { + "description": "If present, only return default ACL listing if the bucket's current metageneration does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/defaultObjectAcl", + "response": { + "$ref": "ObjectAccessControls" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "patch": { + "description": "Patches a default object ACL entry on the specified bucket.", + "httpMethod": "PATCH", + "id": "storage.defaultObjectAccessControls.patch", + "parameterOrder": [ + "bucket", + "entity" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "entity": { + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/defaultObjectAcl/{entity}", + "request": { + "$ref": "ObjectAccessControl" + }, + "response": { + "$ref": "ObjectAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "update": { + "description": "Updates a default object ACL entry on the specified bucket.", + "httpMethod": "PUT", + "id": "storage.defaultObjectAccessControls.update", + "parameterOrder": [ + "bucket", + "entity" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "entity": { + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/defaultObjectAcl/{entity}", + "request": { + "$ref": "ObjectAccessControl" + }, + "response": { + "$ref": "ObjectAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + } + } + }, + "notifications": { + "methods": { + "delete": { + "description": "Permanently deletes a notification subscription.", + "httpMethod": "DELETE", + "id": "storage.notifications.delete", + "parameterOrder": [ + "bucket", + "notification" + ], + "parameters": { + "bucket": { + "description": "The parent bucket of the notification.", + "location": "path", + "required": true, + "type": "string" + }, + "notification": { + "description": "ID of the notification to delete.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/notificationConfigs/{notification}", + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "get": { + "description": "View a notification configuration.", + "httpMethod": "GET", + "id": "storage.notifications.get", + "parameterOrder": [ + "bucket", + "notification" + ], + "parameters": { + "bucket": { + "description": "The parent bucket of the notification.", + "location": "path", + "required": true, + "type": "string" + }, + "notification": { + "description": "Notification ID", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/notificationConfigs/{notification}", + "response": { + "$ref": "Notification" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "insert": { + "description": "Creates a notification subscription for a given bucket.", + "httpMethod": "POST", + "id": "storage.notifications.insert", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "The parent bucket of the notification.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/notificationConfigs", + "request": { + "$ref": "Notification" + }, + "response": { + "$ref": "Notification" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "list": { + "description": "Retrieves a list of notification subscriptions for a given bucket.", + "httpMethod": "GET", + "id": "storage.notifications.list", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of a Google Cloud Storage bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/notificationConfigs", + "response": { + "$ref": "Notifications" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + } + } + }, + "objectAccessControls": { + "methods": { + "delete": { + "description": "Permanently deletes the ACL entry for the specified entity on the specified object.", + "httpMethod": "DELETE", + "id": "storage.objectAccessControls.delete", + "parameterOrder": [ + "bucket", + "object", + "entity" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "entity": { + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "location": "path", + "required": true, + "type": "string" + }, + "generation": { + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "object": { + "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o/{object}/acl/{entity}", + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "get": { + "description": "Returns the ACL entry for the specified entity on the specified object.", + "httpMethod": "GET", + "id": "storage.objectAccessControls.get", + "parameterOrder": [ + "bucket", + "object", + "entity" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "entity": { + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "location": "path", + "required": true, + "type": "string" + }, + "generation": { + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "object": { + "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o/{object}/acl/{entity}", + "response": { + "$ref": "ObjectAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "insert": { + "description": "Creates a new ACL entry on the specified object.", + "httpMethod": "POST", + "id": "storage.objectAccessControls.insert", + "parameterOrder": [ + "bucket", + "object" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "generation": { + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "object": { + "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o/{object}/acl", + "request": { + "$ref": "ObjectAccessControl" + }, + "response": { + "$ref": "ObjectAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "list": { + "description": "Retrieves ACL entries on the specified object.", + "httpMethod": "GET", + "id": "storage.objectAccessControls.list", + "parameterOrder": [ + "bucket", + "object" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "generation": { + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "object": { + "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o/{object}/acl", + "response": { + "$ref": "ObjectAccessControls" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "patch": { + "description": "Patches an ACL entry on the specified object.", + "httpMethod": "PATCH", + "id": "storage.objectAccessControls.patch", + "parameterOrder": [ + "bucket", + "object", + "entity" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "entity": { + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "location": "path", + "required": true, + "type": "string" + }, + "generation": { + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "object": { + "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o/{object}/acl/{entity}", + "request": { + "$ref": "ObjectAccessControl" + }, + "response": { + "$ref": "ObjectAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "update": { + "description": "Updates an ACL entry on the specified object.", + "httpMethod": "PUT", + "id": "storage.objectAccessControls.update", + "parameterOrder": [ + "bucket", + "object", + "entity" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "entity": { + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "location": "path", + "required": true, + "type": "string" + }, + "generation": { + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "object": { + "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o/{object}/acl/{entity}", + "request": { + "$ref": "ObjectAccessControl" + }, + "response": { + "$ref": "ObjectAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + } + } + }, + "objects": { + "methods": { + "compose": { + "description": "Concatenates a list of existing objects into a new object in the same bucket.", + "httpMethod": "POST", + "id": "storage.objects.compose", + "parameterOrder": [ + "destinationBucket", + "destinationObject" + ], + "parameters": { + "destinationBucket": { + "description": "Name of the bucket in which to store the new object.", + "location": "path", + "required": true, + "type": "string" + }, + "destinationObject": { + "description": "Name of the new object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "destinationPredefinedAcl": { + "description": "Apply a predefined set of access controls to the destination object.", + "enum": [ + "authenticatedRead", + "bucketOwnerFullControl", + "bucketOwnerRead", + "private", + "projectPrivate", + "publicRead" + ], + "enumDescriptions": [ + "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + "Object owner gets OWNER access, and project team owners get OWNER access.", + "Object owner gets OWNER access, and project team owners get READER access.", + "Object owner gets OWNER access.", + "Object owner gets OWNER access, and project team members get access according to their roles.", + "Object owner gets OWNER access, and allUsers get READER access." + ], + "location": "query", + "type": "string" + }, + "ifGenerationMatch": { + "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "kmsKeyName": { + "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{destinationBucket}/o/{destinationObject}/compose", + "request": { + "$ref": "ComposeRequest" + }, + "response": { + "$ref": "Object" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "copy": { + "description": "Copies a source object to a destination object. Optionally overrides metadata.", + "httpMethod": "POST", + "id": "storage.objects.copy", + "parameterOrder": [ + "sourceBucket", + "sourceObject", + "destinationBucket", + "destinationObject" + ], + "parameters": { + "destinationBucket": { + "description": "Name of the bucket in which to store the new object. Overrides the provided object metadata's bucket value, if any.For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "destinationObject": { + "description": "Name of the new object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any.", + "location": "path", + "required": true, + "type": "string" + }, + "destinationPredefinedAcl": { + "description": "Apply a predefined set of access controls to the destination object.", + "enum": [ + "authenticatedRead", + "bucketOwnerFullControl", + "bucketOwnerRead", + "private", + "projectPrivate", + "publicRead" + ], + "enumDescriptions": [ + "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + "Object owner gets OWNER access, and project team owners get OWNER access.", + "Object owner gets OWNER access, and project team owners get READER access.", + "Object owner gets OWNER access.", + "Object owner gets OWNER access, and project team members get access according to their roles.", + "Object owner gets OWNER access, and allUsers get READER access." + ], + "location": "query", + "type": "string" + }, + "ifGenerationMatch": { + "description": "Makes the operation conditional on whether the destination object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifGenerationNotMatch": { + "description": "Makes the operation conditional on whether the destination object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "Makes the operation conditional on whether the destination object's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationNotMatch": { + "description": "Makes the operation conditional on whether the destination object's current metageneration does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifSourceGenerationMatch": { + "description": "Makes the operation conditional on whether the source object's current generation matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifSourceGenerationNotMatch": { + "description": "Makes the operation conditional on whether the source object's current generation does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifSourceMetagenerationMatch": { + "description": "Makes the operation conditional on whether the source object's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifSourceMetagenerationNotMatch": { + "description": "Makes the operation conditional on whether the source object's current metageneration does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "projection": { + "description": "Set of properties to return. Defaults to noAcl, unless the object resource specifies the acl property, when it defaults to full.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit the owner, acl property." + ], + "location": "query", + "type": "string" + }, + "sourceBucket": { + "description": "Name of the bucket in which to find the source object.", + "location": "path", + "required": true, + "type": "string" + }, + "sourceGeneration": { + "description": "If present, selects a specific revision of the source object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "sourceObject": { + "description": "Name of the source object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{sourceBucket}/o/{sourceObject}/copyTo/b/{destinationBucket}/o/{destinationObject}", + "request": { + "$ref": "Object" + }, + "response": { + "$ref": "Object" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "delete": { + "description": "Deletes an object and its metadata. Deletions are permanent if versioning is not enabled for the bucket, or if the generation parameter is used.", + "httpMethod": "DELETE", + "id": "storage.objects.delete", + "parameterOrder": [ + "bucket", + "object" + ], + "parameters": { + "bucket": { + "description": "Name of the bucket in which the object resides.", + "location": "path", + "required": true, + "type": "string" + }, + "generation": { + "description": "If present, permanently deletes a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifGenerationMatch": { + "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifGenerationNotMatch": { + "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationNotMatch": { + "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "object": { + "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o/{object}", + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "get": { + "description": "Retrieves an object or its metadata.", + "httpMethod": "GET", + "id": "storage.objects.get", + "parameterOrder": [ + "bucket", + "object" + ], + "parameters": { + "bucket": { + "description": "Name of the bucket in which the object resides.", + "location": "path", + "required": true, + "type": "string" + }, + "generation": { + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifGenerationMatch": { + "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifGenerationNotMatch": { + "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationNotMatch": { + "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "object": { + "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "projection": { + "description": "Set of properties to return. Defaults to noAcl.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit the owner, acl property." + ], + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o/{object}", + "response": { + "$ref": "Object" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ], + "supportsMediaDownload": true, + "useMediaDownloadService": true + }, + "getIamPolicy": { + "description": "Returns an IAM policy for the specified object.", + "httpMethod": "GET", + "id": "storage.objects.getIamPolicy", + "parameterOrder": [ + "bucket", + "object" + ], + "parameters": { + "bucket": { + "description": "Name of the bucket in which the object resides.", + "location": "path", + "required": true, + "type": "string" + }, + "generation": { + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "object": { + "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o/{object}/iam", + "response": { + "$ref": "Policy" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "insert": { + "description": "Stores a new object and metadata.", + "httpMethod": "POST", + "id": "storage.objects.insert", + "mediaUpload": { + "accept": [ + "*/*" + ], + "protocols": { + "resumable": { + "multipart": true, + "path": "/resumable/upload/storage/v1/b/{bucket}/o" + }, + "simple": { + "multipart": true, + "path": "/upload/storage/v1/b/{bucket}/o" + } + } + }, + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of the bucket in which to store the new object. Overrides the provided object metadata's bucket value, if any.", + "location": "path", + "required": true, + "type": "string" + }, + "contentEncoding": { + "description": "If set, sets the contentEncoding property of the final object to this value. Setting this parameter is equivalent to setting the contentEncoding metadata property. This can be useful when uploading an object with uploadType=media to indicate the encoding of the content being uploaded.", + "location": "query", + "type": "string" + }, + "ifGenerationMatch": { + "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifGenerationNotMatch": { + "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationNotMatch": { + "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "kmsKeyName": { + "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any. Limited availability; usable only by enabled projects.", + "location": "query", + "type": "string" + }, + "name": { + "description": "Name of the object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "query", + "type": "string" + }, + "predefinedAcl": { + "description": "Apply a predefined set of access controls to this object.", + "enum": [ + "authenticatedRead", + "bucketOwnerFullControl", + "bucketOwnerRead", + "private", + "projectPrivate", + "publicRead" + ], + "enumDescriptions": [ + "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + "Object owner gets OWNER access, and project team owners get OWNER access.", + "Object owner gets OWNER access, and project team owners get READER access.", + "Object owner gets OWNER access.", + "Object owner gets OWNER access, and project team members get access according to their roles.", + "Object owner gets OWNER access, and allUsers get READER access." + ], + "location": "query", + "type": "string" + }, + "projection": { + "description": "Set of properties to return. Defaults to noAcl, unless the object resource specifies the acl property, when it defaults to full.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit the owner, acl property." + ], + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o", + "request": { + "$ref": "Object" + }, + "response": { + "$ref": "Object" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ], + "supportsMediaUpload": true + }, + "list": { + "description": "Retrieves a list of objects matching the criteria.", + "httpMethod": "GET", + "id": "storage.objects.list", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of the bucket in which to look for objects.", + "location": "path", + "required": true, + "type": "string" + }, + "delimiter": { + "description": "Returns results in a directory-like mode. items will contain only objects whose names, aside from the prefix, do not contain delimiter. Objects whose names, aside from the prefix, contain delimiter will have their name, truncated after the delimiter, returned in prefixes. Duplicate prefixes are omitted.", + "location": "query", + "type": "string" + }, + "maxResults": { + "default": "1000", + "description": "Maximum number of items plus prefixes to return in a single page of responses. As duplicate prefixes are omitted, fewer total results may be returned than requested. The service will use this parameter or 1,000 items, whichever is smaller.", + "format": "uint32", + "location": "query", + "minimum": "0", + "type": "integer" + }, + "pageToken": { + "description": "A previously-returned page token representing part of the larger set of results to view.", + "location": "query", + "type": "string" + }, + "prefix": { + "description": "Filter results to objects whose names begin with this prefix.", + "location": "query", + "type": "string" + }, + "projection": { + "description": "Set of properties to return. Defaults to noAcl.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit the owner, acl property." + ], + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + }, + "versions": { + "description": "If true, lists all versions of an object as distinct results. The default is false. For more information, see Object Versioning.", + "location": "query", + "type": "boolean" + } + }, + "path": "b/{bucket}/o", + "response": { + "$ref": "Objects" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ], + "supportsSubscription": true + }, + "patch": { + "description": "Patches an object's metadata.", + "httpMethod": "PATCH", + "id": "storage.objects.patch", + "parameterOrder": [ + "bucket", + "object" + ], + "parameters": { + "bucket": { + "description": "Name of the bucket in which the object resides.", + "location": "path", + "required": true, + "type": "string" + }, + "generation": { + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifGenerationMatch": { + "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifGenerationNotMatch": { + "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationNotMatch": { + "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "object": { + "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "predefinedAcl": { + "description": "Apply a predefined set of access controls to this object.", + "enum": [ + "authenticatedRead", + "bucketOwnerFullControl", + "bucketOwnerRead", + "private", + "projectPrivate", + "publicRead" + ], + "enumDescriptions": [ + "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + "Object owner gets OWNER access, and project team owners get OWNER access.", + "Object owner gets OWNER access, and project team owners get READER access.", + "Object owner gets OWNER access.", + "Object owner gets OWNER access, and project team members get access according to their roles.", + "Object owner gets OWNER access, and allUsers get READER access." + ], + "location": "query", + "type": "string" + }, + "projection": { + "description": "Set of properties to return. Defaults to full.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit the owner, acl property." + ], + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request, for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o/{object}", + "request": { + "$ref": "Object" + }, + "response": { + "$ref": "Object" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "rewrite": { + "description": "Rewrites a source object to a destination object. Optionally overrides metadata.", + "httpMethod": "POST", + "id": "storage.objects.rewrite", + "parameterOrder": [ + "sourceBucket", + "sourceObject", + "destinationBucket", + "destinationObject" + ], + "parameters": { + "destinationBucket": { + "description": "Name of the bucket in which to store the new object. Overrides the provided object metadata's bucket value, if any.", + "location": "path", + "required": true, + "type": "string" + }, + "destinationKmsKeyName": { + "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", + "location": "query", + "type": "string" + }, + "destinationObject": { + "description": "Name of the new object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "destinationPredefinedAcl": { + "description": "Apply a predefined set of access controls to the destination object.", + "enum": [ + "authenticatedRead", + "bucketOwnerFullControl", + "bucketOwnerRead", + "private", + "projectPrivate", + "publicRead" + ], + "enumDescriptions": [ + "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + "Object owner gets OWNER access, and project team owners get OWNER access.", + "Object owner gets OWNER access, and project team owners get READER access.", + "Object owner gets OWNER access.", + "Object owner gets OWNER access, and project team members get access according to their roles.", + "Object owner gets OWNER access, and allUsers get READER access." + ], + "location": "query", + "type": "string" + }, + "ifGenerationMatch": { + "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifGenerationNotMatch": { + "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "Makes the operation conditional on whether the destination object's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationNotMatch": { + "description": "Makes the operation conditional on whether the destination object's current metageneration does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifSourceGenerationMatch": { + "description": "Makes the operation conditional on whether the source object's current generation matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifSourceGenerationNotMatch": { + "description": "Makes the operation conditional on whether the source object's current generation does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifSourceMetagenerationMatch": { + "description": "Makes the operation conditional on whether the source object's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifSourceMetagenerationNotMatch": { + "description": "Makes the operation conditional on whether the source object's current metageneration does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "maxBytesRewrittenPerCall": { + "description": "The maximum number of bytes that will be rewritten per rewrite request. Most callers shouldn't need to specify this parameter - it is primarily in place to support testing. If specified the value must be an integral multiple of 1 MiB (1048576). Also, this only applies to requests where the source and destination span locations and/or storage classes. Finally, this value must not change across rewrite calls else you'll get an error that the rewriteToken is invalid.", + "format": "int64", + "location": "query", + "type": "string" + }, + "projection": { + "description": "Set of properties to return. Defaults to noAcl, unless the object resource specifies the acl property, when it defaults to full.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit the owner, acl property." + ], + "location": "query", + "type": "string" + }, + "rewriteToken": { + "description": "Include this field (from the previous rewrite response) on each rewrite request after the first one, until the rewrite response 'done' flag is true. Calls that provide a rewriteToken can omit all other request fields, but if included those fields must match the values provided in the first rewrite request.", + "location": "query", + "type": "string" + }, + "sourceBucket": { + "description": "Name of the bucket in which to find the source object.", + "location": "path", + "required": true, + "type": "string" + }, + "sourceGeneration": { + "description": "If present, selects a specific revision of the source object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "sourceObject": { + "description": "Name of the source object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{sourceBucket}/o/{sourceObject}/rewriteTo/b/{destinationBucket}/o/{destinationObject}", + "request": { + "$ref": "Object" + }, + "response": { + "$ref": "RewriteResponse" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "setIamPolicy": { + "description": "Updates an IAM policy for the specified object.", + "httpMethod": "PUT", + "id": "storage.objects.setIamPolicy", + "parameterOrder": [ + "bucket", + "object" + ], + "parameters": { + "bucket": { + "description": "Name of the bucket in which the object resides.", + "location": "path", + "required": true, + "type": "string" + }, + "generation": { + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "object": { + "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o/{object}/iam", + "request": { + "$ref": "Policy" + }, + "response": { + "$ref": "Policy" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "testIamPermissions": { + "description": "Tests a set of permissions on the given object to see which, if any, are held by the caller.", + "httpMethod": "GET", + "id": "storage.objects.testIamPermissions", + "parameterOrder": [ + "bucket", + "object", + "permissions" + ], + "parameters": { + "bucket": { + "description": "Name of the bucket in which the object resides.", + "location": "path", + "required": true, + "type": "string" + }, + "generation": { + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "object": { + "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "permissions": { + "description": "Permissions to test.", + "location": "query", + "repeated": true, + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o/{object}/iam/testPermissions", + "response": { + "$ref": "TestIamPermissionsResponse" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "update": { + "description": "Updates an object's metadata.", + "httpMethod": "PUT", + "id": "storage.objects.update", + "parameterOrder": [ + "bucket", + "object" + ], + "parameters": { + "bucket": { + "description": "Name of the bucket in which the object resides.", + "location": "path", + "required": true, + "type": "string" + }, + "generation": { + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifGenerationMatch": { + "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifGenerationNotMatch": { + "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationNotMatch": { + "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "object": { + "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "predefinedAcl": { + "description": "Apply a predefined set of access controls to this object.", + "enum": [ + "authenticatedRead", + "bucketOwnerFullControl", + "bucketOwnerRead", + "private", + "projectPrivate", + "publicRead" + ], + "enumDescriptions": [ + "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + "Object owner gets OWNER access, and project team owners get OWNER access.", + "Object owner gets OWNER access, and project team owners get READER access.", + "Object owner gets OWNER access.", + "Object owner gets OWNER access, and project team members get access according to their roles.", + "Object owner gets OWNER access, and allUsers get READER access." + ], + "location": "query", + "type": "string" + }, + "projection": { + "description": "Set of properties to return. Defaults to full.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit the owner, acl property." + ], + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o/{object}", + "request": { + "$ref": "Object" + }, + "response": { + "$ref": "Object" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "watchAll": { + "description": "Watch for changes on all objects in a bucket.", + "httpMethod": "POST", + "id": "storage.objects.watchAll", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of the bucket in which to look for objects.", + "location": "path", + "required": true, + "type": "string" + }, + "delimiter": { + "description": "Returns results in a directory-like mode. items will contain only objects whose names, aside from the prefix, do not contain delimiter. Objects whose names, aside from the prefix, contain delimiter will have their name, truncated after the delimiter, returned in prefixes. Duplicate prefixes are omitted.", + "location": "query", + "type": "string" + }, + "maxResults": { + "default": "1000", + "description": "Maximum number of items plus prefixes to return in a single page of responses. As duplicate prefixes are omitted, fewer total results may be returned than requested. The service will use this parameter or 1,000 items, whichever is smaller.", + "format": "uint32", + "location": "query", + "minimum": "0", + "type": "integer" + }, + "pageToken": { + "description": "A previously-returned page token representing part of the larger set of results to view.", + "location": "query", + "type": "string" + }, + "prefix": { + "description": "Filter results to objects whose names begin with this prefix.", + "location": "query", + "type": "string" + }, + "projection": { + "description": "Set of properties to return. Defaults to noAcl.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit the owner, acl property." + ], + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + }, + "versions": { + "description": "If true, lists all versions of an object as distinct results. The default is false. For more information, see Object Versioning.", + "location": "query", + "type": "boolean" + } + }, + "path": "b/{bucket}/o/watch", + "request": { + "$ref": "Channel", + "parameterName": "resource" + }, + "response": { + "$ref": "Channel" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ], + "supportsSubscription": true + } + } + }, + "projects": { + "resources": { + "serviceAccount": { + "methods": { + "get": { + "description": "Get the email address of this project's Google Cloud Storage service account.", + "httpMethod": "GET", + "id": "storage.projects.serviceAccount.get", + "parameterOrder": [ + "projectId" + ], + "parameters": { + "projectId": { + "description": "Project ID", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request.", + "location": "query", + "type": "string" + } + }, + "path": "projects/{projectId}/serviceAccount", + "response": { + "$ref": "ServiceAccount" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + } + } + } + } + } + }, + "revision": "20180305", + "rootUrl": "https://www.googleapis.com/", + "schemas": { + "Bucket": { + "description": "A bucket.", + "id": "Bucket", + "properties": { + "acl": { + "annotations": { + "required": [ + "storage.buckets.update" + ] + }, + "description": "Access controls on the bucket.", + "items": { + "$ref": "BucketAccessControl" + }, + "type": "array" + }, + "billing": { + "description": "The bucket's billing configuration.", + "properties": { + "requesterPays": { + "description": "When set to true, Requester Pays is enabled for this bucket.", + "type": "boolean" + } + }, + "type": "object" + }, + "cors": { + "description": "The bucket's Cross-Origin Resource Sharing (CORS) configuration.", + "items": { + "properties": { + "maxAgeSeconds": { + "description": "The value, in seconds, to return in the Access-Control-Max-Age header used in preflight responses.", + "format": "int32", + "type": "integer" + }, + "method": { + "description": "The list of HTTP methods on which to include CORS response headers, (GET, OPTIONS, POST, etc) Note: \"*\" is permitted in the list of methods, and means \"any method\".", + "items": { + "type": "string" + }, + "type": "array" + }, + "origin": { + "description": "The list of Origins eligible to receive CORS response headers. Note: \"*\" is permitted in the list of origins, and means \"any Origin\".", + "items": { + "type": "string" + }, + "type": "array" + }, + "responseHeader": { + "description": "The list of HTTP headers other than the simple response headers to give permission for the user-agent to share across domains.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "defaultEventBasedHold": { + "description": "Defines the default value for Event-Based hold on newly created objects in this bucket. Event-Based hold is a way to retain objects indefinitely until an event occurs, signified by the hold's release. After being released, such objects will be subject to bucket-level retention (if any). One sample use case of this flag is for banks to hold loan documents for at least 3 years after loan is paid in full. Here bucket-level retention is 3 years and the event is loan being paid in full. In this example these objects will be held intact for any number of years until the event has occurred (hold is released) and then 3 more years after that. Objects under Event-Based hold cannot be deleted, overwritten or archived until the hold is removed.", + "type": "boolean" + }, + "defaultObjectAcl": { + "description": "Default access controls to apply to new objects when no ACL is provided.", + "items": { + "$ref": "ObjectAccessControl" + }, + "type": "array" + }, + "encryption": { + "description": "Encryption configuration used by default for newly inserted objects, when no encryption config is specified.", + "properties": { + "defaultKmsKeyName": { + "description": "A Cloud KMS key that will be used to encrypt objects inserted into this bucket, if no encryption method is specified. Limited availability; usable only by enabled projects.", + "type": "string" + } + }, + "type": "object" + }, + "etag": { + "description": "HTTP 1.1 Entity tag for the bucket.", + "type": "string" + }, + "id": { + "description": "The ID of the bucket. For buckets, the id and name properties are the same.", + "type": "string" + }, + "kind": { + "default": "storage#bucket", + "description": "The kind of item this is. For buckets, this is always storage#bucket.", + "type": "string" + }, + "labels": { + "additionalProperties": { + "description": "An individual label entry.", + "type": "string" + }, + "description": "User-provided labels, in key/value pairs.", + "type": "object" + }, + "lifecycle": { + "description": "The bucket's lifecycle configuration. See lifecycle management for more information.", + "properties": { + "rule": { + "description": "A lifecycle management rule, which is made of an action to take and the condition(s) under which the action will be taken.", + "items": { + "properties": { + "action": { + "description": "The action to take.", + "properties": { + "storageClass": { + "description": "Target storage class. Required iff the type of the action is SetStorageClass.", + "type": "string" + }, + "type": { + "description": "Type of the action. Currently, only Delete and SetStorageClass are supported.", + "type": "string" + } + }, + "type": "object" + }, + "condition": { + "description": "The condition(s) under which the action will be taken.", + "properties": { + "age": { + "description": "Age of an object (in days). This condition is satisfied when an object reaches the specified age.", + "format": "int32", + "type": "integer" + }, + "createdBefore": { + "description": "A date in RFC 3339 format with only the date part (for instance, \"2013-01-15\"). This condition is satisfied when an object is created before midnight of the specified date in UTC.", + "format": "date", + "type": "string" + }, + "isLive": { + "description": "Relevant only for versioned objects. If the value is true, this condition matches live objects; if the value is false, it matches archived objects.", + "type": "boolean" + }, + "matchesStorageClass": { + "description": "Objects having any of the storage classes specified by this condition will be matched. Values include MULTI_REGIONAL, REGIONAL, NEARLINE, COLDLINE, STANDARD, and DURABLE_REDUCED_AVAILABILITY.", + "items": { + "type": "string" + }, + "type": "array" + }, + "numNewerVersions": { + "description": "Relevant only for versioned objects. If the value is N, this condition is satisfied when there are at least N versions (including the live version) newer than this version of the object.", + "format": "int32", + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "location": { + "description": "The location of the bucket. Object data for objects in the bucket resides in physical storage within this region. Defaults to US. See the developer's guide for the authoritative list.", + "type": "string" + }, + "logging": { + "description": "The bucket's logging configuration, which defines the destination bucket and optional name prefix for the current bucket's logs.", + "properties": { + "logBucket": { + "description": "The destination bucket where the current bucket's logs should be placed.", + "type": "string" + }, + "logObjectPrefix": { + "description": "A prefix for log object names.", + "type": "string" + } + }, + "type": "object" + }, + "metageneration": { + "description": "The metadata generation of this bucket.", + "format": "int64", + "type": "string" + }, + "name": { + "annotations": { + "required": [ + "storage.buckets.insert" + ] + }, + "description": "The name of the bucket.", + "type": "string" + }, + "owner": { + "description": "The owner of the bucket. This is always the project team's owner group.", + "properties": { + "entity": { + "description": "The entity, in the form project-owner-projectId.", + "type": "string" + }, + "entityId": { + "description": "The ID for the entity.", + "type": "string" + } + }, + "type": "object" + }, + "projectNumber": { + "description": "The project number of the project the bucket belongs to.", + "format": "uint64", + "type": "string" + }, + "retentionPolicy": { + "description": "Defines the retention policy for a bucket. The Retention policy enforces a minimum retention time for all objects contained in the bucket, based on their creation time. Any attempt to overwrite or delete objects younger than the retention period will result in a PERMISSION_DENIED error. An unlocked retention policy can be modified or removed from the bucket via the UpdateBucketMetadata RPC. A locked retention policy cannot be removed or shortened in duration for the lifetime of the bucket. Attempting to remove or decrease period of a locked retention policy will result in a PERMISSION_DENIED error.", + "properties": { + "effectiveTime": { + "description": "The time from which policy was enforced and effective. RFC 3339 format.", + "format": "date-time", + "type": "string" + }, + "isLocked": { + "description": "Once locked, an object retention policy cannot be modified.", + "type": "boolean" + }, + "retentionPeriod": { + "description": "Specifies the duration that objects need to be retained. Retention duration must be greater than zero and less than 100 years. Note that enforcement of retention periods less than a day is not guaranteed. Such periods should only be used for testing purposes.", + "format": "int64", + "type": "string" + } + }, + "type": "object" + }, + "selfLink": { + "description": "The URI of this bucket.", + "type": "string" + }, + "storageClass": { + "description": "The bucket's default storage class, used whenever no storageClass is specified for a newly-created object. This defines how objects in the bucket are stored and determines the SLA and the cost of storage. Values include MULTI_REGIONAL, REGIONAL, STANDARD, NEARLINE, COLDLINE, and DURABLE_REDUCED_AVAILABILITY. If this value is not specified when the bucket is created, it will default to STANDARD. For more information, see storage classes.", + "type": "string" + }, + "timeCreated": { + "description": "The creation time of the bucket in RFC 3339 format.", + "format": "date-time", + "type": "string" + }, + "updated": { + "description": "The modification time of the bucket in RFC 3339 format.", + "format": "date-time", + "type": "string" + }, + "versioning": { + "description": "The bucket's versioning configuration.", + "properties": { + "enabled": { + "description": "While set to true, versioning is fully enabled for this bucket.", + "type": "boolean" + } + }, + "type": "object" + }, + "website": { + "description": "The bucket's website configuration, controlling how the service behaves when accessing bucket contents as a web site. See the Static Website Examples for more information.", + "properties": { + "mainPageSuffix": { + "description": "If the requested object path is missing, the service will ensure the path has a trailing '/', append this suffix, and attempt to retrieve the resulting object. This allows the creation of index.html objects to represent directory pages.", + "type": "string" + }, + "notFoundPage": { + "description": "If the requested object path is missing, and any mainPageSuffix object is missing, if applicable, the service will return the named object from this bucket as the content for a 404 Not Found result.", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "BucketAccessControl": { + "description": "An access-control entry.", + "id": "BucketAccessControl", + "properties": { + "bucket": { + "description": "The name of the bucket.", + "type": "string" + }, + "domain": { + "description": "The domain associated with the entity, if any.", + "type": "string" + }, + "email": { + "description": "The email address associated with the entity, if any.", + "type": "string" + }, + "entity": { + "annotations": { + "required": [ + "storage.bucketAccessControls.insert" + ] + }, + "description": "The entity holding the permission, in one of the following forms: \n- user-userId \n- user-email \n- group-groupId \n- group-email \n- domain-domain \n- project-team-projectId \n- allUsers \n- allAuthenticatedUsers Examples: \n- The user liz@example.com would be user-liz@example.com. \n- The group example@googlegroups.com would be group-example@googlegroups.com. \n- To refer to all members of the Google Apps for Business domain example.com, the entity would be domain-example.com.", + "type": "string" + }, + "entityId": { + "description": "The ID for the entity, if any.", + "type": "string" + }, + "etag": { + "description": "HTTP 1.1 Entity tag for the access-control entry.", + "type": "string" + }, + "id": { + "description": "The ID of the access-control entry.", + "type": "string" + }, + "kind": { + "default": "storage#bucketAccessControl", + "description": "The kind of item this is. For bucket access control entries, this is always storage#bucketAccessControl.", + "type": "string" + }, + "projectTeam": { + "description": "The project team associated with the entity, if any.", + "properties": { + "projectNumber": { + "description": "The project number.", + "type": "string" + }, + "team": { + "description": "The team.", + "type": "string" + } + }, + "type": "object" + }, + "role": { + "annotations": { + "required": [ + "storage.bucketAccessControls.insert" + ] + }, + "description": "The access permission for the entity.", + "type": "string" + }, + "selfLink": { + "description": "The link to this access-control entry.", + "type": "string" + } + }, + "type": "object" + }, + "BucketAccessControls": { + "description": "An access-control list.", + "id": "BucketAccessControls", + "properties": { + "items": { + "description": "The list of items.", + "items": { + "$ref": "BucketAccessControl" + }, + "type": "array" + }, + "kind": { + "default": "storage#bucketAccessControls", + "description": "The kind of item this is. For lists of bucket access control entries, this is always storage#bucketAccessControls.", + "type": "string" + } + }, + "type": "object" + }, + "Buckets": { + "description": "A list of buckets.", + "id": "Buckets", + "properties": { + "items": { + "description": "The list of items.", + "items": { + "$ref": "Bucket" + }, + "type": "array" + }, + "kind": { + "default": "storage#buckets", + "description": "The kind of item this is. For lists of buckets, this is always storage#buckets.", + "type": "string" + }, + "nextPageToken": { + "description": "The continuation token, used to page through large result sets. Provide this value in a subsequent request to return the next page of results.", + "type": "string" + } + }, + "type": "object" + }, + "Channel": { + "description": "An notification channel used to watch for resource changes.", + "id": "Channel", + "properties": { + "address": { + "description": "The address where notifications are delivered for this channel.", + "type": "string" + }, + "expiration": { + "description": "Date and time of notification channel expiration, expressed as a Unix timestamp, in milliseconds. Optional.", + "format": "int64", + "type": "string" + }, + "id": { + "description": "A UUID or similar unique string that identifies this channel.", + "type": "string" + }, + "kind": { + "default": "api#channel", + "description": "Identifies this as a notification channel used to watch for changes to a resource. Value: the fixed string \"api#channel\".", + "type": "string" + }, + "params": { + "additionalProperties": { + "description": "Declares a new parameter by name.", + "type": "string" + }, + "description": "Additional parameters controlling delivery channel behavior. Optional.", + "type": "object" + }, + "payload": { + "description": "A Boolean value to indicate whether payload is wanted. Optional.", + "type": "boolean" + }, + "resourceId": { + "description": "An opaque ID that identifies the resource being watched on this channel. Stable across different API versions.", + "type": "string" + }, + "resourceUri": { + "description": "A version-specific identifier for the watched resource.", + "type": "string" + }, + "token": { + "description": "An arbitrary string delivered to the target address with each notification delivered over this channel. Optional.", + "type": "string" + }, + "type": { + "description": "The type of delivery mechanism used for this channel.", + "type": "string" + } + }, + "type": "object" + }, + "ComposeRequest": { + "description": "A Compose request.", + "id": "ComposeRequest", + "properties": { + "destination": { + "$ref": "Object", + "description": "Properties of the resulting object." + }, + "kind": { + "default": "storage#composeRequest", + "description": "The kind of item this is.", + "type": "string" + }, + "sourceObjects": { + "annotations": { + "required": [ + "storage.objects.compose" + ] + }, + "description": "The list of source objects that will be concatenated into a single object.", + "items": { + "properties": { + "generation": { + "description": "The generation of this object to use as the source.", + "format": "int64", + "type": "string" + }, + "name": { + "annotations": { + "required": [ + "storage.objects.compose" + ] + }, + "description": "The source object's name. The source object's bucket is implicitly the destination bucket.", + "type": "string" + }, + "objectPreconditions": { + "description": "Conditions that must be met for this operation to execute.", + "properties": { + "ifGenerationMatch": { + "description": "Only perform the composition if the generation of the source object that would be used matches this value. If this value and a generation are both specified, they must be the same value or the call will fail.", + "format": "int64", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "Notification": { + "description": "A subscription to receive Google PubSub notifications.", + "id": "Notification", + "properties": { + "custom_attributes": { + "additionalProperties": { + "type": "string" + }, + "description": "An optional list of additional attributes to attach to each Cloud PubSub message published for this notification subscription.", + "type": "object" + }, + "etag": { + "description": "HTTP 1.1 Entity tag for this subscription notification.", + "type": "string" + }, + "event_types": { + "description": "If present, only send notifications about listed event types. If empty, sent notifications for all event types.", + "items": { + "type": "string" + }, + "type": "array" + }, + "id": { + "description": "The ID of the notification.", + "type": "string" + }, + "kind": { + "default": "storage#notification", + "description": "The kind of item this is. For notifications, this is always storage#notification.", + "type": "string" + }, + "object_name_prefix": { + "description": "If present, only apply this notification configuration to object names that begin with this prefix.", + "type": "string" + }, + "payload_format": { + "annotations": { + "required": [ + "storage.notifications.insert" + ] + }, + "default": "JSON_API_V1", + "description": "The desired content of the Payload.", + "type": "string" + }, + "selfLink": { + "description": "The canonical URL of this notification.", + "type": "string" + }, + "topic": { + "annotations": { + "required": [ + "storage.notifications.insert" + ] + }, + "description": "The Cloud PubSub topic to which this subscription publishes. Formatted as: '//pubsub.googleapis.com/projects/{project-identifier}/topics/{my-topic}'", + "type": "string" + } + }, + "type": "object" + }, + "Notifications": { + "description": "A list of notification subscriptions.", + "id": "Notifications", + "properties": { + "items": { + "description": "The list of items.", + "items": { + "$ref": "Notification" + }, + "type": "array" + }, + "kind": { + "default": "storage#notifications", + "description": "The kind of item this is. For lists of notifications, this is always storage#notifications.", + "type": "string" + } + }, + "type": "object" + }, + "Object": { + "description": "An object.", + "id": "Object", + "properties": { + "acl": { + "annotations": { + "required": [ + "storage.objects.update" + ] + }, + "description": "Access controls on the object.", + "items": { + "$ref": "ObjectAccessControl" + }, + "type": "array" + }, + "bucket": { + "description": "The name of the bucket containing this object.", + "type": "string" + }, + "cacheControl": { + "description": "Cache-Control directive for the object data. If omitted, and the object is accessible to all anonymous users, the default will be public, max-age=3600.", + "type": "string" + }, + "componentCount": { + "description": "Number of underlying components that make up this object. Components are accumulated by compose operations.", + "format": "int32", + "type": "integer" + }, + "contentDisposition": { + "description": "Content-Disposition of the object data.", + "type": "string" + }, + "contentEncoding": { + "description": "Content-Encoding of the object data.", + "type": "string" + }, + "contentLanguage": { + "description": "Content-Language of the object data.", + "type": "string" + }, + "contentType": { + "description": "Content-Type of the object data. If an object is stored without a Content-Type, it is served as application/octet-stream.", + "type": "string" + }, + "crc32c": { + "description": "CRC32c checksum, as described in RFC 4960, Appendix B; encoded using base64 in big-endian byte order. For more information about using the CRC32c checksum, see Hashes and ETags: Best Practices.", + "type": "string" + }, + "customerEncryption": { + "description": "Metadata of customer-supplied encryption key, if the object is encrypted by such a key.", + "properties": { + "encryptionAlgorithm": { + "description": "The encryption algorithm.", + "type": "string" + }, + "keySha256": { + "description": "SHA256 hash value of the encryption key.", + "type": "string" + } + }, + "type": "object" + }, + "etag": { + "description": "HTTP 1.1 Entity tag for the object.", + "type": "string" + }, + "eventBasedHold": { + "description": "Defines the Event-Based hold for an object. Event-Based hold is a way to retain objects indefinitely until an event occurs, signified by the hold's release. After being released, such objects will be subject to bucket-level retention (if any). One sample use case of this flag is for banks to hold loan documents for at least 3 years after loan is paid in full. Here bucket-level retention is 3 years and the event is loan being paid in full. In this example these objects will be held intact for any number of years until the event has occurred (hold is released) and then 3 more years after that.", + "type": "boolean" + }, + "generation": { + "description": "The content generation of this object. Used for object versioning.", + "format": "int64", + "type": "string" + }, + "id": { + "description": "The ID of the object, including the bucket name, object name, and generation number.", + "type": "string" + }, + "kind": { + "default": "storage#object", + "description": "The kind of item this is. For objects, this is always storage#object.", + "type": "string" + }, + "kmsKeyName": { + "description": "Cloud KMS Key used to encrypt this object, if the object is encrypted by such a key. Limited availability; usable only by enabled projects.", + "type": "string" + }, + "md5Hash": { + "description": "MD5 hash of the data; encoded using base64. For more information about using the MD5 hash, see Hashes and ETags: Best Practices.", + "type": "string" + }, + "mediaLink": { + "description": "Media download link.", + "type": "string" + }, + "metadata": { + "additionalProperties": { + "description": "An individual metadata entry.", + "type": "string" + }, + "description": "User-provided metadata, in key/value pairs.", + "type": "object" + }, + "metageneration": { + "description": "The version of the metadata for this object at this generation. Used for preconditions and for detecting changes in metadata. A metageneration number is only meaningful in the context of a particular generation of a particular object.", + "format": "int64", + "type": "string" + }, + "name": { + "description": "The name of the object. Required if not specified by URL parameter.", + "type": "string" + }, + "owner": { + "description": "The owner of the object. This will always be the uploader of the object.", + "properties": { + "entity": { + "description": "The entity, in the form user-userId.", + "type": "string" + }, + "entityId": { + "description": "The ID for the entity.", + "type": "string" + } + }, + "type": "object" + }, + "retentionExpirationTime": { + "description": "Specifies the earliest time that the object's retention period expires. This value is server-determined and is in RFC 3339 format. Note 1: This field is not provided for objects with an active Event-Based hold, since retention expiration is unknown until the hold is removed. Note 2: This value can be provided even when TemporaryHold is set (so that the user can reason about policy without having to first unset the TemporaryHold).", + "format": "date-time", + "type": "string" + }, + "selfLink": { + "description": "The link to this object.", + "type": "string" + }, + "size": { + "description": "Content-Length of the data in bytes.", + "format": "uint64", + "type": "string" + }, + "storageClass": { + "description": "Storage class of the object.", + "type": "string" + }, + "temporaryHold": { + "description": "Defines the temporary hold for an object. This flag is used to enforce a temporary hold on an object. While it is set to true, the object is protected against deletion and overwrites. A common use case of this flag is regulatory investigations where objects need to be retained while the investigation is ongoing.", + "type": "boolean" + }, + "timeCreated": { + "description": "The creation time of the object in RFC 3339 format.", + "format": "date-time", + "type": "string" + }, + "timeDeleted": { + "description": "The deletion time of the object in RFC 3339 format. Will be returned if and only if this version of the object has been deleted.", + "format": "date-time", + "type": "string" + }, + "timeStorageClassUpdated": { + "description": "The time at which the object's storage class was last changed. When the object is initially created, it will be set to timeCreated.", + "format": "date-time", + "type": "string" + }, + "updated": { + "description": "The modification time of the object metadata in RFC 3339 format.", + "format": "date-time", + "type": "string" + } + }, + "type": "object" + }, + "ObjectAccessControl": { + "description": "An access-control entry.", + "id": "ObjectAccessControl", + "properties": { + "bucket": { + "description": "The name of the bucket.", + "type": "string" + }, + "domain": { + "description": "The domain associated with the entity, if any.", + "type": "string" + }, + "email": { + "description": "The email address associated with the entity, if any.", + "type": "string" + }, + "entity": { + "annotations": { + "required": [ + "storage.defaultObjectAccessControls.insert", + "storage.objectAccessControls.insert" + ] + }, + "description": "The entity holding the permission, in one of the following forms: \n- user-userId \n- user-email \n- group-groupId \n- group-email \n- domain-domain \n- project-team-projectId \n- allUsers \n- allAuthenticatedUsers Examples: \n- The user liz@example.com would be user-liz@example.com. \n- The group example@googlegroups.com would be group-example@googlegroups.com. \n- To refer to all members of the Google Apps for Business domain example.com, the entity would be domain-example.com.", + "type": "string" + }, + "entityId": { + "description": "The ID for the entity, if any.", + "type": "string" + }, + "etag": { + "description": "HTTP 1.1 Entity tag for the access-control entry.", + "type": "string" + }, + "generation": { + "description": "The content generation of the object, if applied to an object.", + "format": "int64", + "type": "string" + }, + "id": { + "description": "The ID of the access-control entry.", + "type": "string" + }, + "kind": { + "default": "storage#objectAccessControl", + "description": "The kind of item this is. For object access control entries, this is always storage#objectAccessControl.", + "type": "string" + }, + "object": { + "description": "The name of the object, if applied to an object.", + "type": "string" + }, + "projectTeam": { + "description": "The project team associated with the entity, if any.", + "properties": { + "projectNumber": { + "description": "The project number.", + "type": "string" + }, + "team": { + "description": "The team.", + "type": "string" + } + }, + "type": "object" + }, + "role": { + "annotations": { + "required": [ + "storage.defaultObjectAccessControls.insert", + "storage.objectAccessControls.insert" + ] + }, + "description": "The access permission for the entity.", + "type": "string" + }, + "selfLink": { + "description": "The link to this access-control entry.", + "type": "string" + } + }, + "type": "object" + }, + "ObjectAccessControls": { + "description": "An access-control list.", + "id": "ObjectAccessControls", + "properties": { + "items": { + "description": "The list of items.", + "items": { + "$ref": "ObjectAccessControl" + }, + "type": "array" + }, + "kind": { + "default": "storage#objectAccessControls", + "description": "The kind of item this is. For lists of object access control entries, this is always storage#objectAccessControls.", + "type": "string" + } + }, + "type": "object" + }, + "Objects": { + "description": "A list of objects.", + "id": "Objects", + "properties": { + "items": { + "description": "The list of items.", + "items": { + "$ref": "Object" + }, + "type": "array" + }, + "kind": { + "default": "storage#objects", + "description": "The kind of item this is. For lists of objects, this is always storage#objects.", + "type": "string" + }, + "nextPageToken": { + "description": "The continuation token, used to page through large result sets. Provide this value in a subsequent request to return the next page of results.", + "type": "string" + }, + "prefixes": { + "description": "The list of prefixes of objects matching-but-not-listed up to and including the requested delimiter.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "Policy": { + "description": "A bucket/object IAM policy.", + "id": "Policy", + "properties": { + "bindings": { + "annotations": { + "required": [ + "storage.buckets.setIamPolicy", + "storage.objects.setIamPolicy" + ] + }, + "description": "An association between a role, which comes with a set of permissions, and members who may assume that role.", + "items": { + "properties": { + "condition": { + "type": "any" + }, + "members": { + "annotations": { + "required": [ + "storage.buckets.setIamPolicy", + "storage.objects.setIamPolicy" + ] + }, + "description": "A collection of identifiers for members who may assume the provided role. Recognized identifiers are as follows: \n- allUsers — A special identifier that represents anyone on the internet; with or without a Google account. \n- allAuthenticatedUsers — A special identifier that represents anyone who is authenticated with a Google account or a service account. \n- user:emailid — An email address that represents a specific account. For example, user:alice@gmail.com or user:joe@example.com. \n- serviceAccount:emailid — An email address that represents a service account. For example, serviceAccount:my-other-app@appspot.gserviceaccount.com . \n- group:emailid — An email address that represents a Google group. For example, group:admins@example.com. \n- domain:domain — A Google Apps domain name that represents all the users of that domain. For example, domain:google.com or domain:example.com. \n- projectOwner:projectid — Owners of the given project. For example, projectOwner:my-example-project \n- projectEditor:projectid — Editors of the given project. For example, projectEditor:my-example-project \n- projectViewer:projectid — Viewers of the given project. For example, projectViewer:my-example-project", + "items": { + "type": "string" + }, + "type": "array" + }, + "role": { + "annotations": { + "required": [ + "storage.buckets.setIamPolicy", + "storage.objects.setIamPolicy" + ] + }, + "description": "The role to which members belong. Two types of roles are supported: new IAM roles, which grant permissions that do not map directly to those provided by ACLs, and legacy IAM roles, which do map directly to ACL permissions. All roles are of the format roles/storage.specificRole.\nThe new IAM roles are: \n- roles/storage.admin — Full control of Google Cloud Storage resources. \n- roles/storage.objectViewer — Read-Only access to Google Cloud Storage objects. \n- roles/storage.objectCreator — Access to create objects in Google Cloud Storage. \n- roles/storage.objectAdmin — Full control of Google Cloud Storage objects. The legacy IAM roles are: \n- roles/storage.legacyObjectReader — Read-only access to objects without listing. Equivalent to an ACL entry on an object with the READER role. \n- roles/storage.legacyObjectOwner — Read/write access to existing objects without listing. Equivalent to an ACL entry on an object with the OWNER role. \n- roles/storage.legacyBucketReader — Read access to buckets with object listing. Equivalent to an ACL entry on a bucket with the READER role. \n- roles/storage.legacyBucketWriter — Read access to buckets with object listing/creation/deletion. Equivalent to an ACL entry on a bucket with the WRITER role. \n- roles/storage.legacyBucketOwner — Read and write access to existing buckets with object listing/creation/deletion. Equivalent to an ACL entry on a bucket with the OWNER role.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "etag": { + "description": "HTTP 1.1 Entity tag for the policy.", + "format": "byte", + "type": "string" + }, + "kind": { + "default": "storage#policy", + "description": "The kind of item this is. For policies, this is always storage#policy. This field is ignored on input.", + "type": "string" + }, + "resourceId": { + "description": "The ID of the resource to which this policy belongs. Will be of the form projects/_/buckets/bucket for buckets, and projects/_/buckets/bucket/objects/object for objects. A specific generation may be specified by appending #generationNumber to the end of the object name, e.g. projects/_/buckets/my-bucket/objects/data.txt#17. The current generation can be denoted with #0. This field is ignored on input.", + "type": "string" + } + }, + "type": "object" + }, + "RewriteResponse": { + "description": "A rewrite response.", + "id": "RewriteResponse", + "properties": { + "done": { + "description": "true if the copy is finished; otherwise, false if the copy is in progress. This property is always present in the response.", + "type": "boolean" + }, + "kind": { + "default": "storage#rewriteResponse", + "description": "The kind of item this is.", + "type": "string" + }, + "objectSize": { + "description": "The total size of the object being copied in bytes. This property is always present in the response.", + "format": "int64", + "type": "string" + }, + "resource": { + "$ref": "Object", + "description": "A resource containing the metadata for the copied-to object. This property is present in the response only when copying completes." + }, + "rewriteToken": { + "description": "A token to use in subsequent requests to continue copying data. This token is present in the response only when there is more data to copy.", + "type": "string" + }, + "totalBytesRewritten": { + "description": "The total bytes written so far, which can be used to provide a waiting user with a progress indicator. This property is always present in the response.", + "format": "int64", + "type": "string" + } + }, + "type": "object" + }, + "ServiceAccount": { + "description": "A subscription to receive Google PubSub notifications.", + "id": "ServiceAccount", + "properties": { + "email_address": { + "description": "The ID of the notification.", + "type": "string" + }, + "kind": { + "default": "storage#serviceAccount", + "description": "The kind of item this is. For notifications, this is always storage#notification.", + "type": "string" + } + }, + "type": "object" + }, + "TestIamPermissionsResponse": { + "description": "A storage.(buckets|objects).testIamPermissions response.", + "id": "TestIamPermissionsResponse", + "properties": { + "kind": { + "default": "storage#testIamPermissionsResponse", + "description": "The kind of item this is.", + "type": "string" + }, + "permissions": { + "description": "The permissions held by the caller. Permissions are always of the format storage.resource.capability, where resource is one of buckets or objects. The supported permissions are as follows: \n- storage.buckets.delete — Delete bucket. \n- storage.buckets.get — Read bucket metadata. \n- storage.buckets.getIamPolicy — Read bucket IAM policy. \n- storage.buckets.create — Create bucket. \n- storage.buckets.list — List buckets. \n- storage.buckets.setIamPolicy — Update bucket IAM policy. \n- storage.buckets.update — Update bucket metadata. \n- storage.objects.delete — Delete object. \n- storage.objects.get — Read object data and metadata. \n- storage.objects.getIamPolicy — Read object IAM policy. \n- storage.objects.create — Create object. \n- storage.objects.list — List objects. \n- storage.objects.setIamPolicy — Update object IAM policy. \n- storage.objects.update — Update object metadata.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + } + }, + "servicePath": "storage/v1/", + "title": "Cloud Storage JSON API", + "version": "v1" +} \ No newline at end of file diff --git a/vendor/google.golang.org/api/storage/v1/storage-gen.go b/vendor/google.golang.org/api/storage/v1/storage-gen.go new file mode 100644 index 000000000..36846eb54 --- /dev/null +++ b/vendor/google.golang.org/api/storage/v1/storage-gen.go @@ -0,0 +1,11171 @@ +// Package storage provides access to the Cloud Storage JSON API. +// +// See https://developers.google.com/storage/docs/json_api/ +// +// Usage example: +// +// import "google.golang.org/api/storage/v1" +// ... +// storageService, err := storage.New(oauthHttpClient) +package storage // import "google.golang.org/api/storage/v1" + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + context "golang.org/x/net/context" + ctxhttp "golang.org/x/net/context/ctxhttp" + gensupport "google.golang.org/api/gensupport" + googleapi "google.golang.org/api/googleapi" + "io" + "net/http" + "net/url" + "strconv" + "strings" +) + +// Always reference these packages, just in case the auto-generated code +// below doesn't. +var _ = bytes.NewBuffer +var _ = strconv.Itoa +var _ = fmt.Sprintf +var _ = json.NewDecoder +var _ = io.Copy +var _ = url.Parse +var _ = gensupport.MarshalJSON +var _ = googleapi.Version +var _ = errors.New +var _ = strings.Replace +var _ = context.Canceled +var _ = ctxhttp.Do + +const apiId = "storage:v1" +const apiName = "storage" +const apiVersion = "v1" +const basePath = "https://www.googleapis.com/storage/v1/" + +// OAuth2 scopes used by this API. +const ( + // View and manage your data across Google Cloud Platform services + CloudPlatformScope = "https://www.googleapis.com/auth/cloud-platform" + + // View your data across Google Cloud Platform services + CloudPlatformReadOnlyScope = "https://www.googleapis.com/auth/cloud-platform.read-only" + + // Manage your data and permissions in Google Cloud Storage + DevstorageFullControlScope = "https://www.googleapis.com/auth/devstorage.full_control" + + // View your data in Google Cloud Storage + DevstorageReadOnlyScope = "https://www.googleapis.com/auth/devstorage.read_only" + + // Manage your data in Google Cloud Storage + DevstorageReadWriteScope = "https://www.googleapis.com/auth/devstorage.read_write" +) + +func New(client *http.Client) (*Service, error) { + if client == nil { + return nil, errors.New("client is nil") + } + s := &Service{client: client, BasePath: basePath} + s.BucketAccessControls = NewBucketAccessControlsService(s) + s.Buckets = NewBucketsService(s) + s.Channels = NewChannelsService(s) + s.DefaultObjectAccessControls = NewDefaultObjectAccessControlsService(s) + s.Notifications = NewNotificationsService(s) + s.ObjectAccessControls = NewObjectAccessControlsService(s) + s.Objects = NewObjectsService(s) + s.Projects = NewProjectsService(s) + return s, nil +} + +type Service struct { + client *http.Client + BasePath string // API endpoint base URL + UserAgent string // optional additional User-Agent fragment + + BucketAccessControls *BucketAccessControlsService + + Buckets *BucketsService + + Channels *ChannelsService + + DefaultObjectAccessControls *DefaultObjectAccessControlsService + + Notifications *NotificationsService + + ObjectAccessControls *ObjectAccessControlsService + + Objects *ObjectsService + + Projects *ProjectsService +} + +func (s *Service) userAgent() string { + if s.UserAgent == "" { + return googleapi.UserAgent + } + return googleapi.UserAgent + " " + s.UserAgent +} + +func NewBucketAccessControlsService(s *Service) *BucketAccessControlsService { + rs := &BucketAccessControlsService{s: s} + return rs +} + +type BucketAccessControlsService struct { + s *Service +} + +func NewBucketsService(s *Service) *BucketsService { + rs := &BucketsService{s: s} + return rs +} + +type BucketsService struct { + s *Service +} + +func NewChannelsService(s *Service) *ChannelsService { + rs := &ChannelsService{s: s} + return rs +} + +type ChannelsService struct { + s *Service +} + +func NewDefaultObjectAccessControlsService(s *Service) *DefaultObjectAccessControlsService { + rs := &DefaultObjectAccessControlsService{s: s} + return rs +} + +type DefaultObjectAccessControlsService struct { + s *Service +} + +func NewNotificationsService(s *Service) *NotificationsService { + rs := &NotificationsService{s: s} + return rs +} + +type NotificationsService struct { + s *Service +} + +func NewObjectAccessControlsService(s *Service) *ObjectAccessControlsService { + rs := &ObjectAccessControlsService{s: s} + return rs +} + +type ObjectAccessControlsService struct { + s *Service +} + +func NewObjectsService(s *Service) *ObjectsService { + rs := &ObjectsService{s: s} + return rs +} + +type ObjectsService struct { + s *Service +} + +func NewProjectsService(s *Service) *ProjectsService { + rs := &ProjectsService{s: s} + rs.ServiceAccount = NewProjectsServiceAccountService(s) + return rs +} + +type ProjectsService struct { + s *Service + + ServiceAccount *ProjectsServiceAccountService +} + +func NewProjectsServiceAccountService(s *Service) *ProjectsServiceAccountService { + rs := &ProjectsServiceAccountService{s: s} + return rs +} + +type ProjectsServiceAccountService struct { + s *Service +} + +// Bucket: A bucket. +type Bucket struct { + // Acl: Access controls on the bucket. + Acl []*BucketAccessControl `json:"acl,omitempty"` + + // Billing: The bucket's billing configuration. + Billing *BucketBilling `json:"billing,omitempty"` + + // Cors: The bucket's Cross-Origin Resource Sharing (CORS) + // configuration. + Cors []*BucketCors `json:"cors,omitempty"` + + // DefaultEventBasedHold: Defines the default value for Event-Based hold + // on newly created objects in this bucket. Event-Based hold is a way to + // retain objects indefinitely until an event occurs, signified by the + // hold's release. After being released, such objects will be subject to + // bucket-level retention (if any). One sample use case of this flag is + // for banks to hold loan documents for at least 3 years after loan is + // paid in full. Here bucket-level retention is 3 years and the event is + // loan being paid in full. In this example these objects will be held + // intact for any number of years until the event has occurred (hold is + // released) and then 3 more years after that. Objects under Event-Based + // hold cannot be deleted, overwritten or archived until the hold is + // removed. + DefaultEventBasedHold bool `json:"defaultEventBasedHold,omitempty"` + + // DefaultObjectAcl: Default access controls to apply to new objects + // when no ACL is provided. + DefaultObjectAcl []*ObjectAccessControl `json:"defaultObjectAcl,omitempty"` + + // Encryption: Encryption configuration used by default for newly + // inserted objects, when no encryption config is specified. + Encryption *BucketEncryption `json:"encryption,omitempty"` + + // Etag: HTTP 1.1 Entity tag for the bucket. + Etag string `json:"etag,omitempty"` + + // Id: The ID of the bucket. For buckets, the id and name properties are + // the same. + Id string `json:"id,omitempty"` + + // Kind: The kind of item this is. For buckets, this is always + // storage#bucket. + Kind string `json:"kind,omitempty"` + + // Labels: User-provided labels, in key/value pairs. + Labels map[string]string `json:"labels,omitempty"` + + // Lifecycle: The bucket's lifecycle configuration. See lifecycle + // management for more information. + Lifecycle *BucketLifecycle `json:"lifecycle,omitempty"` + + // Location: The location of the bucket. Object data for objects in the + // bucket resides in physical storage within this region. Defaults to + // US. See the developer's guide for the authoritative list. + Location string `json:"location,omitempty"` + + // Logging: The bucket's logging configuration, which defines the + // destination bucket and optional name prefix for the current bucket's + // logs. + Logging *BucketLogging `json:"logging,omitempty"` + + // Metageneration: The metadata generation of this bucket. + Metageneration int64 `json:"metageneration,omitempty,string"` + + // Name: The name of the bucket. + Name string `json:"name,omitempty"` + + // Owner: The owner of the bucket. This is always the project team's + // owner group. + Owner *BucketOwner `json:"owner,omitempty"` + + // ProjectNumber: The project number of the project the bucket belongs + // to. + ProjectNumber uint64 `json:"projectNumber,omitempty,string"` + + // RetentionPolicy: Defines the retention policy for a bucket. The + // Retention policy enforces a minimum retention time for all objects + // contained in the bucket, based on their creation time. Any attempt to + // overwrite or delete objects younger than the retention period will + // result in a PERMISSION_DENIED error. An unlocked retention policy can + // be modified or removed from the bucket via the UpdateBucketMetadata + // RPC. A locked retention policy cannot be removed or shortened in + // duration for the lifetime of the bucket. Attempting to remove or + // decrease period of a locked retention policy will result in a + // PERMISSION_DENIED error. + RetentionPolicy *BucketRetentionPolicy `json:"retentionPolicy,omitempty"` + + // SelfLink: The URI of this bucket. + SelfLink string `json:"selfLink,omitempty"` + + // StorageClass: The bucket's default storage class, used whenever no + // storageClass is specified for a newly-created object. This defines + // how objects in the bucket are stored and determines the SLA and the + // cost of storage. Values include MULTI_REGIONAL, REGIONAL, STANDARD, + // NEARLINE, COLDLINE, and DURABLE_REDUCED_AVAILABILITY. If this value + // is not specified when the bucket is created, it will default to + // STANDARD. For more information, see storage classes. + StorageClass string `json:"storageClass,omitempty"` + + // TimeCreated: The creation time of the bucket in RFC 3339 format. + TimeCreated string `json:"timeCreated,omitempty"` + + // Updated: The modification time of the bucket in RFC 3339 format. + Updated string `json:"updated,omitempty"` + + // Versioning: The bucket's versioning configuration. + Versioning *BucketVersioning `json:"versioning,omitempty"` + + // Website: The bucket's website configuration, controlling how the + // service behaves when accessing bucket contents as a web site. See the + // Static Website Examples for more information. + Website *BucketWebsite `json:"website,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Acl") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Acl") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *Bucket) MarshalJSON() ([]byte, error) { + type NoMethod Bucket + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketBilling: The bucket's billing configuration. +type BucketBilling struct { + // RequesterPays: When set to true, Requester Pays is enabled for this + // bucket. + RequesterPays bool `json:"requesterPays,omitempty"` + + // ForceSendFields is a list of field names (e.g. "RequesterPays") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "RequesterPays") to include + // in API requests with the JSON null value. By default, fields with + // empty values are omitted from API requests. However, any field with + // an empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *BucketBilling) MarshalJSON() ([]byte, error) { + type NoMethod BucketBilling + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +type BucketCors struct { + // MaxAgeSeconds: The value, in seconds, to return in the + // Access-Control-Max-Age header used in preflight responses. + MaxAgeSeconds int64 `json:"maxAgeSeconds,omitempty"` + + // Method: The list of HTTP methods on which to include CORS response + // headers, (GET, OPTIONS, POST, etc) Note: "*" is permitted in the list + // of methods, and means "any method". + Method []string `json:"method,omitempty"` + + // Origin: The list of Origins eligible to receive CORS response + // headers. Note: "*" is permitted in the list of origins, and means + // "any Origin". + Origin []string `json:"origin,omitempty"` + + // ResponseHeader: The list of HTTP headers other than the simple + // response headers to give permission for the user-agent to share + // across domains. + ResponseHeader []string `json:"responseHeader,omitempty"` + + // ForceSendFields is a list of field names (e.g. "MaxAgeSeconds") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "MaxAgeSeconds") to include + // in API requests with the JSON null value. By default, fields with + // empty values are omitted from API requests. However, any field with + // an empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *BucketCors) MarshalJSON() ([]byte, error) { + type NoMethod BucketCors + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketEncryption: Encryption configuration used by default for newly +// inserted objects, when no encryption config is specified. +type BucketEncryption struct { + // DefaultKmsKeyName: A Cloud KMS key that will be used to encrypt + // objects inserted into this bucket, if no encryption method is + // specified. Limited availability; usable only by enabled projects. + DefaultKmsKeyName string `json:"defaultKmsKeyName,omitempty"` + + // ForceSendFields is a list of field names (e.g. "DefaultKmsKeyName") + // to unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "DefaultKmsKeyName") to + // include in API requests with the JSON null value. By default, fields + // with empty values are omitted from API requests. However, any field + // with an empty value appearing in NullFields will be sent to the + // server as null. It is an error if a field in this list has a + // non-empty value. This may be used to include null fields in Patch + // requests. + NullFields []string `json:"-"` +} + +func (s *BucketEncryption) MarshalJSON() ([]byte, error) { + type NoMethod BucketEncryption + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketLifecycle: The bucket's lifecycle configuration. See lifecycle +// management for more information. +type BucketLifecycle struct { + // Rule: A lifecycle management rule, which is made of an action to take + // and the condition(s) under which the action will be taken. + Rule []*BucketLifecycleRule `json:"rule,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Rule") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Rule") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *BucketLifecycle) MarshalJSON() ([]byte, error) { + type NoMethod BucketLifecycle + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +type BucketLifecycleRule struct { + // Action: The action to take. + Action *BucketLifecycleRuleAction `json:"action,omitempty"` + + // Condition: The condition(s) under which the action will be taken. + Condition *BucketLifecycleRuleCondition `json:"condition,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Action") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Action") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *BucketLifecycleRule) MarshalJSON() ([]byte, error) { + type NoMethod BucketLifecycleRule + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketLifecycleRuleAction: The action to take. +type BucketLifecycleRuleAction struct { + // StorageClass: Target storage class. Required iff the type of the + // action is SetStorageClass. + StorageClass string `json:"storageClass,omitempty"` + + // Type: Type of the action. Currently, only Delete and SetStorageClass + // are supported. + Type string `json:"type,omitempty"` + + // ForceSendFields is a list of field names (e.g. "StorageClass") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "StorageClass") to include + // in API requests with the JSON null value. By default, fields with + // empty values are omitted from API requests. However, any field with + // an empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *BucketLifecycleRuleAction) MarshalJSON() ([]byte, error) { + type NoMethod BucketLifecycleRuleAction + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketLifecycleRuleCondition: The condition(s) under which the action +// will be taken. +type BucketLifecycleRuleCondition struct { + // Age: Age of an object (in days). This condition is satisfied when an + // object reaches the specified age. + Age int64 `json:"age,omitempty"` + + // CreatedBefore: A date in RFC 3339 format with only the date part (for + // instance, "2013-01-15"). This condition is satisfied when an object + // is created before midnight of the specified date in UTC. + CreatedBefore string `json:"createdBefore,omitempty"` + + // IsLive: Relevant only for versioned objects. If the value is true, + // this condition matches live objects; if the value is false, it + // matches archived objects. + IsLive *bool `json:"isLive,omitempty"` + + // MatchesStorageClass: Objects having any of the storage classes + // specified by this condition will be matched. Values include + // MULTI_REGIONAL, REGIONAL, NEARLINE, COLDLINE, STANDARD, and + // DURABLE_REDUCED_AVAILABILITY. + MatchesStorageClass []string `json:"matchesStorageClass,omitempty"` + + // NumNewerVersions: Relevant only for versioned objects. If the value + // is N, this condition is satisfied when there are at least N versions + // (including the live version) newer than this version of the object. + NumNewerVersions int64 `json:"numNewerVersions,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Age") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Age") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *BucketLifecycleRuleCondition) MarshalJSON() ([]byte, error) { + type NoMethod BucketLifecycleRuleCondition + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketLogging: The bucket's logging configuration, which defines the +// destination bucket and optional name prefix for the current bucket's +// logs. +type BucketLogging struct { + // LogBucket: The destination bucket where the current bucket's logs + // should be placed. + LogBucket string `json:"logBucket,omitempty"` + + // LogObjectPrefix: A prefix for log object names. + LogObjectPrefix string `json:"logObjectPrefix,omitempty"` + + // ForceSendFields is a list of field names (e.g. "LogBucket") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "LogBucket") to include in + // API requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *BucketLogging) MarshalJSON() ([]byte, error) { + type NoMethod BucketLogging + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketOwner: The owner of the bucket. This is always the project +// team's owner group. +type BucketOwner struct { + // Entity: The entity, in the form project-owner-projectId. + Entity string `json:"entity,omitempty"` + + // EntityId: The ID for the entity. + EntityId string `json:"entityId,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Entity") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Entity") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *BucketOwner) MarshalJSON() ([]byte, error) { + type NoMethod BucketOwner + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketRetentionPolicy: Defines the retention policy for a bucket. The +// Retention policy enforces a minimum retention time for all objects +// contained in the bucket, based on their creation time. Any attempt to +// overwrite or delete objects younger than the retention period will +// result in a PERMISSION_DENIED error. An unlocked retention policy can +// be modified or removed from the bucket via the UpdateBucketMetadata +// RPC. A locked retention policy cannot be removed or shortened in +// duration for the lifetime of the bucket. Attempting to remove or +// decrease period of a locked retention policy will result in a +// PERMISSION_DENIED error. +type BucketRetentionPolicy struct { + // EffectiveTime: The time from which policy was enforced and effective. + // RFC 3339 format. + EffectiveTime string `json:"effectiveTime,omitempty"` + + // IsLocked: Once locked, an object retention policy cannot be modified. + IsLocked bool `json:"isLocked,omitempty"` + + // RetentionPeriod: Specifies the duration that objects need to be + // retained. Retention duration must be greater than zero and less than + // 100 years. Note that enforcement of retention periods less than a day + // is not guaranteed. Such periods should only be used for testing + // purposes. + RetentionPeriod int64 `json:"retentionPeriod,omitempty,string"` + + // ForceSendFields is a list of field names (e.g. "EffectiveTime") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "EffectiveTime") to include + // in API requests with the JSON null value. By default, fields with + // empty values are omitted from API requests. However, any field with + // an empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *BucketRetentionPolicy) MarshalJSON() ([]byte, error) { + type NoMethod BucketRetentionPolicy + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketVersioning: The bucket's versioning configuration. +type BucketVersioning struct { + // Enabled: While set to true, versioning is fully enabled for this + // bucket. + Enabled bool `json:"enabled,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Enabled") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Enabled") to include in + // API requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *BucketVersioning) MarshalJSON() ([]byte, error) { + type NoMethod BucketVersioning + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketWebsite: The bucket's website configuration, controlling how +// the service behaves when accessing bucket contents as a web site. See +// the Static Website Examples for more information. +type BucketWebsite struct { + // MainPageSuffix: If the requested object path is missing, the service + // will ensure the path has a trailing '/', append this suffix, and + // attempt to retrieve the resulting object. This allows the creation of + // index.html objects to represent directory pages. + MainPageSuffix string `json:"mainPageSuffix,omitempty"` + + // NotFoundPage: If the requested object path is missing, and any + // mainPageSuffix object is missing, if applicable, the service will + // return the named object from this bucket as the content for a 404 Not + // Found result. + NotFoundPage string `json:"notFoundPage,omitempty"` + + // ForceSendFields is a list of field names (e.g. "MainPageSuffix") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "MainPageSuffix") to + // include in API requests with the JSON null value. By default, fields + // with empty values are omitted from API requests. However, any field + // with an empty value appearing in NullFields will be sent to the + // server as null. It is an error if a field in this list has a + // non-empty value. This may be used to include null fields in Patch + // requests. + NullFields []string `json:"-"` +} + +func (s *BucketWebsite) MarshalJSON() ([]byte, error) { + type NoMethod BucketWebsite + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketAccessControl: An access-control entry. +type BucketAccessControl struct { + // Bucket: The name of the bucket. + Bucket string `json:"bucket,omitempty"` + + // Domain: The domain associated with the entity, if any. + Domain string `json:"domain,omitempty"` + + // Email: The email address associated with the entity, if any. + Email string `json:"email,omitempty"` + + // Entity: The entity holding the permission, in one of the following + // forms: + // - user-userId + // - user-email + // - group-groupId + // - group-email + // - domain-domain + // - project-team-projectId + // - allUsers + // - allAuthenticatedUsers Examples: + // - The user liz@example.com would be user-liz@example.com. + // - The group example@googlegroups.com would be + // group-example@googlegroups.com. + // - To refer to all members of the Google Apps for Business domain + // example.com, the entity would be domain-example.com. + Entity string `json:"entity,omitempty"` + + // EntityId: The ID for the entity, if any. + EntityId string `json:"entityId,omitempty"` + + // Etag: HTTP 1.1 Entity tag for the access-control entry. + Etag string `json:"etag,omitempty"` + + // Id: The ID of the access-control entry. + Id string `json:"id,omitempty"` + + // Kind: The kind of item this is. For bucket access control entries, + // this is always storage#bucketAccessControl. + Kind string `json:"kind,omitempty"` + + // ProjectTeam: The project team associated with the entity, if any. + ProjectTeam *BucketAccessControlProjectTeam `json:"projectTeam,omitempty"` + + // Role: The access permission for the entity. + Role string `json:"role,omitempty"` + + // SelfLink: The link to this access-control entry. + SelfLink string `json:"selfLink,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Bucket") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Bucket") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *BucketAccessControl) MarshalJSON() ([]byte, error) { + type NoMethod BucketAccessControl + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketAccessControlProjectTeam: The project team associated with the +// entity, if any. +type BucketAccessControlProjectTeam struct { + // ProjectNumber: The project number. + ProjectNumber string `json:"projectNumber,omitempty"` + + // Team: The team. + Team string `json:"team,omitempty"` + + // ForceSendFields is a list of field names (e.g. "ProjectNumber") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "ProjectNumber") to include + // in API requests with the JSON null value. By default, fields with + // empty values are omitted from API requests. However, any field with + // an empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *BucketAccessControlProjectTeam) MarshalJSON() ([]byte, error) { + type NoMethod BucketAccessControlProjectTeam + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketAccessControls: An access-control list. +type BucketAccessControls struct { + // Items: The list of items. + Items []*BucketAccessControl `json:"items,omitempty"` + + // Kind: The kind of item this is. For lists of bucket access control + // entries, this is always storage#bucketAccessControls. + Kind string `json:"kind,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Items") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Items") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *BucketAccessControls) MarshalJSON() ([]byte, error) { + type NoMethod BucketAccessControls + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// Buckets: A list of buckets. +type Buckets struct { + // Items: The list of items. + Items []*Bucket `json:"items,omitempty"` + + // Kind: The kind of item this is. For lists of buckets, this is always + // storage#buckets. + Kind string `json:"kind,omitempty"` + + // NextPageToken: The continuation token, used to page through large + // result sets. Provide this value in a subsequent request to return the + // next page of results. + NextPageToken string `json:"nextPageToken,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Items") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Items") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *Buckets) MarshalJSON() ([]byte, error) { + type NoMethod Buckets + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// Channel: An notification channel used to watch for resource changes. +type Channel struct { + // Address: The address where notifications are delivered for this + // channel. + Address string `json:"address,omitempty"` + + // Expiration: Date and time of notification channel expiration, + // expressed as a Unix timestamp, in milliseconds. Optional. + Expiration int64 `json:"expiration,omitempty,string"` + + // Id: A UUID or similar unique string that identifies this channel. + Id string `json:"id,omitempty"` + + // Kind: Identifies this as a notification channel used to watch for + // changes to a resource. Value: the fixed string "api#channel". + Kind string `json:"kind,omitempty"` + + // Params: Additional parameters controlling delivery channel behavior. + // Optional. + Params map[string]string `json:"params,omitempty"` + + // Payload: A Boolean value to indicate whether payload is wanted. + // Optional. + Payload bool `json:"payload,omitempty"` + + // ResourceId: An opaque ID that identifies the resource being watched + // on this channel. Stable across different API versions. + ResourceId string `json:"resourceId,omitempty"` + + // ResourceUri: A version-specific identifier for the watched resource. + ResourceUri string `json:"resourceUri,omitempty"` + + // Token: An arbitrary string delivered to the target address with each + // notification delivered over this channel. Optional. + Token string `json:"token,omitempty"` + + // Type: The type of delivery mechanism used for this channel. + Type string `json:"type,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Address") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Address") to include in + // API requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *Channel) MarshalJSON() ([]byte, error) { + type NoMethod Channel + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// ComposeRequest: A Compose request. +type ComposeRequest struct { + // Destination: Properties of the resulting object. + Destination *Object `json:"destination,omitempty"` + + // Kind: The kind of item this is. + Kind string `json:"kind,omitempty"` + + // SourceObjects: The list of source objects that will be concatenated + // into a single object. + SourceObjects []*ComposeRequestSourceObjects `json:"sourceObjects,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Destination") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Destination") to include + // in API requests with the JSON null value. By default, fields with + // empty values are omitted from API requests. However, any field with + // an empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *ComposeRequest) MarshalJSON() ([]byte, error) { + type NoMethod ComposeRequest + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +type ComposeRequestSourceObjects struct { + // Generation: The generation of this object to use as the source. + Generation int64 `json:"generation,omitempty,string"` + + // Name: The source object's name. The source object's bucket is + // implicitly the destination bucket. + Name string `json:"name,omitempty"` + + // ObjectPreconditions: Conditions that must be met for this operation + // to execute. + ObjectPreconditions *ComposeRequestSourceObjectsObjectPreconditions `json:"objectPreconditions,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Generation") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Generation") to include in + // API requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *ComposeRequestSourceObjects) MarshalJSON() ([]byte, error) { + type NoMethod ComposeRequestSourceObjects + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// ComposeRequestSourceObjectsObjectPreconditions: Conditions that must +// be met for this operation to execute. +type ComposeRequestSourceObjectsObjectPreconditions struct { + // IfGenerationMatch: Only perform the composition if the generation of + // the source object that would be used matches this value. If this + // value and a generation are both specified, they must be the same + // value or the call will fail. + IfGenerationMatch int64 `json:"ifGenerationMatch,omitempty,string"` + + // ForceSendFields is a list of field names (e.g. "IfGenerationMatch") + // to unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "IfGenerationMatch") to + // include in API requests with the JSON null value. By default, fields + // with empty values are omitted from API requests. However, any field + // with an empty value appearing in NullFields will be sent to the + // server as null. It is an error if a field in this list has a + // non-empty value. This may be used to include null fields in Patch + // requests. + NullFields []string `json:"-"` +} + +func (s *ComposeRequestSourceObjectsObjectPreconditions) MarshalJSON() ([]byte, error) { + type NoMethod ComposeRequestSourceObjectsObjectPreconditions + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// Notification: A subscription to receive Google PubSub notifications. +type Notification struct { + // CustomAttributes: An optional list of additional attributes to attach + // to each Cloud PubSub message published for this notification + // subscription. + CustomAttributes map[string]string `json:"custom_attributes,omitempty"` + + // Etag: HTTP 1.1 Entity tag for this subscription notification. + Etag string `json:"etag,omitempty"` + + // EventTypes: If present, only send notifications about listed event + // types. If empty, sent notifications for all event types. + EventTypes []string `json:"event_types,omitempty"` + + // Id: The ID of the notification. + Id string `json:"id,omitempty"` + + // Kind: The kind of item this is. For notifications, this is always + // storage#notification. + Kind string `json:"kind,omitempty"` + + // ObjectNamePrefix: If present, only apply this notification + // configuration to object names that begin with this prefix. + ObjectNamePrefix string `json:"object_name_prefix,omitempty"` + + // PayloadFormat: The desired content of the Payload. + PayloadFormat string `json:"payload_format,omitempty"` + + // SelfLink: The canonical URL of this notification. + SelfLink string `json:"selfLink,omitempty"` + + // Topic: The Cloud PubSub topic to which this subscription publishes. + // Formatted as: + // '//pubsub.googleapis.com/projects/{project-identifier}/topics/{my-topi + // c}' + Topic string `json:"topic,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "CustomAttributes") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "CustomAttributes") to + // include in API requests with the JSON null value. By default, fields + // with empty values are omitted from API requests. However, any field + // with an empty value appearing in NullFields will be sent to the + // server as null. It is an error if a field in this list has a + // non-empty value. This may be used to include null fields in Patch + // requests. + NullFields []string `json:"-"` +} + +func (s *Notification) MarshalJSON() ([]byte, error) { + type NoMethod Notification + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// Notifications: A list of notification subscriptions. +type Notifications struct { + // Items: The list of items. + Items []*Notification `json:"items,omitempty"` + + // Kind: The kind of item this is. For lists of notifications, this is + // always storage#notifications. + Kind string `json:"kind,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Items") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Items") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *Notifications) MarshalJSON() ([]byte, error) { + type NoMethod Notifications + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// Object: An object. +type Object struct { + // Acl: Access controls on the object. + Acl []*ObjectAccessControl `json:"acl,omitempty"` + + // Bucket: The name of the bucket containing this object. + Bucket string `json:"bucket,omitempty"` + + // CacheControl: Cache-Control directive for the object data. If + // omitted, and the object is accessible to all anonymous users, the + // default will be public, max-age=3600. + CacheControl string `json:"cacheControl,omitempty"` + + // ComponentCount: Number of underlying components that make up this + // object. Components are accumulated by compose operations. + ComponentCount int64 `json:"componentCount,omitempty"` + + // ContentDisposition: Content-Disposition of the object data. + ContentDisposition string `json:"contentDisposition,omitempty"` + + // ContentEncoding: Content-Encoding of the object data. + ContentEncoding string `json:"contentEncoding,omitempty"` + + // ContentLanguage: Content-Language of the object data. + ContentLanguage string `json:"contentLanguage,omitempty"` + + // ContentType: Content-Type of the object data. If an object is stored + // without a Content-Type, it is served as application/octet-stream. + ContentType string `json:"contentType,omitempty"` + + // Crc32c: CRC32c checksum, as described in RFC 4960, Appendix B; + // encoded using base64 in big-endian byte order. For more information + // about using the CRC32c checksum, see Hashes and ETags: Best + // Practices. + Crc32c string `json:"crc32c,omitempty"` + + // CustomerEncryption: Metadata of customer-supplied encryption key, if + // the object is encrypted by such a key. + CustomerEncryption *ObjectCustomerEncryption `json:"customerEncryption,omitempty"` + + // Etag: HTTP 1.1 Entity tag for the object. + Etag string `json:"etag,omitempty"` + + // EventBasedHold: Defines the Event-Based hold for an object. + // Event-Based hold is a way to retain objects indefinitely until an + // event occurs, signified by the hold's release. After being released, + // such objects will be subject to bucket-level retention (if any). One + // sample use case of this flag is for banks to hold loan documents for + // at least 3 years after loan is paid in full. Here bucket-level + // retention is 3 years and the event is loan being paid in full. In + // this example these objects will be held intact for any number of + // years until the event has occurred (hold is released) and then 3 more + // years after that. + EventBasedHold bool `json:"eventBasedHold,omitempty"` + + // Generation: The content generation of this object. Used for object + // versioning. + Generation int64 `json:"generation,omitempty,string"` + + // Id: The ID of the object, including the bucket name, object name, and + // generation number. + Id string `json:"id,omitempty"` + + // Kind: The kind of item this is. For objects, this is always + // storage#object. + Kind string `json:"kind,omitempty"` + + // KmsKeyName: Cloud KMS Key used to encrypt this object, if the object + // is encrypted by such a key. Limited availability; usable only by + // enabled projects. + KmsKeyName string `json:"kmsKeyName,omitempty"` + + // Md5Hash: MD5 hash of the data; encoded using base64. For more + // information about using the MD5 hash, see Hashes and ETags: Best + // Practices. + Md5Hash string `json:"md5Hash,omitempty"` + + // MediaLink: Media download link. + MediaLink string `json:"mediaLink,omitempty"` + + // Metadata: User-provided metadata, in key/value pairs. + Metadata map[string]string `json:"metadata,omitempty"` + + // Metageneration: The version of the metadata for this object at this + // generation. Used for preconditions and for detecting changes in + // metadata. A metageneration number is only meaningful in the context + // of a particular generation of a particular object. + Metageneration int64 `json:"metageneration,omitempty,string"` + + // Name: The name of the object. Required if not specified by URL + // parameter. + Name string `json:"name,omitempty"` + + // Owner: The owner of the object. This will always be the uploader of + // the object. + Owner *ObjectOwner `json:"owner,omitempty"` + + // RetentionExpirationTime: Specifies the earliest time that the + // object's retention period expires. This value is server-determined + // and is in RFC 3339 format. Note 1: This field is not provided for + // objects with an active Event-Based hold, since retention expiration + // is unknown until the hold is removed. Note 2: This value can be + // provided even when TemporaryHold is set (so that the user can reason + // about policy without having to first unset the TemporaryHold). + RetentionExpirationTime string `json:"retentionExpirationTime,omitempty"` + + // SelfLink: The link to this object. + SelfLink string `json:"selfLink,omitempty"` + + // Size: Content-Length of the data in bytes. + Size uint64 `json:"size,omitempty,string"` + + // StorageClass: Storage class of the object. + StorageClass string `json:"storageClass,omitempty"` + + // TemporaryHold: Defines the temporary hold for an object. This flag is + // used to enforce a temporary hold on an object. While it is set to + // true, the object is protected against deletion and overwrites. A + // common use case of this flag is regulatory investigations where + // objects need to be retained while the investigation is ongoing. + TemporaryHold bool `json:"temporaryHold,omitempty"` + + // TimeCreated: The creation time of the object in RFC 3339 format. + TimeCreated string `json:"timeCreated,omitempty"` + + // TimeDeleted: The deletion time of the object in RFC 3339 format. Will + // be returned if and only if this version of the object has been + // deleted. + TimeDeleted string `json:"timeDeleted,omitempty"` + + // TimeStorageClassUpdated: The time at which the object's storage class + // was last changed. When the object is initially created, it will be + // set to timeCreated. + TimeStorageClassUpdated string `json:"timeStorageClassUpdated,omitempty"` + + // Updated: The modification time of the object metadata in RFC 3339 + // format. + Updated string `json:"updated,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Acl") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Acl") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *Object) MarshalJSON() ([]byte, error) { + type NoMethod Object + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// ObjectCustomerEncryption: Metadata of customer-supplied encryption +// key, if the object is encrypted by such a key. +type ObjectCustomerEncryption struct { + // EncryptionAlgorithm: The encryption algorithm. + EncryptionAlgorithm string `json:"encryptionAlgorithm,omitempty"` + + // KeySha256: SHA256 hash value of the encryption key. + KeySha256 string `json:"keySha256,omitempty"` + + // ForceSendFields is a list of field names (e.g. "EncryptionAlgorithm") + // to unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "EncryptionAlgorithm") to + // include in API requests with the JSON null value. By default, fields + // with empty values are omitted from API requests. However, any field + // with an empty value appearing in NullFields will be sent to the + // server as null. It is an error if a field in this list has a + // non-empty value. This may be used to include null fields in Patch + // requests. + NullFields []string `json:"-"` +} + +func (s *ObjectCustomerEncryption) MarshalJSON() ([]byte, error) { + type NoMethod ObjectCustomerEncryption + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// ObjectOwner: The owner of the object. This will always be the +// uploader of the object. +type ObjectOwner struct { + // Entity: The entity, in the form user-userId. + Entity string `json:"entity,omitempty"` + + // EntityId: The ID for the entity. + EntityId string `json:"entityId,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Entity") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Entity") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *ObjectOwner) MarshalJSON() ([]byte, error) { + type NoMethod ObjectOwner + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// ObjectAccessControl: An access-control entry. +type ObjectAccessControl struct { + // Bucket: The name of the bucket. + Bucket string `json:"bucket,omitempty"` + + // Domain: The domain associated with the entity, if any. + Domain string `json:"domain,omitempty"` + + // Email: The email address associated with the entity, if any. + Email string `json:"email,omitempty"` + + // Entity: The entity holding the permission, in one of the following + // forms: + // - user-userId + // - user-email + // - group-groupId + // - group-email + // - domain-domain + // - project-team-projectId + // - allUsers + // - allAuthenticatedUsers Examples: + // - The user liz@example.com would be user-liz@example.com. + // - The group example@googlegroups.com would be + // group-example@googlegroups.com. + // - To refer to all members of the Google Apps for Business domain + // example.com, the entity would be domain-example.com. + Entity string `json:"entity,omitempty"` + + // EntityId: The ID for the entity, if any. + EntityId string `json:"entityId,omitempty"` + + // Etag: HTTP 1.1 Entity tag for the access-control entry. + Etag string `json:"etag,omitempty"` + + // Generation: The content generation of the object, if applied to an + // object. + Generation int64 `json:"generation,omitempty,string"` + + // Id: The ID of the access-control entry. + Id string `json:"id,omitempty"` + + // Kind: The kind of item this is. For object access control entries, + // this is always storage#objectAccessControl. + Kind string `json:"kind,omitempty"` + + // Object: The name of the object, if applied to an object. + Object string `json:"object,omitempty"` + + // ProjectTeam: The project team associated with the entity, if any. + ProjectTeam *ObjectAccessControlProjectTeam `json:"projectTeam,omitempty"` + + // Role: The access permission for the entity. + Role string `json:"role,omitempty"` + + // SelfLink: The link to this access-control entry. + SelfLink string `json:"selfLink,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Bucket") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Bucket") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *ObjectAccessControl) MarshalJSON() ([]byte, error) { + type NoMethod ObjectAccessControl + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// ObjectAccessControlProjectTeam: The project team associated with the +// entity, if any. +type ObjectAccessControlProjectTeam struct { + // ProjectNumber: The project number. + ProjectNumber string `json:"projectNumber,omitempty"` + + // Team: The team. + Team string `json:"team,omitempty"` + + // ForceSendFields is a list of field names (e.g. "ProjectNumber") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "ProjectNumber") to include + // in API requests with the JSON null value. By default, fields with + // empty values are omitted from API requests. However, any field with + // an empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *ObjectAccessControlProjectTeam) MarshalJSON() ([]byte, error) { + type NoMethod ObjectAccessControlProjectTeam + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// ObjectAccessControls: An access-control list. +type ObjectAccessControls struct { + // Items: The list of items. + Items []*ObjectAccessControl `json:"items,omitempty"` + + // Kind: The kind of item this is. For lists of object access control + // entries, this is always storage#objectAccessControls. + Kind string `json:"kind,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Items") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Items") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *ObjectAccessControls) MarshalJSON() ([]byte, error) { + type NoMethod ObjectAccessControls + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// Objects: A list of objects. +type Objects struct { + // Items: The list of items. + Items []*Object `json:"items,omitempty"` + + // Kind: The kind of item this is. For lists of objects, this is always + // storage#objects. + Kind string `json:"kind,omitempty"` + + // NextPageToken: The continuation token, used to page through large + // result sets. Provide this value in a subsequent request to return the + // next page of results. + NextPageToken string `json:"nextPageToken,omitempty"` + + // Prefixes: The list of prefixes of objects matching-but-not-listed up + // to and including the requested delimiter. + Prefixes []string `json:"prefixes,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Items") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Items") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *Objects) MarshalJSON() ([]byte, error) { + type NoMethod Objects + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// Policy: A bucket/object IAM policy. +type Policy struct { + // Bindings: An association between a role, which comes with a set of + // permissions, and members who may assume that role. + Bindings []*PolicyBindings `json:"bindings,omitempty"` + + // Etag: HTTP 1.1 Entity tag for the policy. + Etag string `json:"etag,omitempty"` + + // Kind: The kind of item this is. For policies, this is always + // storage#policy. This field is ignored on input. + Kind string `json:"kind,omitempty"` + + // ResourceId: The ID of the resource to which this policy belongs. Will + // be of the form projects/_/buckets/bucket for buckets, and + // projects/_/buckets/bucket/objects/object for objects. A specific + // generation may be specified by appending #generationNumber to the end + // of the object name, e.g. + // projects/_/buckets/my-bucket/objects/data.txt#17. The current + // generation can be denoted with #0. This field is ignored on input. + ResourceId string `json:"resourceId,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Bindings") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Bindings") to include in + // API requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *Policy) MarshalJSON() ([]byte, error) { + type NoMethod Policy + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +type PolicyBindings struct { + Condition interface{} `json:"condition,omitempty"` + + // Members: A collection of identifiers for members who may assume the + // provided role. Recognized identifiers are as follows: + // - allUsers — A special identifier that represents anyone on the + // internet; with or without a Google account. + // - allAuthenticatedUsers — A special identifier that represents + // anyone who is authenticated with a Google account or a service + // account. + // - user:emailid — An email address that represents a specific + // account. For example, user:alice@gmail.com or user:joe@example.com. + // + // - serviceAccount:emailid — An email address that represents a + // service account. For example, + // serviceAccount:my-other-app@appspot.gserviceaccount.com . + // - group:emailid — An email address that represents a Google group. + // For example, group:admins@example.com. + // - domain:domain — A Google Apps domain name that represents all the + // users of that domain. For example, domain:google.com or + // domain:example.com. + // - projectOwner:projectid — Owners of the given project. For + // example, projectOwner:my-example-project + // - projectEditor:projectid — Editors of the given project. For + // example, projectEditor:my-example-project + // - projectViewer:projectid — Viewers of the given project. For + // example, projectViewer:my-example-project + Members []string `json:"members,omitempty"` + + // Role: The role to which members belong. Two types of roles are + // supported: new IAM roles, which grant permissions that do not map + // directly to those provided by ACLs, and legacy IAM roles, which do + // map directly to ACL permissions. All roles are of the format + // roles/storage.specificRole. + // The new IAM roles are: + // - roles/storage.admin — Full control of Google Cloud Storage + // resources. + // - roles/storage.objectViewer — Read-Only access to Google Cloud + // Storage objects. + // - roles/storage.objectCreator — Access to create objects in Google + // Cloud Storage. + // - roles/storage.objectAdmin — Full control of Google Cloud Storage + // objects. The legacy IAM roles are: + // - roles/storage.legacyObjectReader — Read-only access to objects + // without listing. Equivalent to an ACL entry on an object with the + // READER role. + // - roles/storage.legacyObjectOwner — Read/write access to existing + // objects without listing. Equivalent to an ACL entry on an object with + // the OWNER role. + // - roles/storage.legacyBucketReader — Read access to buckets with + // object listing. Equivalent to an ACL entry on a bucket with the + // READER role. + // - roles/storage.legacyBucketWriter — Read access to buckets with + // object listing/creation/deletion. Equivalent to an ACL entry on a + // bucket with the WRITER role. + // - roles/storage.legacyBucketOwner — Read and write access to + // existing buckets with object listing/creation/deletion. Equivalent to + // an ACL entry on a bucket with the OWNER role. + Role string `json:"role,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Condition") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Condition") to include in + // API requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *PolicyBindings) MarshalJSON() ([]byte, error) { + type NoMethod PolicyBindings + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// RewriteResponse: A rewrite response. +type RewriteResponse struct { + // Done: true if the copy is finished; otherwise, false if the copy is + // in progress. This property is always present in the response. + Done bool `json:"done,omitempty"` + + // Kind: The kind of item this is. + Kind string `json:"kind,omitempty"` + + // ObjectSize: The total size of the object being copied in bytes. This + // property is always present in the response. + ObjectSize int64 `json:"objectSize,omitempty,string"` + + // Resource: A resource containing the metadata for the copied-to + // object. This property is present in the response only when copying + // completes. + Resource *Object `json:"resource,omitempty"` + + // RewriteToken: A token to use in subsequent requests to continue + // copying data. This token is present in the response only when there + // is more data to copy. + RewriteToken string `json:"rewriteToken,omitempty"` + + // TotalBytesRewritten: The total bytes written so far, which can be + // used to provide a waiting user with a progress indicator. This + // property is always present in the response. + TotalBytesRewritten int64 `json:"totalBytesRewritten,omitempty,string"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Done") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Done") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *RewriteResponse) MarshalJSON() ([]byte, error) { + type NoMethod RewriteResponse + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// ServiceAccount: A subscription to receive Google PubSub +// notifications. +type ServiceAccount struct { + // EmailAddress: The ID of the notification. + EmailAddress string `json:"email_address,omitempty"` + + // Kind: The kind of item this is. For notifications, this is always + // storage#notification. + Kind string `json:"kind,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "EmailAddress") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "EmailAddress") to include + // in API requests with the JSON null value. By default, fields with + // empty values are omitted from API requests. However, any field with + // an empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *ServiceAccount) MarshalJSON() ([]byte, error) { + type NoMethod ServiceAccount + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// TestIamPermissionsResponse: A +// storage.(buckets|objects).testIamPermissions response. +type TestIamPermissionsResponse struct { + // Kind: The kind of item this is. + Kind string `json:"kind,omitempty"` + + // Permissions: The permissions held by the caller. Permissions are + // always of the format storage.resource.capability, where resource is + // one of buckets or objects. The supported permissions are as follows: + // + // - storage.buckets.delete — Delete bucket. + // - storage.buckets.get — Read bucket metadata. + // - storage.buckets.getIamPolicy — Read bucket IAM policy. + // - storage.buckets.create — Create bucket. + // - storage.buckets.list — List buckets. + // - storage.buckets.setIamPolicy — Update bucket IAM policy. + // - storage.buckets.update — Update bucket metadata. + // - storage.objects.delete — Delete object. + // - storage.objects.get — Read object data and metadata. + // - storage.objects.getIamPolicy — Read object IAM policy. + // - storage.objects.create — Create object. + // - storage.objects.list — List objects. + // - storage.objects.setIamPolicy — Update object IAM policy. + // - storage.objects.update — Update object metadata. + Permissions []string `json:"permissions,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Kind") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Kind") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *TestIamPermissionsResponse) MarshalJSON() ([]byte, error) { + type NoMethod TestIamPermissionsResponse + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// method id "storage.bucketAccessControls.delete": + +type BucketAccessControlsDeleteCall struct { + s *Service + bucket string + entity string + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Delete: Permanently deletes the ACL entry for the specified entity on +// the specified bucket. +func (r *BucketAccessControlsService) Delete(bucket string, entity string) *BucketAccessControlsDeleteCall { + c := &BucketAccessControlsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.entity = entity + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketAccessControlsDeleteCall) UserProject(userProject string) *BucketAccessControlsDeleteCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketAccessControlsDeleteCall) Fields(s ...googleapi.Field) *BucketAccessControlsDeleteCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketAccessControlsDeleteCall) Context(ctx context.Context) *BucketAccessControlsDeleteCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketAccessControlsDeleteCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketAccessControlsDeleteCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/acl/{entity}") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("DELETE", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "entity": c.entity, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.bucketAccessControls.delete" call. +func (c *BucketAccessControlsDeleteCall) Do(opts ...googleapi.CallOption) error { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if err != nil { + return err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return err + } + return nil + // { + // "description": "Permanently deletes the ACL entry for the specified entity on the specified bucket.", + // "httpMethod": "DELETE", + // "id": "storage.bucketAccessControls.delete", + // "parameterOrder": [ + // "bucket", + // "entity" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "entity": { + // "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/acl/{entity}", + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.bucketAccessControls.get": + +type BucketAccessControlsGetCall struct { + s *Service + bucket string + entity string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// Get: Returns the ACL entry for the specified entity on the specified +// bucket. +func (r *BucketAccessControlsService) Get(bucket string, entity string) *BucketAccessControlsGetCall { + c := &BucketAccessControlsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.entity = entity + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketAccessControlsGetCall) UserProject(userProject string) *BucketAccessControlsGetCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketAccessControlsGetCall) Fields(s ...googleapi.Field) *BucketAccessControlsGetCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *BucketAccessControlsGetCall) IfNoneMatch(entityTag string) *BucketAccessControlsGetCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketAccessControlsGetCall) Context(ctx context.Context) *BucketAccessControlsGetCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketAccessControlsGetCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketAccessControlsGetCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/acl/{entity}") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("GET", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "entity": c.entity, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.bucketAccessControls.get" call. +// Exactly one of *BucketAccessControl or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *BucketAccessControl.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *BucketAccessControlsGetCall) Do(opts ...googleapi.CallOption) (*BucketAccessControl, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &BucketAccessControl{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Returns the ACL entry for the specified entity on the specified bucket.", + // "httpMethod": "GET", + // "id": "storage.bucketAccessControls.get", + // "parameterOrder": [ + // "bucket", + // "entity" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "entity": { + // "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/acl/{entity}", + // "response": { + // "$ref": "BucketAccessControl" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.bucketAccessControls.insert": + +type BucketAccessControlsInsertCall struct { + s *Service + bucket string + bucketaccesscontrol *BucketAccessControl + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Insert: Creates a new ACL entry on the specified bucket. +func (r *BucketAccessControlsService) Insert(bucket string, bucketaccesscontrol *BucketAccessControl) *BucketAccessControlsInsertCall { + c := &BucketAccessControlsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.bucketaccesscontrol = bucketaccesscontrol + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketAccessControlsInsertCall) UserProject(userProject string) *BucketAccessControlsInsertCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketAccessControlsInsertCall) Fields(s ...googleapi.Field) *BucketAccessControlsInsertCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketAccessControlsInsertCall) Context(ctx context.Context) *BucketAccessControlsInsertCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketAccessControlsInsertCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketAccessControlsInsertCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.bucketaccesscontrol) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/acl") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("POST", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.bucketAccessControls.insert" call. +// Exactly one of *BucketAccessControl or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *BucketAccessControl.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *BucketAccessControlsInsertCall) Do(opts ...googleapi.CallOption) (*BucketAccessControl, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &BucketAccessControl{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Creates a new ACL entry on the specified bucket.", + // "httpMethod": "POST", + // "id": "storage.bucketAccessControls.insert", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/acl", + // "request": { + // "$ref": "BucketAccessControl" + // }, + // "response": { + // "$ref": "BucketAccessControl" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.bucketAccessControls.list": + +type BucketAccessControlsListCall struct { + s *Service + bucket string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// List: Retrieves ACL entries on the specified bucket. +func (r *BucketAccessControlsService) List(bucket string) *BucketAccessControlsListCall { + c := &BucketAccessControlsListCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketAccessControlsListCall) UserProject(userProject string) *BucketAccessControlsListCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketAccessControlsListCall) Fields(s ...googleapi.Field) *BucketAccessControlsListCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *BucketAccessControlsListCall) IfNoneMatch(entityTag string) *BucketAccessControlsListCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketAccessControlsListCall) Context(ctx context.Context) *BucketAccessControlsListCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketAccessControlsListCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketAccessControlsListCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/acl") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("GET", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.bucketAccessControls.list" call. +// Exactly one of *BucketAccessControls or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *BucketAccessControls.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *BucketAccessControlsListCall) Do(opts ...googleapi.CallOption) (*BucketAccessControls, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &BucketAccessControls{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Retrieves ACL entries on the specified bucket.", + // "httpMethod": "GET", + // "id": "storage.bucketAccessControls.list", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/acl", + // "response": { + // "$ref": "BucketAccessControls" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.bucketAccessControls.patch": + +type BucketAccessControlsPatchCall struct { + s *Service + bucket string + entity string + bucketaccesscontrol *BucketAccessControl + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Patch: Patches an ACL entry on the specified bucket. +func (r *BucketAccessControlsService) Patch(bucket string, entity string, bucketaccesscontrol *BucketAccessControl) *BucketAccessControlsPatchCall { + c := &BucketAccessControlsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.entity = entity + c.bucketaccesscontrol = bucketaccesscontrol + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketAccessControlsPatchCall) UserProject(userProject string) *BucketAccessControlsPatchCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketAccessControlsPatchCall) Fields(s ...googleapi.Field) *BucketAccessControlsPatchCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketAccessControlsPatchCall) Context(ctx context.Context) *BucketAccessControlsPatchCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketAccessControlsPatchCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketAccessControlsPatchCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.bucketaccesscontrol) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/acl/{entity}") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("PATCH", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "entity": c.entity, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.bucketAccessControls.patch" call. +// Exactly one of *BucketAccessControl or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *BucketAccessControl.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *BucketAccessControlsPatchCall) Do(opts ...googleapi.CallOption) (*BucketAccessControl, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &BucketAccessControl{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Patches an ACL entry on the specified bucket.", + // "httpMethod": "PATCH", + // "id": "storage.bucketAccessControls.patch", + // "parameterOrder": [ + // "bucket", + // "entity" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "entity": { + // "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/acl/{entity}", + // "request": { + // "$ref": "BucketAccessControl" + // }, + // "response": { + // "$ref": "BucketAccessControl" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.bucketAccessControls.update": + +type BucketAccessControlsUpdateCall struct { + s *Service + bucket string + entity string + bucketaccesscontrol *BucketAccessControl + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Update: Updates an ACL entry on the specified bucket. +func (r *BucketAccessControlsService) Update(bucket string, entity string, bucketaccesscontrol *BucketAccessControl) *BucketAccessControlsUpdateCall { + c := &BucketAccessControlsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.entity = entity + c.bucketaccesscontrol = bucketaccesscontrol + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketAccessControlsUpdateCall) UserProject(userProject string) *BucketAccessControlsUpdateCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketAccessControlsUpdateCall) Fields(s ...googleapi.Field) *BucketAccessControlsUpdateCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketAccessControlsUpdateCall) Context(ctx context.Context) *BucketAccessControlsUpdateCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketAccessControlsUpdateCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketAccessControlsUpdateCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.bucketaccesscontrol) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/acl/{entity}") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("PUT", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "entity": c.entity, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.bucketAccessControls.update" call. +// Exactly one of *BucketAccessControl or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *BucketAccessControl.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *BucketAccessControlsUpdateCall) Do(opts ...googleapi.CallOption) (*BucketAccessControl, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &BucketAccessControl{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates an ACL entry on the specified bucket.", + // "httpMethod": "PUT", + // "id": "storage.bucketAccessControls.update", + // "parameterOrder": [ + // "bucket", + // "entity" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "entity": { + // "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/acl/{entity}", + // "request": { + // "$ref": "BucketAccessControl" + // }, + // "response": { + // "$ref": "BucketAccessControl" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.buckets.delete": + +type BucketsDeleteCall struct { + s *Service + bucket string + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Delete: Permanently deletes an empty bucket. +func (r *BucketsService) Delete(bucket string) *BucketsDeleteCall { + c := &BucketsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + return c +} + +// IfMetagenerationMatch sets the optional parameter +// "ifMetagenerationMatch": If set, only deletes the bucket if its +// metageneration matches this value. +func (c *BucketsDeleteCall) IfMetagenerationMatch(ifMetagenerationMatch int64) *BucketsDeleteCall { + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// IfMetagenerationNotMatch sets the optional parameter +// "ifMetagenerationNotMatch": If set, only deletes the bucket if its +// metageneration does not match this value. +func (c *BucketsDeleteCall) IfMetagenerationNotMatch(ifMetagenerationNotMatch int64) *BucketsDeleteCall { + c.urlParams_.Set("ifMetagenerationNotMatch", fmt.Sprint(ifMetagenerationNotMatch)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketsDeleteCall) UserProject(userProject string) *BucketsDeleteCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketsDeleteCall) Fields(s ...googleapi.Field) *BucketsDeleteCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketsDeleteCall) Context(ctx context.Context) *BucketsDeleteCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketsDeleteCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketsDeleteCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("DELETE", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.buckets.delete" call. +func (c *BucketsDeleteCall) Do(opts ...googleapi.CallOption) error { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if err != nil { + return err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return err + } + return nil + // { + // "description": "Permanently deletes an empty bucket.", + // "httpMethod": "DELETE", + // "id": "storage.buckets.delete", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "If set, only deletes the bucket if its metageneration matches this value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationNotMatch": { + // "description": "If set, only deletes the bucket if its metageneration does not match this value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}", + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.buckets.get": + +type BucketsGetCall struct { + s *Service + bucket string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// Get: Returns metadata for the specified bucket. +func (r *BucketsService) Get(bucket string) *BucketsGetCall { + c := &BucketsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + return c +} + +// IfMetagenerationMatch sets the optional parameter +// "ifMetagenerationMatch": Makes the return of the bucket metadata +// conditional on whether the bucket's current metageneration matches +// the given value. +func (c *BucketsGetCall) IfMetagenerationMatch(ifMetagenerationMatch int64) *BucketsGetCall { + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// IfMetagenerationNotMatch sets the optional parameter +// "ifMetagenerationNotMatch": Makes the return of the bucket metadata +// conditional on whether the bucket's current metageneration does not +// match the given value. +func (c *BucketsGetCall) IfMetagenerationNotMatch(ifMetagenerationNotMatch int64) *BucketsGetCall { + c.urlParams_.Set("ifMetagenerationNotMatch", fmt.Sprint(ifMetagenerationNotMatch)) + return c +} + +// Projection sets the optional parameter "projection": Set of +// properties to return. Defaults to noAcl. +// +// Possible values: +// "full" - Include all properties. +// "noAcl" - Omit owner, acl and defaultObjectAcl properties. +func (c *BucketsGetCall) Projection(projection string) *BucketsGetCall { + c.urlParams_.Set("projection", projection) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketsGetCall) UserProject(userProject string) *BucketsGetCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketsGetCall) Fields(s ...googleapi.Field) *BucketsGetCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *BucketsGetCall) IfNoneMatch(entityTag string) *BucketsGetCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketsGetCall) Context(ctx context.Context) *BucketsGetCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketsGetCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketsGetCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("GET", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.buckets.get" call. +// Exactly one of *Bucket or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Bucket.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *BucketsGetCall) Do(opts ...googleapi.CallOption) (*Bucket, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Bucket{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Returns metadata for the specified bucket.", + // "httpMethod": "GET", + // "id": "storage.buckets.get", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationNotMatch": { + // "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "projection": { + // "description": "Set of properties to return. Defaults to noAcl.", + // "enum": [ + // "full", + // "noAcl" + // ], + // "enumDescriptions": [ + // "Include all properties.", + // "Omit owner, acl and defaultObjectAcl properties." + // ], + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}", + // "response": { + // "$ref": "Bucket" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_only", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.buckets.getIamPolicy": + +type BucketsGetIamPolicyCall struct { + s *Service + bucket string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// GetIamPolicy: Returns an IAM policy for the specified bucket. +func (r *BucketsService) GetIamPolicy(bucket string) *BucketsGetIamPolicyCall { + c := &BucketsGetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketsGetIamPolicyCall) UserProject(userProject string) *BucketsGetIamPolicyCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketsGetIamPolicyCall) Fields(s ...googleapi.Field) *BucketsGetIamPolicyCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *BucketsGetIamPolicyCall) IfNoneMatch(entityTag string) *BucketsGetIamPolicyCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketsGetIamPolicyCall) Context(ctx context.Context) *BucketsGetIamPolicyCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketsGetIamPolicyCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketsGetIamPolicyCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/iam") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("GET", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.buckets.getIamPolicy" call. +// Exactly one of *Policy or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Policy.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *BucketsGetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Policy{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Returns an IAM policy for the specified bucket.", + // "httpMethod": "GET", + // "id": "storage.buckets.getIamPolicy", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/iam", + // "response": { + // "$ref": "Policy" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_only", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.buckets.insert": + +type BucketsInsertCall struct { + s *Service + bucket *Bucket + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Insert: Creates a new bucket. +func (r *BucketsService) Insert(projectid string, bucket *Bucket) *BucketsInsertCall { + c := &BucketsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.urlParams_.Set("project", projectid) + c.bucket = bucket + return c +} + +// PredefinedAcl sets the optional parameter "predefinedAcl": Apply a +// predefined set of access controls to this bucket. +// +// Possible values: +// "authenticatedRead" - Project team owners get OWNER access, and +// allAuthenticatedUsers get READER access. +// "private" - Project team owners get OWNER access. +// "projectPrivate" - Project team members get access according to +// their roles. +// "publicRead" - Project team owners get OWNER access, and allUsers +// get READER access. +// "publicReadWrite" - Project team owners get OWNER access, and +// allUsers get WRITER access. +func (c *BucketsInsertCall) PredefinedAcl(predefinedAcl string) *BucketsInsertCall { + c.urlParams_.Set("predefinedAcl", predefinedAcl) + return c +} + +// PredefinedDefaultObjectAcl sets the optional parameter +// "predefinedDefaultObjectAcl": Apply a predefined set of default +// object access controls to this bucket. +// +// Possible values: +// "authenticatedRead" - Object owner gets OWNER access, and +// allAuthenticatedUsers get READER access. +// "bucketOwnerFullControl" - Object owner gets OWNER access, and +// project team owners get OWNER access. +// "bucketOwnerRead" - Object owner gets OWNER access, and project +// team owners get READER access. +// "private" - Object owner gets OWNER access. +// "projectPrivate" - Object owner gets OWNER access, and project team +// members get access according to their roles. +// "publicRead" - Object owner gets OWNER access, and allUsers get +// READER access. +func (c *BucketsInsertCall) PredefinedDefaultObjectAcl(predefinedDefaultObjectAcl string) *BucketsInsertCall { + c.urlParams_.Set("predefinedDefaultObjectAcl", predefinedDefaultObjectAcl) + return c +} + +// Projection sets the optional parameter "projection": Set of +// properties to return. Defaults to noAcl, unless the bucket resource +// specifies acl or defaultObjectAcl properties, when it defaults to +// full. +// +// Possible values: +// "full" - Include all properties. +// "noAcl" - Omit owner, acl and defaultObjectAcl properties. +func (c *BucketsInsertCall) Projection(projection string) *BucketsInsertCall { + c.urlParams_.Set("projection", projection) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. +func (c *BucketsInsertCall) UserProject(userProject string) *BucketsInsertCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketsInsertCall) Fields(s ...googleapi.Field) *BucketsInsertCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketsInsertCall) Context(ctx context.Context) *BucketsInsertCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketsInsertCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketsInsertCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.bucket) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("POST", urls, body) + req.Header = reqHeaders + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.buckets.insert" call. +// Exactly one of *Bucket or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Bucket.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *BucketsInsertCall) Do(opts ...googleapi.CallOption) (*Bucket, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Bucket{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Creates a new bucket.", + // "httpMethod": "POST", + // "id": "storage.buckets.insert", + // "parameterOrder": [ + // "project" + // ], + // "parameters": { + // "predefinedAcl": { + // "description": "Apply a predefined set of access controls to this bucket.", + // "enum": [ + // "authenticatedRead", + // "private", + // "projectPrivate", + // "publicRead", + // "publicReadWrite" + // ], + // "enumDescriptions": [ + // "Project team owners get OWNER access, and allAuthenticatedUsers get READER access.", + // "Project team owners get OWNER access.", + // "Project team members get access according to their roles.", + // "Project team owners get OWNER access, and allUsers get READER access.", + // "Project team owners get OWNER access, and allUsers get WRITER access." + // ], + // "location": "query", + // "type": "string" + // }, + // "predefinedDefaultObjectAcl": { + // "description": "Apply a predefined set of default object access controls to this bucket.", + // "enum": [ + // "authenticatedRead", + // "bucketOwnerFullControl", + // "bucketOwnerRead", + // "private", + // "projectPrivate", + // "publicRead" + // ], + // "enumDescriptions": [ + // "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + // "Object owner gets OWNER access, and project team owners get OWNER access.", + // "Object owner gets OWNER access, and project team owners get READER access.", + // "Object owner gets OWNER access.", + // "Object owner gets OWNER access, and project team members get access according to their roles.", + // "Object owner gets OWNER access, and allUsers get READER access." + // ], + // "location": "query", + // "type": "string" + // }, + // "project": { + // "description": "A valid API project identifier.", + // "location": "query", + // "required": true, + // "type": "string" + // }, + // "projection": { + // "description": "Set of properties to return. Defaults to noAcl, unless the bucket resource specifies acl or defaultObjectAcl properties, when it defaults to full.", + // "enum": [ + // "full", + // "noAcl" + // ], + // "enumDescriptions": [ + // "Include all properties.", + // "Omit owner, acl and defaultObjectAcl properties." + // ], + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b", + // "request": { + // "$ref": "Bucket" + // }, + // "response": { + // "$ref": "Bucket" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.buckets.list": + +type BucketsListCall struct { + s *Service + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// List: Retrieves a list of buckets for a given project. +func (r *BucketsService) List(projectid string) *BucketsListCall { + c := &BucketsListCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.urlParams_.Set("project", projectid) + return c +} + +// MaxResults sets the optional parameter "maxResults": Maximum number +// of buckets to return in a single response. The service will use this +// parameter or 1,000 items, whichever is smaller. +func (c *BucketsListCall) MaxResults(maxResults int64) *BucketsListCall { + c.urlParams_.Set("maxResults", fmt.Sprint(maxResults)) + return c +} + +// PageToken sets the optional parameter "pageToken": A +// previously-returned page token representing part of the larger set of +// results to view. +func (c *BucketsListCall) PageToken(pageToken string) *BucketsListCall { + c.urlParams_.Set("pageToken", pageToken) + return c +} + +// Prefix sets the optional parameter "prefix": Filter results to +// buckets whose names begin with this prefix. +func (c *BucketsListCall) Prefix(prefix string) *BucketsListCall { + c.urlParams_.Set("prefix", prefix) + return c +} + +// Projection sets the optional parameter "projection": Set of +// properties to return. Defaults to noAcl. +// +// Possible values: +// "full" - Include all properties. +// "noAcl" - Omit owner, acl and defaultObjectAcl properties. +func (c *BucketsListCall) Projection(projection string) *BucketsListCall { + c.urlParams_.Set("projection", projection) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. +func (c *BucketsListCall) UserProject(userProject string) *BucketsListCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketsListCall) Fields(s ...googleapi.Field) *BucketsListCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *BucketsListCall) IfNoneMatch(entityTag string) *BucketsListCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketsListCall) Context(ctx context.Context) *BucketsListCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketsListCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketsListCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("GET", urls, body) + req.Header = reqHeaders + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.buckets.list" call. +// Exactly one of *Buckets or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Buckets.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *BucketsListCall) Do(opts ...googleapi.CallOption) (*Buckets, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Buckets{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Retrieves a list of buckets for a given project.", + // "httpMethod": "GET", + // "id": "storage.buckets.list", + // "parameterOrder": [ + // "project" + // ], + // "parameters": { + // "maxResults": { + // "default": "1000", + // "description": "Maximum number of buckets to return in a single response. The service will use this parameter or 1,000 items, whichever is smaller.", + // "format": "uint32", + // "location": "query", + // "minimum": "0", + // "type": "integer" + // }, + // "pageToken": { + // "description": "A previously-returned page token representing part of the larger set of results to view.", + // "location": "query", + // "type": "string" + // }, + // "prefix": { + // "description": "Filter results to buckets whose names begin with this prefix.", + // "location": "query", + // "type": "string" + // }, + // "project": { + // "description": "A valid API project identifier.", + // "location": "query", + // "required": true, + // "type": "string" + // }, + // "projection": { + // "description": "Set of properties to return. Defaults to noAcl.", + // "enum": [ + // "full", + // "noAcl" + // ], + // "enumDescriptions": [ + // "Include all properties.", + // "Omit owner, acl and defaultObjectAcl properties." + // ], + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b", + // "response": { + // "$ref": "Buckets" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_only", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// Pages invokes f for each page of results. +// A non-nil error returned from f will halt the iteration. +// The provided context supersedes any context provided to the Context method. +func (c *BucketsListCall) Pages(ctx context.Context, f func(*Buckets) error) error { + c.ctx_ = ctx + defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point + for { + x, err := c.Do() + if err != nil { + return err + } + if err := f(x); err != nil { + return err + } + if x.NextPageToken == "" { + return nil + } + c.PageToken(x.NextPageToken) + } +} + +// method id "storage.buckets.lockRetentionPolicy": + +type BucketsLockRetentionPolicyCall struct { + s *Service + bucket string + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// LockRetentionPolicy: Locks retention policy on a bucket. +func (r *BucketsService) LockRetentionPolicy(bucket string, ifMetagenerationMatch int64) *BucketsLockRetentionPolicyCall { + c := &BucketsLockRetentionPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketsLockRetentionPolicyCall) UserProject(userProject string) *BucketsLockRetentionPolicyCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketsLockRetentionPolicyCall) Fields(s ...googleapi.Field) *BucketsLockRetentionPolicyCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketsLockRetentionPolicyCall) Context(ctx context.Context) *BucketsLockRetentionPolicyCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketsLockRetentionPolicyCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketsLockRetentionPolicyCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/lockRetentionPolicy") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("POST", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.buckets.lockRetentionPolicy" call. +// Exactly one of *Bucket or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Bucket.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *BucketsLockRetentionPolicyCall) Do(opts ...googleapi.CallOption) (*Bucket, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Bucket{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Locks retention policy on a bucket.", + // "httpMethod": "POST", + // "id": "storage.buckets.lockRetentionPolicy", + // "parameterOrder": [ + // "bucket", + // "ifMetagenerationMatch" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "Makes the operation conditional on whether bucket's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/lockRetentionPolicy", + // "response": { + // "$ref": "Bucket" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.buckets.patch": + +type BucketsPatchCall struct { + s *Service + bucket string + bucket2 *Bucket + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Patch: Updates a bucket. Changes to the bucket will be readable +// immediately after writing, but configuration changes may take time to +// propagate. This method supports patch semantics. +func (r *BucketsService) Patch(bucket string, bucket2 *Bucket) *BucketsPatchCall { + c := &BucketsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.bucket2 = bucket2 + return c +} + +// IfMetagenerationMatch sets the optional parameter +// "ifMetagenerationMatch": Makes the return of the bucket metadata +// conditional on whether the bucket's current metageneration matches +// the given value. +func (c *BucketsPatchCall) IfMetagenerationMatch(ifMetagenerationMatch int64) *BucketsPatchCall { + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// IfMetagenerationNotMatch sets the optional parameter +// "ifMetagenerationNotMatch": Makes the return of the bucket metadata +// conditional on whether the bucket's current metageneration does not +// match the given value. +func (c *BucketsPatchCall) IfMetagenerationNotMatch(ifMetagenerationNotMatch int64) *BucketsPatchCall { + c.urlParams_.Set("ifMetagenerationNotMatch", fmt.Sprint(ifMetagenerationNotMatch)) + return c +} + +// PredefinedAcl sets the optional parameter "predefinedAcl": Apply a +// predefined set of access controls to this bucket. +// +// Possible values: +// "authenticatedRead" - Project team owners get OWNER access, and +// allAuthenticatedUsers get READER access. +// "private" - Project team owners get OWNER access. +// "projectPrivate" - Project team members get access according to +// their roles. +// "publicRead" - Project team owners get OWNER access, and allUsers +// get READER access. +// "publicReadWrite" - Project team owners get OWNER access, and +// allUsers get WRITER access. +func (c *BucketsPatchCall) PredefinedAcl(predefinedAcl string) *BucketsPatchCall { + c.urlParams_.Set("predefinedAcl", predefinedAcl) + return c +} + +// PredefinedDefaultObjectAcl sets the optional parameter +// "predefinedDefaultObjectAcl": Apply a predefined set of default +// object access controls to this bucket. +// +// Possible values: +// "authenticatedRead" - Object owner gets OWNER access, and +// allAuthenticatedUsers get READER access. +// "bucketOwnerFullControl" - Object owner gets OWNER access, and +// project team owners get OWNER access. +// "bucketOwnerRead" - Object owner gets OWNER access, and project +// team owners get READER access. +// "private" - Object owner gets OWNER access. +// "projectPrivate" - Object owner gets OWNER access, and project team +// members get access according to their roles. +// "publicRead" - Object owner gets OWNER access, and allUsers get +// READER access. +func (c *BucketsPatchCall) PredefinedDefaultObjectAcl(predefinedDefaultObjectAcl string) *BucketsPatchCall { + c.urlParams_.Set("predefinedDefaultObjectAcl", predefinedDefaultObjectAcl) + return c +} + +// Projection sets the optional parameter "projection": Set of +// properties to return. Defaults to full. +// +// Possible values: +// "full" - Include all properties. +// "noAcl" - Omit owner, acl and defaultObjectAcl properties. +func (c *BucketsPatchCall) Projection(projection string) *BucketsPatchCall { + c.urlParams_.Set("projection", projection) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketsPatchCall) UserProject(userProject string) *BucketsPatchCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketsPatchCall) Fields(s ...googleapi.Field) *BucketsPatchCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketsPatchCall) Context(ctx context.Context) *BucketsPatchCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketsPatchCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketsPatchCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.bucket2) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("PATCH", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.buckets.patch" call. +// Exactly one of *Bucket or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Bucket.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *BucketsPatchCall) Do(opts ...googleapi.CallOption) (*Bucket, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Bucket{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates a bucket. Changes to the bucket will be readable immediately after writing, but configuration changes may take time to propagate. This method supports patch semantics.", + // "httpMethod": "PATCH", + // "id": "storage.buckets.patch", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationNotMatch": { + // "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "predefinedAcl": { + // "description": "Apply a predefined set of access controls to this bucket.", + // "enum": [ + // "authenticatedRead", + // "private", + // "projectPrivate", + // "publicRead", + // "publicReadWrite" + // ], + // "enumDescriptions": [ + // "Project team owners get OWNER access, and allAuthenticatedUsers get READER access.", + // "Project team owners get OWNER access.", + // "Project team members get access according to their roles.", + // "Project team owners get OWNER access, and allUsers get READER access.", + // "Project team owners get OWNER access, and allUsers get WRITER access." + // ], + // "location": "query", + // "type": "string" + // }, + // "predefinedDefaultObjectAcl": { + // "description": "Apply a predefined set of default object access controls to this bucket.", + // "enum": [ + // "authenticatedRead", + // "bucketOwnerFullControl", + // "bucketOwnerRead", + // "private", + // "projectPrivate", + // "publicRead" + // ], + // "enumDescriptions": [ + // "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + // "Object owner gets OWNER access, and project team owners get OWNER access.", + // "Object owner gets OWNER access, and project team owners get READER access.", + // "Object owner gets OWNER access.", + // "Object owner gets OWNER access, and project team members get access according to their roles.", + // "Object owner gets OWNER access, and allUsers get READER access." + // ], + // "location": "query", + // "type": "string" + // }, + // "projection": { + // "description": "Set of properties to return. Defaults to full.", + // "enum": [ + // "full", + // "noAcl" + // ], + // "enumDescriptions": [ + // "Include all properties.", + // "Omit owner, acl and defaultObjectAcl properties." + // ], + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}", + // "request": { + // "$ref": "Bucket" + // }, + // "response": { + // "$ref": "Bucket" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.buckets.setIamPolicy": + +type BucketsSetIamPolicyCall struct { + s *Service + bucket string + policy *Policy + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// SetIamPolicy: Updates an IAM policy for the specified bucket. +func (r *BucketsService) SetIamPolicy(bucket string, policy *Policy) *BucketsSetIamPolicyCall { + c := &BucketsSetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.policy = policy + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketsSetIamPolicyCall) UserProject(userProject string) *BucketsSetIamPolicyCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketsSetIamPolicyCall) Fields(s ...googleapi.Field) *BucketsSetIamPolicyCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketsSetIamPolicyCall) Context(ctx context.Context) *BucketsSetIamPolicyCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketsSetIamPolicyCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketsSetIamPolicyCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.policy) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/iam") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("PUT", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.buckets.setIamPolicy" call. +// Exactly one of *Policy or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Policy.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *BucketsSetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Policy{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates an IAM policy for the specified bucket.", + // "httpMethod": "PUT", + // "id": "storage.buckets.setIamPolicy", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/iam", + // "request": { + // "$ref": "Policy" + // }, + // "response": { + // "$ref": "Policy" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.buckets.testIamPermissions": + +type BucketsTestIamPermissionsCall struct { + s *Service + bucket string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// TestIamPermissions: Tests a set of permissions on the given bucket to +// see which, if any, are held by the caller. +func (r *BucketsService) TestIamPermissions(bucket string, permissions []string) *BucketsTestIamPermissionsCall { + c := &BucketsTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.urlParams_.SetMulti("permissions", append([]string{}, permissions...)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketsTestIamPermissionsCall) UserProject(userProject string) *BucketsTestIamPermissionsCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketsTestIamPermissionsCall) Fields(s ...googleapi.Field) *BucketsTestIamPermissionsCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *BucketsTestIamPermissionsCall) IfNoneMatch(entityTag string) *BucketsTestIamPermissionsCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketsTestIamPermissionsCall) Context(ctx context.Context) *BucketsTestIamPermissionsCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketsTestIamPermissionsCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketsTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/iam/testPermissions") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("GET", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.buckets.testIamPermissions" call. +// Exactly one of *TestIamPermissionsResponse or error will be non-nil. +// Any non-2xx status code is an error. Response headers are in either +// *TestIamPermissionsResponse.ServerResponse.Header or (if a response +// was returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *BucketsTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*TestIamPermissionsResponse, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &TestIamPermissionsResponse{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Tests a set of permissions on the given bucket to see which, if any, are held by the caller.", + // "httpMethod": "GET", + // "id": "storage.buckets.testIamPermissions", + // "parameterOrder": [ + // "bucket", + // "permissions" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "permissions": { + // "description": "Permissions to test.", + // "location": "query", + // "repeated": true, + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/iam/testPermissions", + // "response": { + // "$ref": "TestIamPermissionsResponse" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_only", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.buckets.update": + +type BucketsUpdateCall struct { + s *Service + bucket string + bucket2 *Bucket + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Update: Updates a bucket. Changes to the bucket will be readable +// immediately after writing, but configuration changes may take time to +// propagate. +func (r *BucketsService) Update(bucket string, bucket2 *Bucket) *BucketsUpdateCall { + c := &BucketsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.bucket2 = bucket2 + return c +} + +// IfMetagenerationMatch sets the optional parameter +// "ifMetagenerationMatch": Makes the return of the bucket metadata +// conditional on whether the bucket's current metageneration matches +// the given value. +func (c *BucketsUpdateCall) IfMetagenerationMatch(ifMetagenerationMatch int64) *BucketsUpdateCall { + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// IfMetagenerationNotMatch sets the optional parameter +// "ifMetagenerationNotMatch": Makes the return of the bucket metadata +// conditional on whether the bucket's current metageneration does not +// match the given value. +func (c *BucketsUpdateCall) IfMetagenerationNotMatch(ifMetagenerationNotMatch int64) *BucketsUpdateCall { + c.urlParams_.Set("ifMetagenerationNotMatch", fmt.Sprint(ifMetagenerationNotMatch)) + return c +} + +// PredefinedAcl sets the optional parameter "predefinedAcl": Apply a +// predefined set of access controls to this bucket. +// +// Possible values: +// "authenticatedRead" - Project team owners get OWNER access, and +// allAuthenticatedUsers get READER access. +// "private" - Project team owners get OWNER access. +// "projectPrivate" - Project team members get access according to +// their roles. +// "publicRead" - Project team owners get OWNER access, and allUsers +// get READER access. +// "publicReadWrite" - Project team owners get OWNER access, and +// allUsers get WRITER access. +func (c *BucketsUpdateCall) PredefinedAcl(predefinedAcl string) *BucketsUpdateCall { + c.urlParams_.Set("predefinedAcl", predefinedAcl) + return c +} + +// PredefinedDefaultObjectAcl sets the optional parameter +// "predefinedDefaultObjectAcl": Apply a predefined set of default +// object access controls to this bucket. +// +// Possible values: +// "authenticatedRead" - Object owner gets OWNER access, and +// allAuthenticatedUsers get READER access. +// "bucketOwnerFullControl" - Object owner gets OWNER access, and +// project team owners get OWNER access. +// "bucketOwnerRead" - Object owner gets OWNER access, and project +// team owners get READER access. +// "private" - Object owner gets OWNER access. +// "projectPrivate" - Object owner gets OWNER access, and project team +// members get access according to their roles. +// "publicRead" - Object owner gets OWNER access, and allUsers get +// READER access. +func (c *BucketsUpdateCall) PredefinedDefaultObjectAcl(predefinedDefaultObjectAcl string) *BucketsUpdateCall { + c.urlParams_.Set("predefinedDefaultObjectAcl", predefinedDefaultObjectAcl) + return c +} + +// Projection sets the optional parameter "projection": Set of +// properties to return. Defaults to full. +// +// Possible values: +// "full" - Include all properties. +// "noAcl" - Omit owner, acl and defaultObjectAcl properties. +func (c *BucketsUpdateCall) Projection(projection string) *BucketsUpdateCall { + c.urlParams_.Set("projection", projection) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketsUpdateCall) UserProject(userProject string) *BucketsUpdateCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketsUpdateCall) Fields(s ...googleapi.Field) *BucketsUpdateCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketsUpdateCall) Context(ctx context.Context) *BucketsUpdateCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketsUpdateCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketsUpdateCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.bucket2) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("PUT", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.buckets.update" call. +// Exactly one of *Bucket or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Bucket.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *BucketsUpdateCall) Do(opts ...googleapi.CallOption) (*Bucket, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Bucket{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates a bucket. Changes to the bucket will be readable immediately after writing, but configuration changes may take time to propagate.", + // "httpMethod": "PUT", + // "id": "storage.buckets.update", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationNotMatch": { + // "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "predefinedAcl": { + // "description": "Apply a predefined set of access controls to this bucket.", + // "enum": [ + // "authenticatedRead", + // "private", + // "projectPrivate", + // "publicRead", + // "publicReadWrite" + // ], + // "enumDescriptions": [ + // "Project team owners get OWNER access, and allAuthenticatedUsers get READER access.", + // "Project team owners get OWNER access.", + // "Project team members get access according to their roles.", + // "Project team owners get OWNER access, and allUsers get READER access.", + // "Project team owners get OWNER access, and allUsers get WRITER access." + // ], + // "location": "query", + // "type": "string" + // }, + // "predefinedDefaultObjectAcl": { + // "description": "Apply a predefined set of default object access controls to this bucket.", + // "enum": [ + // "authenticatedRead", + // "bucketOwnerFullControl", + // "bucketOwnerRead", + // "private", + // "projectPrivate", + // "publicRead" + // ], + // "enumDescriptions": [ + // "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + // "Object owner gets OWNER access, and project team owners get OWNER access.", + // "Object owner gets OWNER access, and project team owners get READER access.", + // "Object owner gets OWNER access.", + // "Object owner gets OWNER access, and project team members get access according to their roles.", + // "Object owner gets OWNER access, and allUsers get READER access." + // ], + // "location": "query", + // "type": "string" + // }, + // "projection": { + // "description": "Set of properties to return. Defaults to full.", + // "enum": [ + // "full", + // "noAcl" + // ], + // "enumDescriptions": [ + // "Include all properties.", + // "Omit owner, acl and defaultObjectAcl properties." + // ], + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}", + // "request": { + // "$ref": "Bucket" + // }, + // "response": { + // "$ref": "Bucket" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.channels.stop": + +type ChannelsStopCall struct { + s *Service + channel *Channel + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Stop: Stop watching resources through this channel +func (r *ChannelsService) Stop(channel *Channel) *ChannelsStopCall { + c := &ChannelsStopCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.channel = channel + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ChannelsStopCall) Fields(s ...googleapi.Field) *ChannelsStopCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ChannelsStopCall) Context(ctx context.Context) *ChannelsStopCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ChannelsStopCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ChannelsStopCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.channel) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "channels/stop") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("POST", urls, body) + req.Header = reqHeaders + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.channels.stop" call. +func (c *ChannelsStopCall) Do(opts ...googleapi.CallOption) error { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if err != nil { + return err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return err + } + return nil + // { + // "description": "Stop watching resources through this channel", + // "httpMethod": "POST", + // "id": "storage.channels.stop", + // "path": "channels/stop", + // "request": { + // "$ref": "Channel", + // "parameterName": "resource" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_only", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.defaultObjectAccessControls.delete": + +type DefaultObjectAccessControlsDeleteCall struct { + s *Service + bucket string + entity string + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Delete: Permanently deletes the default object ACL entry for the +// specified entity on the specified bucket. +func (r *DefaultObjectAccessControlsService) Delete(bucket string, entity string) *DefaultObjectAccessControlsDeleteCall { + c := &DefaultObjectAccessControlsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.entity = entity + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *DefaultObjectAccessControlsDeleteCall) UserProject(userProject string) *DefaultObjectAccessControlsDeleteCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *DefaultObjectAccessControlsDeleteCall) Fields(s ...googleapi.Field) *DefaultObjectAccessControlsDeleteCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *DefaultObjectAccessControlsDeleteCall) Context(ctx context.Context) *DefaultObjectAccessControlsDeleteCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *DefaultObjectAccessControlsDeleteCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *DefaultObjectAccessControlsDeleteCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/defaultObjectAcl/{entity}") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("DELETE", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "entity": c.entity, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.defaultObjectAccessControls.delete" call. +func (c *DefaultObjectAccessControlsDeleteCall) Do(opts ...googleapi.CallOption) error { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if err != nil { + return err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return err + } + return nil + // { + // "description": "Permanently deletes the default object ACL entry for the specified entity on the specified bucket.", + // "httpMethod": "DELETE", + // "id": "storage.defaultObjectAccessControls.delete", + // "parameterOrder": [ + // "bucket", + // "entity" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "entity": { + // "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/defaultObjectAcl/{entity}", + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.defaultObjectAccessControls.get": + +type DefaultObjectAccessControlsGetCall struct { + s *Service + bucket string + entity string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// Get: Returns the default object ACL entry for the specified entity on +// the specified bucket. +func (r *DefaultObjectAccessControlsService) Get(bucket string, entity string) *DefaultObjectAccessControlsGetCall { + c := &DefaultObjectAccessControlsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.entity = entity + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *DefaultObjectAccessControlsGetCall) UserProject(userProject string) *DefaultObjectAccessControlsGetCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *DefaultObjectAccessControlsGetCall) Fields(s ...googleapi.Field) *DefaultObjectAccessControlsGetCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *DefaultObjectAccessControlsGetCall) IfNoneMatch(entityTag string) *DefaultObjectAccessControlsGetCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *DefaultObjectAccessControlsGetCall) Context(ctx context.Context) *DefaultObjectAccessControlsGetCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *DefaultObjectAccessControlsGetCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *DefaultObjectAccessControlsGetCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/defaultObjectAcl/{entity}") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("GET", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "entity": c.entity, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.defaultObjectAccessControls.get" call. +// Exactly one of *ObjectAccessControl or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *ObjectAccessControl.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *DefaultObjectAccessControlsGetCall) Do(opts ...googleapi.CallOption) (*ObjectAccessControl, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ObjectAccessControl{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Returns the default object ACL entry for the specified entity on the specified bucket.", + // "httpMethod": "GET", + // "id": "storage.defaultObjectAccessControls.get", + // "parameterOrder": [ + // "bucket", + // "entity" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "entity": { + // "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/defaultObjectAcl/{entity}", + // "response": { + // "$ref": "ObjectAccessControl" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.defaultObjectAccessControls.insert": + +type DefaultObjectAccessControlsInsertCall struct { + s *Service + bucket string + objectaccesscontrol *ObjectAccessControl + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Insert: Creates a new default object ACL entry on the specified +// bucket. +func (r *DefaultObjectAccessControlsService) Insert(bucket string, objectaccesscontrol *ObjectAccessControl) *DefaultObjectAccessControlsInsertCall { + c := &DefaultObjectAccessControlsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.objectaccesscontrol = objectaccesscontrol + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *DefaultObjectAccessControlsInsertCall) UserProject(userProject string) *DefaultObjectAccessControlsInsertCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *DefaultObjectAccessControlsInsertCall) Fields(s ...googleapi.Field) *DefaultObjectAccessControlsInsertCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *DefaultObjectAccessControlsInsertCall) Context(ctx context.Context) *DefaultObjectAccessControlsInsertCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *DefaultObjectAccessControlsInsertCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *DefaultObjectAccessControlsInsertCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.objectaccesscontrol) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/defaultObjectAcl") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("POST", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.defaultObjectAccessControls.insert" call. +// Exactly one of *ObjectAccessControl or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *ObjectAccessControl.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *DefaultObjectAccessControlsInsertCall) Do(opts ...googleapi.CallOption) (*ObjectAccessControl, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ObjectAccessControl{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Creates a new default object ACL entry on the specified bucket.", + // "httpMethod": "POST", + // "id": "storage.defaultObjectAccessControls.insert", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/defaultObjectAcl", + // "request": { + // "$ref": "ObjectAccessControl" + // }, + // "response": { + // "$ref": "ObjectAccessControl" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.defaultObjectAccessControls.list": + +type DefaultObjectAccessControlsListCall struct { + s *Service + bucket string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// List: Retrieves default object ACL entries on the specified bucket. +func (r *DefaultObjectAccessControlsService) List(bucket string) *DefaultObjectAccessControlsListCall { + c := &DefaultObjectAccessControlsListCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + return c +} + +// IfMetagenerationMatch sets the optional parameter +// "ifMetagenerationMatch": If present, only return default ACL listing +// if the bucket's current metageneration matches this value. +func (c *DefaultObjectAccessControlsListCall) IfMetagenerationMatch(ifMetagenerationMatch int64) *DefaultObjectAccessControlsListCall { + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// IfMetagenerationNotMatch sets the optional parameter +// "ifMetagenerationNotMatch": If present, only return default ACL +// listing if the bucket's current metageneration does not match the +// given value. +func (c *DefaultObjectAccessControlsListCall) IfMetagenerationNotMatch(ifMetagenerationNotMatch int64) *DefaultObjectAccessControlsListCall { + c.urlParams_.Set("ifMetagenerationNotMatch", fmt.Sprint(ifMetagenerationNotMatch)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *DefaultObjectAccessControlsListCall) UserProject(userProject string) *DefaultObjectAccessControlsListCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *DefaultObjectAccessControlsListCall) Fields(s ...googleapi.Field) *DefaultObjectAccessControlsListCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *DefaultObjectAccessControlsListCall) IfNoneMatch(entityTag string) *DefaultObjectAccessControlsListCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *DefaultObjectAccessControlsListCall) Context(ctx context.Context) *DefaultObjectAccessControlsListCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *DefaultObjectAccessControlsListCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *DefaultObjectAccessControlsListCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/defaultObjectAcl") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("GET", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.defaultObjectAccessControls.list" call. +// Exactly one of *ObjectAccessControls or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *ObjectAccessControls.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *DefaultObjectAccessControlsListCall) Do(opts ...googleapi.CallOption) (*ObjectAccessControls, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ObjectAccessControls{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Retrieves default object ACL entries on the specified bucket.", + // "httpMethod": "GET", + // "id": "storage.defaultObjectAccessControls.list", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "If present, only return default ACL listing if the bucket's current metageneration matches this value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationNotMatch": { + // "description": "If present, only return default ACL listing if the bucket's current metageneration does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/defaultObjectAcl", + // "response": { + // "$ref": "ObjectAccessControls" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.defaultObjectAccessControls.patch": + +type DefaultObjectAccessControlsPatchCall struct { + s *Service + bucket string + entity string + objectaccesscontrol *ObjectAccessControl + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Patch: Patches a default object ACL entry on the specified bucket. +func (r *DefaultObjectAccessControlsService) Patch(bucket string, entity string, objectaccesscontrol *ObjectAccessControl) *DefaultObjectAccessControlsPatchCall { + c := &DefaultObjectAccessControlsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.entity = entity + c.objectaccesscontrol = objectaccesscontrol + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *DefaultObjectAccessControlsPatchCall) UserProject(userProject string) *DefaultObjectAccessControlsPatchCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *DefaultObjectAccessControlsPatchCall) Fields(s ...googleapi.Field) *DefaultObjectAccessControlsPatchCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *DefaultObjectAccessControlsPatchCall) Context(ctx context.Context) *DefaultObjectAccessControlsPatchCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *DefaultObjectAccessControlsPatchCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *DefaultObjectAccessControlsPatchCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.objectaccesscontrol) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/defaultObjectAcl/{entity}") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("PATCH", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "entity": c.entity, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.defaultObjectAccessControls.patch" call. +// Exactly one of *ObjectAccessControl or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *ObjectAccessControl.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *DefaultObjectAccessControlsPatchCall) Do(opts ...googleapi.CallOption) (*ObjectAccessControl, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ObjectAccessControl{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Patches a default object ACL entry on the specified bucket.", + // "httpMethod": "PATCH", + // "id": "storage.defaultObjectAccessControls.patch", + // "parameterOrder": [ + // "bucket", + // "entity" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "entity": { + // "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/defaultObjectAcl/{entity}", + // "request": { + // "$ref": "ObjectAccessControl" + // }, + // "response": { + // "$ref": "ObjectAccessControl" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.defaultObjectAccessControls.update": + +type DefaultObjectAccessControlsUpdateCall struct { + s *Service + bucket string + entity string + objectaccesscontrol *ObjectAccessControl + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Update: Updates a default object ACL entry on the specified bucket. +func (r *DefaultObjectAccessControlsService) Update(bucket string, entity string, objectaccesscontrol *ObjectAccessControl) *DefaultObjectAccessControlsUpdateCall { + c := &DefaultObjectAccessControlsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.entity = entity + c.objectaccesscontrol = objectaccesscontrol + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *DefaultObjectAccessControlsUpdateCall) UserProject(userProject string) *DefaultObjectAccessControlsUpdateCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *DefaultObjectAccessControlsUpdateCall) Fields(s ...googleapi.Field) *DefaultObjectAccessControlsUpdateCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *DefaultObjectAccessControlsUpdateCall) Context(ctx context.Context) *DefaultObjectAccessControlsUpdateCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *DefaultObjectAccessControlsUpdateCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *DefaultObjectAccessControlsUpdateCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.objectaccesscontrol) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/defaultObjectAcl/{entity}") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("PUT", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "entity": c.entity, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.defaultObjectAccessControls.update" call. +// Exactly one of *ObjectAccessControl or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *ObjectAccessControl.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *DefaultObjectAccessControlsUpdateCall) Do(opts ...googleapi.CallOption) (*ObjectAccessControl, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ObjectAccessControl{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates a default object ACL entry on the specified bucket.", + // "httpMethod": "PUT", + // "id": "storage.defaultObjectAccessControls.update", + // "parameterOrder": [ + // "bucket", + // "entity" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "entity": { + // "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/defaultObjectAcl/{entity}", + // "request": { + // "$ref": "ObjectAccessControl" + // }, + // "response": { + // "$ref": "ObjectAccessControl" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.notifications.delete": + +type NotificationsDeleteCall struct { + s *Service + bucket string + notification string + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Delete: Permanently deletes a notification subscription. +func (r *NotificationsService) Delete(bucket string, notification string) *NotificationsDeleteCall { + c := &NotificationsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.notification = notification + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *NotificationsDeleteCall) UserProject(userProject string) *NotificationsDeleteCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *NotificationsDeleteCall) Fields(s ...googleapi.Field) *NotificationsDeleteCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *NotificationsDeleteCall) Context(ctx context.Context) *NotificationsDeleteCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *NotificationsDeleteCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *NotificationsDeleteCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/notificationConfigs/{notification}") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("DELETE", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "notification": c.notification, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.notifications.delete" call. +func (c *NotificationsDeleteCall) Do(opts ...googleapi.CallOption) error { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if err != nil { + return err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return err + } + return nil + // { + // "description": "Permanently deletes a notification subscription.", + // "httpMethod": "DELETE", + // "id": "storage.notifications.delete", + // "parameterOrder": [ + // "bucket", + // "notification" + // ], + // "parameters": { + // "bucket": { + // "description": "The parent bucket of the notification.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "notification": { + // "description": "ID of the notification to delete.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/notificationConfigs/{notification}", + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.notifications.get": + +type NotificationsGetCall struct { + s *Service + bucket string + notification string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// Get: View a notification configuration. +func (r *NotificationsService) Get(bucket string, notification string) *NotificationsGetCall { + c := &NotificationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.notification = notification + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *NotificationsGetCall) UserProject(userProject string) *NotificationsGetCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *NotificationsGetCall) Fields(s ...googleapi.Field) *NotificationsGetCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *NotificationsGetCall) IfNoneMatch(entityTag string) *NotificationsGetCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *NotificationsGetCall) Context(ctx context.Context) *NotificationsGetCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *NotificationsGetCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *NotificationsGetCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/notificationConfigs/{notification}") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("GET", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "notification": c.notification, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.notifications.get" call. +// Exactly one of *Notification or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *Notification.ServerResponse.Header or (if a response was returned at +// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified +// to check whether the returned error was because +// http.StatusNotModified was returned. +func (c *NotificationsGetCall) Do(opts ...googleapi.CallOption) (*Notification, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Notification{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "View a notification configuration.", + // "httpMethod": "GET", + // "id": "storage.notifications.get", + // "parameterOrder": [ + // "bucket", + // "notification" + // ], + // "parameters": { + // "bucket": { + // "description": "The parent bucket of the notification.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "notification": { + // "description": "Notification ID", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/notificationConfigs/{notification}", + // "response": { + // "$ref": "Notification" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_only", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.notifications.insert": + +type NotificationsInsertCall struct { + s *Service + bucket string + notification *Notification + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Insert: Creates a notification subscription for a given bucket. +func (r *NotificationsService) Insert(bucket string, notification *Notification) *NotificationsInsertCall { + c := &NotificationsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.notification = notification + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *NotificationsInsertCall) UserProject(userProject string) *NotificationsInsertCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *NotificationsInsertCall) Fields(s ...googleapi.Field) *NotificationsInsertCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *NotificationsInsertCall) Context(ctx context.Context) *NotificationsInsertCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *NotificationsInsertCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *NotificationsInsertCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.notification) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/notificationConfigs") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("POST", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.notifications.insert" call. +// Exactly one of *Notification or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *Notification.ServerResponse.Header or (if a response was returned at +// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified +// to check whether the returned error was because +// http.StatusNotModified was returned. +func (c *NotificationsInsertCall) Do(opts ...googleapi.CallOption) (*Notification, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Notification{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Creates a notification subscription for a given bucket.", + // "httpMethod": "POST", + // "id": "storage.notifications.insert", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "The parent bucket of the notification.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/notificationConfigs", + // "request": { + // "$ref": "Notification" + // }, + // "response": { + // "$ref": "Notification" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.notifications.list": + +type NotificationsListCall struct { + s *Service + bucket string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// List: Retrieves a list of notification subscriptions for a given +// bucket. +func (r *NotificationsService) List(bucket string) *NotificationsListCall { + c := &NotificationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *NotificationsListCall) UserProject(userProject string) *NotificationsListCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *NotificationsListCall) Fields(s ...googleapi.Field) *NotificationsListCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *NotificationsListCall) IfNoneMatch(entityTag string) *NotificationsListCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *NotificationsListCall) Context(ctx context.Context) *NotificationsListCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *NotificationsListCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *NotificationsListCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/notificationConfigs") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("GET", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.notifications.list" call. +// Exactly one of *Notifications or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *Notifications.ServerResponse.Header or (if a response was returned +// at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *NotificationsListCall) Do(opts ...googleapi.CallOption) (*Notifications, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Notifications{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Retrieves a list of notification subscriptions for a given bucket.", + // "httpMethod": "GET", + // "id": "storage.notifications.list", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a Google Cloud Storage bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/notificationConfigs", + // "response": { + // "$ref": "Notifications" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_only", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.objectAccessControls.delete": + +type ObjectAccessControlsDeleteCall struct { + s *Service + bucket string + object string + entity string + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Delete: Permanently deletes the ACL entry for the specified entity on +// the specified object. +func (r *ObjectAccessControlsService) Delete(bucket string, object string, entity string) *ObjectAccessControlsDeleteCall { + c := &ObjectAccessControlsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + c.entity = entity + return c +} + +// Generation sets the optional parameter "generation": If present, +// selects a specific revision of this object (as opposed to the latest +// version, the default). +func (c *ObjectAccessControlsDeleteCall) Generation(generation int64) *ObjectAccessControlsDeleteCall { + c.urlParams_.Set("generation", fmt.Sprint(generation)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectAccessControlsDeleteCall) UserProject(userProject string) *ObjectAccessControlsDeleteCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectAccessControlsDeleteCall) Fields(s ...googleapi.Field) *ObjectAccessControlsDeleteCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectAccessControlsDeleteCall) Context(ctx context.Context) *ObjectAccessControlsDeleteCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectAccessControlsDeleteCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectAccessControlsDeleteCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/{object}/acl/{entity}") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("DELETE", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "object": c.object, + "entity": c.entity, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objectAccessControls.delete" call. +func (c *ObjectAccessControlsDeleteCall) Do(opts ...googleapi.CallOption) error { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if err != nil { + return err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return err + } + return nil + // { + // "description": "Permanently deletes the ACL entry for the specified entity on the specified object.", + // "httpMethod": "DELETE", + // "id": "storage.objectAccessControls.delete", + // "parameterOrder": [ + // "bucket", + // "object", + // "entity" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "entity": { + // "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "generation": { + // "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "object": { + // "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o/{object}/acl/{entity}", + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.objectAccessControls.get": + +type ObjectAccessControlsGetCall struct { + s *Service + bucket string + object string + entity string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// Get: Returns the ACL entry for the specified entity on the specified +// object. +func (r *ObjectAccessControlsService) Get(bucket string, object string, entity string) *ObjectAccessControlsGetCall { + c := &ObjectAccessControlsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + c.entity = entity + return c +} + +// Generation sets the optional parameter "generation": If present, +// selects a specific revision of this object (as opposed to the latest +// version, the default). +func (c *ObjectAccessControlsGetCall) Generation(generation int64) *ObjectAccessControlsGetCall { + c.urlParams_.Set("generation", fmt.Sprint(generation)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectAccessControlsGetCall) UserProject(userProject string) *ObjectAccessControlsGetCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectAccessControlsGetCall) Fields(s ...googleapi.Field) *ObjectAccessControlsGetCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ObjectAccessControlsGetCall) IfNoneMatch(entityTag string) *ObjectAccessControlsGetCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectAccessControlsGetCall) Context(ctx context.Context) *ObjectAccessControlsGetCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectAccessControlsGetCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectAccessControlsGetCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/{object}/acl/{entity}") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("GET", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "object": c.object, + "entity": c.entity, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objectAccessControls.get" call. +// Exactly one of *ObjectAccessControl or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *ObjectAccessControl.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ObjectAccessControlsGetCall) Do(opts ...googleapi.CallOption) (*ObjectAccessControl, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ObjectAccessControl{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Returns the ACL entry for the specified entity on the specified object.", + // "httpMethod": "GET", + // "id": "storage.objectAccessControls.get", + // "parameterOrder": [ + // "bucket", + // "object", + // "entity" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "entity": { + // "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "generation": { + // "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "object": { + // "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o/{object}/acl/{entity}", + // "response": { + // "$ref": "ObjectAccessControl" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.objectAccessControls.insert": + +type ObjectAccessControlsInsertCall struct { + s *Service + bucket string + object string + objectaccesscontrol *ObjectAccessControl + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Insert: Creates a new ACL entry on the specified object. +func (r *ObjectAccessControlsService) Insert(bucket string, object string, objectaccesscontrol *ObjectAccessControl) *ObjectAccessControlsInsertCall { + c := &ObjectAccessControlsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + c.objectaccesscontrol = objectaccesscontrol + return c +} + +// Generation sets the optional parameter "generation": If present, +// selects a specific revision of this object (as opposed to the latest +// version, the default). +func (c *ObjectAccessControlsInsertCall) Generation(generation int64) *ObjectAccessControlsInsertCall { + c.urlParams_.Set("generation", fmt.Sprint(generation)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectAccessControlsInsertCall) UserProject(userProject string) *ObjectAccessControlsInsertCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectAccessControlsInsertCall) Fields(s ...googleapi.Field) *ObjectAccessControlsInsertCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectAccessControlsInsertCall) Context(ctx context.Context) *ObjectAccessControlsInsertCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectAccessControlsInsertCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectAccessControlsInsertCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.objectaccesscontrol) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/{object}/acl") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("POST", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "object": c.object, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objectAccessControls.insert" call. +// Exactly one of *ObjectAccessControl or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *ObjectAccessControl.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ObjectAccessControlsInsertCall) Do(opts ...googleapi.CallOption) (*ObjectAccessControl, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ObjectAccessControl{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Creates a new ACL entry on the specified object.", + // "httpMethod": "POST", + // "id": "storage.objectAccessControls.insert", + // "parameterOrder": [ + // "bucket", + // "object" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "generation": { + // "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "object": { + // "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o/{object}/acl", + // "request": { + // "$ref": "ObjectAccessControl" + // }, + // "response": { + // "$ref": "ObjectAccessControl" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.objectAccessControls.list": + +type ObjectAccessControlsListCall struct { + s *Service + bucket string + object string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// List: Retrieves ACL entries on the specified object. +func (r *ObjectAccessControlsService) List(bucket string, object string) *ObjectAccessControlsListCall { + c := &ObjectAccessControlsListCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + return c +} + +// Generation sets the optional parameter "generation": If present, +// selects a specific revision of this object (as opposed to the latest +// version, the default). +func (c *ObjectAccessControlsListCall) Generation(generation int64) *ObjectAccessControlsListCall { + c.urlParams_.Set("generation", fmt.Sprint(generation)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectAccessControlsListCall) UserProject(userProject string) *ObjectAccessControlsListCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectAccessControlsListCall) Fields(s ...googleapi.Field) *ObjectAccessControlsListCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ObjectAccessControlsListCall) IfNoneMatch(entityTag string) *ObjectAccessControlsListCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectAccessControlsListCall) Context(ctx context.Context) *ObjectAccessControlsListCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectAccessControlsListCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectAccessControlsListCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/{object}/acl") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("GET", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "object": c.object, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objectAccessControls.list" call. +// Exactly one of *ObjectAccessControls or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *ObjectAccessControls.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ObjectAccessControlsListCall) Do(opts ...googleapi.CallOption) (*ObjectAccessControls, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ObjectAccessControls{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Retrieves ACL entries on the specified object.", + // "httpMethod": "GET", + // "id": "storage.objectAccessControls.list", + // "parameterOrder": [ + // "bucket", + // "object" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "generation": { + // "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "object": { + // "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o/{object}/acl", + // "response": { + // "$ref": "ObjectAccessControls" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.objectAccessControls.patch": + +type ObjectAccessControlsPatchCall struct { + s *Service + bucket string + object string + entity string + objectaccesscontrol *ObjectAccessControl + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Patch: Patches an ACL entry on the specified object. +func (r *ObjectAccessControlsService) Patch(bucket string, object string, entity string, objectaccesscontrol *ObjectAccessControl) *ObjectAccessControlsPatchCall { + c := &ObjectAccessControlsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + c.entity = entity + c.objectaccesscontrol = objectaccesscontrol + return c +} + +// Generation sets the optional parameter "generation": If present, +// selects a specific revision of this object (as opposed to the latest +// version, the default). +func (c *ObjectAccessControlsPatchCall) Generation(generation int64) *ObjectAccessControlsPatchCall { + c.urlParams_.Set("generation", fmt.Sprint(generation)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectAccessControlsPatchCall) UserProject(userProject string) *ObjectAccessControlsPatchCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectAccessControlsPatchCall) Fields(s ...googleapi.Field) *ObjectAccessControlsPatchCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectAccessControlsPatchCall) Context(ctx context.Context) *ObjectAccessControlsPatchCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectAccessControlsPatchCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectAccessControlsPatchCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.objectaccesscontrol) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/{object}/acl/{entity}") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("PATCH", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "object": c.object, + "entity": c.entity, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objectAccessControls.patch" call. +// Exactly one of *ObjectAccessControl or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *ObjectAccessControl.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ObjectAccessControlsPatchCall) Do(opts ...googleapi.CallOption) (*ObjectAccessControl, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ObjectAccessControl{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Patches an ACL entry on the specified object.", + // "httpMethod": "PATCH", + // "id": "storage.objectAccessControls.patch", + // "parameterOrder": [ + // "bucket", + // "object", + // "entity" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "entity": { + // "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "generation": { + // "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "object": { + // "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o/{object}/acl/{entity}", + // "request": { + // "$ref": "ObjectAccessControl" + // }, + // "response": { + // "$ref": "ObjectAccessControl" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.objectAccessControls.update": + +type ObjectAccessControlsUpdateCall struct { + s *Service + bucket string + object string + entity string + objectaccesscontrol *ObjectAccessControl + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Update: Updates an ACL entry on the specified object. +func (r *ObjectAccessControlsService) Update(bucket string, object string, entity string, objectaccesscontrol *ObjectAccessControl) *ObjectAccessControlsUpdateCall { + c := &ObjectAccessControlsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + c.entity = entity + c.objectaccesscontrol = objectaccesscontrol + return c +} + +// Generation sets the optional parameter "generation": If present, +// selects a specific revision of this object (as opposed to the latest +// version, the default). +func (c *ObjectAccessControlsUpdateCall) Generation(generation int64) *ObjectAccessControlsUpdateCall { + c.urlParams_.Set("generation", fmt.Sprint(generation)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectAccessControlsUpdateCall) UserProject(userProject string) *ObjectAccessControlsUpdateCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectAccessControlsUpdateCall) Fields(s ...googleapi.Field) *ObjectAccessControlsUpdateCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectAccessControlsUpdateCall) Context(ctx context.Context) *ObjectAccessControlsUpdateCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectAccessControlsUpdateCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectAccessControlsUpdateCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.objectaccesscontrol) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/{object}/acl/{entity}") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("PUT", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "object": c.object, + "entity": c.entity, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objectAccessControls.update" call. +// Exactly one of *ObjectAccessControl or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *ObjectAccessControl.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ObjectAccessControlsUpdateCall) Do(opts ...googleapi.CallOption) (*ObjectAccessControl, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ObjectAccessControl{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates an ACL entry on the specified object.", + // "httpMethod": "PUT", + // "id": "storage.objectAccessControls.update", + // "parameterOrder": [ + // "bucket", + // "object", + // "entity" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "entity": { + // "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "generation": { + // "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "object": { + // "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o/{object}/acl/{entity}", + // "request": { + // "$ref": "ObjectAccessControl" + // }, + // "response": { + // "$ref": "ObjectAccessControl" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.objects.compose": + +type ObjectsComposeCall struct { + s *Service + destinationBucket string + destinationObject string + composerequest *ComposeRequest + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Compose: Concatenates a list of existing objects into a new object in +// the same bucket. +func (r *ObjectsService) Compose(destinationBucket string, destinationObject string, composerequest *ComposeRequest) *ObjectsComposeCall { + c := &ObjectsComposeCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.destinationBucket = destinationBucket + c.destinationObject = destinationObject + c.composerequest = composerequest + return c +} + +// DestinationPredefinedAcl sets the optional parameter +// "destinationPredefinedAcl": Apply a predefined set of access controls +// to the destination object. +// +// Possible values: +// "authenticatedRead" - Object owner gets OWNER access, and +// allAuthenticatedUsers get READER access. +// "bucketOwnerFullControl" - Object owner gets OWNER access, and +// project team owners get OWNER access. +// "bucketOwnerRead" - Object owner gets OWNER access, and project +// team owners get READER access. +// "private" - Object owner gets OWNER access. +// "projectPrivate" - Object owner gets OWNER access, and project team +// members get access according to their roles. +// "publicRead" - Object owner gets OWNER access, and allUsers get +// READER access. +func (c *ObjectsComposeCall) DestinationPredefinedAcl(destinationPredefinedAcl string) *ObjectsComposeCall { + c.urlParams_.Set("destinationPredefinedAcl", destinationPredefinedAcl) + return c +} + +// IfGenerationMatch sets the optional parameter "ifGenerationMatch": +// Makes the operation conditional on whether the object's current +// generation matches the given value. Setting to 0 makes the operation +// succeed only if there are no live versions of the object. +func (c *ObjectsComposeCall) IfGenerationMatch(ifGenerationMatch int64) *ObjectsComposeCall { + c.urlParams_.Set("ifGenerationMatch", fmt.Sprint(ifGenerationMatch)) + return c +} + +// IfMetagenerationMatch sets the optional parameter +// "ifMetagenerationMatch": Makes the operation conditional on whether +// the object's current metageneration matches the given value. +func (c *ObjectsComposeCall) IfMetagenerationMatch(ifMetagenerationMatch int64) *ObjectsComposeCall { + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// KmsKeyName sets the optional parameter "kmsKeyName": Resource name of +// the Cloud KMS key, of the form +// projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, +// that will be used to encrypt the object. Overrides the object +// metadata's kms_key_name value, if any. +func (c *ObjectsComposeCall) KmsKeyName(kmsKeyName string) *ObjectsComposeCall { + c.urlParams_.Set("kmsKeyName", kmsKeyName) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectsComposeCall) UserProject(userProject string) *ObjectsComposeCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectsComposeCall) Fields(s ...googleapi.Field) *ObjectsComposeCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectsComposeCall) Context(ctx context.Context) *ObjectsComposeCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectsComposeCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectsComposeCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.composerequest) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{destinationBucket}/o/{destinationObject}/compose") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("POST", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "destinationBucket": c.destinationBucket, + "destinationObject": c.destinationObject, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objects.compose" call. +// Exactly one of *Object or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Object.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ObjectsComposeCall) Do(opts ...googleapi.CallOption) (*Object, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Object{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Concatenates a list of existing objects into a new object in the same bucket.", + // "httpMethod": "POST", + // "id": "storage.objects.compose", + // "parameterOrder": [ + // "destinationBucket", + // "destinationObject" + // ], + // "parameters": { + // "destinationBucket": { + // "description": "Name of the bucket in which to store the new object.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "destinationObject": { + // "description": "Name of the new object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "destinationPredefinedAcl": { + // "description": "Apply a predefined set of access controls to the destination object.", + // "enum": [ + // "authenticatedRead", + // "bucketOwnerFullControl", + // "bucketOwnerRead", + // "private", + // "projectPrivate", + // "publicRead" + // ], + // "enumDescriptions": [ + // "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + // "Object owner gets OWNER access, and project team owners get OWNER access.", + // "Object owner gets OWNER access, and project team owners get READER access.", + // "Object owner gets OWNER access.", + // "Object owner gets OWNER access, and project team members get access according to their roles.", + // "Object owner gets OWNER access, and allUsers get READER access." + // ], + // "location": "query", + // "type": "string" + // }, + // "ifGenerationMatch": { + // "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "kmsKeyName": { + // "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{destinationBucket}/o/{destinationObject}/compose", + // "request": { + // "$ref": "ComposeRequest" + // }, + // "response": { + // "$ref": "Object" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.objects.copy": + +type ObjectsCopyCall struct { + s *Service + sourceBucket string + sourceObject string + destinationBucket string + destinationObject string + object *Object + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Copy: Copies a source object to a destination object. Optionally +// overrides metadata. +func (r *ObjectsService) Copy(sourceBucket string, sourceObject string, destinationBucket string, destinationObject string, object *Object) *ObjectsCopyCall { + c := &ObjectsCopyCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.sourceBucket = sourceBucket + c.sourceObject = sourceObject + c.destinationBucket = destinationBucket + c.destinationObject = destinationObject + c.object = object + return c +} + +// DestinationPredefinedAcl sets the optional parameter +// "destinationPredefinedAcl": Apply a predefined set of access controls +// to the destination object. +// +// Possible values: +// "authenticatedRead" - Object owner gets OWNER access, and +// allAuthenticatedUsers get READER access. +// "bucketOwnerFullControl" - Object owner gets OWNER access, and +// project team owners get OWNER access. +// "bucketOwnerRead" - Object owner gets OWNER access, and project +// team owners get READER access. +// "private" - Object owner gets OWNER access. +// "projectPrivate" - Object owner gets OWNER access, and project team +// members get access according to their roles. +// "publicRead" - Object owner gets OWNER access, and allUsers get +// READER access. +func (c *ObjectsCopyCall) DestinationPredefinedAcl(destinationPredefinedAcl string) *ObjectsCopyCall { + c.urlParams_.Set("destinationPredefinedAcl", destinationPredefinedAcl) + return c +} + +// IfGenerationMatch sets the optional parameter "ifGenerationMatch": +// Makes the operation conditional on whether the destination object's +// current generation matches the given value. Setting to 0 makes the +// operation succeed only if there are no live versions of the object. +func (c *ObjectsCopyCall) IfGenerationMatch(ifGenerationMatch int64) *ObjectsCopyCall { + c.urlParams_.Set("ifGenerationMatch", fmt.Sprint(ifGenerationMatch)) + return c +} + +// IfGenerationNotMatch sets the optional parameter +// "ifGenerationNotMatch": Makes the operation conditional on whether +// the destination object's current generation does not match the given +// value. If no live object exists, the precondition fails. Setting to 0 +// makes the operation succeed only if there is a live version of the +// object. +func (c *ObjectsCopyCall) IfGenerationNotMatch(ifGenerationNotMatch int64) *ObjectsCopyCall { + c.urlParams_.Set("ifGenerationNotMatch", fmt.Sprint(ifGenerationNotMatch)) + return c +} + +// IfMetagenerationMatch sets the optional parameter +// "ifMetagenerationMatch": Makes the operation conditional on whether +// the destination object's current metageneration matches the given +// value. +func (c *ObjectsCopyCall) IfMetagenerationMatch(ifMetagenerationMatch int64) *ObjectsCopyCall { + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// IfMetagenerationNotMatch sets the optional parameter +// "ifMetagenerationNotMatch": Makes the operation conditional on +// whether the destination object's current metageneration does not +// match the given value. +func (c *ObjectsCopyCall) IfMetagenerationNotMatch(ifMetagenerationNotMatch int64) *ObjectsCopyCall { + c.urlParams_.Set("ifMetagenerationNotMatch", fmt.Sprint(ifMetagenerationNotMatch)) + return c +} + +// IfSourceGenerationMatch sets the optional parameter +// "ifSourceGenerationMatch": Makes the operation conditional on whether +// the source object's current generation matches the given value. +func (c *ObjectsCopyCall) IfSourceGenerationMatch(ifSourceGenerationMatch int64) *ObjectsCopyCall { + c.urlParams_.Set("ifSourceGenerationMatch", fmt.Sprint(ifSourceGenerationMatch)) + return c +} + +// IfSourceGenerationNotMatch sets the optional parameter +// "ifSourceGenerationNotMatch": Makes the operation conditional on +// whether the source object's current generation does not match the +// given value. +func (c *ObjectsCopyCall) IfSourceGenerationNotMatch(ifSourceGenerationNotMatch int64) *ObjectsCopyCall { + c.urlParams_.Set("ifSourceGenerationNotMatch", fmt.Sprint(ifSourceGenerationNotMatch)) + return c +} + +// IfSourceMetagenerationMatch sets the optional parameter +// "ifSourceMetagenerationMatch": Makes the operation conditional on +// whether the source object's current metageneration matches the given +// value. +func (c *ObjectsCopyCall) IfSourceMetagenerationMatch(ifSourceMetagenerationMatch int64) *ObjectsCopyCall { + c.urlParams_.Set("ifSourceMetagenerationMatch", fmt.Sprint(ifSourceMetagenerationMatch)) + return c +} + +// IfSourceMetagenerationNotMatch sets the optional parameter +// "ifSourceMetagenerationNotMatch": Makes the operation conditional on +// whether the source object's current metageneration does not match the +// given value. +func (c *ObjectsCopyCall) IfSourceMetagenerationNotMatch(ifSourceMetagenerationNotMatch int64) *ObjectsCopyCall { + c.urlParams_.Set("ifSourceMetagenerationNotMatch", fmt.Sprint(ifSourceMetagenerationNotMatch)) + return c +} + +// Projection sets the optional parameter "projection": Set of +// properties to return. Defaults to noAcl, unless the object resource +// specifies the acl property, when it defaults to full. +// +// Possible values: +// "full" - Include all properties. +// "noAcl" - Omit the owner, acl property. +func (c *ObjectsCopyCall) Projection(projection string) *ObjectsCopyCall { + c.urlParams_.Set("projection", projection) + return c +} + +// SourceGeneration sets the optional parameter "sourceGeneration": If +// present, selects a specific revision of the source object (as opposed +// to the latest version, the default). +func (c *ObjectsCopyCall) SourceGeneration(sourceGeneration int64) *ObjectsCopyCall { + c.urlParams_.Set("sourceGeneration", fmt.Sprint(sourceGeneration)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectsCopyCall) UserProject(userProject string) *ObjectsCopyCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectsCopyCall) Fields(s ...googleapi.Field) *ObjectsCopyCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectsCopyCall) Context(ctx context.Context) *ObjectsCopyCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectsCopyCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectsCopyCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.object) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{sourceBucket}/o/{sourceObject}/copyTo/b/{destinationBucket}/o/{destinationObject}") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("POST", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "sourceBucket": c.sourceBucket, + "sourceObject": c.sourceObject, + "destinationBucket": c.destinationBucket, + "destinationObject": c.destinationObject, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objects.copy" call. +// Exactly one of *Object or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Object.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ObjectsCopyCall) Do(opts ...googleapi.CallOption) (*Object, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Object{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Copies a source object to a destination object. Optionally overrides metadata.", + // "httpMethod": "POST", + // "id": "storage.objects.copy", + // "parameterOrder": [ + // "sourceBucket", + // "sourceObject", + // "destinationBucket", + // "destinationObject" + // ], + // "parameters": { + // "destinationBucket": { + // "description": "Name of the bucket in which to store the new object. Overrides the provided object metadata's bucket value, if any.For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "destinationObject": { + // "description": "Name of the new object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "destinationPredefinedAcl": { + // "description": "Apply a predefined set of access controls to the destination object.", + // "enum": [ + // "authenticatedRead", + // "bucketOwnerFullControl", + // "bucketOwnerRead", + // "private", + // "projectPrivate", + // "publicRead" + // ], + // "enumDescriptions": [ + // "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + // "Object owner gets OWNER access, and project team owners get OWNER access.", + // "Object owner gets OWNER access, and project team owners get READER access.", + // "Object owner gets OWNER access.", + // "Object owner gets OWNER access, and project team members get access according to their roles.", + // "Object owner gets OWNER access, and allUsers get READER access." + // ], + // "location": "query", + // "type": "string" + // }, + // "ifGenerationMatch": { + // "description": "Makes the operation conditional on whether the destination object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifGenerationNotMatch": { + // "description": "Makes the operation conditional on whether the destination object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "Makes the operation conditional on whether the destination object's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationNotMatch": { + // "description": "Makes the operation conditional on whether the destination object's current metageneration does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifSourceGenerationMatch": { + // "description": "Makes the operation conditional on whether the source object's current generation matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifSourceGenerationNotMatch": { + // "description": "Makes the operation conditional on whether the source object's current generation does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifSourceMetagenerationMatch": { + // "description": "Makes the operation conditional on whether the source object's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifSourceMetagenerationNotMatch": { + // "description": "Makes the operation conditional on whether the source object's current metageneration does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "projection": { + // "description": "Set of properties to return. Defaults to noAcl, unless the object resource specifies the acl property, when it defaults to full.", + // "enum": [ + // "full", + // "noAcl" + // ], + // "enumDescriptions": [ + // "Include all properties.", + // "Omit the owner, acl property." + // ], + // "location": "query", + // "type": "string" + // }, + // "sourceBucket": { + // "description": "Name of the bucket in which to find the source object.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "sourceGeneration": { + // "description": "If present, selects a specific revision of the source object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "sourceObject": { + // "description": "Name of the source object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{sourceBucket}/o/{sourceObject}/copyTo/b/{destinationBucket}/o/{destinationObject}", + // "request": { + // "$ref": "Object" + // }, + // "response": { + // "$ref": "Object" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.objects.delete": + +type ObjectsDeleteCall struct { + s *Service + bucket string + object string + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Delete: Deletes an object and its metadata. Deletions are permanent +// if versioning is not enabled for the bucket, or if the generation +// parameter is used. +func (r *ObjectsService) Delete(bucket string, object string) *ObjectsDeleteCall { + c := &ObjectsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + return c +} + +// Generation sets the optional parameter "generation": If present, +// permanently deletes a specific revision of this object (as opposed to +// the latest version, the default). +func (c *ObjectsDeleteCall) Generation(generation int64) *ObjectsDeleteCall { + c.urlParams_.Set("generation", fmt.Sprint(generation)) + return c +} + +// IfGenerationMatch sets the optional parameter "ifGenerationMatch": +// Makes the operation conditional on whether the object's current +// generation matches the given value. Setting to 0 makes the operation +// succeed only if there are no live versions of the object. +func (c *ObjectsDeleteCall) IfGenerationMatch(ifGenerationMatch int64) *ObjectsDeleteCall { + c.urlParams_.Set("ifGenerationMatch", fmt.Sprint(ifGenerationMatch)) + return c +} + +// IfGenerationNotMatch sets the optional parameter +// "ifGenerationNotMatch": Makes the operation conditional on whether +// the object's current generation does not match the given value. If no +// live object exists, the precondition fails. Setting to 0 makes the +// operation succeed only if there is a live version of the object. +func (c *ObjectsDeleteCall) IfGenerationNotMatch(ifGenerationNotMatch int64) *ObjectsDeleteCall { + c.urlParams_.Set("ifGenerationNotMatch", fmt.Sprint(ifGenerationNotMatch)) + return c +} + +// IfMetagenerationMatch sets the optional parameter +// "ifMetagenerationMatch": Makes the operation conditional on whether +// the object's current metageneration matches the given value. +func (c *ObjectsDeleteCall) IfMetagenerationMatch(ifMetagenerationMatch int64) *ObjectsDeleteCall { + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// IfMetagenerationNotMatch sets the optional parameter +// "ifMetagenerationNotMatch": Makes the operation conditional on +// whether the object's current metageneration does not match the given +// value. +func (c *ObjectsDeleteCall) IfMetagenerationNotMatch(ifMetagenerationNotMatch int64) *ObjectsDeleteCall { + c.urlParams_.Set("ifMetagenerationNotMatch", fmt.Sprint(ifMetagenerationNotMatch)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectsDeleteCall) UserProject(userProject string) *ObjectsDeleteCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectsDeleteCall) Fields(s ...googleapi.Field) *ObjectsDeleteCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectsDeleteCall) Context(ctx context.Context) *ObjectsDeleteCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectsDeleteCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectsDeleteCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/{object}") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("DELETE", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "object": c.object, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objects.delete" call. +func (c *ObjectsDeleteCall) Do(opts ...googleapi.CallOption) error { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if err != nil { + return err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return err + } + return nil + // { + // "description": "Deletes an object and its metadata. Deletions are permanent if versioning is not enabled for the bucket, or if the generation parameter is used.", + // "httpMethod": "DELETE", + // "id": "storage.objects.delete", + // "parameterOrder": [ + // "bucket", + // "object" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of the bucket in which the object resides.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "generation": { + // "description": "If present, permanently deletes a specific revision of this object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifGenerationMatch": { + // "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifGenerationNotMatch": { + // "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationNotMatch": { + // "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "object": { + // "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o/{object}", + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.objects.get": + +type ObjectsGetCall struct { + s *Service + bucket string + object string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// Get: Retrieves an object or its metadata. +func (r *ObjectsService) Get(bucket string, object string) *ObjectsGetCall { + c := &ObjectsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + return c +} + +// Generation sets the optional parameter "generation": If present, +// selects a specific revision of this object (as opposed to the latest +// version, the default). +func (c *ObjectsGetCall) Generation(generation int64) *ObjectsGetCall { + c.urlParams_.Set("generation", fmt.Sprint(generation)) + return c +} + +// IfGenerationMatch sets the optional parameter "ifGenerationMatch": +// Makes the operation conditional on whether the object's current +// generation matches the given value. Setting to 0 makes the operation +// succeed only if there are no live versions of the object. +func (c *ObjectsGetCall) IfGenerationMatch(ifGenerationMatch int64) *ObjectsGetCall { + c.urlParams_.Set("ifGenerationMatch", fmt.Sprint(ifGenerationMatch)) + return c +} + +// IfGenerationNotMatch sets the optional parameter +// "ifGenerationNotMatch": Makes the operation conditional on whether +// the object's current generation does not match the given value. If no +// live object exists, the precondition fails. Setting to 0 makes the +// operation succeed only if there is a live version of the object. +func (c *ObjectsGetCall) IfGenerationNotMatch(ifGenerationNotMatch int64) *ObjectsGetCall { + c.urlParams_.Set("ifGenerationNotMatch", fmt.Sprint(ifGenerationNotMatch)) + return c +} + +// IfMetagenerationMatch sets the optional parameter +// "ifMetagenerationMatch": Makes the operation conditional on whether +// the object's current metageneration matches the given value. +func (c *ObjectsGetCall) IfMetagenerationMatch(ifMetagenerationMatch int64) *ObjectsGetCall { + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// IfMetagenerationNotMatch sets the optional parameter +// "ifMetagenerationNotMatch": Makes the operation conditional on +// whether the object's current metageneration does not match the given +// value. +func (c *ObjectsGetCall) IfMetagenerationNotMatch(ifMetagenerationNotMatch int64) *ObjectsGetCall { + c.urlParams_.Set("ifMetagenerationNotMatch", fmt.Sprint(ifMetagenerationNotMatch)) + return c +} + +// Projection sets the optional parameter "projection": Set of +// properties to return. Defaults to noAcl. +// +// Possible values: +// "full" - Include all properties. +// "noAcl" - Omit the owner, acl property. +func (c *ObjectsGetCall) Projection(projection string) *ObjectsGetCall { + c.urlParams_.Set("projection", projection) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectsGetCall) UserProject(userProject string) *ObjectsGetCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectsGetCall) Fields(s ...googleapi.Field) *ObjectsGetCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ObjectsGetCall) IfNoneMatch(entityTag string) *ObjectsGetCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do and Download +// methods. Any pending HTTP request will be aborted if the provided +// context is canceled. +func (c *ObjectsGetCall) Context(ctx context.Context) *ObjectsGetCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectsGetCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectsGetCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/{object}") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("GET", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "object": c.object, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Download fetches the API endpoint's "media" value, instead of the normal +// API response value. If the returned error is nil, the Response is guaranteed to +// have a 2xx status code. Callers must close the Response.Body as usual. +func (c *ObjectsGetCall) Download(opts ...googleapi.CallOption) (*http.Response, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("media") + if err != nil { + return nil, err + } + if err := googleapi.CheckMediaResponse(res); err != nil { + res.Body.Close() + return nil, err + } + return res, nil +} + +// Do executes the "storage.objects.get" call. +// Exactly one of *Object or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Object.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ObjectsGetCall) Do(opts ...googleapi.CallOption) (*Object, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Object{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Retrieves an object or its metadata.", + // "httpMethod": "GET", + // "id": "storage.objects.get", + // "parameterOrder": [ + // "bucket", + // "object" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of the bucket in which the object resides.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "generation": { + // "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifGenerationMatch": { + // "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifGenerationNotMatch": { + // "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationNotMatch": { + // "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "object": { + // "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "projection": { + // "description": "Set of properties to return. Defaults to noAcl.", + // "enum": [ + // "full", + // "noAcl" + // ], + // "enumDescriptions": [ + // "Include all properties.", + // "Omit the owner, acl property." + // ], + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o/{object}", + // "response": { + // "$ref": "Object" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_only", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ], + // "supportsMediaDownload": true, + // "useMediaDownloadService": true + // } + +} + +// method id "storage.objects.getIamPolicy": + +type ObjectsGetIamPolicyCall struct { + s *Service + bucket string + object string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// GetIamPolicy: Returns an IAM policy for the specified object. +func (r *ObjectsService) GetIamPolicy(bucket string, object string) *ObjectsGetIamPolicyCall { + c := &ObjectsGetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + return c +} + +// Generation sets the optional parameter "generation": If present, +// selects a specific revision of this object (as opposed to the latest +// version, the default). +func (c *ObjectsGetIamPolicyCall) Generation(generation int64) *ObjectsGetIamPolicyCall { + c.urlParams_.Set("generation", fmt.Sprint(generation)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectsGetIamPolicyCall) UserProject(userProject string) *ObjectsGetIamPolicyCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectsGetIamPolicyCall) Fields(s ...googleapi.Field) *ObjectsGetIamPolicyCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ObjectsGetIamPolicyCall) IfNoneMatch(entityTag string) *ObjectsGetIamPolicyCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectsGetIamPolicyCall) Context(ctx context.Context) *ObjectsGetIamPolicyCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectsGetIamPolicyCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectsGetIamPolicyCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/{object}/iam") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("GET", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "object": c.object, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objects.getIamPolicy" call. +// Exactly one of *Policy or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Policy.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ObjectsGetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Policy{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Returns an IAM policy for the specified object.", + // "httpMethod": "GET", + // "id": "storage.objects.getIamPolicy", + // "parameterOrder": [ + // "bucket", + // "object" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of the bucket in which the object resides.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "generation": { + // "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "object": { + // "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o/{object}/iam", + // "response": { + // "$ref": "Policy" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_only", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.objects.insert": + +type ObjectsInsertCall struct { + s *Service + bucket string + object *Object + urlParams_ gensupport.URLParams + mediaInfo_ *gensupport.MediaInfo + ctx_ context.Context + header_ http.Header +} + +// Insert: Stores a new object and metadata. +func (r *ObjectsService) Insert(bucket string, object *Object) *ObjectsInsertCall { + c := &ObjectsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + return c +} + +// ContentEncoding sets the optional parameter "contentEncoding": If +// set, sets the contentEncoding property of the final object to this +// value. Setting this parameter is equivalent to setting the +// contentEncoding metadata property. This can be useful when uploading +// an object with uploadType=media to indicate the encoding of the +// content being uploaded. +func (c *ObjectsInsertCall) ContentEncoding(contentEncoding string) *ObjectsInsertCall { + c.urlParams_.Set("contentEncoding", contentEncoding) + return c +} + +// IfGenerationMatch sets the optional parameter "ifGenerationMatch": +// Makes the operation conditional on whether the object's current +// generation matches the given value. Setting to 0 makes the operation +// succeed only if there are no live versions of the object. +func (c *ObjectsInsertCall) IfGenerationMatch(ifGenerationMatch int64) *ObjectsInsertCall { + c.urlParams_.Set("ifGenerationMatch", fmt.Sprint(ifGenerationMatch)) + return c +} + +// IfGenerationNotMatch sets the optional parameter +// "ifGenerationNotMatch": Makes the operation conditional on whether +// the object's current generation does not match the given value. If no +// live object exists, the precondition fails. Setting to 0 makes the +// operation succeed only if there is a live version of the object. +func (c *ObjectsInsertCall) IfGenerationNotMatch(ifGenerationNotMatch int64) *ObjectsInsertCall { + c.urlParams_.Set("ifGenerationNotMatch", fmt.Sprint(ifGenerationNotMatch)) + return c +} + +// IfMetagenerationMatch sets the optional parameter +// "ifMetagenerationMatch": Makes the operation conditional on whether +// the object's current metageneration matches the given value. +func (c *ObjectsInsertCall) IfMetagenerationMatch(ifMetagenerationMatch int64) *ObjectsInsertCall { + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// IfMetagenerationNotMatch sets the optional parameter +// "ifMetagenerationNotMatch": Makes the operation conditional on +// whether the object's current metageneration does not match the given +// value. +func (c *ObjectsInsertCall) IfMetagenerationNotMatch(ifMetagenerationNotMatch int64) *ObjectsInsertCall { + c.urlParams_.Set("ifMetagenerationNotMatch", fmt.Sprint(ifMetagenerationNotMatch)) + return c +} + +// KmsKeyName sets the optional parameter "kmsKeyName": Resource name of +// the Cloud KMS key, of the form +// projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, +// that will be used to encrypt the object. Overrides the object +// metadata's kms_key_name value, if any. Limited availability; usable +// only by enabled projects. +func (c *ObjectsInsertCall) KmsKeyName(kmsKeyName string) *ObjectsInsertCall { + c.urlParams_.Set("kmsKeyName", kmsKeyName) + return c +} + +// Name sets the optional parameter "name": Name of the object. Required +// when the object metadata is not otherwise provided. Overrides the +// object metadata's name value, if any. For information about how to +// URL encode object names to be path safe, see Encoding URI Path Parts. +func (c *ObjectsInsertCall) Name(name string) *ObjectsInsertCall { + c.urlParams_.Set("name", name) + return c +} + +// PredefinedAcl sets the optional parameter "predefinedAcl": Apply a +// predefined set of access controls to this object. +// +// Possible values: +// "authenticatedRead" - Object owner gets OWNER access, and +// allAuthenticatedUsers get READER access. +// "bucketOwnerFullControl" - Object owner gets OWNER access, and +// project team owners get OWNER access. +// "bucketOwnerRead" - Object owner gets OWNER access, and project +// team owners get READER access. +// "private" - Object owner gets OWNER access. +// "projectPrivate" - Object owner gets OWNER access, and project team +// members get access according to their roles. +// "publicRead" - Object owner gets OWNER access, and allUsers get +// READER access. +func (c *ObjectsInsertCall) PredefinedAcl(predefinedAcl string) *ObjectsInsertCall { + c.urlParams_.Set("predefinedAcl", predefinedAcl) + return c +} + +// Projection sets the optional parameter "projection": Set of +// properties to return. Defaults to noAcl, unless the object resource +// specifies the acl property, when it defaults to full. +// +// Possible values: +// "full" - Include all properties. +// "noAcl" - Omit the owner, acl property. +func (c *ObjectsInsertCall) Projection(projection string) *ObjectsInsertCall { + c.urlParams_.Set("projection", projection) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectsInsertCall) UserProject(userProject string) *ObjectsInsertCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Media specifies the media to upload in one or more chunks. The chunk +// size may be controlled by supplying a MediaOption generated by +// googleapi.ChunkSize. The chunk size defaults to +// googleapi.DefaultUploadChunkSize.The Content-Type header used in the +// upload request will be determined by sniffing the contents of r, +// unless a MediaOption generated by googleapi.ContentType is +// supplied. +// At most one of Media and ResumableMedia may be set. +func (c *ObjectsInsertCall) Media(r io.Reader, options ...googleapi.MediaOption) *ObjectsInsertCall { + if ct := c.object.ContentType; ct != "" { + options = append([]googleapi.MediaOption{googleapi.ContentType(ct)}, options...) + } + c.mediaInfo_ = gensupport.NewInfoFromMedia(r, options) + return c +} + +// ResumableMedia specifies the media to upload in chunks and can be +// canceled with ctx. +// +// Deprecated: use Media instead. +// +// At most one of Media and ResumableMedia may be set. mediaType +// identifies the MIME media type of the upload, such as "image/png". If +// mediaType is "", it will be auto-detected. The provided ctx will +// supersede any context previously provided to the Context method. +func (c *ObjectsInsertCall) ResumableMedia(ctx context.Context, r io.ReaderAt, size int64, mediaType string) *ObjectsInsertCall { + c.ctx_ = ctx + c.mediaInfo_ = gensupport.NewInfoFromResumableMedia(r, size, mediaType) + return c +} + +// ProgressUpdater provides a callback function that will be called +// after every chunk. It should be a low-latency function in order to +// not slow down the upload operation. This should only be called when +// using ResumableMedia (as opposed to Media). +func (c *ObjectsInsertCall) ProgressUpdater(pu googleapi.ProgressUpdater) *ObjectsInsertCall { + c.mediaInfo_.SetProgressUpdater(pu) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectsInsertCall) Fields(s ...googleapi.Field) *ObjectsInsertCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +// This context will supersede any context previously provided to the +// ResumableMedia method. +func (c *ObjectsInsertCall) Context(ctx context.Context) *ObjectsInsertCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectsInsertCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectsInsertCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.object) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o") + if c.mediaInfo_ != nil { + urls = strings.Replace(urls, "https://www.googleapis.com/", "https://www.googleapis.com/upload/", 1) + c.urlParams_.Set("uploadType", c.mediaInfo_.UploadType()) + } + if body == nil { + body = new(bytes.Buffer) + reqHeaders.Set("Content-Type", "application/json") + } + body, getBody, cleanup := c.mediaInfo_.UploadRequest(reqHeaders, body) + defer cleanup() + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("POST", urls, body) + req.Header = reqHeaders + gensupport.SetGetBody(req, getBody) + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objects.insert" call. +// Exactly one of *Object or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Object.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ObjectsInsertCall) Do(opts ...googleapi.CallOption) (*Object, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + rx := c.mediaInfo_.ResumableUpload(res.Header.Get("Location")) + if rx != nil { + rx.Client = c.s.client + rx.UserAgent = c.s.userAgent() + ctx := c.ctx_ + if ctx == nil { + ctx = context.TODO() + } + res, err = rx.Upload(ctx) + if err != nil { + return nil, err + } + defer res.Body.Close() + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + } + ret := &Object{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Stores a new object and metadata.", + // "httpMethod": "POST", + // "id": "storage.objects.insert", + // "mediaUpload": { + // "accept": [ + // "*/*" + // ], + // "protocols": { + // "resumable": { + // "multipart": true, + // "path": "/resumable/upload/storage/v1/b/{bucket}/o" + // }, + // "simple": { + // "multipart": true, + // "path": "/upload/storage/v1/b/{bucket}/o" + // } + // } + // }, + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of the bucket in which to store the new object. Overrides the provided object metadata's bucket value, if any.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "contentEncoding": { + // "description": "If set, sets the contentEncoding property of the final object to this value. Setting this parameter is equivalent to setting the contentEncoding metadata property. This can be useful when uploading an object with uploadType=media to indicate the encoding of the content being uploaded.", + // "location": "query", + // "type": "string" + // }, + // "ifGenerationMatch": { + // "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifGenerationNotMatch": { + // "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationNotMatch": { + // "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "kmsKeyName": { + // "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any. Limited availability; usable only by enabled projects.", + // "location": "query", + // "type": "string" + // }, + // "name": { + // "description": "Name of the object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "query", + // "type": "string" + // }, + // "predefinedAcl": { + // "description": "Apply a predefined set of access controls to this object.", + // "enum": [ + // "authenticatedRead", + // "bucketOwnerFullControl", + // "bucketOwnerRead", + // "private", + // "projectPrivate", + // "publicRead" + // ], + // "enumDescriptions": [ + // "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + // "Object owner gets OWNER access, and project team owners get OWNER access.", + // "Object owner gets OWNER access, and project team owners get READER access.", + // "Object owner gets OWNER access.", + // "Object owner gets OWNER access, and project team members get access according to their roles.", + // "Object owner gets OWNER access, and allUsers get READER access." + // ], + // "location": "query", + // "type": "string" + // }, + // "projection": { + // "description": "Set of properties to return. Defaults to noAcl, unless the object resource specifies the acl property, when it defaults to full.", + // "enum": [ + // "full", + // "noAcl" + // ], + // "enumDescriptions": [ + // "Include all properties.", + // "Omit the owner, acl property." + // ], + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o", + // "request": { + // "$ref": "Object" + // }, + // "response": { + // "$ref": "Object" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ], + // "supportsMediaUpload": true + // } + +} + +// method id "storage.objects.list": + +type ObjectsListCall struct { + s *Service + bucket string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// List: Retrieves a list of objects matching the criteria. +func (r *ObjectsService) List(bucket string) *ObjectsListCall { + c := &ObjectsListCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + return c +} + +// Delimiter sets the optional parameter "delimiter": Returns results in +// a directory-like mode. items will contain only objects whose names, +// aside from the prefix, do not contain delimiter. Objects whose names, +// aside from the prefix, contain delimiter will have their name, +// truncated after the delimiter, returned in prefixes. Duplicate +// prefixes are omitted. +func (c *ObjectsListCall) Delimiter(delimiter string) *ObjectsListCall { + c.urlParams_.Set("delimiter", delimiter) + return c +} + +// MaxResults sets the optional parameter "maxResults": Maximum number +// of items plus prefixes to return in a single page of responses. As +// duplicate prefixes are omitted, fewer total results may be returned +// than requested. The service will use this parameter or 1,000 items, +// whichever is smaller. +func (c *ObjectsListCall) MaxResults(maxResults int64) *ObjectsListCall { + c.urlParams_.Set("maxResults", fmt.Sprint(maxResults)) + return c +} + +// PageToken sets the optional parameter "pageToken": A +// previously-returned page token representing part of the larger set of +// results to view. +func (c *ObjectsListCall) PageToken(pageToken string) *ObjectsListCall { + c.urlParams_.Set("pageToken", pageToken) + return c +} + +// Prefix sets the optional parameter "prefix": Filter results to +// objects whose names begin with this prefix. +func (c *ObjectsListCall) Prefix(prefix string) *ObjectsListCall { + c.urlParams_.Set("prefix", prefix) + return c +} + +// Projection sets the optional parameter "projection": Set of +// properties to return. Defaults to noAcl. +// +// Possible values: +// "full" - Include all properties. +// "noAcl" - Omit the owner, acl property. +func (c *ObjectsListCall) Projection(projection string) *ObjectsListCall { + c.urlParams_.Set("projection", projection) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectsListCall) UserProject(userProject string) *ObjectsListCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Versions sets the optional parameter "versions": If true, lists all +// versions of an object as distinct results. The default is false. For +// more information, see Object Versioning. +func (c *ObjectsListCall) Versions(versions bool) *ObjectsListCall { + c.urlParams_.Set("versions", fmt.Sprint(versions)) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectsListCall) Fields(s ...googleapi.Field) *ObjectsListCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ObjectsListCall) IfNoneMatch(entityTag string) *ObjectsListCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectsListCall) Context(ctx context.Context) *ObjectsListCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectsListCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectsListCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("GET", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objects.list" call. +// Exactly one of *Objects or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Objects.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ObjectsListCall) Do(opts ...googleapi.CallOption) (*Objects, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Objects{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Retrieves a list of objects matching the criteria.", + // "httpMethod": "GET", + // "id": "storage.objects.list", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of the bucket in which to look for objects.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "delimiter": { + // "description": "Returns results in a directory-like mode. items will contain only objects whose names, aside from the prefix, do not contain delimiter. Objects whose names, aside from the prefix, contain delimiter will have their name, truncated after the delimiter, returned in prefixes. Duplicate prefixes are omitted.", + // "location": "query", + // "type": "string" + // }, + // "maxResults": { + // "default": "1000", + // "description": "Maximum number of items plus prefixes to return in a single page of responses. As duplicate prefixes are omitted, fewer total results may be returned than requested. The service will use this parameter or 1,000 items, whichever is smaller.", + // "format": "uint32", + // "location": "query", + // "minimum": "0", + // "type": "integer" + // }, + // "pageToken": { + // "description": "A previously-returned page token representing part of the larger set of results to view.", + // "location": "query", + // "type": "string" + // }, + // "prefix": { + // "description": "Filter results to objects whose names begin with this prefix.", + // "location": "query", + // "type": "string" + // }, + // "projection": { + // "description": "Set of properties to return. Defaults to noAcl.", + // "enum": [ + // "full", + // "noAcl" + // ], + // "enumDescriptions": [ + // "Include all properties.", + // "Omit the owner, acl property." + // ], + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // }, + // "versions": { + // "description": "If true, lists all versions of an object as distinct results. The default is false. For more information, see Object Versioning.", + // "location": "query", + // "type": "boolean" + // } + // }, + // "path": "b/{bucket}/o", + // "response": { + // "$ref": "Objects" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_only", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ], + // "supportsSubscription": true + // } + +} + +// Pages invokes f for each page of results. +// A non-nil error returned from f will halt the iteration. +// The provided context supersedes any context provided to the Context method. +func (c *ObjectsListCall) Pages(ctx context.Context, f func(*Objects) error) error { + c.ctx_ = ctx + defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point + for { + x, err := c.Do() + if err != nil { + return err + } + if err := f(x); err != nil { + return err + } + if x.NextPageToken == "" { + return nil + } + c.PageToken(x.NextPageToken) + } +} + +// method id "storage.objects.patch": + +type ObjectsPatchCall struct { + s *Service + bucket string + object string + object2 *Object + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Patch: Patches an object's metadata. +func (r *ObjectsService) Patch(bucket string, object string, object2 *Object) *ObjectsPatchCall { + c := &ObjectsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + c.object2 = object2 + return c +} + +// Generation sets the optional parameter "generation": If present, +// selects a specific revision of this object (as opposed to the latest +// version, the default). +func (c *ObjectsPatchCall) Generation(generation int64) *ObjectsPatchCall { + c.urlParams_.Set("generation", fmt.Sprint(generation)) + return c +} + +// IfGenerationMatch sets the optional parameter "ifGenerationMatch": +// Makes the operation conditional on whether the object's current +// generation matches the given value. Setting to 0 makes the operation +// succeed only if there are no live versions of the object. +func (c *ObjectsPatchCall) IfGenerationMatch(ifGenerationMatch int64) *ObjectsPatchCall { + c.urlParams_.Set("ifGenerationMatch", fmt.Sprint(ifGenerationMatch)) + return c +} + +// IfGenerationNotMatch sets the optional parameter +// "ifGenerationNotMatch": Makes the operation conditional on whether +// the object's current generation does not match the given value. If no +// live object exists, the precondition fails. Setting to 0 makes the +// operation succeed only if there is a live version of the object. +func (c *ObjectsPatchCall) IfGenerationNotMatch(ifGenerationNotMatch int64) *ObjectsPatchCall { + c.urlParams_.Set("ifGenerationNotMatch", fmt.Sprint(ifGenerationNotMatch)) + return c +} + +// IfMetagenerationMatch sets the optional parameter +// "ifMetagenerationMatch": Makes the operation conditional on whether +// the object's current metageneration matches the given value. +func (c *ObjectsPatchCall) IfMetagenerationMatch(ifMetagenerationMatch int64) *ObjectsPatchCall { + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// IfMetagenerationNotMatch sets the optional parameter +// "ifMetagenerationNotMatch": Makes the operation conditional on +// whether the object's current metageneration does not match the given +// value. +func (c *ObjectsPatchCall) IfMetagenerationNotMatch(ifMetagenerationNotMatch int64) *ObjectsPatchCall { + c.urlParams_.Set("ifMetagenerationNotMatch", fmt.Sprint(ifMetagenerationNotMatch)) + return c +} + +// PredefinedAcl sets the optional parameter "predefinedAcl": Apply a +// predefined set of access controls to this object. +// +// Possible values: +// "authenticatedRead" - Object owner gets OWNER access, and +// allAuthenticatedUsers get READER access. +// "bucketOwnerFullControl" - Object owner gets OWNER access, and +// project team owners get OWNER access. +// "bucketOwnerRead" - Object owner gets OWNER access, and project +// team owners get READER access. +// "private" - Object owner gets OWNER access. +// "projectPrivate" - Object owner gets OWNER access, and project team +// members get access according to their roles. +// "publicRead" - Object owner gets OWNER access, and allUsers get +// READER access. +func (c *ObjectsPatchCall) PredefinedAcl(predefinedAcl string) *ObjectsPatchCall { + c.urlParams_.Set("predefinedAcl", predefinedAcl) + return c +} + +// Projection sets the optional parameter "projection": Set of +// properties to return. Defaults to full. +// +// Possible values: +// "full" - Include all properties. +// "noAcl" - Omit the owner, acl property. +func (c *ObjectsPatchCall) Projection(projection string) *ObjectsPatchCall { + c.urlParams_.Set("projection", projection) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request, for Requester Pays buckets. +func (c *ObjectsPatchCall) UserProject(userProject string) *ObjectsPatchCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectsPatchCall) Fields(s ...googleapi.Field) *ObjectsPatchCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectsPatchCall) Context(ctx context.Context) *ObjectsPatchCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectsPatchCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectsPatchCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.object2) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/{object}") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("PATCH", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "object": c.object, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objects.patch" call. +// Exactly one of *Object or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Object.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ObjectsPatchCall) Do(opts ...googleapi.CallOption) (*Object, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Object{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Patches an object's metadata.", + // "httpMethod": "PATCH", + // "id": "storage.objects.patch", + // "parameterOrder": [ + // "bucket", + // "object" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of the bucket in which the object resides.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "generation": { + // "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifGenerationMatch": { + // "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifGenerationNotMatch": { + // "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationNotMatch": { + // "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "object": { + // "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "predefinedAcl": { + // "description": "Apply a predefined set of access controls to this object.", + // "enum": [ + // "authenticatedRead", + // "bucketOwnerFullControl", + // "bucketOwnerRead", + // "private", + // "projectPrivate", + // "publicRead" + // ], + // "enumDescriptions": [ + // "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + // "Object owner gets OWNER access, and project team owners get OWNER access.", + // "Object owner gets OWNER access, and project team owners get READER access.", + // "Object owner gets OWNER access.", + // "Object owner gets OWNER access, and project team members get access according to their roles.", + // "Object owner gets OWNER access, and allUsers get READER access." + // ], + // "location": "query", + // "type": "string" + // }, + // "projection": { + // "description": "Set of properties to return. Defaults to full.", + // "enum": [ + // "full", + // "noAcl" + // ], + // "enumDescriptions": [ + // "Include all properties.", + // "Omit the owner, acl property." + // ], + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request, for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o/{object}", + // "request": { + // "$ref": "Object" + // }, + // "response": { + // "$ref": "Object" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.objects.rewrite": + +type ObjectsRewriteCall struct { + s *Service + sourceBucket string + sourceObject string + destinationBucket string + destinationObject string + object *Object + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Rewrite: Rewrites a source object to a destination object. Optionally +// overrides metadata. +func (r *ObjectsService) Rewrite(sourceBucket string, sourceObject string, destinationBucket string, destinationObject string, object *Object) *ObjectsRewriteCall { + c := &ObjectsRewriteCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.sourceBucket = sourceBucket + c.sourceObject = sourceObject + c.destinationBucket = destinationBucket + c.destinationObject = destinationObject + c.object = object + return c +} + +// DestinationKmsKeyName sets the optional parameter +// "destinationKmsKeyName": Resource name of the Cloud KMS key, of the +// form +// projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, +// that will be used to encrypt the object. Overrides the object +// metadata's kms_key_name value, if any. +func (c *ObjectsRewriteCall) DestinationKmsKeyName(destinationKmsKeyName string) *ObjectsRewriteCall { + c.urlParams_.Set("destinationKmsKeyName", destinationKmsKeyName) + return c +} + +// DestinationPredefinedAcl sets the optional parameter +// "destinationPredefinedAcl": Apply a predefined set of access controls +// to the destination object. +// +// Possible values: +// "authenticatedRead" - Object owner gets OWNER access, and +// allAuthenticatedUsers get READER access. +// "bucketOwnerFullControl" - Object owner gets OWNER access, and +// project team owners get OWNER access. +// "bucketOwnerRead" - Object owner gets OWNER access, and project +// team owners get READER access. +// "private" - Object owner gets OWNER access. +// "projectPrivate" - Object owner gets OWNER access, and project team +// members get access according to their roles. +// "publicRead" - Object owner gets OWNER access, and allUsers get +// READER access. +func (c *ObjectsRewriteCall) DestinationPredefinedAcl(destinationPredefinedAcl string) *ObjectsRewriteCall { + c.urlParams_.Set("destinationPredefinedAcl", destinationPredefinedAcl) + return c +} + +// IfGenerationMatch sets the optional parameter "ifGenerationMatch": +// Makes the operation conditional on whether the object's current +// generation matches the given value. Setting to 0 makes the operation +// succeed only if there are no live versions of the object. +func (c *ObjectsRewriteCall) IfGenerationMatch(ifGenerationMatch int64) *ObjectsRewriteCall { + c.urlParams_.Set("ifGenerationMatch", fmt.Sprint(ifGenerationMatch)) + return c +} + +// IfGenerationNotMatch sets the optional parameter +// "ifGenerationNotMatch": Makes the operation conditional on whether +// the object's current generation does not match the given value. If no +// live object exists, the precondition fails. Setting to 0 makes the +// operation succeed only if there is a live version of the object. +func (c *ObjectsRewriteCall) IfGenerationNotMatch(ifGenerationNotMatch int64) *ObjectsRewriteCall { + c.urlParams_.Set("ifGenerationNotMatch", fmt.Sprint(ifGenerationNotMatch)) + return c +} + +// IfMetagenerationMatch sets the optional parameter +// "ifMetagenerationMatch": Makes the operation conditional on whether +// the destination object's current metageneration matches the given +// value. +func (c *ObjectsRewriteCall) IfMetagenerationMatch(ifMetagenerationMatch int64) *ObjectsRewriteCall { + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// IfMetagenerationNotMatch sets the optional parameter +// "ifMetagenerationNotMatch": Makes the operation conditional on +// whether the destination object's current metageneration does not +// match the given value. +func (c *ObjectsRewriteCall) IfMetagenerationNotMatch(ifMetagenerationNotMatch int64) *ObjectsRewriteCall { + c.urlParams_.Set("ifMetagenerationNotMatch", fmt.Sprint(ifMetagenerationNotMatch)) + return c +} + +// IfSourceGenerationMatch sets the optional parameter +// "ifSourceGenerationMatch": Makes the operation conditional on whether +// the source object's current generation matches the given value. +func (c *ObjectsRewriteCall) IfSourceGenerationMatch(ifSourceGenerationMatch int64) *ObjectsRewriteCall { + c.urlParams_.Set("ifSourceGenerationMatch", fmt.Sprint(ifSourceGenerationMatch)) + return c +} + +// IfSourceGenerationNotMatch sets the optional parameter +// "ifSourceGenerationNotMatch": Makes the operation conditional on +// whether the source object's current generation does not match the +// given value. +func (c *ObjectsRewriteCall) IfSourceGenerationNotMatch(ifSourceGenerationNotMatch int64) *ObjectsRewriteCall { + c.urlParams_.Set("ifSourceGenerationNotMatch", fmt.Sprint(ifSourceGenerationNotMatch)) + return c +} + +// IfSourceMetagenerationMatch sets the optional parameter +// "ifSourceMetagenerationMatch": Makes the operation conditional on +// whether the source object's current metageneration matches the given +// value. +func (c *ObjectsRewriteCall) IfSourceMetagenerationMatch(ifSourceMetagenerationMatch int64) *ObjectsRewriteCall { + c.urlParams_.Set("ifSourceMetagenerationMatch", fmt.Sprint(ifSourceMetagenerationMatch)) + return c +} + +// IfSourceMetagenerationNotMatch sets the optional parameter +// "ifSourceMetagenerationNotMatch": Makes the operation conditional on +// whether the source object's current metageneration does not match the +// given value. +func (c *ObjectsRewriteCall) IfSourceMetagenerationNotMatch(ifSourceMetagenerationNotMatch int64) *ObjectsRewriteCall { + c.urlParams_.Set("ifSourceMetagenerationNotMatch", fmt.Sprint(ifSourceMetagenerationNotMatch)) + return c +} + +// MaxBytesRewrittenPerCall sets the optional parameter +// "maxBytesRewrittenPerCall": The maximum number of bytes that will be +// rewritten per rewrite request. Most callers shouldn't need to specify +// this parameter - it is primarily in place to support testing. If +// specified the value must be an integral multiple of 1 MiB (1048576). +// Also, this only applies to requests where the source and destination +// span locations and/or storage classes. Finally, this value must not +// change across rewrite calls else you'll get an error that the +// rewriteToken is invalid. +func (c *ObjectsRewriteCall) MaxBytesRewrittenPerCall(maxBytesRewrittenPerCall int64) *ObjectsRewriteCall { + c.urlParams_.Set("maxBytesRewrittenPerCall", fmt.Sprint(maxBytesRewrittenPerCall)) + return c +} + +// Projection sets the optional parameter "projection": Set of +// properties to return. Defaults to noAcl, unless the object resource +// specifies the acl property, when it defaults to full. +// +// Possible values: +// "full" - Include all properties. +// "noAcl" - Omit the owner, acl property. +func (c *ObjectsRewriteCall) Projection(projection string) *ObjectsRewriteCall { + c.urlParams_.Set("projection", projection) + return c +} + +// RewriteToken sets the optional parameter "rewriteToken": Include this +// field (from the previous rewrite response) on each rewrite request +// after the first one, until the rewrite response 'done' flag is true. +// Calls that provide a rewriteToken can omit all other request fields, +// but if included those fields must match the values provided in the +// first rewrite request. +func (c *ObjectsRewriteCall) RewriteToken(rewriteToken string) *ObjectsRewriteCall { + c.urlParams_.Set("rewriteToken", rewriteToken) + return c +} + +// SourceGeneration sets the optional parameter "sourceGeneration": If +// present, selects a specific revision of the source object (as opposed +// to the latest version, the default). +func (c *ObjectsRewriteCall) SourceGeneration(sourceGeneration int64) *ObjectsRewriteCall { + c.urlParams_.Set("sourceGeneration", fmt.Sprint(sourceGeneration)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectsRewriteCall) UserProject(userProject string) *ObjectsRewriteCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectsRewriteCall) Fields(s ...googleapi.Field) *ObjectsRewriteCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectsRewriteCall) Context(ctx context.Context) *ObjectsRewriteCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectsRewriteCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectsRewriteCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.object) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{sourceBucket}/o/{sourceObject}/rewriteTo/b/{destinationBucket}/o/{destinationObject}") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("POST", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "sourceBucket": c.sourceBucket, + "sourceObject": c.sourceObject, + "destinationBucket": c.destinationBucket, + "destinationObject": c.destinationObject, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objects.rewrite" call. +// Exactly one of *RewriteResponse or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *RewriteResponse.ServerResponse.Header or (if a response was returned +// at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ObjectsRewriteCall) Do(opts ...googleapi.CallOption) (*RewriteResponse, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &RewriteResponse{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Rewrites a source object to a destination object. Optionally overrides metadata.", + // "httpMethod": "POST", + // "id": "storage.objects.rewrite", + // "parameterOrder": [ + // "sourceBucket", + // "sourceObject", + // "destinationBucket", + // "destinationObject" + // ], + // "parameters": { + // "destinationBucket": { + // "description": "Name of the bucket in which to store the new object. Overrides the provided object metadata's bucket value, if any.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "destinationKmsKeyName": { + // "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", + // "location": "query", + // "type": "string" + // }, + // "destinationObject": { + // "description": "Name of the new object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "destinationPredefinedAcl": { + // "description": "Apply a predefined set of access controls to the destination object.", + // "enum": [ + // "authenticatedRead", + // "bucketOwnerFullControl", + // "bucketOwnerRead", + // "private", + // "projectPrivate", + // "publicRead" + // ], + // "enumDescriptions": [ + // "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + // "Object owner gets OWNER access, and project team owners get OWNER access.", + // "Object owner gets OWNER access, and project team owners get READER access.", + // "Object owner gets OWNER access.", + // "Object owner gets OWNER access, and project team members get access according to their roles.", + // "Object owner gets OWNER access, and allUsers get READER access." + // ], + // "location": "query", + // "type": "string" + // }, + // "ifGenerationMatch": { + // "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifGenerationNotMatch": { + // "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "Makes the operation conditional on whether the destination object's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationNotMatch": { + // "description": "Makes the operation conditional on whether the destination object's current metageneration does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifSourceGenerationMatch": { + // "description": "Makes the operation conditional on whether the source object's current generation matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifSourceGenerationNotMatch": { + // "description": "Makes the operation conditional on whether the source object's current generation does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifSourceMetagenerationMatch": { + // "description": "Makes the operation conditional on whether the source object's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifSourceMetagenerationNotMatch": { + // "description": "Makes the operation conditional on whether the source object's current metageneration does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "maxBytesRewrittenPerCall": { + // "description": "The maximum number of bytes that will be rewritten per rewrite request. Most callers shouldn't need to specify this parameter - it is primarily in place to support testing. If specified the value must be an integral multiple of 1 MiB (1048576). Also, this only applies to requests where the source and destination span locations and/or storage classes. Finally, this value must not change across rewrite calls else you'll get an error that the rewriteToken is invalid.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "projection": { + // "description": "Set of properties to return. Defaults to noAcl, unless the object resource specifies the acl property, when it defaults to full.", + // "enum": [ + // "full", + // "noAcl" + // ], + // "enumDescriptions": [ + // "Include all properties.", + // "Omit the owner, acl property." + // ], + // "location": "query", + // "type": "string" + // }, + // "rewriteToken": { + // "description": "Include this field (from the previous rewrite response) on each rewrite request after the first one, until the rewrite response 'done' flag is true. Calls that provide a rewriteToken can omit all other request fields, but if included those fields must match the values provided in the first rewrite request.", + // "location": "query", + // "type": "string" + // }, + // "sourceBucket": { + // "description": "Name of the bucket in which to find the source object.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "sourceGeneration": { + // "description": "If present, selects a specific revision of the source object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "sourceObject": { + // "description": "Name of the source object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{sourceBucket}/o/{sourceObject}/rewriteTo/b/{destinationBucket}/o/{destinationObject}", + // "request": { + // "$ref": "Object" + // }, + // "response": { + // "$ref": "RewriteResponse" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.objects.setIamPolicy": + +type ObjectsSetIamPolicyCall struct { + s *Service + bucket string + object string + policy *Policy + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// SetIamPolicy: Updates an IAM policy for the specified object. +func (r *ObjectsService) SetIamPolicy(bucket string, object string, policy *Policy) *ObjectsSetIamPolicyCall { + c := &ObjectsSetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + c.policy = policy + return c +} + +// Generation sets the optional parameter "generation": If present, +// selects a specific revision of this object (as opposed to the latest +// version, the default). +func (c *ObjectsSetIamPolicyCall) Generation(generation int64) *ObjectsSetIamPolicyCall { + c.urlParams_.Set("generation", fmt.Sprint(generation)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectsSetIamPolicyCall) UserProject(userProject string) *ObjectsSetIamPolicyCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectsSetIamPolicyCall) Fields(s ...googleapi.Field) *ObjectsSetIamPolicyCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectsSetIamPolicyCall) Context(ctx context.Context) *ObjectsSetIamPolicyCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectsSetIamPolicyCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectsSetIamPolicyCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.policy) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/{object}/iam") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("PUT", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "object": c.object, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objects.setIamPolicy" call. +// Exactly one of *Policy or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Policy.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ObjectsSetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Policy{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates an IAM policy for the specified object.", + // "httpMethod": "PUT", + // "id": "storage.objects.setIamPolicy", + // "parameterOrder": [ + // "bucket", + // "object" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of the bucket in which the object resides.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "generation": { + // "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "object": { + // "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o/{object}/iam", + // "request": { + // "$ref": "Policy" + // }, + // "response": { + // "$ref": "Policy" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.objects.testIamPermissions": + +type ObjectsTestIamPermissionsCall struct { + s *Service + bucket string + object string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// TestIamPermissions: Tests a set of permissions on the given object to +// see which, if any, are held by the caller. +func (r *ObjectsService) TestIamPermissions(bucket string, object string, permissions []string) *ObjectsTestIamPermissionsCall { + c := &ObjectsTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + c.urlParams_.SetMulti("permissions", append([]string{}, permissions...)) + return c +} + +// Generation sets the optional parameter "generation": If present, +// selects a specific revision of this object (as opposed to the latest +// version, the default). +func (c *ObjectsTestIamPermissionsCall) Generation(generation int64) *ObjectsTestIamPermissionsCall { + c.urlParams_.Set("generation", fmt.Sprint(generation)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectsTestIamPermissionsCall) UserProject(userProject string) *ObjectsTestIamPermissionsCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectsTestIamPermissionsCall) Fields(s ...googleapi.Field) *ObjectsTestIamPermissionsCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ObjectsTestIamPermissionsCall) IfNoneMatch(entityTag string) *ObjectsTestIamPermissionsCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectsTestIamPermissionsCall) Context(ctx context.Context) *ObjectsTestIamPermissionsCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectsTestIamPermissionsCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectsTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/{object}/iam/testPermissions") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("GET", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "object": c.object, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objects.testIamPermissions" call. +// Exactly one of *TestIamPermissionsResponse or error will be non-nil. +// Any non-2xx status code is an error. Response headers are in either +// *TestIamPermissionsResponse.ServerResponse.Header or (if a response +// was returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ObjectsTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*TestIamPermissionsResponse, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &TestIamPermissionsResponse{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Tests a set of permissions on the given object to see which, if any, are held by the caller.", + // "httpMethod": "GET", + // "id": "storage.objects.testIamPermissions", + // "parameterOrder": [ + // "bucket", + // "object", + // "permissions" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of the bucket in which the object resides.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "generation": { + // "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "object": { + // "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "permissions": { + // "description": "Permissions to test.", + // "location": "query", + // "repeated": true, + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o/{object}/iam/testPermissions", + // "response": { + // "$ref": "TestIamPermissionsResponse" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_only", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.objects.update": + +type ObjectsUpdateCall struct { + s *Service + bucket string + object string + object2 *Object + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Update: Updates an object's metadata. +func (r *ObjectsService) Update(bucket string, object string, object2 *Object) *ObjectsUpdateCall { + c := &ObjectsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + c.object2 = object2 + return c +} + +// Generation sets the optional parameter "generation": If present, +// selects a specific revision of this object (as opposed to the latest +// version, the default). +func (c *ObjectsUpdateCall) Generation(generation int64) *ObjectsUpdateCall { + c.urlParams_.Set("generation", fmt.Sprint(generation)) + return c +} + +// IfGenerationMatch sets the optional parameter "ifGenerationMatch": +// Makes the operation conditional on whether the object's current +// generation matches the given value. Setting to 0 makes the operation +// succeed only if there are no live versions of the object. +func (c *ObjectsUpdateCall) IfGenerationMatch(ifGenerationMatch int64) *ObjectsUpdateCall { + c.urlParams_.Set("ifGenerationMatch", fmt.Sprint(ifGenerationMatch)) + return c +} + +// IfGenerationNotMatch sets the optional parameter +// "ifGenerationNotMatch": Makes the operation conditional on whether +// the object's current generation does not match the given value. If no +// live object exists, the precondition fails. Setting to 0 makes the +// operation succeed only if there is a live version of the object. +func (c *ObjectsUpdateCall) IfGenerationNotMatch(ifGenerationNotMatch int64) *ObjectsUpdateCall { + c.urlParams_.Set("ifGenerationNotMatch", fmt.Sprint(ifGenerationNotMatch)) + return c +} + +// IfMetagenerationMatch sets the optional parameter +// "ifMetagenerationMatch": Makes the operation conditional on whether +// the object's current metageneration matches the given value. +func (c *ObjectsUpdateCall) IfMetagenerationMatch(ifMetagenerationMatch int64) *ObjectsUpdateCall { + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// IfMetagenerationNotMatch sets the optional parameter +// "ifMetagenerationNotMatch": Makes the operation conditional on +// whether the object's current metageneration does not match the given +// value. +func (c *ObjectsUpdateCall) IfMetagenerationNotMatch(ifMetagenerationNotMatch int64) *ObjectsUpdateCall { + c.urlParams_.Set("ifMetagenerationNotMatch", fmt.Sprint(ifMetagenerationNotMatch)) + return c +} + +// PredefinedAcl sets the optional parameter "predefinedAcl": Apply a +// predefined set of access controls to this object. +// +// Possible values: +// "authenticatedRead" - Object owner gets OWNER access, and +// allAuthenticatedUsers get READER access. +// "bucketOwnerFullControl" - Object owner gets OWNER access, and +// project team owners get OWNER access. +// "bucketOwnerRead" - Object owner gets OWNER access, and project +// team owners get READER access. +// "private" - Object owner gets OWNER access. +// "projectPrivate" - Object owner gets OWNER access, and project team +// members get access according to their roles. +// "publicRead" - Object owner gets OWNER access, and allUsers get +// READER access. +func (c *ObjectsUpdateCall) PredefinedAcl(predefinedAcl string) *ObjectsUpdateCall { + c.urlParams_.Set("predefinedAcl", predefinedAcl) + return c +} + +// Projection sets the optional parameter "projection": Set of +// properties to return. Defaults to full. +// +// Possible values: +// "full" - Include all properties. +// "noAcl" - Omit the owner, acl property. +func (c *ObjectsUpdateCall) Projection(projection string) *ObjectsUpdateCall { + c.urlParams_.Set("projection", projection) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectsUpdateCall) UserProject(userProject string) *ObjectsUpdateCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectsUpdateCall) Fields(s ...googleapi.Field) *ObjectsUpdateCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectsUpdateCall) Context(ctx context.Context) *ObjectsUpdateCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectsUpdateCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectsUpdateCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.object2) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/{object}") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("PUT", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "object": c.object, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objects.update" call. +// Exactly one of *Object or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Object.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ObjectsUpdateCall) Do(opts ...googleapi.CallOption) (*Object, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Object{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates an object's metadata.", + // "httpMethod": "PUT", + // "id": "storage.objects.update", + // "parameterOrder": [ + // "bucket", + // "object" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of the bucket in which the object resides.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "generation": { + // "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifGenerationMatch": { + // "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifGenerationNotMatch": { + // "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationNotMatch": { + // "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "object": { + // "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "predefinedAcl": { + // "description": "Apply a predefined set of access controls to this object.", + // "enum": [ + // "authenticatedRead", + // "bucketOwnerFullControl", + // "bucketOwnerRead", + // "private", + // "projectPrivate", + // "publicRead" + // ], + // "enumDescriptions": [ + // "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + // "Object owner gets OWNER access, and project team owners get OWNER access.", + // "Object owner gets OWNER access, and project team owners get READER access.", + // "Object owner gets OWNER access.", + // "Object owner gets OWNER access, and project team members get access according to their roles.", + // "Object owner gets OWNER access, and allUsers get READER access." + // ], + // "location": "query", + // "type": "string" + // }, + // "projection": { + // "description": "Set of properties to return. Defaults to full.", + // "enum": [ + // "full", + // "noAcl" + // ], + // "enumDescriptions": [ + // "Include all properties.", + // "Omit the owner, acl property." + // ], + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o/{object}", + // "request": { + // "$ref": "Object" + // }, + // "response": { + // "$ref": "Object" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.objects.watchAll": + +type ObjectsWatchAllCall struct { + s *Service + bucket string + channel *Channel + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// WatchAll: Watch for changes on all objects in a bucket. +func (r *ObjectsService) WatchAll(bucket string, channel *Channel) *ObjectsWatchAllCall { + c := &ObjectsWatchAllCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.channel = channel + return c +} + +// Delimiter sets the optional parameter "delimiter": Returns results in +// a directory-like mode. items will contain only objects whose names, +// aside from the prefix, do not contain delimiter. Objects whose names, +// aside from the prefix, contain delimiter will have their name, +// truncated after the delimiter, returned in prefixes. Duplicate +// prefixes are omitted. +func (c *ObjectsWatchAllCall) Delimiter(delimiter string) *ObjectsWatchAllCall { + c.urlParams_.Set("delimiter", delimiter) + return c +} + +// MaxResults sets the optional parameter "maxResults": Maximum number +// of items plus prefixes to return in a single page of responses. As +// duplicate prefixes are omitted, fewer total results may be returned +// than requested. The service will use this parameter or 1,000 items, +// whichever is smaller. +func (c *ObjectsWatchAllCall) MaxResults(maxResults int64) *ObjectsWatchAllCall { + c.urlParams_.Set("maxResults", fmt.Sprint(maxResults)) + return c +} + +// PageToken sets the optional parameter "pageToken": A +// previously-returned page token representing part of the larger set of +// results to view. +func (c *ObjectsWatchAllCall) PageToken(pageToken string) *ObjectsWatchAllCall { + c.urlParams_.Set("pageToken", pageToken) + return c +} + +// Prefix sets the optional parameter "prefix": Filter results to +// objects whose names begin with this prefix. +func (c *ObjectsWatchAllCall) Prefix(prefix string) *ObjectsWatchAllCall { + c.urlParams_.Set("prefix", prefix) + return c +} + +// Projection sets the optional parameter "projection": Set of +// properties to return. Defaults to noAcl. +// +// Possible values: +// "full" - Include all properties. +// "noAcl" - Omit the owner, acl property. +func (c *ObjectsWatchAllCall) Projection(projection string) *ObjectsWatchAllCall { + c.urlParams_.Set("projection", projection) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectsWatchAllCall) UserProject(userProject string) *ObjectsWatchAllCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Versions sets the optional parameter "versions": If true, lists all +// versions of an object as distinct results. The default is false. For +// more information, see Object Versioning. +func (c *ObjectsWatchAllCall) Versions(versions bool) *ObjectsWatchAllCall { + c.urlParams_.Set("versions", fmt.Sprint(versions)) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectsWatchAllCall) Fields(s ...googleapi.Field) *ObjectsWatchAllCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectsWatchAllCall) Context(ctx context.Context) *ObjectsWatchAllCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectsWatchAllCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectsWatchAllCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.channel) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/watch") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("POST", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objects.watchAll" call. +// Exactly one of *Channel or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Channel.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ObjectsWatchAllCall) Do(opts ...googleapi.CallOption) (*Channel, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Channel{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Watch for changes on all objects in a bucket.", + // "httpMethod": "POST", + // "id": "storage.objects.watchAll", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of the bucket in which to look for objects.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "delimiter": { + // "description": "Returns results in a directory-like mode. items will contain only objects whose names, aside from the prefix, do not contain delimiter. Objects whose names, aside from the prefix, contain delimiter will have their name, truncated after the delimiter, returned in prefixes. Duplicate prefixes are omitted.", + // "location": "query", + // "type": "string" + // }, + // "maxResults": { + // "default": "1000", + // "description": "Maximum number of items plus prefixes to return in a single page of responses. As duplicate prefixes are omitted, fewer total results may be returned than requested. The service will use this parameter or 1,000 items, whichever is smaller.", + // "format": "uint32", + // "location": "query", + // "minimum": "0", + // "type": "integer" + // }, + // "pageToken": { + // "description": "A previously-returned page token representing part of the larger set of results to view.", + // "location": "query", + // "type": "string" + // }, + // "prefix": { + // "description": "Filter results to objects whose names begin with this prefix.", + // "location": "query", + // "type": "string" + // }, + // "projection": { + // "description": "Set of properties to return. Defaults to noAcl.", + // "enum": [ + // "full", + // "noAcl" + // ], + // "enumDescriptions": [ + // "Include all properties.", + // "Omit the owner, acl property." + // ], + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // }, + // "versions": { + // "description": "If true, lists all versions of an object as distinct results. The default is false. For more information, see Object Versioning.", + // "location": "query", + // "type": "boolean" + // } + // }, + // "path": "b/{bucket}/o/watch", + // "request": { + // "$ref": "Channel", + // "parameterName": "resource" + // }, + // "response": { + // "$ref": "Channel" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_only", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ], + // "supportsSubscription": true + // } + +} + +// method id "storage.projects.serviceAccount.get": + +type ProjectsServiceAccountGetCall struct { + s *Service + projectId string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// Get: Get the email address of this project's Google Cloud Storage +// service account. +func (r *ProjectsServiceAccountService) Get(projectId string) *ProjectsServiceAccountGetCall { + c := &ProjectsServiceAccountGetCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.projectId = projectId + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. +func (c *ProjectsServiceAccountGetCall) UserProject(userProject string) *ProjectsServiceAccountGetCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ProjectsServiceAccountGetCall) Fields(s ...googleapi.Field) *ProjectsServiceAccountGetCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ProjectsServiceAccountGetCall) IfNoneMatch(entityTag string) *ProjectsServiceAccountGetCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ProjectsServiceAccountGetCall) Context(ctx context.Context) *ProjectsServiceAccountGetCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ProjectsServiceAccountGetCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ProjectsServiceAccountGetCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + urls := googleapi.ResolveRelative(c.s.BasePath, "projects/{projectId}/serviceAccount") + urls += "?" + c.urlParams_.Encode() + req, _ := http.NewRequest("GET", urls, body) + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "projectId": c.projectId, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.projects.serviceAccount.get" call. +// Exactly one of *ServiceAccount or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *ServiceAccount.ServerResponse.Header or (if a response was returned +// at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ProjectsServiceAccountGetCall) Do(opts ...googleapi.CallOption) (*ServiceAccount, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ServiceAccount{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Get the email address of this project's Google Cloud Storage service account.", + // "httpMethod": "GET", + // "id": "storage.projects.serviceAccount.get", + // "parameterOrder": [ + // "projectId" + // ], + // "parameters": { + // "projectId": { + // "description": "Project ID", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "projects/{projectId}/serviceAccount", + // "response": { + // "$ref": "ServiceAccount" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_only", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} diff --git a/vendor/vendor.json b/vendor/vendor.json index 7f7d5ae68..0ae028187 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -1568,10 +1568,10 @@ "revisionTime": "2017-07-07T17:19:04Z" }, { - "checksumSHA1": "gvrxuXnqGhfzY0O3MFbS8XhMH/k=", + "checksumSHA1": "EooPqEpEyY/7NCRwHDMWhhlkQNw=", "path": "google.golang.org/api/gensupport", - "revision": "e665075b5ff79143ba49c58fab02df9dc122afd5", - "revisionTime": "2017-07-09T10:32:00Z" + "revision": "9c79deebf7496e355d7e95d82d4af1fe4e769b2f", + "revisionTime": "2018-04-16T00:04:00Z" }, { "checksumSHA1": "yQREK/OWrz9PLljbr127+xFk6J0=", @@ -1583,6 +1583,12 @@ "path": "google.golang.org/api/googleapi/internal/uritemplates", "revision": "ff0a1ff302946b997eb1832381419d1f95143483" }, + { + "checksumSHA1": "Zpu9YB1omKr0VhFb8iycN1u+42Y=", + "path": "google.golang.org/api/storage/v1", + "revision": "9c79deebf7496e355d7e95d82d4af1fe4e769b2f", + "revisionTime": "2018-04-16T00:04:00Z" + }, { "checksumSHA1": "SSYsrizGeHQRKn/S7j5CQu86egU=", "path": "google.golang.org/appengine", diff --git a/website/source/docs/post-processors/googlecompute-import.html.md b/website/source/docs/post-processors/googlecompute-import.html.md new file mode 100644 index 000000000..8f6c4f825 --- /dev/null +++ b/website/source/docs/post-processors/googlecompute-import.html.md @@ -0,0 +1,145 @@ +--- +description: | + The Google Compute Image Import post-processor takes a compressed raw disk + image and imports it to a GCE image available to Google Compute Engine. + +layout: docs +page_title: 'Google Compute Image Import - Post-Processors' +sidebar_current: 'docs-post-processors-googlecompute-import' +--- + +# Google Compute Image Import Post-Processor + +Type: `googlecompute-import` + +The Google Compute Image Import post-processor takes a compressed raw disk +image and imports it to a GCE image available to Google Compute Engine. + +~> This post-processor is for advanced users. Please ensure you read the [GCE import documentation](https://cloud.google.com/compute/docs/images/import-existing-image) before using this post-processor. + +## How Does it Work? + +The import process operates by uploading a temporary copy of the compressed raw disk image +to a GCS bucket, and calling an import task in GCP on the raw disk file. Once completed, a +GCE image is created containing the converted virtual machine. The temporary raw disk image +copy in GCS can be discarded after the import is complete. + +Google Cloud has very specific requirements for images being imported. Please see the +[GCE import documentation](https://cloud.google.com/compute/docs/images/import-existing-image) +for details. + +## Configuration + +### Required + +- `account_file` (string) - The JSON file containing your account credentials. + +- `bucket` (string) - The name of the GCS bucket where the raw disk image + will be uploaded. + +- `image_name` (string) - The unique name of the resulting image. + +- `project_id` (string) - The project ID where the GCS bucket exists and + where the GCE image is stored. + +### Optional + +- `gcs_object_name` (string) - The name of the GCS object in `bucket` where the RAW disk image will be copied for import. Defaults to "packer-import-{{timestamp}}.tar.gz". + +- `image_description` (string) - The description of the resulting image. + +- `image_family` (string) - The name of the image family to which the resulting image belongs. + +- `image_labels` (object of key/value strings) - Key/value pair labels to apply to the created image. + +- `keep_input_artifact` (boolean) - if true, do not delete the compressed RAW disk image. Defaults to false. + + +## Basic Example + +Here is a basic example. This assumes that the builder has produced an compressed +raw disk image artifact for us to work with, and that the GCS bucket has been created. + +``` json +{ + "type": "googlecompute-import", + "account_file": "account.json", + "project_id": "my-project", + "bucket": "my-bucket", + "image_name": "my-gce-image" +} + +``` + +## QEMU Builder Example + +Here is a complete example for building a Fedora 28 server GCE image. For this example +packer was run from a CentOS 7 server with KVM installed. The CentOS 7 server was running +in GCE with the nested hypervisor feature enabled. + +``` +$ packer build -var serial=$(tty) build.json +``` + +``` json +{ + "variables": { + "serial": "" + }, + "builders": [ + { + "type": "qemu", + "accelerator": "kvm", + "communicator": "none", + "boot_command": [" console=ttyS0,115200n8 inst.text inst.ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/fedora-28-ks.cfg rd.live.check=0"], + "disk_size": "15000", + "format": "raw", + "iso_checksum_type": "sha256", + "iso_checksum": "ea1efdc692356b3346326f82e2f468903e8da59324fdee8b10eac4fea83f23fe", + "iso_url": "https://download-ib01.fedoraproject.org/pub/fedora/linux/releases/28/Server/x86_64/iso/Fedora-Server-netinst-x86_64-28-1.1.iso", + "headless": "true", + "http_directory": "http", + "http_port_max": "10089", + "http_port_min": "10082", + "output_directory": "output", + "shutdown_timeout": "30m", + "vm_name": "disk.raw", + "qemu_binary": "/usr/libexec/qemu-kvm", + "qemuargs": [ + [ + "-m", "1024" + ], + [ + "-cpu", "host" + ], + [ + "-chardev", "tty,id=pts,path={{user `serial`}}" + ], + [ + "-device", "isa-serial,chardev=pts" + ], + [ + "-device", "virtio-net,netdev=user.0" + ] + ] + } + ], + "post-processors": [ + [ + { + "type": "compress", + "output": "output/disk.raw.tar.gz" + }, + { + "type": "googlecompute-import", + "project_id": "my-project", + "account_file": "account.json", + "bucket": "my-bucket", + "image_name": "fedora28-server-{{timestamp}}", + "image_description": "Fedora 28 Server", + "image_family": "fedora28-server" + } + ] + ] +} +``` From 8715bfbf70c1ad8a4ca21360e9bfef35dc9a363f Mon Sep 17 00:00:00 2001 From: Adam Robinson Date: Tue, 26 Jun 2018 14:06:37 -0400 Subject: [PATCH 038/220] set all tar timestamp fields to the zero date --- post-processor/compress/tar_fix_go110.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/post-processor/compress/tar_fix_go110.go b/post-processor/compress/tar_fix_go110.go index 016b6b656..be8456321 100644 --- a/post-processor/compress/tar_fix_go110.go +++ b/post-processor/compress/tar_fix_go110.go @@ -2,10 +2,16 @@ package compress -import "archive/tar" +import ( + "archive/tar" + "time" +) func setHeaderFormat(header *tar.Header) { // We have to set the Format explicitly for the googlecompute-import // post-processor. Google Cloud only allows importing GNU tar format. header.Format = tar.FormatGNU + header.AccessTime = time.Time{} + header.ModTime = time.Time{} + header.ChangeTime = time.Time{} } From 2b2c860df8190ff5de32639822745a5d9676dc47 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 28 Jun 2018 14:21:28 -0700 Subject: [PATCH 039/220] make the convert retryable in case it takes a bit to release a lock --- builder/qemu/step_convert_disk.go | 33 ++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/builder/qemu/step_convert_disk.go b/builder/qemu/step_convert_disk.go index bc5c3f3b1..299c36e65 100644 --- a/builder/qemu/step_convert_disk.go +++ b/builder/qemu/step_convert_disk.go @@ -4,7 +4,9 @@ import ( "context" "fmt" "path/filepath" + "strings" + "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" @@ -46,11 +48,32 @@ func (s *stepConvertDisk) Run(_ context.Context, state multistep.StateBag) multi ) ui.Say("Converting hard drive...") - if err := driver.QemuImg(command...); err != nil { - err := fmt.Errorf("Error converting hard drive: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt + // Retry the conversion a few times in case it takes the qemu process a + // moment to release the lock + err := common.Retry(1, 10, 10, func(_ uint) (bool, error) { + if err := driver.QemuImg(command...); err != nil { + if strings.Contains(err.Error(), `Failed to get shared "write" lock`) { + ui.Say("Error getting file lock for conversion; retrying...") + return false, nil + } + err = fmt.Errorf("Error converting hard drive: %s", err) + return true, err + } + return true, nil + }) + + if err != nil { + if err == common.RetryExhaustedError { + err = fmt.Errorf("Exhausted retries for getting file lock: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } else { + err := fmt.Errorf("Error converting hard drive: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } } if err := os.Rename(targetPath, sourcePath); err != nil { From 5952892e105087bb5872e6fb0837980a0b5d6ad6 Mon Sep 17 00:00:00 2001 From: Matthew Hooker Date: Thu, 28 Jun 2018 14:49:09 -0700 Subject: [PATCH 040/220] add back in tests on latest go, but allow it to fail. this is an important early warning sign, and I think it's good to add it back in in a way that doesn't cause the build to fail. --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 51b42a75a..7bf4fb6db 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ language: go go: - 1.9.x - 1.10.x + - master install: - make deps @@ -20,4 +21,6 @@ branches: - master matrix: + allow_failures: + - go: master fast_finish: true From eda85a4daf8801c1e26c04997913f0fdd7032202 Mon Sep 17 00:00:00 2001 From: Julien BONACHERA Date: Fri, 29 Jun 2018 19:44:56 +0200 Subject: [PATCH 041/220] scaleway: add 'bootscript' configuration parameter --- builder/scaleway/config.go | 1 + builder/scaleway/step_create_server.go | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/builder/scaleway/config.go b/builder/scaleway/config.go index d658e1dad..84b5e989e 100644 --- a/builder/scaleway/config.go +++ b/builder/scaleway/config.go @@ -29,6 +29,7 @@ type Config struct { SnapshotName string `mapstructure:"snapshot_name"` ImageName string `mapstructure:"image_name"` ServerName string `mapstructure:"server_name"` + Bootscript string `mapstructure:"bootscript"` UserAgent string ctx interpolate.Context diff --git a/builder/scaleway/step_create_server.go b/builder/scaleway/step_create_server.go index 57511d149..63350548d 100644 --- a/builder/scaleway/step_create_server.go +++ b/builder/scaleway/step_create_server.go @@ -20,9 +20,14 @@ func (s *stepCreateServer) Run(_ context.Context, state multistep.StateBag) mult c := state.Get("config").(Config) sshPubKey := state.Get("ssh_pubkey").(string) tags := []string{} + var bootscript *string ui.Say("Creating server...") + if c.Bootscript != "" { + bootscript = &c.Bootscript + } + if sshPubKey != "" { tags = []string{fmt.Sprintf("AUTHORIZED_KEY=%s", strings.TrimSpace(sshPubKey))} } @@ -33,6 +38,7 @@ func (s *stepCreateServer) Run(_ context.Context, state multistep.StateBag) mult Organization: c.Organization, CommercialType: c.CommercialType, Tags: tags, + Bootscript: bootscript, }) if err != nil { From 3ea887a9a7952c23a90c918f4d94bd7ab220036a Mon Sep 17 00:00:00 2001 From: Julien BONACHERA Date: Fri, 29 Jun 2018 22:00:44 +0200 Subject: [PATCH 042/220] scaleway: mention new 'bootscript' parameter in documentation --- website/source/docs/builders/scaleway.html.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/website/source/docs/builders/scaleway.html.md b/website/source/docs/builders/scaleway.html.md index 1a525dbfa..bcef9f900 100644 --- a/website/source/docs/builders/scaleway.html.md +++ b/website/source/docs/builders/scaleway.html.md @@ -74,6 +74,9 @@ builder. - `snapshot_name` (string) - The name of the resulting snapshot that will appear in your account. Default `packer-TIMESTAMP` +- `bootscript` (string) - The id of an existing bootscript to use when booting + the server. + ## Basic Example Here is a basic example. It is completely valid as soon as you enter your own From d9b69249864bf4771166bd0ef87bd15e2de9233e Mon Sep 17 00:00:00 2001 From: Conrad Jones Date: Sat, 30 Jun 2018 16:31:42 +0100 Subject: [PATCH 043/220] Add cloneType to fusion driver --- builder/vmware/common/driver_fusion6.go | 10 +++++++++- builder/vmware/common/driver_player6.go | 9 ++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/builder/vmware/common/driver_fusion6.go b/builder/vmware/common/driver_fusion6.go index 9e84ce3db..ff5e9d73e 100644 --- a/builder/vmware/common/driver_fusion6.go +++ b/builder/vmware/common/driver_fusion6.go @@ -19,10 +19,18 @@ type Fusion6Driver struct { } func (d *Fusion6Driver) Clone(dst, src string, linked bool) error { + + var cloneType string + if linked { + cloneType = "linked" + } else { + cloneType = "full" + } + cmd := exec.Command(d.vmrunPath(), "-T", "fusion", "clone", src, dst, - "full") + cloneType) if _, _, err := runAndLog(cmd); err != nil { if strings.Contains(err.Error(), "parameters was invalid") { return fmt.Errorf( diff --git a/builder/vmware/common/driver_player6.go b/builder/vmware/common/driver_player6.go index f0d57e51d..d121f02bc 100644 --- a/builder/vmware/common/driver_player6.go +++ b/builder/vmware/common/driver_player6.go @@ -16,10 +16,17 @@ type Player6Driver struct { func (d *Player6Driver) Clone(dst, src string, linked bool) error { // TODO(rasa) check if running player+, not just player + var cloneType string + if linked { + cloneType = "linked" + } else { + cloneType = "full" + } + cmd := exec.Command(d.Player5Driver.VmrunPath, "-T", "ws", "clone", src, dst, - "full") + cloneType) if _, _, err := runAndLog(cmd); err != nil { return err From fff72780e1c19b4b12e2e7a261fbca1b35b6a8c2 Mon Sep 17 00:00:00 2001 From: DanHam Date: Sun, 27 May 2018 10:43:01 +0100 Subject: [PATCH 044/220] Further simplify enumeration of attached disks for VMware VMX builder * Collate separate regexp's into one for greater efficiency * Inline function and remove unnecessary struct and variables --- builder/vmware/vmx/step_clone_vmx.go | 79 ++++++++-------------------- 1 file changed, 23 insertions(+), 56 deletions(-) diff --git a/builder/vmware/vmx/step_clone_vmx.go b/builder/vmware/vmx/step_clone_vmx.go index 9eebc0096..76f328bd7 100644 --- a/builder/vmware/vmx/step_clone_vmx.go +++ b/builder/vmware/vmx/step_clone_vmx.go @@ -19,42 +19,6 @@ type StepCloneVMX struct { VMName string } -type vmxAdapter struct { - diskPathKeyRe string -} - -var ( - // The VMX file stores the path to a configured disk, and information - // about that disks attachment to a virtual adapter/controller, as a - // key/value pair. - // For a virtual disk attached to bus ID 3 of the virtual machines - // first SCSI adapter the key/value pair would look something like: - // scsi0:3.fileName = "relative/path/to/scsiDisk.vmdk" - // The supported adapter types and configuration maximums for each type - // vary according to the VMware platform type and version, and the - // Virtual Machine Hardware version used. See the 'Virtual Machine - // Maximums' section within VMware's 'Configuration Maximums' - // documentation for each platform: - // https://kb.vmware.com/s/article/1003497 - // Information about the supported Virtual Machine Hardware versions: - // https://kb.vmware.com/s/article/1003746 - // The following regexp's are used to match all possible disk attachment - // points that may be found in the VMX file across all VMware - // platforms/versions and Virtual Machine Hardware versions - scsiAdapter = vmxAdapter{ - diskPathKeyRe: `(?i)^scsi[[:digit:]]:[[:digit:]]{1,2}\.fileName`, - } - sataAdapter = vmxAdapter{ - diskPathKeyRe: `(?i)^sata[[:digit:]]:[[:digit:]]{1,2}\.fileName`, - } - nvmeAdapter = vmxAdapter{ - diskPathKeyRe: `(?i)^nvme[[:digit:]]:[[:digit:]]{1,2}\.fileName`, - } - ideAdapter = vmxAdapter{ - diskPathKeyRe: `(?i)^ide[[:digit:]]:[[:digit:]]\.fileName`, - } -) - func (s *StepCloneVMX) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(vmwcommon.Driver) ui := state.Get("ui").(packer.Ui) @@ -81,16 +45,30 @@ func (s *StepCloneVMX) Run(_ context.Context, state multistep.StateBag) multiste return multistep.ActionHalt } - // Search across all adapter types to get the filenames of attached disks - allDiskAdapters := []vmxAdapter{ - scsiAdapter, - sataAdapter, - nvmeAdapter, - ideAdapter, - } var diskFilenames []string - for _, adapter := range allDiskAdapters { - diskFilenames = append(diskFilenames, getAttachedDisks(adapter, vmxData)...) + // The VMX file stores the path to a configured disk, and information + // about that disks attachment to a virtual adapter/controller, as a + // key/value pair. + // For a virtual disk attached to bus ID 3 of the virtual machines + // first SCSI adapter the key/value pair would look something like: + // scsi0:3.fileName = "relative/path/to/scsiDisk.vmdk" + // The supported adapter types and configuration maximums for each type + // vary according to the VMware platform type and version, and the + // Virtual Machine Hardware version used. See the 'Virtual Machine + // Maximums' section within VMware's 'Configuration Maximums' + // documentation for each platform: + // https://kb.vmware.com/s/article/1003497 + // Information about the supported Virtual Machine Hardware versions: + // https://kb.vmware.com/s/article/1003746 + // The following regexp is used to match all possible disk attachment + // points that may be found in the VMX file across all VMware + // platforms/versions and Virtual Machine Hardware versions + diskPathKeyRe := regexp.MustCompile(`(?i)^(scsi|sata|ide|nvme)[[:digit:]]:[[:digit:]]{1,2}\.fileName`) + for k, v := range vmxData { + match := diskPathKeyRe.FindString(k) + if match != "" && filepath.Ext(v) == ".vmdk" { + diskFilenames = append(diskFilenames, v) + } } // Write out the relative, host filesystem paths to the disks @@ -126,14 +104,3 @@ func (s *StepCloneVMX) Run(_ context.Context, state multistep.StateBag) multiste func (s *StepCloneVMX) Cleanup(state multistep.StateBag) { } - -func getAttachedDisks(a vmxAdapter, data map[string]string) (attachedDisks []string) { - pathKeyRe := regexp.MustCompile(a.diskPathKeyRe) - for k, v := range data { - match := pathKeyRe.FindString(k) - if match != "" && filepath.Ext(v) == ".vmdk" { - attachedDisks = append(attachedDisks, v) - } - } - return -} From b1639a782b0931d641db0afa21523bb3f9e966e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thor=20K=2E=20H=C3=B8g=C3=A5s?= Date: Mon, 2 Jul 2018 10:17:24 +0200 Subject: [PATCH 045/220] Highlight which user Ansible provisioner uses SSIA. --- website/source/docs/provisioners/ansible.html.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/website/source/docs/provisioners/ansible.html.md b/website/source/docs/provisioners/ansible.html.md index b20e53bbf..cac00ab60 100644 --- a/website/source/docs/provisioners/ansible.html.md +++ b/website/source/docs/provisioners/ansible.html.md @@ -14,9 +14,10 @@ Type: `ansible` The `ansible` Packer provisioner runs Ansible playbooks. It dynamically creates an Ansible inventory file configured to use SSH, runs an SSH server, executes `ansible-playbook`, and marshals Ansible plays through the SSH server to the -machine being provisioned by Packer. Note, this means that any `remote_user` -defined in tasks will be ignored. Packer will always connect with the user -given in the json config. +machine being provisioned by Packer. + +-> **Note:**: Any `remote_user` defined in tasks will be ignored. Packer will +always connect with the user given in the json config for this provisioner. ## Basic Example From 22e5523faa45cdfd7c2c3a1f2b9318c86d203961 Mon Sep 17 00:00:00 2001 From: Robert Neumayer Date: Mon, 2 Jul 2018 10:48:08 +0200 Subject: [PATCH 046/220] Allow instance metadata to be specified in config --- builder/oracle/oci/config.go | 3 +++ builder/oracle/oci/config_test.go | 4 ++++ builder/oracle/oci/driver_oci.go | 5 +++++ website/source/docs/builders/oracle-oci.html.md | 2 ++ 4 files changed, 14 insertions(+) diff --git a/builder/oracle/oci/config.go b/builder/oracle/oci/config.go index c82246762..16e80f2b0 100644 --- a/builder/oracle/oci/config.go +++ b/builder/oracle/oci/config.go @@ -48,6 +48,9 @@ type Config struct { // Instance InstanceName string `mapstructure:"instance_name"` + // MetaData is optional but will be constructed to include UserData or UserDataFile under the "user_data" key + MetaData map[string]string `mapstructure:"metadata"` + // UserData and UserDataFile file are both optional and mutually exclusive. UserData string `mapstructure:"user_data"` UserDataFile string `mapstructure:"user_data_file"` diff --git a/builder/oracle/oci/config_test.go b/builder/oracle/oci/config_test.go index 72491d8d0..b590bf392 100644 --- a/builder/oracle/oci/config_test.go +++ b/builder/oracle/oci/config_test.go @@ -29,6 +29,9 @@ func testConfig(accessConfFile *os.File) map[string]interface{} { // Comm "ssh_username": "opc", "use_private_ip": false, + "metadata": map[string]string{ + "key": "value", + }, } } @@ -235,6 +238,7 @@ func TestConfig(t *testing.T) { t.Errorf("Expected ConfigProvider.KeyFingerprint: %s, got %s", expected, fingerprint) } }) + } // BaseTestConfig creates the base (DEFAULT) config including a temporary key diff --git a/builder/oracle/oci/driver_oci.go b/builder/oracle/oci/driver_oci.go index 4a752c0a2..b1386b8c6 100644 --- a/builder/oracle/oci/driver_oci.go +++ b/builder/oracle/oci/driver_oci.go @@ -42,6 +42,11 @@ func (d *driverOCI) CreateInstance(ctx context.Context, publicKey string) (strin metadata := map[string]string{ "ssh_authorized_keys": publicKey, } + if d.cfg.MetaData != nil { + for key, value := range d.cfg.MetaData { + metadata[key] = value + } + } if d.cfg.UserData != "" { metadata["user_data"] = d.cfg.UserData } diff --git a/website/source/docs/builders/oracle-oci.html.md b/website/source/docs/builders/oracle-oci.html.md index 4329a56f5..b651196d1 100644 --- a/website/source/docs/builders/oracle-oci.html.md +++ b/website/source/docs/builders/oracle-oci.html.md @@ -125,6 +125,8 @@ builder. - `use_private_ip` (boolean) - Use private ip addresses to connect to the instance via ssh. + - `metadata` (map of strings) - Metadata to be injected in the build instance. + - `user_data` (string) - user_data to be used by cloud init. See [the Oracle docs](https://docs.us-phoenix-1.oraclecloud.com/api/#/en/iaas/20160918/LaunchInstanceDetails) for more details. Generally speaking, it is easier to use the `user_data_file`, but you can use this option to put either the platintext data or the base64 From c8199458a76eef9cd5b19b57deeaf410cf40cbf8 Mon Sep 17 00:00:00 2001 From: DanHam Date: Fri, 8 Jun 2018 10:49:17 +0100 Subject: [PATCH 047/220] Prevent hang on export for remote ESXi build due to empty remote_password --- builder/vmware/iso/builder.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/builder/vmware/iso/builder.go b/builder/vmware/iso/builder.go index 31a024455..0944db927 100644 --- a/builder/vmware/iso/builder.go +++ b/builder/vmware/iso/builder.go @@ -221,6 +221,11 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { fmt.Errorf("format must be one of ova, ovf, or vmx")) } + if b.config.RemoteType == "esx5" && b.config.SkipExport != true && b.config.RemotePassword == "" { + errs = packer.MultiErrorAppend(errs, + fmt.Errorf("exporting the vm (with ovftool) requires that you set a value for remote_password")) + } + // Warnings if b.config.ShutdownCommand == "" { warnings = append(warnings, From eee16262b6778ca4061a07089b8415f62f5d87a0 Mon Sep 17 00:00:00 2001 From: DanHam Date: Fri, 8 Jun 2018 11:13:32 +0100 Subject: [PATCH 048/220] Remove duplicate/redundant test --- builder/vmware/iso/builder_test.go | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/builder/vmware/iso/builder_test.go b/builder/vmware/iso/builder_test.go index b123c1ba9..4b191b2a8 100644 --- a/builder/vmware/iso/builder_test.go +++ b/builder/vmware/iso/builder_test.go @@ -177,18 +177,6 @@ func TestBuilderPrepare_RemoteType(t *testing.T) { if err != nil { t.Fatalf("should not have error: %s", err) } - - // Good - config["remote_type"] = "esx5" - config["remote_host"] = "foobar.example.com" - b = Builder{} - warns, err = b.Prepare(config) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err != nil { - t.Fatalf("should not have error: %s", err) - } } func TestBuilderPrepare_Format(t *testing.T) { From 0d9134bdbce5685b458af5f42850a5f53616ca30 Mon Sep 17 00:00:00 2001 From: DanHam Date: Fri, 8 Jun 2018 11:29:10 +0100 Subject: [PATCH 049/220] Fix existing tests as they were not doing what they should have been * Fix test to check for remote_host when remote_type is set * Fix tests by including remote_password where required --- builder/vmware/iso/builder_test.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/builder/vmware/iso/builder_test.go b/builder/vmware/iso/builder_test.go index 4b191b2a8..067e0483b 100644 --- a/builder/vmware/iso/builder_test.go +++ b/builder/vmware/iso/builder_test.go @@ -145,6 +145,7 @@ func TestBuilderPrepare_RemoteType(t *testing.T) { config["format"] = "ovf" config["remote_host"] = "foobar.example.com" + config["remote_password"] = "supersecret" // Bad config["remote_type"] = "foobar" warns, err := b.Prepare(config) @@ -155,9 +156,10 @@ func TestBuilderPrepare_RemoteType(t *testing.T) { t.Fatal("should have error") } - config["remote_host"] = "" - config["remote_type"] = "" + config["remote_type"] = "esx5" // Bad + config["remote_host"] = "" + b = Builder{} warns, err = b.Prepare(config) if len(warns) > 0 { t.Fatalf("bad: %#v", warns) @@ -169,6 +171,7 @@ func TestBuilderPrepare_RemoteType(t *testing.T) { // Good config["remote_type"] = "esx5" config["remote_host"] = "foobar.example.com" + config["remote_password"] = "supersecret" b = Builder{} warns, err = b.Prepare(config) if len(warns) > 0 { From efcdf60d96a05364dfc1074fc74c4b9995f3c1a1 Mon Sep 17 00:00:00 2001 From: DanHam Date: Sat, 9 Jun 2018 08:54:20 +0100 Subject: [PATCH 050/220] Add tests to ensure remote_password is set when exporting with ovftool --- builder/vmware/iso/builder_test.go | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/builder/vmware/iso/builder_test.go b/builder/vmware/iso/builder_test.go index 067e0483b..d1a7282a9 100644 --- a/builder/vmware/iso/builder_test.go +++ b/builder/vmware/iso/builder_test.go @@ -182,6 +182,34 @@ func TestBuilderPrepare_RemoteType(t *testing.T) { } } +func TestBuilderPrepare_RemoteExport(t *testing.T) { + var b Builder + config := testConfig() + + config["remote_type"] = "esx5" + config["remote_host"] = "foobar.example.com" + // Bad + config["remote_password"] = "" + warns, err := b.Prepare(config) + if len(warns) != 0 { + t.Fatalf("bad: %#v", warns) + } + if err == nil { + t.Fatal("should have error") + } + + // Good + config["remote_password"] = "supersecret" + b = Builder{} + warns, err = b.Prepare(config) + if len(warns) != 0 { + t.Fatalf("err: %s", err) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } +} + func TestBuilderPrepare_Format(t *testing.T) { var b Builder config := testConfig() From 939aa7e289f61ee48cc1bb3517f07f9b878a9985 Mon Sep 17 00:00:00 2001 From: DanHam Date: Mon, 2 Jul 2018 18:07:05 +0100 Subject: [PATCH 051/220] Add test: We shouldn't error when main remote options are unset --- builder/vmware/iso/builder_test.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/builder/vmware/iso/builder_test.go b/builder/vmware/iso/builder_test.go index d1a7282a9..59e18907d 100644 --- a/builder/vmware/iso/builder_test.go +++ b/builder/vmware/iso/builder_test.go @@ -168,6 +168,20 @@ func TestBuilderPrepare_RemoteType(t *testing.T) { t.Fatal("should have error") } + // Good + config["remote_type"] = "" + config["remote_host"] = "" + config["remote_password"] = "" + config["remote_private_key_file"] = "" + b = Builder{} + warns, err = b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + // Good config["remote_type"] = "esx5" config["remote_host"] = "foobar.example.com" From 66f9b64ff1a7aae4199b6b30eb2d40d20829c1e8 Mon Sep 17 00:00:00 2001 From: DanHam Date: Tue, 12 Jun 2018 14:27:08 +0100 Subject: [PATCH 052/220] Docs: Users must set remote_password when exporting the VM with ovftool --- website/source/docs/builders/vmware-iso.html.md.erb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/website/source/docs/builders/vmware-iso.html.md.erb b/website/source/docs/builders/vmware-iso.html.md.erb index 21d19c183..8e1a77415 100644 --- a/website/source/docs/builders/vmware-iso.html.md.erb +++ b/website/source/docs/builders/vmware-iso.html.md.erb @@ -540,6 +540,9 @@ modify as well: format of the exported virtual machine. This defaults to "ovf". Before using this option, you need to install `ovftool`. This option works currently only with option remote_type set to "esx5". + Since ovftool is only capable of password based authentication + `remote_password` must be set when exporting the VM. + ### VNC port discovery From 71f649456967daa72c40d50208592b489f1dee64 Mon Sep 17 00:00:00 2001 From: DanHam Date: Mon, 2 Jul 2018 18:08:55 +0100 Subject: [PATCH 053/220] Docs: Try and clarify export and export related opts only work with ESXi --- .../source/docs/builders/vmware-iso.html.md.erb | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/website/source/docs/builders/vmware-iso.html.md.erb b/website/source/docs/builders/vmware-iso.html.md.erb index 8e1a77415..ee47b5a47 100644 --- a/website/source/docs/builders/vmware-iso.html.md.erb +++ b/website/source/docs/builders/vmware-iso.html.md.erb @@ -332,8 +332,13 @@ builder. using this configuration value. Defaults to `false`. - `skip_export` (boolean) - Defaults to `false`. When enabled, Packer will - not export the VM. Useful if the build output is not the resultant image, - but created inside the VM. + not export the VM. Useful if the build output is not the resultant + image, but created inside the VM. + Currently, exporting the build VM is only supported when building on + ESXi e.g. when `remote_type` is set to `esx5`. See the [Building on a + Remote vSphere + Hypervisor](/docs/builders/vmware-iso.html#building-on-a-remote-vsphere-hypervisor) + section below for more info. - `keep_registered` (boolean) - Set this to `true` if you would like to keep the VM registered with the remote ESXi server. This is convenient if you @@ -345,6 +350,11 @@ builder. during export. Each item in the array is a new argument. The options `--noSSLVerify`, `--skipManifestCheck`, and `--targetType` are reserved, and should not be passed to this argument. + Currently, exporting the build VM (with ovftool) is only supported when + building on ESXi e.g. when `remote_type` is set to `esx5`. See the + [Building on a Remote vSphere + Hypervisor](/docs/builders/vmware-iso.html#building-on-a-remote-vsphere-hypervisor) + section below for more info. - `sound` (boolean) - Enable VMware's virtual soundcard device for the VM. @@ -539,7 +549,7 @@ modify as well: - `format` (string) - Either "ovf", "ova" or "vmx", this specifies the output format of the exported virtual machine. This defaults to "ovf". Before using this option, you need to install `ovftool`. This option - works currently only with option remote_type set to "esx5". + currently only works when option remote_type is set to "esx5". Since ovftool is only capable of password based authentication `remote_password` must be set when exporting the VM. From dde6805ee8f1688316b1f71ea1ed9d97ce072691 Mon Sep 17 00:00:00 2001 From: Matthew Hooker Date: Mon, 2 Jul 2018 13:57:11 -0700 Subject: [PATCH 054/220] ignore empty top-level config keys when vetting fix --- command/validate.go | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/command/validate.go b/command/validate.go index 8c0bef8e4..f31b106dd 100644 --- a/command/validate.go +++ b/command/validate.go @@ -84,12 +84,21 @@ func (c *ValidateCommand) Run(args []string) int { } // Check if any of the configuration is fixable - var templateData map[string]interface{} - json.Unmarshal(tpl.RawContents, &templateData) + var rawTemplateData map[string]interface{} input := make(map[string]interface{}) - for k, v := range templateData { - input[k] = v + templateData := make(map[string]interface{}) + json.Unmarshal(tpl.RawContents, &rawTemplateData) + for k, v := range rawTemplateData { + if vals, ok := v.([]interface{}); ok { + if len(vals) == 0 { + continue + } + } + templateData[strings.ToLower(k)] = v + input[strings.ToLower(k)] = v } + + // fix rawTemplateData into input for _, name := range fix.FixerOrder { var err error fixer, ok := fix.Fixers[name] @@ -98,7 +107,7 @@ func (c *ValidateCommand) Run(args []string) int { } input, err = fixer.Fix(input) if err != nil { - c.Ui.Error(fmt.Sprintf("Error fixing: %s", err)) + c.Ui.Error(fmt.Sprintf("Error checking against fixers: %s", err)) return 1 } } @@ -113,10 +122,12 @@ func (c *ValidateCommand) Run(args []string) int { delete(input, k) } } - // Guaranteed to be valid json, so we can ignore errors + // marshal/unmarshal to make comparable to templateData var fixedData map[string]interface{} + // Guaranteed to be valid json, so we can ignore errors j, _ := json.Marshal(input) json.Unmarshal(j, &fixedData) + if diff := cmp.Diff(templateData, fixedData); diff != "" { c.Ui.Say("[warning] Fixable configuration found.") c.Ui.Say("You may need to run `packer fix` to get your build to run") From d8b229b59a3910e52b3e5094f7dba6be50dc6093 Mon Sep 17 00:00:00 2001 From: Sean Malloy Date: Mon, 2 Jul 2018 21:44:30 -0500 Subject: [PATCH 055/220] Add feature to googlecompute-import post-processor to delete GCS files New skip_clean config option added to control deleting import tar files from GCS bucket. Defaults to false meaning by default delete import tar files from the GCS bucket. --- .../googlecompute-import/post-processor.go | 41 +++++++++++++++++++ .../googlecompute-import.html.md | 2 + 2 files changed, 43 insertions(+) diff --git a/post-processor/googlecompute-import/post-processor.go b/post-processor/googlecompute-import/post-processor.go index a043a8ade..3e773cbda 100644 --- a/post-processor/googlecompute-import/post-processor.go +++ b/post-processor/googlecompute-import/post-processor.go @@ -34,6 +34,7 @@ type Config struct { ProjectId string `mapstructure:"project_id"` AccountFile string `mapstructure:"account_file"` KeepOriginalImage bool `mapstructure:"keep_input_artifact"` + SkipClean bool `mapstructure:"skip_clean"` ctx interpolate.Context } @@ -115,6 +116,13 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac return nil, p.config.KeepOriginalImage, err } + if !p.config.SkipClean { + err = DeleteFromBucket(p.config.AccountFile, ui, p.config.Bucket, p.config.GCSObjectName) + if err != nil { + return nil, p.config.KeepOriginalImage, err + } + } + return gceImageArtifact, p.config.KeepOriginalImage, nil } @@ -233,3 +241,36 @@ func CreateGceImage(accountFile string, ui packer.Ui, project string, rawImageUR return &Artifact{paths: []string{op.TargetLink}}, nil } + +func DeleteFromBucket(accountFile string, ui packer.Ui, bucket string, gcsObjectName string) error { + var client *http.Client + var account googlecompute.AccountFile + + err := googlecompute.ProcessAccountFile(&account, accountFile) + if err != nil { + return err + } + + var DriverScopes = []string{"https://www.googleapis.com/auth/devstorage.full_control"} + conf := jwt.Config{ + Email: account.ClientEmail, + PrivateKey: []byte(account.PrivateKey), + Scopes: DriverScopes, + TokenURL: "https://accounts.google.com/o/oauth2/token", + } + + client = conf.Client(oauth2.NoContext) + service, err := storage.New(client) + if err != nil { + return err + } + + ui.Say(fmt.Sprintf("Deleting import source from GCS %s/%s...", bucket, gcsObjectName)) + err = service.Objects.Delete(bucket, gcsObjectName).Do() + if err != nil { + ui.Say(fmt.Sprintf("Failed to delete: %v/%v", bucket, gcsObjectName)) + return err + } + + return nil +} diff --git a/website/source/docs/post-processors/googlecompute-import.html.md b/website/source/docs/post-processors/googlecompute-import.html.md index 8f6c4f825..9281c4c5e 100644 --- a/website/source/docs/post-processors/googlecompute-import.html.md +++ b/website/source/docs/post-processors/googlecompute-import.html.md @@ -54,6 +54,8 @@ for details. - `keep_input_artifact` (boolean) - if true, do not delete the compressed RAW disk image. Defaults to false. +- `skip_clean` (boolean) - Skip removing the TAR file uploaded to the GCS bucket after the import process has completed. "true" means that we should leave it in the GCS bucket, "false" means to clean it out. Defaults to `false`. + ## Basic Example From 0c6e6ba637fe9454dd20f046170158c3e4873bce Mon Sep 17 00:00:00 2001 From: Adam Robinson Date: Tue, 3 Jul 2018 11:12:12 -0400 Subject: [PATCH 056/220] Update Ansible provisioner docs for WinRM --- .../source/docs/provisioners/ansible.html.md | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/website/source/docs/provisioners/ansible.html.md b/website/source/docs/provisioners/ansible.html.md index cac00ab60..82047070d 100644 --- a/website/source/docs/provisioners/ansible.html.md +++ b/website/source/docs/provisioners/ansible.html.md @@ -192,7 +192,8 @@ Building within a chroot (e.g. `amazon-chroot`) requires changing the Ansible co ### winrm communicator -Windows builds require a custom Ansible connection plugin and a particular configuration. Assuming a directory named `connection_plugins` is next to the playbook and contains a file named `packer.py` whose contents is +Windows builds require a custom Ansible connection plugin and a particular configuration. Assuming a directory named `connection_plugins` is next to the playbook and contains a file named `packer.py` which implements +the connection plugin. On versions of Ansible before 2.4.x, the following works as the connection plugin ``` python from __future__ import (absolute_import, division, print_function) @@ -213,6 +214,43 @@ class Connection(SSHConnection): super(Connection, self).__init__(*args, **kwargs) ``` +Newer versions of Ansible require all plugins to have a documentation string. You will need to copy +the `options` from the `DOCUMENTATION` string from the [ssh.py Ansible connection plugin](https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/connection/ssh.py) +of the Ansible version you are using and add it to packer.py similar to as follows + +``` python +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from ansible.plugins.connection.ssh import Connection as SSHConnection + +DOCUMENTATION = ''' + connection: packer + short_description: ssh based connections for powershell via packer + description: + - This connection plugin allows ansible to communicate to the target packer + machines via ssh based connections for powershell. + author: Packer + version_added: na + options: + **** Copy the options from + https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/connection/ssh.py + for the version of Ansible you are using **** +''' + +class Connection(SSHConnection): + ''' ssh based connections for powershell via packer''' + + transport = 'packer' + has_pipelining = True + become_methods = [] + allow_executable = False + module_implementation_preferences = ('.ps1', '') + + def __init__(self, *args, **kwargs): + super(Connection, self).__init__(*args, **kwargs) +``` + This template should build a Windows Server 2012 image on Google Cloud Platform: ``` json From 73c532e772c2994a1a0eb63a0572b65ee7e0f63d Mon Sep 17 00:00:00 2001 From: Brendan Devenney Date: Thu, 5 Jul 2018 16:57:54 +0100 Subject: [PATCH 057/220] Ensure amazon-private-ip fixes string values The "ssh_private_ip" key works with either boolean values or string representations of booleans. The fixer errors when the value is defined as, for example, "true" (with quotation marks). This commit will attempt to convert the string into a bool when necessary to ensure this case is handled. Signed-off-by: Brendan Devenney --- fix/fixer_amazon_private_ip.go | 9 +++++++-- fix/fixer_amazon_private_ip_test.go | 13 +++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/fix/fixer_amazon_private_ip.go b/fix/fixer_amazon_private_ip.go index 7bfce1291..7b0189ca5 100644 --- a/fix/fixer_amazon_private_ip.go +++ b/fix/fixer_amazon_private_ip.go @@ -2,6 +2,7 @@ package fix import ( "log" + "strconv" "strings" "github.com/mitchellh/mapstructure" @@ -49,8 +50,12 @@ func (FixerAmazonPrivateIP) Fix(input map[string]interface{}) (map[string]interf } privateIP, ok := privateIPi.(bool) if !ok { - log.Fatalf("Wrong type for ssh_private_ip") - continue + var err error + privateIP, err = strconv.ParseBool(privateIPi.(string)) + if err != nil { + log.Fatalf("Wrong type for ssh_private_ip") + continue + } } delete(builder, "ssh_private_ip") diff --git a/fix/fixer_amazon_private_ip_test.go b/fix/fixer_amazon_private_ip_test.go index 554584ded..71961f2f8 100644 --- a/fix/fixer_amazon_private_ip_test.go +++ b/fix/fixer_amazon_private_ip_test.go @@ -39,6 +39,19 @@ func TestFixerAmazonPrivateIP(t *testing.T) { "ssh_interface": "private_ip", }, }, + + // ssh_private_ip specified as string + { + Input: map[string]interface{}{ + "type": "amazon-ebs", + "ssh_private_ip": "true", + }, + + Expected: map[string]interface{}{ + "type": "amazon-ebs", + "ssh_interface": "private_ip", + }, + }, } for _, tc := range cases { From 5f750bfc347aa50e74555d989155084ab01e9118 Mon Sep 17 00:00:00 2001 From: Jason Moody Date: Thu, 5 Jul 2018 17:46:06 -0500 Subject: [PATCH 058/220] Update build-image.html.md Small grammar update in "A Windows Example" section of build-image.html.md. --- website/source/intro/getting-started/build-image.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/intro/getting-started/build-image.html.md b/website/source/intro/getting-started/build-image.html.md index 73a93bc7e..e65d621c1 100644 --- a/website/source/intro/getting-started/build-image.html.md +++ b/website/source/intro/getting-started/build-image.html.md @@ -338,7 +338,7 @@ customize the image. Finally, when all is done, Packer will wrap the whole customized package up into a brand new AMI that will be available from the [AWS AMI management page]( https://console.aws.amazon.com/ec2/home?region=us-east-1#s=Images). Any -instances we subsequently create from this AMI will have our all of our +instances we subsequently create from this AMI will have all of our customizations baked in. This is the core benefit we are looking to achieve from using the [Amazon EBS builder](/docs/builders/amazon-ebs.html) in this example. From 3eab3cc99bfd497d87784382edbaec01a5f5c619 Mon Sep 17 00:00:00 2001 From: DanHam Date: Mon, 2 Jul 2018 12:33:55 +0100 Subject: [PATCH 059/220] ESXi builds require we store the value of displayName in the statebag The value of displayName is needed by later steps: * When determining the IP address of the build VM * When exporting the VM using ovftool By default Packer will configure the VMX so `displayName` is equal to the value defined for `vm_name` in the build template. However, it is possible (and sometimes desirable) to set a custom value for `displayName`. Users can set a custom `displayName` through use of the `vmx_data` option in their template. --- builder/vmware/common/step_configure_vmx.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/builder/vmware/common/step_configure_vmx.go b/builder/vmware/common/step_configure_vmx.go index 102ac52ee..c3f63b2b2 100644 --- a/builder/vmware/common/step_configure_vmx.go +++ b/builder/vmware/common/step_configure_vmx.go @@ -16,6 +16,9 @@ import ( // // Uses: // vmx_path string +// +// Produces: +// display_name string - Value of the displayName key set in the VMX file type StepConfigureVMX struct { CustomData map[string]string SkipFloppy bool @@ -73,6 +76,19 @@ func (s *StepConfigureVMX) Run(_ context.Context, state multistep.StateBag) mult return multistep.ActionHalt } + // If the build is taking place on a remote ESX server, the displayName + // will be needed for discovery of the VM's IP address and for export + // of the VM. The displayName key should always be set in the VMX file, + // so error if we don't find it + if displayName, ok := vmxData["displayname"]; !ok { // Packer converts key names to lowercase! + err := fmt.Errorf("Error: Could not get value of displayName from VMX data") + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } else { + state.Put("display_name", displayName) + } + return multistep.ActionContinue } From cd7d3812ea2d23a0e7ae63ef72bd1c943fb7d21d Mon Sep 17 00:00:00 2001 From: DanHam Date: Mon, 2 Jul 2018 13:19:41 +0100 Subject: [PATCH 060/220] ESXi: Fix failure to get VM IP when `displayName` differs from `vm_name` The value in the Name field returned by 'esxcli network vm list' actually returns the VMs `displayName`. As such, we need to match against `displayName` to discover the VMs 'WorldID'. 'WorldId' is ultimately used/needed as an argument in the command that returns the VMs IP. --- builder/vmware/iso/driver_esx5.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/builder/vmware/iso/driver_esx5.go b/builder/vmware/iso/driver_esx5.go index b3eb8c078..bfeee8d24 100644 --- a/builder/vmware/iso/driver_esx5.go +++ b/builder/vmware/iso/driver_esx5.go @@ -389,7 +389,13 @@ func (d *ESX5Driver) CommHost(state multistep.StateBag) (string, error) { return "", err } - record, err := r.find("Name", config.VMName) + // The value in the Name field returned by 'esxcli network vm list' + // corresponds directly to the value of displayName set in the VMX file + var displayName string + if v, ok := state.GetOk("display_name"); ok { + displayName = v.(string) + } + record, err := r.find("Name", displayName) if err != nil { return "", err } From 902cea0f306d06cf748c64c9c1b4d8c113daedb1 Mon Sep 17 00:00:00 2001 From: DanHam Date: Mon, 2 Jul 2018 13:35:07 +0100 Subject: [PATCH 061/220] ESXi: Fix failure to export VM when `displayName` differs from `vm_name` ovftool requires we pass in `displayName` as part of the source locator string so that it can successfully determine the VM intended for export. --- builder/vmware/iso/step_export.go | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/builder/vmware/iso/step_export.go b/builder/vmware/iso/step_export.go index 50b1efd9f..c39443c8f 100644 --- a/builder/vmware/iso/step_export.go +++ b/builder/vmware/iso/step_export.go @@ -14,13 +14,17 @@ import ( "github.com/hashicorp/packer/packer" ) +// This step exports a VM built on ESXi using ovftool +// +// Uses: +// display_name string type StepExport struct { Format string SkipExport bool OutputDir string } -func (s *StepExport) generateArgs(c *Config, hidePassword bool) []string { +func (s *StepExport) generateArgs(c *Config, displayName string, hidePassword bool) []string { password := url.QueryEscape(c.RemotePassword) if hidePassword { password = "****" @@ -29,7 +33,7 @@ func (s *StepExport) generateArgs(c *Config, hidePassword bool) []string { "--noSSLVerify=true", "--skipManifestCheck", "-tt=" + s.Format, - "vi://" + c.RemoteUser + ":" + password + "@" + c.RemoteHost + "/" + c.VMName, + "vi://" + c.RemoteUser + ":" + password + "@" + c.RemoteHost + "/" + displayName, s.OutputDir, } return append(c.OVFToolOptions, args...) @@ -72,9 +76,13 @@ func (s *StepExport) Run(_ context.Context, state multistep.StateBag) multistep. } ui.Say("Exporting virtual machine...") - ui.Message(fmt.Sprintf("Executing: %s %s", ovftool, strings.Join(s.generateArgs(c, true), " "))) + var displayName string + if v, ok := state.GetOk("display_name"); ok { + displayName = v.(string) + } + ui.Message(fmt.Sprintf("Executing: %s %s", ovftool, strings.Join(s.generateArgs(c, displayName, true), " "))) var out bytes.Buffer - cmd := exec.Command(ovftool, s.generateArgs(c, false)...) + cmd := exec.Command(ovftool, s.generateArgs(c, displayName, false)...) cmd.Stdout = &out if err := cmd.Run(); err != nil { err := fmt.Errorf("Error exporting virtual machine: %s\n%s\n", err, out.String()) From d68d26a6e51ef256256508c0f4beb7934b4a295e Mon Sep 17 00:00:00 2001 From: DanHam Date: Mon, 2 Jul 2018 13:44:41 +0100 Subject: [PATCH 062/220] Fix tests: We now need to set `displayName` key/val pair in the test VMX --- .../vmware/common/step_configure_vmx_test.go | 35 ++++++++++++++----- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/builder/vmware/common/step_configure_vmx_test.go b/builder/vmware/common/step_configure_vmx_test.go index c5e242a51..b6e9312ac 100644 --- a/builder/vmware/common/step_configure_vmx_test.go +++ b/builder/vmware/common/step_configure_vmx_test.go @@ -14,6 +14,9 @@ func testVMXFile(t *testing.T) string { if err != nil { t.Fatalf("err: %s", err) } + + // displayName must always be set + err = WriteVMX(tf.Name(), map[string]string{"displayName": "PackerBuild"}) tf.Close() return tf.Name() @@ -132,12 +135,29 @@ func TestStepConfigureVMX_generatedAddresses(t *testing.T) { vmxPath := testVMXFile(t) defer os.Remove(vmxPath) - err := WriteVMX(vmxPath, map[string]string{ - "foo": "bar", - "ethernet0.generatedAddress": "foo", - "ethernet1.generatedAddress": "foo", - "ethernet1.generatedAddressOffset": "foo", - }) + additionalTestVmxData := []struct { + Key string + Value string + }{ + {"foo", "bar"}, + {"ethernet0.generatedaddress", "foo"}, + {"ethernet1.generatedaddress", "foo"}, + {"ethernet1.generatedaddressoffset", "foo"}, + } + + // Get any existing VMX data from the VMX file + vmxData, err := ReadVMX(vmxPath) + if err != nil { + t.Fatalf("err %s", err) + } + + // Add the additional key/value pairs we need for this test to the existing VMX data + for _, data := range additionalTestVmxData { + vmxData[data.Key] = data.Value + } + + // Recreate the VMX file so it includes all the data needed for this test + err = WriteVMX(vmxPath, vmxData) if err != nil { t.Fatalf("err: %s", err) } @@ -157,7 +177,7 @@ func TestStepConfigureVMX_generatedAddresses(t *testing.T) { if err != nil { t.Fatalf("err: %s", err) } - vmxData := ParseVMX(string(vmxContents)) + vmxData = ParseVMX(string(vmxContents)) cases := []struct { Key string @@ -180,5 +200,4 @@ func TestStepConfigureVMX_generatedAddresses(t *testing.T) { } } } - } From 88c43ec98d00e3e06e8b3ec14a4fe18fae8cb76d Mon Sep 17 00:00:00 2001 From: DanHam Date: Mon, 2 Jul 2018 14:33:04 +0100 Subject: [PATCH 063/220] Test we fail if the displayName key is not found in the VMX --- .../vmware/common/step_configure_vmx_test.go | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/builder/vmware/common/step_configure_vmx_test.go b/builder/vmware/common/step_configure_vmx_test.go index b6e9312ac..5a4eb6a5c 100644 --- a/builder/vmware/common/step_configure_vmx_test.go +++ b/builder/vmware/common/step_configure_vmx_test.go @@ -201,3 +201,29 @@ func TestStepConfigureVMX_generatedAddresses(t *testing.T) { } } } + +// Should fail if the displayName key is not found in the VMX +func TestStepConfigureVMX_displayNameMissing(t *testing.T) { + state := testState(t) + step := new(StepConfigureVMX) + + // testVMXFile adds displayName key/value pair to the VMX + vmxPath := testVMXFile(t) + defer os.Remove(vmxPath) + + // Bad: Delete displayName from the VMX/Create an empty VMX file + err := WriteVMX(vmxPath, map[string]string{}) + if err != nil { + t.Fatalf("err: %s", err) + } + + state.Put("vmx_path", vmxPath) + + // Test the run + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { + t.Fatalf("bad action: %#v. Should halt when displayName key is missing from VMX", action) + } + if _, ok := state.GetOk("error"); !ok { + t.Fatal("should store error in state when displayName key is missing from VMX") + } +} From 21117e5d38188df29589fd7ea61e3d00e3662610 Mon Sep 17 00:00:00 2001 From: DanHam Date: Mon, 2 Jul 2018 14:44:55 +0100 Subject: [PATCH 064/220] Test we fail if displayName is not stored in the statebag as 'display_name' --- .../vmware/common/step_configure_vmx_test.go | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/builder/vmware/common/step_configure_vmx_test.go b/builder/vmware/common/step_configure_vmx_test.go index 5a4eb6a5c..cf025a70a 100644 --- a/builder/vmware/common/step_configure_vmx_test.go +++ b/builder/vmware/common/step_configure_vmx_test.go @@ -227,3 +227,28 @@ func TestStepConfigureVMX_displayNameMissing(t *testing.T) { t.Fatal("should store error in state when displayName key is missing from VMX") } } + +// Should store the value of displayName in the statebag +func TestStepConfigureVMX_displayNameStore(t *testing.T) { + state := testState(t) + step := new(StepConfigureVMX) + + // testVMXFile adds displayName key/value pair to the VMX + vmxPath := testVMXFile(t) + defer os.Remove(vmxPath) + + state.Put("vmx_path", vmxPath) + + // Test the run + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { + t.Fatalf("bad action: %#v", action) + } + if _, ok := state.GetOk("error"); ok { + t.Fatal("should NOT have error") + } + + // The value of displayName must be stored in the statebag + if _, ok := state.GetOk("display_name"); !ok { + t.Fatalf("displayName should be stored in the statebag as 'display_name'") + } +} From a39c5887fb8ee53db338f456f859b3dc1f680cab Mon Sep 17 00:00:00 2001 From: DanHam Date: Mon, 2 Jul 2018 15:04:21 +0100 Subject: [PATCH 065/220] Test we halt if a bad path is set in vmx_path --- builder/vmware/common/step_configure_vmx_test.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/builder/vmware/common/step_configure_vmx_test.go b/builder/vmware/common/step_configure_vmx_test.go index cf025a70a..d06ae51b9 100644 --- a/builder/vmware/common/step_configure_vmx_test.go +++ b/builder/vmware/common/step_configure_vmx_test.go @@ -252,3 +252,19 @@ func TestStepConfigureVMX_displayNameStore(t *testing.T) { t.Fatalf("displayName should be stored in the statebag as 'display_name'") } } + +func TestStepConfigureVMX_vmxPathBad(t *testing.T) { + state := testState(t) + step := new(StepConfigureVMX) + + state.Put("vmx_path", "some_bad_path") + + // Test the run + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { + t.Fatalf("bad action: %#v. Should halt when vmxPath is bad", action) + } + if _, ok := state.GetOk("error"); !ok { + t.Fatal("should store error in state when vmxPath is bad") + } + +} From 2ee7aea0767d3a261151b7e9e9369b705aa4540d Mon Sep 17 00:00:00 2001 From: DanHam Date: Fri, 6 Jul 2018 22:26:35 +0100 Subject: [PATCH 066/220] VMX builder: Extend doc for new linked clones capability --- website/source/docs/builders/vmware-vmx.html.md.erb | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/website/source/docs/builders/vmware-vmx.html.md.erb b/website/source/docs/builders/vmware-vmx.html.md.erb index 03c144de9..5ce8ef4e3 100644 --- a/website/source/docs/builders/vmware-vmx.html.md.erb +++ b/website/source/docs/builders/vmware-vmx.html.md.erb @@ -137,7 +137,18 @@ builder. doesn't shut down in this time, it is an error. By default, the timeout is `5m` or five minutes. -- `linked` (boolean) - Virtual machine is created a linked clone. +- `linked` (boolean) - By default Packer creates a 'full' clone of + the virtual machine specified in `source_path`. The resultant virtual + machine is fully independant from the parent it was cloned from. + + Setting `linked` to `true` instead causes Packer to create the virtual + machine as a 'linked' clone. Linked clones use and require ongoing + access to the disks of the parent virtual machine. The benefit of a + linked clone is that the clones virtual disk is typically very much + smaller than would be the case for a full clone. Additionally, the + cloned virtual machine can also be created much faster. Creating a + linked clone will typically only be of benefit in some advanced build + scenarios. Most users will wish to create a full clone instead. Defaults to `false`. - `skip_compaction` (boolean) - VMware-created disks are defragmented and From e7fc651f60691a8e6d28cdc0caee1cbcc8dee47b Mon Sep 17 00:00:00 2001 From: Patrick Double Date: Fri, 6 Jul 2018 17:11:24 -0500 Subject: [PATCH 067/220] First cut at vagrant post-processor for docker --- Vagrantfile | 4 ++++ post-processor/vagrant/docker.go | 26 +++++++++++++++++++++++ post-processor/vagrant/docker_test.go | 9 ++++++++ post-processor/vagrant/post-processor.go | 27 +++++++++++++----------- 4 files changed, 54 insertions(+), 12 deletions(-) create mode 100644 post-processor/vagrant/docker.go create mode 100644 post-processor/vagrant/docker_test.go diff --git a/Vagrantfile b/Vagrantfile index dd6370f04..c998e31c0 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -5,6 +5,10 @@ LINUX_BASE_BOX = "bento/ubuntu-16.04" FREEBSD_BASE_BOX = "jen20/FreeBSD-12.0-CURRENT" Vagrant.configure(2) do |config| + if Vagrant.has_plugin?("vagrant-cachier") + config.cache.scope = :box + end + # Compilation and development boxes config.vm.define "linux", autostart: true, primary: true do |vmCfg| vmCfg.vm.box = LINUX_BASE_BOX diff --git a/post-processor/vagrant/docker.go b/post-processor/vagrant/docker.go new file mode 100644 index 000000000..50b811c8f --- /dev/null +++ b/post-processor/vagrant/docker.go @@ -0,0 +1,26 @@ +package vagrant + +import ( + "fmt" + + "github.com/hashicorp/packer/packer" +) + +type DockerProvider struct{} + +func (p *DockerProvider) KeepInputArtifact() bool { + return false +} + +func (p *DockerProvider) Process(ui packer.Ui, artifact packer.Artifact, dir string) (vagrantfile string, metadata map[string]interface{}, err error) { + // Create the metadata + metadata = map[string]interface{}{"provider": "docker"} + + vagrantfile = fmt.Sprintf(dockerVagrantfile) + return +} + +var dockerVagrantfile = ` +Vagrant.configure("2") do |config| +end +` diff --git a/post-processor/vagrant/docker_test.go b/post-processor/vagrant/docker_test.go new file mode 100644 index 000000000..380846bcc --- /dev/null +++ b/post-processor/vagrant/docker_test.go @@ -0,0 +1,9 @@ +package vagrant + +import ( + "testing" +) + +func TestDockerProvider_impl(t *testing.T) { + var _ Provider = new(DockerProvider) +} diff --git a/post-processor/vagrant/post-processor.go b/post-processor/vagrant/post-processor.go index d4b587316..3d54d49f7 100644 --- a/post-processor/vagrant/post-processor.go +++ b/post-processor/vagrant/post-processor.go @@ -19,18 +19,19 @@ import ( ) var builtins = map[string]string{ - "mitchellh.amazonebs": "aws", - "mitchellh.amazon.instance": "aws", - "mitchellh.virtualbox": "virtualbox", - "mitchellh.vmware": "vmware", - "mitchellh.vmware-esx": "vmware", - "pearkes.digitalocean": "digitalocean", - "packer.googlecompute": "google", - "hashicorp.scaleway": "scaleway", - "packer.parallels": "parallels", - "MSOpenTech.hyperv": "hyperv", - "transcend.qemu": "libvirt", - "ustream.lxc": "lxc", + "mitchellh.amazonebs": "aws", + "mitchellh.amazon.instance": "aws", + "mitchellh.virtualbox": "virtualbox", + "mitchellh.vmware": "vmware", + "mitchellh.vmware-esx": "vmware", + "pearkes.digitalocean": "digitalocean", + "packer.googlecompute": "google", + "hashicorp.scaleway": "scaleway", + "packer.parallels": "parallels", + "MSOpenTech.hyperv": "hyperv", + "transcend.qemu": "libvirt", + "ustream.lxc": "lxc", + "packer.post-processor.docker-import": "docker", } type Config struct { @@ -241,6 +242,8 @@ func providerForName(name string) Provider { return new(GoogleProvider) case "lxc": return new(LXCProvider) + case "docker": + return new(DockerProvider) default: return nil } From bcaa5e49f1f06979a52410c7697eefc5406dac2e Mon Sep 17 00:00:00 2001 From: Mark Meyer Date: Fri, 13 Oct 2017 08:45:46 +0200 Subject: [PATCH 068/220] Document the `spot_tags` parameter --- website/source/docs/builders/amazon-ebs.html.md | 4 ++++ website/source/docs/builders/amazon-ebssurrogate.html.md | 4 ++++ website/source/docs/builders/amazon-ebsvolume.html.md | 4 ++++ website/source/docs/builders/amazon-instance.html.md | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/website/source/docs/builders/amazon-ebs.html.md b/website/source/docs/builders/amazon-ebs.html.md index f8d75ebd0..2db8c6d9f 100644 --- a/website/source/docs/builders/amazon-ebs.html.md +++ b/website/source/docs/builders/amazon-ebs.html.md @@ -343,6 +343,10 @@ builder. best spot price. This must be one of: `Linux/UNIX`, `SUSE Linux`, `Windows`, `Linux/UNIX (Amazon VPC)`, `SUSE Linux (Amazon VPC)`, `Windows (Amazon VPC)` +- `spot_tags` (object of key/value strings) - Requires `spot_price` to + be set. This tells Packer to aplly tags to the spot request that is + issued. + - `sriov_support` (boolean) - Enable enhanced networking (SriovNetSupport but not ENA) on HVM-compatible AMIs. If true, add `ec2:ModifyInstanceAttribute` to your AWS IAM policy. Note: you must make sure enhanced networking is enabled on your instance. See [Amazon's diff --git a/website/source/docs/builders/amazon-ebssurrogate.html.md b/website/source/docs/builders/amazon-ebssurrogate.html.md index eb21c1525..f29eb6507 100644 --- a/website/source/docs/builders/amazon-ebssurrogate.html.md +++ b/website/source/docs/builders/amazon-ebssurrogate.html.md @@ -336,6 +336,10 @@ builder. best spot price. This must be one of: `Linux/UNIX`, `SUSE Linux`, `Windows`, `Linux/UNIX (Amazon VPC)`, `SUSE Linux (Amazon VPC)`, `Windows (Amazon VPC)` +- `spot_tags` (object of key/value strings) - Requires `spot_price` to + be set. This tells Packer to aplly tags to the spot request that is + issued. + - `sriov_support` (boolean) - Enable enhanced networking (SriovNetSupport but not ENA) on HVM-compatible AMIs. If true, add `ec2:ModifyInstanceAttribute` to your AWS IAM policy. Note: you must make sure enhanced networking is enabled on your instance. See [Amazon's diff --git a/website/source/docs/builders/amazon-ebsvolume.html.md b/website/source/docs/builders/amazon-ebsvolume.html.md index acfa33e84..880d8b49f 100644 --- a/website/source/docs/builders/amazon-ebsvolume.html.md +++ b/website/source/docs/builders/amazon-ebsvolume.html.md @@ -264,6 +264,10 @@ builder. best spot price. This must be one of: `Linux/UNIX`, `SUSE Linux`, `Windows`, `Linux/UNIX (Amazon VPC)`, `SUSE Linux (Amazon VPC)` or `Windows (Amazon VPC)` +- `spot_tags` (object of key/value strings) - Requires `spot_price` to + be set. This tells Packer to aplly tags to the spot request that is + issued. + - `sriov_support` (boolean) - Enable enhanced networking (SriovNetSupport but not ENA) on HVM-compatible AMIs. If true, add `ec2:ModifyInstanceAttribute` to your AWS IAM policy. Note: you must make sure enhanced networking is enabled on your instance. See [Amazon's diff --git a/website/source/docs/builders/amazon-instance.html.md b/website/source/docs/builders/amazon-instance.html.md index 52686aeec..c3f3d76b8 100644 --- a/website/source/docs/builders/amazon-instance.html.md +++ b/website/source/docs/builders/amazon-instance.html.md @@ -339,6 +339,10 @@ builder. best spot price. This must be one of: `Linux/UNIX`, `SUSE Linux`, `Windows`, `Linux/UNIX (Amazon VPC)`, `SUSE Linux (Amazon VPC)`, `Windows (Amazon VPC)` +- `spot_tags` (object of key/value strings) - Requires `spot_price` to + be set. This tells Packer to aplly tags to the spot request that is + issued. + - `sriov_support` (boolean) - Enable enhanced networking (SriovNetSupport but not ENA) on HVM-compatible AMIs. If true, add `ec2:ModifyInstanceAttribute` to your AWS IAM policy. Note: you must make sure enhanced networking is enabled on your instance. See [Amazon's From 3dbf1cb371b3eddfe752ce444e6d14f72723009f Mon Sep 17 00:00:00 2001 From: Mark Meyer Date: Thu, 12 Oct 2017 23:33:01 +0200 Subject: [PATCH 069/220] Enable tagging of spot requests This adds a new parameter to the EBS builders named `spot_tags'. This parameter accepts a map of tags, much like `tags'. These tags will be applied to a spot request that is created. Improve visibility. --- builder/amazon/common/run_config.go | 5 ++++ .../amazon/common/step_run_spot_instance.go | 28 +++++++++++++++++++ builder/amazon/ebs/builder.go | 2 ++ builder/amazon/ebssurrogate/builder.go | 2 ++ builder/amazon/ebsvolume/builder.go | 2 ++ builder/amazon/instance/builder.go | 2 ++ 6 files changed, 41 insertions(+) diff --git a/builder/amazon/common/run_config.go b/builder/amazon/common/run_config.go index 129d4d541..b6e13dcc0 100644 --- a/builder/amazon/common/run_config.go +++ b/builder/amazon/common/run_config.go @@ -43,6 +43,7 @@ type RunConfig struct { SourceAmiFilter AmiFilterOptions `mapstructure:"source_ami_filter"` SpotPrice string `mapstructure:"spot_price"` SpotPriceAutoProduct string `mapstructure:"spot_price_auto_product"` + SpotTags map[string]string `mapstructure:"spot_tags"` SubnetId string `mapstructure:"subnet_id"` TemporaryKeyPairName string `mapstructure:"temporary_key_pair_name"` TemporarySGSourceCidr string `mapstructure:"temporary_security_group_source_cidr"` @@ -76,6 +77,10 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { c.RunTags = make(map[string]string) } + if c.SpotTags == nil { + c.SpotTags = make(map[string]string) + } + // Validation errs := c.Comm.Prepare(ctx) diff --git a/builder/amazon/common/step_run_spot_instance.go b/builder/amazon/common/step_run_spot_instance.go index 8c7cbf74a..7b96544bb 100644 --- a/builder/amazon/common/step_run_spot_instance.go +++ b/builder/amazon/common/step_run_spot_instance.go @@ -32,6 +32,7 @@ type StepRunSpotInstance struct { SourceAMI string SpotPrice string SpotPriceProduct string + SpotTags TagMap SubnetId string Tags TagMap VolumeTags TagMap @@ -227,6 +228,33 @@ func (s *StepRunSpotInstance) Run(ctx context.Context, state multistep.StateBag) } instanceId = *spotResp.SpotInstanceRequests[0].InstanceId + // Tag spot instance request + spotTags, err := s.SpotTags.EC2Tags(s.Ctx, *ec2conn.Config.Region, state) + if err != nil { + err := fmt.Errorf("Error tagging spot request: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + spotTags.Report(ui) + + if len(spotTags) > 0 && s.SpotTags.IsSet() { + // Retry creating tags for about 2.5 minutes + err = retry.Retry(0.2, 30, 11, func(_ uint) (bool, error) { + _, err := ec2conn.CreateTags(&ec2.CreateTagsInput{ + Tags: spotTags, + Resources: []*string{spotRequestId}, + }) + return true, err + }) + if err != nil { + err := fmt.Errorf("Error tagging spot request: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + // Set the instance ID so that the cleanup works properly s.instanceId = instanceId diff --git a/builder/amazon/ebs/builder.go b/builder/amazon/ebs/builder.go index 665bf8098..bd10ad36a 100644 --- a/builder/amazon/ebs/builder.go +++ b/builder/amazon/ebs/builder.go @@ -48,6 +48,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { "ami_description", "run_tags", "run_volume_tags", + "spot_tags", "snapshot_tags", "tags", }, @@ -134,6 +135,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe SourceAMI: b.config.SourceAmi, SpotPrice: b.config.SpotPrice, SpotPriceProduct: b.config.SpotPriceAutoProduct, + SpotTags: b.config.SpotTags, SubnetId: b.config.SubnetId, Tags: b.config.RunTags, UserData: b.config.UserData, diff --git a/builder/amazon/ebssurrogate/builder.go b/builder/amazon/ebssurrogate/builder.go index 52a151b22..9642c1a83 100644 --- a/builder/amazon/ebssurrogate/builder.go +++ b/builder/amazon/ebssurrogate/builder.go @@ -48,6 +48,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { "run_tags", "run_volume_tags", "snapshot_tags", + "spot_tags", "tags", }, }, @@ -148,6 +149,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe SourceAMI: b.config.SourceAmi, SpotPrice: b.config.SpotPrice, SpotPriceProduct: b.config.SpotPriceAutoProduct, + SpotTags: b.config.SpotTags, SubnetId: b.config.SubnetId, Tags: b.config.RunTags, UserData: b.config.UserData, diff --git a/builder/amazon/ebsvolume/builder.go b/builder/amazon/ebsvolume/builder.go index 1a79b964e..222febc56 100644 --- a/builder/amazon/ebsvolume/builder.go +++ b/builder/amazon/ebsvolume/builder.go @@ -44,6 +44,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { InterpolateFilter: &interpolate.RenderFilter{ Exclude: []string{ "run_tags", + "spot_tags", "ebs_volumes", }, }, @@ -132,6 +133,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe SourceAMI: b.config.SourceAmi, SpotPrice: b.config.SpotPrice, SpotPriceProduct: b.config.SpotPriceAutoProduct, + SpotTags: b.config.SpotTags, SubnetId: b.config.SubnetId, Tags: b.config.RunTags, UserData: b.config.UserData, diff --git a/builder/amazon/instance/builder.go b/builder/amazon/instance/builder.go index c197cadeb..fb59fff95 100644 --- a/builder/amazon/instance/builder.go +++ b/builder/amazon/instance/builder.go @@ -69,6 +69,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { "run_volume_tags", "snapshot_tags", "tags", + "spot_tags", }, }, }, configs...) @@ -219,6 +220,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe SpotPriceProduct: b.config.SpotPriceAutoProduct, SubnetId: b.config.SubnetId, Tags: b.config.RunTags, + SpotTags: b.config.SpotTags, UserData: b.config.UserData, UserDataFile: b.config.UserDataFile, } From 456208388333bb10233822ce033ee433ff47909a Mon Sep 17 00:00:00 2001 From: Gergely Szabo Date: Mon, 9 Jul 2018 13:32:08 +0200 Subject: [PATCH 070/220] Fixing shutdown_command doc for qemu builder --- website/source/docs/builders/qemu.html.md.erb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/website/source/docs/builders/qemu.html.md.erb b/website/source/docs/builders/qemu.html.md.erb index 5d6de7e45..86bb8431f 100644 --- a/website/source/docs/builders/qemu.html.md.erb +++ b/website/source/docs/builders/qemu.html.md.erb @@ -36,7 +36,7 @@ to files, URLS for ISOs and checksums. "iso_checksum": "af4a1640c0c6f348c6c41f1ea9e192a2", "iso_checksum_type": "md5", "output_directory": "output_centos_tdhtest", - "shutdown_command": "shutdown -P now", + "shutdown_command": "echo 'packer' | sudo -S shutdown -P now" "disk_size": 5000, "format": "qcow2", "headless": false, @@ -326,10 +326,10 @@ default port of `5985` or whatever value you have the service set to listen on. - `shutdown_command` (string) - The command to use to gracefully shut down the machine once all the provisioning is done. By default this is an empty string, which tells Packer to just forcefully shut down the machine unless a - shutdown command takes place inside script so this may safely be omitted. If - one or more scripts require a reboot it is suggested to leave this blank - since reboots may fail and specify the final shutdown command in your - last script. + shutdown command takes place inside script so this may safely be omitted. It + is important to add a `shutdown_command`. By default Packer halts the virtual + machine and the file system may not be sync'd. Thus, changes made in a + provisioner might not be saved. - `shutdown_timeout` (string) - The amount of time to wait after executing the `shutdown_command` for the virtual machine to actually shut down. If it From 3d1bb332e1f6a8558c9fdf2fef8a6333bba89c72 Mon Sep 17 00:00:00 2001 From: Gergely Szabo Date: Mon, 9 Jul 2018 13:42:54 +0200 Subject: [PATCH 071/220] Shutdown_command for qemu improved. --- website/source/docs/builders/qemu.html.md.erb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/website/source/docs/builders/qemu.html.md.erb b/website/source/docs/builders/qemu.html.md.erb index 86bb8431f..4f51fdc94 100644 --- a/website/source/docs/builders/qemu.html.md.erb +++ b/website/source/docs/builders/qemu.html.md.erb @@ -329,7 +329,9 @@ default port of `5985` or whatever value you have the service set to listen on. shutdown command takes place inside script so this may safely be omitted. It is important to add a `shutdown_command`. By default Packer halts the virtual machine and the file system may not be sync'd. Thus, changes made in a - provisioner might not be saved. + provisioner might not be saved. If one or more scripts require a reboot it is + suggested to leave this blank since reboots may fail and specify the final + shutdown command in your last script. - `shutdown_timeout` (string) - The amount of time to wait after executing the `shutdown_command` for the virtual machine to actually shut down. If it From b2098ce9d565a14160ceb590cc28d89d245d13c2 Mon Sep 17 00:00:00 2001 From: Gergely Szabo Date: Mon, 9 Jul 2018 13:46:15 +0200 Subject: [PATCH 072/220] Missing comma in the qemu builder example --- website/source/docs/builders/qemu.html.md.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/builders/qemu.html.md.erb b/website/source/docs/builders/qemu.html.md.erb index 4f51fdc94..c4b6aa26c 100644 --- a/website/source/docs/builders/qemu.html.md.erb +++ b/website/source/docs/builders/qemu.html.md.erb @@ -36,7 +36,7 @@ to files, URLS for ISOs and checksums. "iso_checksum": "af4a1640c0c6f348c6c41f1ea9e192a2", "iso_checksum_type": "md5", "output_directory": "output_centos_tdhtest", - "shutdown_command": "echo 'packer' | sudo -S shutdown -P now" + "shutdown_command": "echo 'packer' | sudo -S shutdown -P now", "disk_size": 5000, "format": "qcow2", "headless": false, From 4662d3eb9561dfaf0fb6f7b65086fe57d921837c Mon Sep 17 00:00:00 2001 From: jabbera Date: Mon, 9 Jul 2018 14:49:32 -0400 Subject: [PATCH 073/220] make deps should download goimports --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index b22d61e93..345a27cac 100644 --- a/Makefile +++ b/Makefile @@ -46,6 +46,7 @@ deps: @go get golang.org/x/tools/cmd/stringer @go get -u github.com/mna/pigeon @go get github.com/kardianos/govendor + @go get golang.org/x/tools/cmd/goimports @govendor sync dev: deps ## Build and install a development build From 7e4fb9adb5a1dd6d5c32fd623a13000566e3ffda Mon Sep 17 00:00:00 2001 From: Michael Gibson Date: Mon, 9 Jul 2018 14:05:39 -0600 Subject: [PATCH 074/220] vnc_bind_address not getting passed through to qemu This was mostly addressed in commit hashicorp/packer@fa273f3 Just missing vncIP from step_type_boot_command.go --- builder/qemu/step_type_boot_command.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/builder/qemu/step_type_boot_command.go b/builder/qemu/step_type_boot_command.go index a21256b6b..79bcd1338 100644 --- a/builder/qemu/step_type_boot_command.go +++ b/builder/qemu/step_type_boot_command.go @@ -41,6 +41,7 @@ func (s *stepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) httpPort := state.Get("http_port").(uint) ui := state.Get("ui").(packer.Ui) vncPort := state.Get("vnc_port").(uint) + vncIP := state.Get("vnc_ip").(string) if config.VNCConfig.DisableVNC { log.Println("Skipping boot command step...") @@ -65,7 +66,7 @@ func (s *stepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) // Connect to VNC ui.Say("Connecting to VM via VNC") - nc, err := net.Dial("tcp", fmt.Sprintf("127.0.0.1:%d", vncPort)) + nc, err := net.Dial("tcp", fmt.Sprintf("%s:%d", vncIP, vncPort)) if err != nil { err := fmt.Errorf("Error connecting to VNC: %s", err) state.Put("error", err) From 883c74f21c5cd11d2d1b8fa670dbe6b211983b3a Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Mon, 9 Jul 2018 15:20:49 -0700 Subject: [PATCH 075/220] remove reference to Atlas from getting started guide, as it's near the end of its deprecation cycle. --- website/source/intro/getting-started/build-image.html.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/website/source/intro/getting-started/build-image.html.md b/website/source/intro/getting-started/build-image.html.md index e65d621c1..a550cee18 100644 --- a/website/source/intro/getting-started/build-image.html.md +++ b/website/source/intro/getting-started/build-image.html.md @@ -181,10 +181,7 @@ you will also need to set `associate_public_ip_address` to `true`, or set up a ## Managing the Image Packer only builds images. It does not attempt to manage them in any way. After -they're built, it is up to you to launch or destroy them as you see fit. If you -want to store and namespace images for quick reference, you can use [Atlas by -HashiCorp](https://atlas.hashicorp.com). We'll cover remotely building and -storing images at the end of this getting started guide. +they're built, it is up to you to launch or destroy them as you see fit. After running the above example, your AWS account now has an AMI associated with it. AMIs are stored in S3 by Amazon, so unless you want to be charged From 4cfa49596a907e8e0373f7d01caa9be0cf7f68e6 Mon Sep 17 00:00:00 2001 From: Adam Robinson Date: Tue, 10 Jul 2018 17:10:53 -0400 Subject: [PATCH 076/220] Add ansible connection plugin examples --- .../ansible/connection-plugin/2.4.x/packer.py | 186 +++++++++++++++ .../ansible/connection-plugin/2.5.x/packer.py | 204 ++++++++++++++++ .../ansible/connection-plugin/2.6.x/packer.py | 218 ++++++++++++++++++ 3 files changed, 608 insertions(+) create mode 100644 examples/ansible/connection-plugin/2.4.x/packer.py create mode 100644 examples/ansible/connection-plugin/2.5.x/packer.py create mode 100644 examples/ansible/connection-plugin/2.6.x/packer.py diff --git a/examples/ansible/connection-plugin/2.4.x/packer.py b/examples/ansible/connection-plugin/2.4.x/packer.py new file mode 100644 index 000000000..ea4210d32 --- /dev/null +++ b/examples/ansible/connection-plugin/2.4.x/packer.py @@ -0,0 +1,186 @@ +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from ansible.plugins.connection.ssh import Connection as SSHConnection + +DOCUMENTATION = ''' + connection: packer + short_description: ssh based connections for powershell via packer + description: + - This connection plugin allows ansible to communicate to the target packer machines via ssh based connections for powershell. + author: Packer Community + version_added: na + options: + host: + description: Hostname/ip to connect to. + default: inventory_hostname + vars: + - name: ansible_host + - name: ansible_ssh_host + host_key_checking: + #constant: HOST_KEY_CHECKING + description: Determines if ssh should check host keys + type: boolean + ini: + - section: defaults + key: 'host_key_checking' + env: + - name: ANSIBLE_HOST_KEY_CHECKING + password: + description: Authentication password for the C(remote_user). Can be supplied as CLI option. + vars: + - name: ansible_password + - name: ansible_ssh_pass + ssh_args: + description: Arguments to pass to all ssh cli tools + default: '-C -o ControlMaster=auto -o ControlPersist=60s' + ini: + - section: 'ssh_connection' + key: 'ssh_args' + env: + - name: ANSIBLE_SSH_ARGS + ssh_common_args: + description: Common extra args for all ssh CLI tools + vars: + - name: ansible_ssh_common_args + ssh_executable: + default: ssh + description: + - This defines the location of the ssh binary. It defaults to `ssh` which will use the first ssh binary available in $PATH. + - This option is usually not required, it might be useful when access to system ssh is restricted, + or when using ssh wrappers to connect to remote hosts. + env: [{name: ANSIBLE_SSH_EXECUTABLE}] + ini: + - {key: ssh_executable, section: ssh_connection} + yaml: {key: ssh_connection.ssh_executable} + #const: ANSIBLE_SSH_EXECUTABLE + version_added: "2.2" + scp_extra_args: + description: Extra exclusive to the 'scp' CLI + vars: + - name: ansible_scp_extra_args + sftp_extra_args: + description: Extra exclusive to the 'sftp' CLI + vars: + - name: ansible_sftp_extra_args + ssh_extra_args: + description: Extra exclusive to the 'ssh' CLI + vars: + - name: ansible_ssh_extra_args + retries: + # constant: ANSIBLE_SSH_RETRIES + description: Number of attempts to connect. + default: 3 + type: integer + env: + - name: ANSIBLE_SSH_RETRIES + ini: + - section: connection + key: retries + - section: ssh_connection + key: retries + port: + description: Remote port to connect to. + type: int + default: 22 + ini: + - section: defaults + key: remote_port + env: + - name: ANSIBLE_REMOTE_PORT + vars: + - name: ansible_port + - name: ansible_ssh_port + remote_user: + description: + - User name with which to login to the remote server, normally set by the remote_user keyword. + - If no user is supplied, Ansible will let the ssh client binary choose the user as it normally + ini: + - section: defaults + key: remote_user + env: + - name: ANSIBLE_REMOTE_USER + vars: + - name: ansible_user + - name: ansible_ssh_user + pipelining: + default: ANSIBLE_PIPELINING + description: + - Pipelining reduces the number of SSH operations required to execute a module on the remote server, + by executing many Ansible modules without actual file transfer. + - This can result in a very significant performance improvement when enabled. + - However this conflicts with privilege escalation (become). + For example, when using sudo operations you must first disable 'requiretty' in the sudoers file for the target hosts, + which is why this feature is disabled by default. + env: + - name: ANSIBLE_PIPELINING + #- name: ANSIBLE_SSH_PIPELINING + ini: + - section: defaults + key: pipelining + #- section: ssh_connection + # key: pipelining + type: boolean + vars: + - name: ansible_pipelining + - name: ansible_ssh_pipelining + private_key_file: + description: + - Path to private key file to use for authentication + ini: + - section: defaults + key: private_key_file + env: + - name: ANSIBLE_PRIVATE_KEY_FILE + vars: + - name: ansible_private_key_file + - name: ansible_ssh_private_key_file + control_path: + default: null + description: + - This is the location to save ssh's ControlPath sockets, it uses ssh's variable substitution. + - Since 2.3, if null, ansible will generate a unique hash. Use `%(directory)s` to indicate where to use the control dir path setting. + env: + - name: ANSIBLE_SSH_CONTROL_PATH + ini: + - key: control_path + section: ssh_connection + control_path_dir: + default: ~/.ansible/cp + description: + - This sets the directory to use for ssh control path if the control path setting is null. + - Also, provides the `%(directory)s` variable for the control path setting. + env: + - name: ANSIBLE_SSH_CONTROL_PATH_DIR + ini: + - section: ssh_connection + key: control_path_dir + sftp_batch_mode: + default: True + description: 'TODO: write it' + env: [{name: ANSIBLE_SFTP_BATCH_MODE}] + ini: + - {key: sftp_batch_mode, section: ssh_connection} + type: boolean + scp_if_ssh: + default: smart + description: + - "Prefered method to use when transfering files over ssh" + - When set to smart, Ansible will try them until one succeeds or they all fail + - If set to True, it will force 'scp', if False it will use 'sftp' + env: [{name: ANSIBLE_SCP_IF_SSH}] + ini: + - {key: scp_if_ssh, section: ssh_connection} +''' + +class Connection(SSHConnection): + ''' ssh based connections for powershell via packer''' + + transport = 'packer' + has_pipelining = True + become_methods = [] + allow_executable = False + module_implementation_preferences = ('.ps1', '') + + def __init__(self, *args, **kwargs): + super(Connection, self).__init__(*args, **kwargs) \ No newline at end of file diff --git a/examples/ansible/connection-plugin/2.5.x/packer.py b/examples/ansible/connection-plugin/2.5.x/packer.py new file mode 100644 index 000000000..e133aeea4 --- /dev/null +++ b/examples/ansible/connection-plugin/2.5.x/packer.py @@ -0,0 +1,204 @@ +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from ansible.plugins.connection.ssh import Connection as SSHConnection + +DOCUMENTATION = ''' + connection: packer + short_description: ssh based connections for powershell via packer + description: + - This connection plugin allows ansible to communicate to the target packer machines via ssh based connections for powershell. + author: Packer Community + version_added: na + options: + host: + description: Hostname/ip to connect to. + default: inventory_hostname + vars: + - name: ansible_host + - name: ansible_ssh_host + host_key_checking: + description: Determines if ssh should check host keys + type: boolean + ini: + - section: defaults + key: 'host_key_checking' + - section: ssh_connection + key: 'host_key_checking' + version_added: '2.5' + env: + - name: ANSIBLE_HOST_KEY_CHECKING + - name: ANSIBLE_SSH_HOST_KEY_CHECKING + version_added: '2.5' + vars: + - name: ansible_host_key_checking + version_added: '2.5' + - name: ansible_ssh_host_key_checking + version_added: '2.5' + password: + description: Authentication password for the C(remote_user). Can be supplied as CLI option. + vars: + - name: ansible_password + - name: ansible_ssh_pass + ssh_args: + description: Arguments to pass to all ssh cli tools + default: '-C -o ControlMaster=auto -o ControlPersist=60s' + ini: + - section: 'ssh_connection' + key: 'ssh_args' + env: + - name: ANSIBLE_SSH_ARGS + ssh_common_args: + description: Common extra args for all ssh CLI tools + vars: + - name: ansible_ssh_common_args + ssh_executable: + default: ssh + description: + - This defines the location of the ssh binary. It defaults to `ssh` which will use the first ssh binary available in $PATH. + - This option is usually not required, it might be useful when access to system ssh is restricted, + or when using ssh wrappers to connect to remote hosts. + env: [{name: ANSIBLE_SSH_EXECUTABLE}] + ini: + - {key: ssh_executable, section: ssh_connection} + yaml: {key: ssh_connection.ssh_executable} + #const: ANSIBLE_SSH_EXECUTABLE + version_added: "2.2" + scp_extra_args: + description: Extra exclusive to the 'scp' CLI + vars: + - name: ansible_scp_extra_args + sftp_extra_args: + description: Extra exclusive to the 'sftp' CLI + vars: + - name: ansible_sftp_extra_args + ssh_extra_args: + description: Extra exclusive to the 'ssh' CLI + vars: + - name: ansible_ssh_extra_args + retries: + # constant: ANSIBLE_SSH_RETRIES + description: Number of attempts to connect. + default: 3 + type: integer + env: + - name: ANSIBLE_SSH_RETRIES + ini: + - section: connection + key: retries + - section: ssh_connection + key: retries + port: + description: Remote port to connect to. + type: int + default: 22 + ini: + - section: defaults + key: remote_port + env: + - name: ANSIBLE_REMOTE_PORT + vars: + - name: ansible_port + - name: ansible_ssh_port + remote_user: + description: + - User name with which to login to the remote server, normally set by the remote_user keyword. + - If no user is supplied, Ansible will let the ssh client binary choose the user as it normally + ini: + - section: defaults + key: remote_user + env: + - name: ANSIBLE_REMOTE_USER + vars: + - name: ansible_user + - name: ansible_ssh_user + pipelining: + default: ANSIBLE_PIPELINING + description: + - Pipelining reduces the number of SSH operations required to execute a module on the remote server, + by executing many Ansible modules without actual file transfer. + - This can result in a very significant performance improvement when enabled. + - However this conflicts with privilege escalation (become). + For example, when using sudo operations you must first disable 'requiretty' in the sudoers file for the target hosts, + which is why this feature is disabled by default. + env: + - name: ANSIBLE_PIPELINING + #- name: ANSIBLE_SSH_PIPELINING + ini: + - section: defaults + key: pipelining + #- section: ssh_connection + # key: pipelining + type: boolean + vars: + - name: ansible_pipelining + - name: ansible_ssh_pipelining + private_key_file: + description: + - Path to private key file to use for authentication + ini: + - section: defaults + key: private_key_file + env: + - name: ANSIBLE_PRIVATE_KEY_FILE + vars: + - name: ansible_private_key_file + - name: ansible_ssh_private_key_file + control_path: + default: null + description: + - This is the location to save ssh's ControlPath sockets, it uses ssh's variable substitution. + - Since 2.3, if null, ansible will generate a unique hash. Use `%(directory)s` to indicate where to use the control dir path setting. + env: + - name: ANSIBLE_SSH_CONTROL_PATH + ini: + - key: control_path + section: ssh_connection + control_path_dir: + default: ~/.ansible/cp + description: + - This sets the directory to use for ssh control path if the control path setting is null. + - Also, provides the `%(directory)s` variable for the control path setting. + env: + - name: ANSIBLE_SSH_CONTROL_PATH_DIR + ini: + - section: ssh_connection + key: control_path_dir + sftp_batch_mode: + default: True + description: 'TODO: write it' + env: [{name: ANSIBLE_SFTP_BATCH_MODE}] + ini: + - {key: sftp_batch_mode, section: ssh_connection} + type: boolean + scp_if_ssh: + default: smart + description: + - "Prefered method to use when transfering files over ssh" + - When set to smart, Ansible will try them until one succeeds or they all fail + - If set to True, it will force 'scp', if False it will use 'sftp' + env: [{name: ANSIBLE_SCP_IF_SSH}] + ini: + - {key: scp_if_ssh, section: ssh_connection} + use_tty: + version_added: '2.5' + default: True + description: add -tt to ssh commands to force tty allocation + env: [{name: ANSIBLE_SSH_USETTY}] + ini: + - {key: usetty, section: ssh_connection} + type: boolean + yaml: {key: connection.usetty} +''' + +class Connection(SSHConnection): + ''' ssh based connections for powershell via packer''' + + transport = 'packer' + has_pipelining = True + become_methods = [] + allow_executable = False + module_implementation_preferences = ('.ps1', '') + + def __init__(self, *args, **kwargs): + super(Connection, self).__init__(*args, **kwargs) \ No newline at end of file diff --git a/examples/ansible/connection-plugin/2.6.x/packer.py b/examples/ansible/connection-plugin/2.6.x/packer.py new file mode 100644 index 000000000..8ef8c0548 --- /dev/null +++ b/examples/ansible/connection-plugin/2.6.x/packer.py @@ -0,0 +1,218 @@ +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from ansible.plugins.connection.ssh import Connection as SSHConnection + +DOCUMENTATION = ''' + connection: packer + short_description: ssh based connections for powershell via packer + description: + - This connection plugin allows ansible to communicate to the target packer machines via ssh based connections for powershell. + author: Packer Community + version_added: na + options: + host: + description: Hostname/ip to connect to. + default: inventory_hostname + vars: + - name: ansible_host + - name: ansible_ssh_host + host_key_checking: + description: Determines if ssh should check host keys + type: boolean + ini: + - section: defaults + key: 'host_key_checking' + - section: ssh_connection + key: 'host_key_checking' + version_added: '2.5' + env: + - name: ANSIBLE_HOST_KEY_CHECKING + - name: ANSIBLE_SSH_HOST_KEY_CHECKING + version_added: '2.5' + vars: + - name: ansible_host_key_checking + version_added: '2.5' + - name: ansible_ssh_host_key_checking + version_added: '2.5' + password: + description: Authentication password for the C(remote_user). Can be supplied as CLI option. + vars: + - name: ansible_password + - name: ansible_ssh_pass + ssh_args: + description: Arguments to pass to all ssh cli tools + default: '-C -o ControlMaster=auto -o ControlPersist=60s' + ini: + - section: 'ssh_connection' + key: 'ssh_args' + env: + - name: ANSIBLE_SSH_ARGS + ssh_common_args: + description: Common extra args for all ssh CLI tools + vars: + - name: ansible_ssh_common_args + ssh_executable: + default: ssh + description: + - This defines the location of the ssh binary. It defaults to ``ssh`` which will use the first ssh binary available in $PATH. + - This option is usually not required, it might be useful when access to system ssh is restricted, + or when using ssh wrappers to connect to remote hosts. + env: [{name: ANSIBLE_SSH_EXECUTABLE}] + ini: + - {key: ssh_executable, section: ssh_connection} + #const: ANSIBLE_SSH_EXECUTABLE + version_added: "2.2" + sftp_executable: + default: sftp + description: + - This defines the location of the sftp binary. It defaults to ``sftp`` which will use the first binary available in $PATH. + env: [{name: ANSIBLE_SFTP_EXECUTABLE}] + ini: + - {key: sftp_executable, section: ssh_connection} + version_added: "2.6" + scp_executable: + default: scp + description: + - This defines the location of the scp binary. It defaults to `scp` which will use the first binary available in $PATH. + env: [{name: ANSIBLE_SCP_EXECUTABLE}] + ini: + - {key: scp_executable, section: ssh_connection} + version_added: "2.6" + scp_extra_args: + description: Extra exclusive to the ``scp`` CLI + vars: + - name: ansible_scp_extra_args + sftp_extra_args: + description: Extra exclusive to the ``sftp`` CLI + vars: + - name: ansible_sftp_extra_args + ssh_extra_args: + description: Extra exclusive to the 'ssh' CLI + vars: + - name: ansible_ssh_extra_args + retries: + # constant: ANSIBLE_SSH_RETRIES + description: Number of attempts to connect. + default: 3 + type: integer + env: + - name: ANSIBLE_SSH_RETRIES + ini: + - section: connection + key: retries + - section: ssh_connection + key: retries + port: + description: Remote port to connect to. + type: int + default: 22 + ini: + - section: defaults + key: remote_port + env: + - name: ANSIBLE_REMOTE_PORT + vars: + - name: ansible_port + - name: ansible_ssh_port + remote_user: + description: + - User name with which to login to the remote server, normally set by the remote_user keyword. + - If no user is supplied, Ansible will let the ssh client binary choose the user as it normally + ini: + - section: defaults + key: remote_user + env: + - name: ANSIBLE_REMOTE_USER + vars: + - name: ansible_user + - name: ansible_ssh_user + pipelining: + default: ANSIBLE_PIPELINING + description: + - Pipelining reduces the number of SSH operations required to execute a module on the remote server, + by executing many Ansible modules without actual file transfer. + - This can result in a very significant performance improvement when enabled. + - However this conflicts with privilege escalation (become). + For example, when using sudo operations you must first disable 'requiretty' in the sudoers file for the target hosts, + which is why this feature is disabled by default. + env: + - name: ANSIBLE_PIPELINING + #- name: ANSIBLE_SSH_PIPELINING + ini: + - section: defaults + key: pipelining + #- section: ssh_connection + # key: pipelining + type: boolean + vars: + - name: ansible_pipelining + - name: ansible_ssh_pipelining + private_key_file: + description: + - Path to private key file to use for authentication + ini: + - section: defaults + key: private_key_file + env: + - name: ANSIBLE_PRIVATE_KEY_FILE + vars: + - name: ansible_private_key_file + - name: ansible_ssh_private_key_file + control_path: + description: + - This is the location to save ssh's ControlPath sockets, it uses ssh's variable substitution. + - Since 2.3, if null, ansible will generate a unique hash. Use `%(directory)s` to indicate where to use the control dir path setting. + env: + - name: ANSIBLE_SSH_CONTROL_PATH + ini: + - key: control_path + section: ssh_connection + control_path_dir: + default: ~/.ansible/cp + description: + - This sets the directory to use for ssh control path if the control path setting is null. + - Also, provides the `%(directory)s` variable for the control path setting. + env: + - name: ANSIBLE_SSH_CONTROL_PATH_DIR + ini: + - section: ssh_connection + key: control_path_dir + sftp_batch_mode: + default: 'yes' + description: 'TODO: write it' + env: [{name: ANSIBLE_SFTP_BATCH_MODE}] + ini: + - {key: sftp_batch_mode, section: ssh_connection} + type: bool + scp_if_ssh: + default: smart + description: + - "Prefered method to use when transfering files over ssh" + - When set to smart, Ansible will try them until one succeeds or they all fail + - If set to True, it will force 'scp', if False it will use 'sftp' + env: [{name: ANSIBLE_SCP_IF_SSH}] + ini: + - {key: scp_if_ssh, section: ssh_connection} + use_tty: + version_added: '2.5' + default: 'yes' + description: add -tt to ssh commands to force tty allocation + env: [{name: ANSIBLE_SSH_USETTY}] + ini: + - {key: usetty, section: ssh_connection} + type: bool + yaml: {key: connection.usetty} +''' + +class Connection(SSHConnection): + ''' ssh based connections for powershell via packer''' + + transport = 'packer' + has_pipelining = True + become_methods = [] + allow_executable = False + module_implementation_preferences = ('.ps1', '') + + def __init__(self, *args, **kwargs): + super(Connection, self).__init__(*args, **kwargs) \ No newline at end of file From 37cb3ec055d3b77907e9a83d955cdb5a62085957 Mon Sep 17 00:00:00 2001 From: Adam Robinson Date: Tue, 10 Jul 2018 17:15:22 -0400 Subject: [PATCH 077/220] clarify ansible connection plugin creation and link to working examples --- website/source/docs/provisioners/ansible.html.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/website/source/docs/provisioners/ansible.html.md b/website/source/docs/provisioners/ansible.html.md index 82047070d..26047458d 100644 --- a/website/source/docs/provisioners/ansible.html.md +++ b/website/source/docs/provisioners/ansible.html.md @@ -214,9 +214,12 @@ class Connection(SSHConnection): super(Connection, self).__init__(*args, **kwargs) ``` -Newer versions of Ansible require all plugins to have a documentation string. You will need to copy -the `options` from the `DOCUMENTATION` string from the [ssh.py Ansible connection plugin](https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/connection/ssh.py) -of the Ansible version you are using and add it to packer.py similar to as follows +Newer versions of Ansible require all plugins to have a documentation string. You can see if there is a +plugin available for the version of Ansible you are using [here](https://github.com/hashicorp/packer/tree/master/examples/ansible/connection-plugin). + +To create the plugin yourself, you will need to copy all of the `options` from the `DOCUMENTATION` string +from the [ssh.py Ansible connection plugin](https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/connection/ssh.py) +of the Ansible version you are using and add it to a packer.py file similar to as follows ``` python from __future__ import (absolute_import, division, print_function) @@ -233,7 +236,7 @@ DOCUMENTATION = ''' author: Packer version_added: na options: - **** Copy the options from + **** Copy ALL the options from https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/connection/ssh.py for the version of Ansible you are using **** ''' From 3f1cfed3c52bff9bde989b276bf30e4b6d76c6de Mon Sep 17 00:00:00 2001 From: Darwin Date: Wed, 11 Jul 2018 07:22:27 -0400 Subject: [PATCH 078/220] Add "Undo-WinRMConfig" open source project link Implemented as a powershell script which can be called from github or locally. Also provided as a chocolatey package on chocolatey.org --- website/source/community-tools.html.md | 1 + 1 file changed, 1 insertion(+) diff --git a/website/source/community-tools.html.md b/website/source/community-tools.html.md index cffed03da..e7bc33d8c 100644 --- a/website/source/community-tools.html.md +++ b/website/source/community-tools.html.md @@ -52,3 +52,4 @@ power of Packer templates. ## Other - [suitcase](https://github.com/tmclaugh/suitcase) - Packer based build system for CentOS OS images +- [Undo-WinRMConfig(https://cloudywindows.io/post/winrm-for-provisioning---close-the-door-on-the-way-out-eh/) - Open source automation to stage WinRM reset to pristine state at next shtudown From 1347f0761837e8cea0d09a386dac311462ee5f57 Mon Sep 17 00:00:00 2001 From: DanHam Date: Tue, 10 Jul 2018 16:59:26 +0100 Subject: [PATCH 079/220] Update 'packer fix' command usage output to include all fixers --- command/fix.go | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/command/fix.go b/command/fix.go index 12d351e92..d04cdfd0b 100644 --- a/command/fix.go +++ b/command/fix.go @@ -122,14 +122,37 @@ Usage: packer fix [options] TEMPLATE Fixes that are run: - iso-md5 Replaces "iso_md5" in builders with newer "iso_checksum" - createtime Replaces ".CreateTime" in builder configs with "{{timestamp}}" - virtualbox-gaattach Updates VirtualBox builders using "guest_additions_attach" - to use "guest_additions_mode" - pp-vagrant-override Replaces old-style provider overrides for the Vagrant - post-processor to new-style as of Packer 0.5.0. - virtualbox-rename Updates "virtualbox" builders to "virtualbox-iso" - vmware-rename Updates "vmware" builders to "vmware-iso" + iso-md5 Replaces "iso_md5" in builders with newer + "iso_checksum" + createtime Replaces ".CreateTime" in builder configs with + "{{timestamp}}" + virtualbox-gaattach Updates VirtualBox builders using + "guest_additions_attach" to use + "guest_additions_mode" + pp-vagrant-override Replaces old-style provider overrides for the + Vagrant post-processor to new-style as of Packer + 0.5.0. + virtualbox-rename Updates "virtualbox" builders to "virtualbox-iso" + vmware-rename Updates "vmware" builders to "vmware-iso" + parallels-headless Removes unused "headless" setting from Parallels + builders + parallels-deprecations Removes deprecated "parallels_tools_host_path" from + Parallels builders + sshkeypath Updates builders using "ssh_key_path" to use + "ssh_private_key_file" + sshdisableagent Updates builders using "ssh_disable_agent" to use + "ssh_disable_agent_forwarding" + manifest-filename Updates "manifest" post-processor so any "filename" + field is renamed to "output" + amazon-shutdown_behavior Changes "shutdown_behaviour" to "shutdown_behavior" + in Amazon builders + amazon-enhanced-networking Replaces "enhanced_networking" in builders with + "ena_support" + amazon-private-ip Replaces "ssh_private_ip": true in amazon builders + with "ssh_interface": "private_ip" + docker-email Removes "login_email" from the Docker builder + powershell-escapes Removes PowerShell escapes from user env vars and + elevated username and password strings Options: From 5ea6429cd692ecd47a431e6b4968d44b23dc95e5 Mon Sep 17 00:00:00 2001 From: Mike Date: Wed, 11 Jul 2018 11:31:51 -0400 Subject: [PATCH 080/220] managed_image_resource_group_name max length change --- builder/azure/arm/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/azure/arm/config.go b/builder/azure/arm/config.go index 7fef5f0ae..98e24dd81 100644 --- a/builder/azure/arm/config.go +++ b/builder/azure/arm/config.go @@ -47,7 +47,7 @@ const ( // -> ^[^_\W][\w-._]{0,79}(? Date: Wed, 11 Jul 2018 09:30:02 -0700 Subject: [PATCH 081/220] Fix markdown link --- website/source/community-tools.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/community-tools.html.md b/website/source/community-tools.html.md index e7bc33d8c..799373a1b 100644 --- a/website/source/community-tools.html.md +++ b/website/source/community-tools.html.md @@ -52,4 +52,4 @@ power of Packer templates. ## Other - [suitcase](https://github.com/tmclaugh/suitcase) - Packer based build system for CentOS OS images -- [Undo-WinRMConfig(https://cloudywindows.io/post/winrm-for-provisioning---close-the-door-on-the-way-out-eh/) - Open source automation to stage WinRM reset to pristine state at next shtudown +- [Undo-WinRMConfig](https://cloudywindows.io/post/winrm-for-provisioning---close-the-door-on-the-way-out-eh/) - Open source automation to stage WinRM reset to pristine state at next shtudown From cf63dd10bfaacb17cc0ca1c0ce879ce6fed0cc34 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 31 May 2018 11:29:04 -0700 Subject: [PATCH 082/220] replace AMIStateRefreshFunc, InstanceStateRefreshFunc, our spot instance waiter, our chroot volume waiter, and our snapshot waiters with waiters form AWS's SDK. --- builder/amazon/chroot/step_attach_volume.go | 53 +-- builder/amazon/chroot/step_create_volume.go | 17 +- builder/amazon/chroot/step_register_ami.go | 14 +- builder/amazon/chroot/step_snapshot.go | 22 +- builder/amazon/common/state.go | 358 ++++++++++-------- builder/amazon/common/step_ami_region_copy.go | 10 +- builder/amazon/common/step_encrypted_ami.go | 9 +- .../amazon/common/step_run_source_instance.go | 8 +- .../amazon/common/step_run_spot_instance.go | 23 +- builder/amazon/ebs/step_create_ami.go | 9 +- .../amazon/ebssurrogate/step_register_ami.go | 9 +- .../ebssurrogate/step_snapshot_volumes.go | 26 +- builder/amazon/instance/step_register_ami.go | 9 +- .../amazon-import/post-processor.go | 19 +- 14 files changed, 215 insertions(+), 371 deletions(-) diff --git a/builder/amazon/chroot/step_attach_volume.go b/builder/amazon/chroot/step_attach_volume.go index 01ab32464..7698ece07 100644 --- a/builder/amazon/chroot/step_attach_volume.go +++ b/builder/amazon/chroot/step_attach_volume.go @@ -2,10 +2,8 @@ package chroot import ( "context" - "errors" "fmt" "strings" - "time" "github.com/aws/aws-sdk-go/service/ec2" awscommon "github.com/hashicorp/packer/builder/amazon/common" @@ -52,35 +50,7 @@ func (s *StepAttachVolume) Run(_ context.Context, state multistep.StateBag) mult s.volumeId = volumeId // Wait for the volume to become attached - stateChange := awscommon.StateChangeConf{ - Pending: []string{"attaching"}, - StepState: state, - Target: "attached", - Refresh: func() (interface{}, string, error) { - attempts := 0 - for attempts < 30 { - resp, err := ec2conn.DescribeVolumes(&ec2.DescribeVolumesInput{VolumeIds: []*string{&volumeId}}) - if err != nil { - return nil, "", err - } - if len(resp.Volumes[0].Attachments) > 0 { - a := resp.Volumes[0].Attachments[0] - return a, *a.State, nil - } - // When Attachment on volume is not present sleep for 2s and retry - attempts += 1 - ui.Say(fmt.Sprintf( - "Volume %s show no attachments. Attempt %d/30. Sleeping for 2s and will retry.", - volumeId, attempts)) - time.Sleep(2 * time.Second) - } - - // Attachment on volume is not present after all attempts - return nil, "", errors.New("No attachments on volume.") - }, - } - - _, err = awscommon.WaitForState(&stateChange) + err = awscommon.WaitUntilVolumeAttached(ec2conn, s.volumeId) if err != nil { err := fmt.Errorf("Error waiting for volume: %s", err) state.Put("error", err) @@ -116,26 +86,7 @@ func (s *StepAttachVolume) CleanupFunc(state multistep.StateBag) error { s.attached = false // Wait for the volume to detach - stateChange := awscommon.StateChangeConf{ - Pending: []string{"attaching", "attached", "detaching"}, - StepState: state, - Target: "detached", - Refresh: func() (interface{}, string, error) { - resp, err := ec2conn.DescribeVolumes(&ec2.DescribeVolumesInput{VolumeIds: []*string{&s.volumeId}}) - if err != nil { - return nil, "", err - } - - v := resp.Volumes[0] - if len(v.Attachments) > 0 { - return v, *v.Attachments[0].State, nil - } else { - return v, "detached", nil - } - }, - } - - _, err = awscommon.WaitForState(&stateChange) + err = awscommon.WaitUntilVolumeDetached(ec2conn, s.volumeId) if err != nil { return fmt.Errorf("Error waiting for volume: %s", err) } diff --git a/builder/amazon/chroot/step_create_volume.go b/builder/amazon/chroot/step_create_volume.go index b3c205b26..c10fda4da 100644 --- a/builder/amazon/chroot/step_create_volume.go +++ b/builder/amazon/chroot/step_create_volume.go @@ -84,22 +84,7 @@ func (s *StepCreateVolume) Run(_ context.Context, state multistep.StateBag) mult log.Printf("Volume ID: %s", s.volumeId) // Wait for the volume to become ready - stateChange := awscommon.StateChangeConf{ - Pending: []string{"creating"}, - StepState: state, - Target: "available", - Refresh: func() (interface{}, string, error) { - resp, err := ec2conn.DescribeVolumes(&ec2.DescribeVolumesInput{VolumeIds: []*string{&s.volumeId}}) - if err != nil { - return nil, "", err - } - - v := resp.Volumes[0] - return v, *v.State, nil - }, - } - - _, err = awscommon.WaitForState(&stateChange) + err = awscommon.WaitUntilVolumeAvailable(ec2conn, s.volumeId) if err != nil { err := fmt.Errorf("Error waiting for volume: %s", err) state.Put("error", err) diff --git a/builder/amazon/chroot/step_register_ami.go b/builder/amazon/chroot/step_register_ami.go index 6fa9838b0..31a41cb9d 100644 --- a/builder/amazon/chroot/step_register_ami.go +++ b/builder/amazon/chroot/step_register_ami.go @@ -18,7 +18,7 @@ type StepRegisterAMI struct { EnableAMISriovNetSupport bool } -func (s *StepRegisterAMI) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *StepRegisterAMI) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) ec2conn := state.Get("ec2").(*ec2.EC2) snapshotId := state.Get("snapshot_id").(string) @@ -103,21 +103,15 @@ func (s *StepRegisterAMI) Run(_ context.Context, state multistep.StateBag) multi state.Put("amis", amis) // Wait for the image to become ready - stateChange := awscommon.StateChangeConf{ - Pending: []string{"pending"}, - Target: "available", - Refresh: awscommon.AMIStateRefreshFunc(ec2conn, *registerResp.ImageId), - StepState: state, - } - - ui.Say("Waiting for AMI to become ready...") - if _, err := awscommon.WaitForState(&stateChange); err != nil { + if err := awscommon.WaitUntilAMIAvailable(ec2conn, *registerResp.ImageId); err != nil { err := fmt.Errorf("Error waiting for AMI: %s", err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } + ui.Say("Waiting for AMI to become ready...") + return multistep.ActionContinue } diff --git a/builder/amazon/chroot/step_snapshot.go b/builder/amazon/chroot/step_snapshot.go index 3fb3ff701..4e9070bc5 100644 --- a/builder/amazon/chroot/step_snapshot.go +++ b/builder/amazon/chroot/step_snapshot.go @@ -2,7 +2,6 @@ package chroot import ( "context" - "errors" "fmt" "time" @@ -44,26 +43,7 @@ func (s *StepSnapshot) Run(_ context.Context, state multistep.StateBag) multiste ui.Message(fmt.Sprintf("Snapshot ID: %s", s.snapshotId)) // Wait for the snapshot to be ready - stateChange := awscommon.StateChangeConf{ - Pending: []string{"pending"}, - StepState: state, - Target: "completed", - Refresh: func() (interface{}, string, error) { - resp, err := ec2conn.DescribeSnapshots(&ec2.DescribeSnapshotsInput{SnapshotIds: []*string{&s.snapshotId}}) - if err != nil { - return nil, "", err - } - - if len(resp.Snapshots) == 0 { - return nil, "", errors.New("No snapshots found.") - } - - s := resp.Snapshots[0] - return s, *s.State, nil - }, - } - - _, err = awscommon.WaitForState(&stateChange) + err = awscommon.WaitUntilSnapshotDone(ec2conn, s.snapshotId) if err != nil { err := fmt.Errorf("Error waiting for snapshot: %s", err) state.Put("error", err) diff --git a/builder/amazon/common/state.go b/builder/amazon/common/state.go index 4b5fe0d46..50e4e4b7a 100644 --- a/builder/amazon/common/state.go +++ b/builder/amazon/common/state.go @@ -1,16 +1,13 @@ package common import ( - "errors" - "fmt" "log" - "net" "os" "strconv" - "strings" "time" - "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/packer/helper/multistep" ) @@ -35,189 +32,220 @@ type StateChangeConf struct { Target string } -// AMIStateRefreshFunc returns a StateRefreshFunc that is used to watch -// an AMI for state changes. -func AMIStateRefreshFunc(conn *ec2.EC2, imageId string) StateRefreshFunc { - return func() (interface{}, string, error) { - resp, err := conn.DescribeImages(&ec2.DescribeImagesInput{ - ImageIds: []*string{&imageId}, - }) - if err != nil { - if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidAMIID.NotFound" { - // Set this to nil as if we didn't find anything. - resp = nil - } else if isTransientNetworkError(err) { - // Transient network error, treat it as if we didn't find anything - resp = nil - } else { - log.Printf("Error on AMIStateRefresh: %s", err) - return nil, "", err - } - } +// Following are wrapper functions that use Packer's environment-variables to +// determing retry logic, then call the AWS SDK's built-in waiters. - if resp == nil || len(resp.Images) == 0 { - // Sometimes AWS has consistency issues and doesn't see the - // AMI. Return an empty state. - return nil, "", nil - } - - i := resp.Images[0] - return i, *i.State, nil +func WaitUntilAMIAvailable(conn *ec2.EC2, imageId string) error { + imageInput := ec2.DescribeImagesInput{ + ImageIds: []*string{&imageId}, } + + err := conn.WaitUntilImageAvailableWithContext(aws.BackgroundContext(), + &imageInput, + getWaiterOptions()...) + return err } -// InstanceStateRefreshFunc returns a StateRefreshFunc that is used to watch -// an EC2 instance. -func InstanceStateRefreshFunc(conn *ec2.EC2, instanceId string) StateRefreshFunc { - return func() (interface{}, string, error) { - resp, err := conn.DescribeInstances(&ec2.DescribeInstancesInput{ - InstanceIds: []*string{&instanceId}, - }) - if err != nil { - if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidInstanceID.NotFound" { - // Set this to nil as if we didn't find anything. - resp = nil - } else if isTransientNetworkError(err) { - // Transient network error, treat it as if we didn't find anything - resp = nil - } else { - log.Printf("Error on InstanceStateRefresh: %s", err) - return nil, "", err - } - } +func WaitUntilInstanceTerminated(conn *ec2.EC2, instanceId string) error { - if resp == nil || len(resp.Reservations) == 0 || len(resp.Reservations[0].Instances) == 0 { - // Sometimes AWS just has consistency issues and doesn't see - // our instance yet. Return an empty state. - return nil, "", nil - } - - i := resp.Reservations[0].Instances[0] - return i, *i.State.Name, nil + instanceInput := ec2.DescribeInstancesInput{ + InstanceIds: []*string{&instanceId}, } + + err := conn.WaitUntilInstanceTerminatedWithContext(aws.BackgroundContext(), + &instanceInput, + getWaiterOptions()...) + return err } -// SpotRequestStateRefreshFunc returns a StateRefreshFunc that is used to watch -// a spot request for state changes. -func SpotRequestStateRefreshFunc(conn *ec2.EC2, spotRequestId string) StateRefreshFunc { - return func() (interface{}, string, error) { - resp, err := conn.DescribeSpotInstanceRequests(&ec2.DescribeSpotInstanceRequestsInput{ - SpotInstanceRequestIds: []*string{&spotRequestId}, - }) - - if err != nil { - if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidSpotInstanceRequestID.NotFound" { - // Set this to nil as if we didn't find anything. - resp = nil - } else if isTransientNetworkError(err) { - // Transient network error, treat it as if we didn't find anything - resp = nil - } else { - log.Printf("Error on SpotRequestStateRefresh: %s", err) - return nil, "", err - } - } - - if resp == nil || len(resp.SpotInstanceRequests) == 0 { - // Sometimes AWS has consistency issues and doesn't see the - // SpotRequest. Return an empty state. - return nil, "", nil - } - - i := resp.SpotInstanceRequests[0] - return i, *i.State, nil +// This function works for both requesting and cancelling spot instances. +func WaitUntilSpotRequestFulfilled(conn *ec2.EC2, spotRequestId string) error { + spotRequestInput := ec2.DescribeSpotInstanceRequestsInput{ + SpotInstanceRequestIds: []*string{&spotRequestId}, } + + err := conn.WaitUntilSpotInstanceRequestFulfilledWithContext(aws.BackgroundContext(), + &spotRequestInput, + getWaiterOptions()...) + return err } -func ImportImageRefreshFunc(conn *ec2.EC2, importTaskId string) StateRefreshFunc { - return func() (interface{}, string, error) { - resp, err := conn.DescribeImportImageTasks(&ec2.DescribeImportImageTasksInput{ - ImportTaskIds: []*string{ - &importTaskId, +func WaitUntilVolumeAvailable(conn *ec2.EC2, volumeId string) error { + volumeInput := ec2.DescribeVolumesInput{ + VolumeIds: []*string{&volumeId}, + } + + err := conn.WaitUntilVolumeAvailableWithContext(aws.BackgroundContext(), + &volumeInput, + getWaiterOptions()...) + return err +} + +func WaitUntilSnapshotDone(conn *ec2.EC2, snapshotID string) error { + snapInput := ec2.DescribeSnapshotsInput{ + SnapshotIds: []*string{&snapshotID}, + } + + err := conn.WaitUntilSnapshotCompletedWithContext(aws.BackgroundContext(), + &snapInput, + getWaiterOptions()...) + return err +} + +// Wrappers for our custom AWS waiters + +func WaitUntilVolumeAttached(conn *ec2.EC2, volumeId string) error { + volumeInput := ec2.DescribeVolumesInput{ + VolumeIds: []*string{&volumeId}, + } + + err := WaitForVolumeToBeAttached(conn, + aws.BackgroundContext(), + &volumeInput, + getWaiterOptions()...) + return err +} + +func WaitUntilVolumeDetached(conn *ec2.EC2, volumeId string) error { + volumeInput := ec2.DescribeVolumesInput{ + VolumeIds: []*string{&volumeId}, + } + + err := WaitForVolumeToBeAttached(conn, + aws.BackgroundContext(), + &volumeInput, + getWaiterOptions()...) + return err +} + +func WaitUntilImageImported(conn *ec2.EC2, taskID string) error { + importInput := ec2.DescribeImportImageTasksInput{ + ImportTaskIds: []*string{&taskID}, + } + + err := WaitForImageToBeImported(conn, + aws.BackgroundContext(), + &importInput, + getWaiterOptions()...) + return err +} + +// Custom waiters using AWS's request.Waiter + +func WaitForVolumeToBeAttached(c *ec2.EC2, ctx aws.Context, input *ec2.DescribeVolumesInput, opts ...request.WaiterOption) error { + w := request.Waiter{ + Name: "DescribeVolumes", + MaxAttempts: 40, + Delay: request.ConstantWaiterDelay(5 * time.Second), + Acceptors: []request.WaiterAcceptor{ + { + State: request.SuccessWaiterState, + Matcher: request.PathAllWaiterMatch, + Argument: "Volumes[].State", + Expected: "attached", + }, + { + State: request.FailureWaiterState, + Matcher: request.PathAnyWaiterMatch, + Argument: "Volumes[].State", + Expected: "deleted", }, }, - ) - if err != nil { - if ec2err, ok := err.(awserr.Error); ok && strings.HasPrefix(ec2err.Code(), "InvalidConversionTaskId") { - resp = nil - } else if isTransientNetworkError(err) { - resp = nil - } else { - log.Printf("Error on ImportImageRefresh: %s", err) - return nil, "", err + Logger: c.Config.Logger, + NewRequest: func(opts []request.Option) (*request.Request, error) { + var inCpy *ec2.DescribeVolumesInput + if input != nil { + tmp := *input + inCpy = &tmp } - } - - if resp == nil || len(resp.ImportImageTasks) == 0 { - return nil, "", nil - } - - i := resp.ImportImageTasks[0] - return i, *i.Status, nil + req, _ := c.DescribeVolumesRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, } + return w.WaitWithContext(ctx) } -// WaitForState watches an object and waits for it to achieve a certain -// state. -func WaitForState(conf *StateChangeConf) (i interface{}, err error) { - log.Printf("Waiting for state to become: %s", conf.Target) - - sleepSeconds := SleepSeconds() - maxTicks := TimeoutSeconds()/sleepSeconds + 1 - notfoundTick := 0 - - for { - var currentState string - i, currentState, err = conf.Refresh() - if err != nil { - return - } - - if i == nil { - // If we didn't find the resource, check if we have been - // not finding it for awhile, and if so, report an error. - notfoundTick += 1 - if notfoundTick > maxTicks { - return nil, errors.New("couldn't find resource") +func WaitForVolumeToBeDetached(c *ec2.EC2, ctx aws.Context, input *ec2.DescribeVolumesInput, opts ...request.WaiterOption) error { + w := request.Waiter{ + Name: "DescribeVolumes", + MaxAttempts: 40, + Delay: request.ConstantWaiterDelay(5 * time.Second), + Acceptors: []request.WaiterAcceptor{ + { + State: request.SuccessWaiterState, + Matcher: request.PathAllWaiterMatch, + Argument: "Volumes[].State", + Expected: "detached", + }, + }, + Logger: c.Config.Logger, + NewRequest: func(opts []request.Option) (*request.Request, error) { + var inCpy *ec2.DescribeVolumesInput + if input != nil { + tmp := *input + inCpy = &tmp } - } else { - // Reset the counter for when a resource isn't found - notfoundTick = 0 - - if currentState == conf.Target { - return - } - - if conf.StepState != nil { - if _, ok := conf.StepState.GetOk(multistep.StateCancelled); ok { - return nil, errors.New("interrupted") - } - } - - found := false - for _, allowed := range conf.Pending { - if currentState == allowed { - found = true - break - } - } - - if !found { - err := fmt.Errorf("unexpected state '%s', wanted target '%s'", currentState, conf.Target) - return nil, err - } - } - - time.Sleep(time.Duration(sleepSeconds) * time.Second) + req, _ := c.DescribeVolumesRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, } + return w.WaitWithContext(ctx) } -func isTransientNetworkError(err error) bool { - if nerr, ok := err.(net.Error); ok && nerr.Temporary() { - return true +func WaitForImageToBeImported(c *ec2.EC2, ctx aws.Context, input *ec2.DescribeImportImageTasksInput, opts ...request.WaiterOption) error { + w := request.Waiter{ + Name: "DescribeImages", + MaxAttempts: 40, + Delay: request.ConstantWaiterDelay(5 * time.Second), + Acceptors: []request.WaiterAcceptor{ + { + State: request.SuccessWaiterState, + Matcher: request.PathAllWaiterMatch, + Argument: "ImportImageTasks[].State", + Expected: "completed", + }, + { + State: request.RetryWaiterState, + Matcher: request.ErrorWaiterMatch, + Expected: "InvalidConversionTaskId", + }, + }, + Logger: c.Config.Logger, + NewRequest: func(opts []request.Option) (*request.Request, error) { + var inCpy *ec2.DescribeImportImageTasksInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.DescribeImportImageTasksRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, } + return w.WaitWithContext(ctx) +} - return false +// This helper function uses the environment variables AWS_TIMEOUT_SECONDS and +// AWS_POLL_DELAY_SECONDS to generate waiter options that can be passed into any +// request.Waiter function. These options will control how many times the waiter +// will retry the request, as well as how long to wait between the retries. +func getWaiterOptions() []request.WaiterOption { + // use env vars to read in the wait delay and the max amount of time to wait + delay := SleepSeconds() + timeoutSeconds := TimeoutSeconds() + // AWS sdk uses max attempts instead of a timeout; convert timeout into + // max attempts + maxAttempts := timeoutSeconds / delay + delaySeconds := request.ConstantWaiterDelay(time.Duration(delay) * time.Second) + + return []request.WaiterOption{ + request.WithWaiterDelay(delaySeconds), + request.WithWaiterMaxAttempts(maxAttempts)} } // Returns 300 seconds (5 minutes) by default diff --git a/builder/amazon/common/step_ami_region_copy.go b/builder/amazon/common/step_ami_region_copy.go index a3d92b467..511a523fb 100644 --- a/builder/amazon/common/step_ami_region_copy.go +++ b/builder/amazon/common/step_ami_region_copy.go @@ -116,14 +116,8 @@ func amiRegionCopy(state multistep.StateBag, config *AccessConfig, name string, imageId, target, err) } - stateChange := StateChangeConf{ - Pending: []string{"pending"}, - Target: "available", - Refresh: AMIStateRefreshFunc(regionconn, *resp.ImageId), - StepState: state, - } - - if _, err := WaitForState(&stateChange); err != nil { + // Wait for the image to become ready + if err := WaitUntilAMIAvailable(regionconn, *resp.ImageId); err != nil { return "", snapshotIds, fmt.Errorf("Error waiting for AMI (%s) in region (%s): %s", *resp.ImageId, target, err) } diff --git a/builder/amazon/common/step_encrypted_ami.go b/builder/amazon/common/step_encrypted_ami.go index a07c0ee25..5125a70b0 100644 --- a/builder/amazon/common/step_encrypted_ami.go +++ b/builder/amazon/common/step_encrypted_ami.go @@ -65,15 +65,8 @@ func (s *StepCreateEncryptedAMICopy) Run(_ context.Context, state multistep.Stat } // Wait for the copy to become ready - stateChange := StateChangeConf{ - Pending: []string{"pending"}, - Target: "available", - Refresh: AMIStateRefreshFunc(ec2conn, *copyResp.ImageId), - StepState: state, - } - ui.Say("Waiting for AMI copy to become ready...") - if _, err := WaitForState(&stateChange); err != nil { + if err := WaitUntilAMIAvailable(ec2conn, *copyResp.ImageId); err != nil { err := fmt.Errorf("Error waiting for AMI Copy: %s", err) state.Put("error", err) ui.Error(err.Error()) diff --git a/builder/amazon/common/step_run_source_instance.go b/builder/amazon/common/step_run_source_instance.go index 4dd8fbe74..a7fb84076 100644 --- a/builder/amazon/common/step_run_source_instance.go +++ b/builder/amazon/common/step_run_source_instance.go @@ -303,14 +303,8 @@ func (s *StepRunSourceInstance) Cleanup(state multistep.StateBag) { ui.Error(fmt.Sprintf("Error terminating instance, may still be around: %s", err)) return } - stateChange := StateChangeConf{ - Pending: []string{"pending", "running", "shutting-down", "stopped", "stopping"}, - Refresh: InstanceStateRefreshFunc(ec2conn, s.instanceId), - Target: "terminated", - } - _, err := WaitForState(&stateChange) - if err != nil { + if err := WaitUntilInstanceTerminated(ec2conn, s.instanceId); err != nil { ui.Error(err.Error()) } } diff --git a/builder/amazon/common/step_run_spot_instance.go b/builder/amazon/common/step_run_spot_instance.go index 8c7cbf74a..4b0dc6005 100644 --- a/builder/amazon/common/step_run_spot_instance.go +++ b/builder/amazon/common/step_run_spot_instance.go @@ -202,13 +202,7 @@ func (s *StepRunSpotInstance) Run(ctx context.Context, state multistep.StateBag) spotRequestId := s.spotRequest.SpotInstanceRequestId ui.Message(fmt.Sprintf("Waiting for spot request (%s) to become active...", *spotRequestId)) - stateChange := StateChangeConf{ - Pending: []string{"open"}, - Target: "active", - Refresh: SpotRequestStateRefreshFunc(ec2conn, *spotRequestId), - StepState: state, - } - _, err = WaitForState(&stateChange) + err = WaitUntilSpotRequestFulfilled(ec2conn, *spotRequestId) if err != nil { err := fmt.Errorf("Error waiting for spot request (%s) to become ready: %s", *spotRequestId, err) state.Put("error", err) @@ -344,13 +338,8 @@ func (s *StepRunSpotInstance) Cleanup(state multistep.StateBag) { ui.Error(fmt.Sprintf("Error cancelling the spot request, may still be around: %s", err)) return } - stateChange := StateChangeConf{ - Pending: []string{"active", "open"}, - Refresh: SpotRequestStateRefreshFunc(ec2conn, *s.spotRequest.SpotInstanceRequestId), - Target: "cancelled", - } - _, err := WaitForState(&stateChange) + err := WaitUntilSpotRequestFulfilled(ec2conn, *s.spotRequest.SpotInstanceRequestId) if err != nil { ui.Error(err.Error()) } @@ -364,14 +353,8 @@ func (s *StepRunSpotInstance) Cleanup(state multistep.StateBag) { ui.Error(fmt.Sprintf("Error terminating instance, may still be around: %s", err)) return } - stateChange := StateChangeConf{ - Pending: []string{"pending", "running", "shutting-down", "stopped", "stopping"}, - Refresh: InstanceStateRefreshFunc(ec2conn, s.instanceId), - Target: "terminated", - } - _, err := WaitForState(&stateChange) - if err != nil { + if err := WaitUntilInstanceTerminated(ec2conn, s.instanceId); err != nil { ui.Error(err.Error()) } } diff --git a/builder/amazon/ebs/step_create_ami.go b/builder/amazon/ebs/step_create_ami.go index 4782f533b..cb3329325 100644 --- a/builder/amazon/ebs/step_create_ami.go +++ b/builder/amazon/ebs/step_create_ami.go @@ -44,15 +44,8 @@ func (s *stepCreateAMI) Run(_ context.Context, state multistep.StateBag) multist state.Put("amis", amis) // Wait for the image to become ready - stateChange := awscommon.StateChangeConf{ - Pending: []string{"pending"}, - Target: "available", - Refresh: awscommon.AMIStateRefreshFunc(ec2conn, *createResp.ImageId), - StepState: state, - } - ui.Say("Waiting for AMI to become ready...") - if _, err := awscommon.WaitForState(&stateChange); err != nil { + if err := awscommon.WaitUntilAMIAvailable(ec2conn, *createResp.ImageId); err != nil { log.Printf("Error waiting for AMI: %s", err) imagesResp, err := ec2conn.DescribeImages(&ec2.DescribeImagesInput{ImageIds: []*string{createResp.ImageId}}) if err != nil { diff --git a/builder/amazon/ebssurrogate/step_register_ami.go b/builder/amazon/ebssurrogate/step_register_ami.go index 4c12adca6..4f6a88667 100644 --- a/builder/amazon/ebssurrogate/step_register_ami.go +++ b/builder/amazon/ebssurrogate/step_register_ami.go @@ -63,15 +63,8 @@ func (s *StepRegisterAMI) Run(_ context.Context, state multistep.StateBag) multi state.Put("amis", amis) // Wait for the image to become ready - stateChange := awscommon.StateChangeConf{ - Pending: []string{"pending"}, - Target: "available", - Refresh: awscommon.AMIStateRefreshFunc(ec2conn, *registerResp.ImageId), - StepState: state, - } - ui.Say("Waiting for AMI to become ready...") - if _, err := awscommon.WaitForState(&stateChange); err != nil { + if err := awscommon.WaitUntilAMIAvailable(ec2conn, *registerResp.ImageId); err != nil { err := fmt.Errorf("Error waiting for AMI: %s", err) state.Put("error", err) ui.Error(err.Error()) diff --git a/builder/amazon/ebssurrogate/step_snapshot_volumes.go b/builder/amazon/ebssurrogate/step_snapshot_volumes.go index 9de755ca5..3beef0a8e 100644 --- a/builder/amazon/ebssurrogate/step_snapshot_volumes.go +++ b/builder/amazon/ebssurrogate/step_snapshot_volumes.go @@ -2,7 +2,6 @@ package ebssurrogate import ( "context" - "errors" "fmt" "sync" "time" @@ -52,29 +51,8 @@ func (s *StepSnapshotVolumes) snapshotVolume(deviceName string, state multistep. // Set the snapshot ID so we can delete it later s.snapshotIds[deviceName] = *createSnapResp.SnapshotId - // Wait for the snapshot to be ready - stateChange := awscommon.StateChangeConf{ - Pending: []string{"pending"}, - StepState: state, - Target: "completed", - Refresh: func() (interface{}, string, error) { - resp, err := ec2conn.DescribeSnapshots(&ec2.DescribeSnapshotsInput{ - SnapshotIds: []*string{createSnapResp.SnapshotId}, - }) - if err != nil { - return nil, "", err - } - - if len(resp.Snapshots) == 0 { - return nil, "", errors.New("No snapshots found.") - } - - s := resp.Snapshots[0] - return s, *s.State, nil - }, - } - - _, err = awscommon.WaitForState(&stateChange) + // Wait for snapshot to be created + err = awscommon.WaitUntilSnapshotDone(ec2conn, *createSnapResp.SnapshotId) return err } diff --git a/builder/amazon/instance/step_register_ami.go b/builder/amazon/instance/step_register_ami.go index c46ff8ae4..7ddb5bd57 100644 --- a/builder/amazon/instance/step_register_ami.go +++ b/builder/amazon/instance/step_register_ami.go @@ -58,15 +58,8 @@ func (s *StepRegisterAMI) Run(_ context.Context, state multistep.StateBag) multi state.Put("amis", amis) // Wait for the image to become ready - stateChange := awscommon.StateChangeConf{ - Pending: []string{"pending"}, - Target: "available", - Refresh: awscommon.AMIStateRefreshFunc(ec2conn, *registerResp.ImageId), - StepState: state, - } - ui.Say("Waiting for AMI to become ready...") - if _, err := awscommon.WaitForState(&stateChange); err != nil { + if err := awscommon.WaitUntilAMIAvailable(ec2conn, *registerResp.ImageId); err != nil { err := fmt.Errorf("Error waiting for AMI: %s", err) state.Put("error", err) ui.Error(err.Error()) diff --git a/post-processor/amazon-import/post-processor.go b/post-processor/amazon-import/post-processor.go index 5be505b0e..2dbbcc6c7 100644 --- a/post-processor/amazon-import/post-processor.go +++ b/post-processor/amazon-import/post-processor.go @@ -186,16 +186,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac // Wait for import process to complete, this takes a while ui.Message(fmt.Sprintf("Waiting for task %s to complete (may take a while)", *import_start.ImportTaskId)) - - stateChange := awscommon.StateChangeConf{ - Pending: []string{"pending", "active"}, - Refresh: awscommon.ImportImageRefreshFunc(ec2conn, *import_start.ImportTaskId), - Target: "completed", - } - - // Actually do the wait for state change - // We ignore errors out of this and check job state in AWS API - awscommon.WaitForState(&stateChange) + err = awscommon.WaitUntilImageImported(ec2conn, *import_start.ImportTaskId) // Retrieve what the outcome was for the import task import_result, err := ec2conn.DescribeImportImageTasks(&ec2.DescribeImportImageTasksInput{ @@ -235,13 +226,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac ui.Message(fmt.Sprintf("Waiting for AMI rename to complete (may take a while)")) - stateChange := awscommon.StateChangeConf{ - Pending: []string{"pending"}, - Target: "available", - Refresh: awscommon.AMIStateRefreshFunc(ec2conn, *resp.ImageId), - } - - if _, err := awscommon.WaitForState(&stateChange); err != nil { + if err := awscommon.WaitUntilAMIAvailable(ec2conn, *resp.ImageId); err != nil { return nil, false, fmt.Errorf("Error waiting for AMI (%s): %s", *resp.ImageId, err) } From f49a2d8aed87e73094f30603a87592d60363c8d6 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Fri, 1 Jun 2018 16:17:30 -0700 Subject: [PATCH 083/220] move UI call to before the wait; add context to these steps --- builder/amazon/chroot/step_attach_volume.go | 7 ++-- builder/amazon/chroot/step_create_volume.go | 4 +- builder/amazon/chroot/step_register_ami.go | 6 +-- builder/amazon/chroot/step_snapshot.go | 4 +- builder/amazon/common/state.go | 39 +++++++++++-------- builder/amazon/common/step_ami_region_copy.go | 8 ++-- builder/amazon/common/step_encrypted_ami.go | 4 +- .../amazon/common/step_run_source_instance.go | 2 +- .../amazon/common/step_run_spot_instance.go | 6 +-- builder/amazon/ebs/step_create_ami.go | 4 +- .../amazon/ebssurrogate/step_register_ami.go | 4 +- .../ebssurrogate/step_snapshot_volumes.go | 8 ++-- builder/amazon/instance/step_register_ami.go | 4 +- .../amazon-import/post-processor.go | 4 +- 14 files changed, 54 insertions(+), 50 deletions(-) diff --git a/builder/amazon/chroot/step_attach_volume.go b/builder/amazon/chroot/step_attach_volume.go index 7698ece07..7044e0218 100644 --- a/builder/amazon/chroot/step_attach_volume.go +++ b/builder/amazon/chroot/step_attach_volume.go @@ -5,6 +5,7 @@ import ( "fmt" "strings" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" awscommon "github.com/hashicorp/packer/builder/amazon/common" "github.com/hashicorp/packer/helper/multistep" @@ -22,7 +23,7 @@ type StepAttachVolume struct { volumeId string } -func (s *StepAttachVolume) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *StepAttachVolume) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) device := state.Get("device").(string) instance := state.Get("instance").(*ec2.Instance) @@ -50,7 +51,7 @@ func (s *StepAttachVolume) Run(_ context.Context, state multistep.StateBag) mult s.volumeId = volumeId // Wait for the volume to become attached - err = awscommon.WaitUntilVolumeAttached(ec2conn, s.volumeId) + err = awscommon.WaitUntilVolumeAttached(ctx, ec2conn, s.volumeId) if err != nil { err := fmt.Errorf("Error waiting for volume: %s", err) state.Put("error", err) @@ -86,7 +87,7 @@ func (s *StepAttachVolume) CleanupFunc(state multistep.StateBag) error { s.attached = false // Wait for the volume to detach - err = awscommon.WaitUntilVolumeDetached(ec2conn, s.volumeId) + err = awscommon.WaitUntilVolumeDetached(aws.BackgroundContext(), ec2conn, s.volumeId) if err != nil { return fmt.Errorf("Error waiting for volume: %s", err) } diff --git a/builder/amazon/chroot/step_create_volume.go b/builder/amazon/chroot/step_create_volume.go index c10fda4da..725c8240b 100644 --- a/builder/amazon/chroot/step_create_volume.go +++ b/builder/amazon/chroot/step_create_volume.go @@ -22,7 +22,7 @@ type StepCreateVolume struct { RootVolumeSize int64 } -func (s *StepCreateVolume) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *StepCreateVolume) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) ec2conn := state.Get("ec2").(*ec2.EC2) instance := state.Get("instance").(*ec2.Instance) @@ -84,7 +84,7 @@ func (s *StepCreateVolume) Run(_ context.Context, state multistep.StateBag) mult log.Printf("Volume ID: %s", s.volumeId) // Wait for the volume to become ready - err = awscommon.WaitUntilVolumeAvailable(ec2conn, s.volumeId) + err = awscommon.WaitUntilVolumeAvailable(ctx, ec2conn, s.volumeId) if err != nil { err := fmt.Errorf("Error waiting for volume: %s", err) state.Put("error", err) diff --git a/builder/amazon/chroot/step_register_ami.go b/builder/amazon/chroot/step_register_ami.go index 31a41cb9d..4f3ad54c4 100644 --- a/builder/amazon/chroot/step_register_ami.go +++ b/builder/amazon/chroot/step_register_ami.go @@ -102,16 +102,14 @@ func (s *StepRegisterAMI) Run(ctx context.Context, state multistep.StateBag) mul amis[*ec2conn.Config.Region] = *registerResp.ImageId state.Put("amis", amis) - // Wait for the image to become ready - if err := awscommon.WaitUntilAMIAvailable(ec2conn, *registerResp.ImageId); err != nil { + ui.Say("Waiting for AMI to become ready...") + if err := awscommon.WaitUntilAMIAvailable(ctx, ec2conn, *registerResp.ImageId); err != nil { err := fmt.Errorf("Error waiting for AMI: %s", err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } - ui.Say("Waiting for AMI to become ready...") - return multistep.ActionContinue } diff --git a/builder/amazon/chroot/step_snapshot.go b/builder/amazon/chroot/step_snapshot.go index 4e9070bc5..4c66b4fd1 100644 --- a/builder/amazon/chroot/step_snapshot.go +++ b/builder/amazon/chroot/step_snapshot.go @@ -19,7 +19,7 @@ type StepSnapshot struct { snapshotId string } -func (s *StepSnapshot) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *StepSnapshot) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) ui := state.Get("ui").(packer.Ui) volumeId := state.Get("volume_id").(string) @@ -43,7 +43,7 @@ func (s *StepSnapshot) Run(_ context.Context, state multistep.StateBag) multiste ui.Message(fmt.Sprintf("Snapshot ID: %s", s.snapshotId)) // Wait for the snapshot to be ready - err = awscommon.WaitUntilSnapshotDone(ec2conn, s.snapshotId) + err = awscommon.WaitUntilSnapshotDone(ctx, ec2conn, s.snapshotId) if err != nil { err := fmt.Errorf("Error waiting for snapshot: %s", err) state.Put("error", err) diff --git a/builder/amazon/common/state.go b/builder/amazon/common/state.go index 50e4e4b7a..7104bc7ab 100644 --- a/builder/amazon/common/state.go +++ b/builder/amazon/common/state.go @@ -35,58 +35,63 @@ type StateChangeConf struct { // Following are wrapper functions that use Packer's environment-variables to // determing retry logic, then call the AWS SDK's built-in waiters. -func WaitUntilAMIAvailable(conn *ec2.EC2, imageId string) error { +func WaitUntilAMIAvailable(ctx aws.Context, conn *ec2.EC2, imageId string) error { imageInput := ec2.DescribeImagesInput{ ImageIds: []*string{&imageId}, } - err := conn.WaitUntilImageAvailableWithContext(aws.BackgroundContext(), + err := conn.WaitUntilImageAvailableWithContext( + ctx, &imageInput, getWaiterOptions()...) return err } -func WaitUntilInstanceTerminated(conn *ec2.EC2, instanceId string) error { +func WaitUntilInstanceTerminated(ctx aws.Context, conn *ec2.EC2, instanceId string) error { instanceInput := ec2.DescribeInstancesInput{ InstanceIds: []*string{&instanceId}, } - err := conn.WaitUntilInstanceTerminatedWithContext(aws.BackgroundContext(), + err := conn.WaitUntilInstanceTerminatedWithContext( + ctx, &instanceInput, getWaiterOptions()...) return err } // This function works for both requesting and cancelling spot instances. -func WaitUntilSpotRequestFulfilled(conn *ec2.EC2, spotRequestId string) error { +func WaitUntilSpotRequestFulfilled(ctx aws.Context, conn *ec2.EC2, spotRequestId string) error { spotRequestInput := ec2.DescribeSpotInstanceRequestsInput{ SpotInstanceRequestIds: []*string{&spotRequestId}, } - err := conn.WaitUntilSpotInstanceRequestFulfilledWithContext(aws.BackgroundContext(), + err := conn.WaitUntilSpotInstanceRequestFulfilledWithContext( + ctx, &spotRequestInput, getWaiterOptions()...) return err } -func WaitUntilVolumeAvailable(conn *ec2.EC2, volumeId string) error { +func WaitUntilVolumeAvailable(ctx aws.Context, conn *ec2.EC2, volumeId string) error { volumeInput := ec2.DescribeVolumesInput{ VolumeIds: []*string{&volumeId}, } - err := conn.WaitUntilVolumeAvailableWithContext(aws.BackgroundContext(), + err := conn.WaitUntilVolumeAvailableWithContext( + ctx, &volumeInput, getWaiterOptions()...) return err } -func WaitUntilSnapshotDone(conn *ec2.EC2, snapshotID string) error { +func WaitUntilSnapshotDone(ctx aws.Context, conn *ec2.EC2, snapshotID string) error { snapInput := ec2.DescribeSnapshotsInput{ SnapshotIds: []*string{&snapshotID}, } - err := conn.WaitUntilSnapshotCompletedWithContext(aws.BackgroundContext(), + err := conn.WaitUntilSnapshotCompletedWithContext( + ctx, &snapInput, getWaiterOptions()...) return err @@ -94,37 +99,37 @@ func WaitUntilSnapshotDone(conn *ec2.EC2, snapshotID string) error { // Wrappers for our custom AWS waiters -func WaitUntilVolumeAttached(conn *ec2.EC2, volumeId string) error { +func WaitUntilVolumeAttached(ctx aws.Context, conn *ec2.EC2, volumeId string) error { volumeInput := ec2.DescribeVolumesInput{ VolumeIds: []*string{&volumeId}, } err := WaitForVolumeToBeAttached(conn, - aws.BackgroundContext(), + ctx, &volumeInput, getWaiterOptions()...) return err } -func WaitUntilVolumeDetached(conn *ec2.EC2, volumeId string) error { +func WaitUntilVolumeDetached(ctx aws.Context, conn *ec2.EC2, volumeId string) error { volumeInput := ec2.DescribeVolumesInput{ VolumeIds: []*string{&volumeId}, } - err := WaitForVolumeToBeAttached(conn, - aws.BackgroundContext(), + err := WaitForVolumeToBeDetached(conn, + ctx, &volumeInput, getWaiterOptions()...) return err } -func WaitUntilImageImported(conn *ec2.EC2, taskID string) error { +func WaitUntilImageImported(ctx aws.Context, conn *ec2.EC2, taskID string) error { importInput := ec2.DescribeImportImageTasksInput{ ImportTaskIds: []*string{&taskID}, } err := WaitForImageToBeImported(conn, - aws.BackgroundContext(), + ctx, &importInput, getWaiterOptions()...) return err diff --git a/builder/amazon/common/step_ami_region_copy.go b/builder/amazon/common/step_ami_region_copy.go index 511a523fb..d14fa472e 100644 --- a/builder/amazon/common/step_ami_region_copy.go +++ b/builder/amazon/common/step_ami_region_copy.go @@ -20,7 +20,7 @@ type StepAMIRegionCopy struct { Name string } -func (s *StepAMIRegionCopy) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *StepAMIRegionCopy) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) ui := state.Get("ui").(packer.Ui) amis := state.Get("amis").(map[string]string) @@ -53,7 +53,7 @@ func (s *StepAMIRegionCopy) Run(_ context.Context, state multistep.StateBag) mul go func(region string) { defer wg.Done() - id, snapshotIds, err := amiRegionCopy(state, s.AccessConfig, s.Name, ami, region, *ec2conn.Config.Region, regKeyID) + id, snapshotIds, err := amiRegionCopy(ctx, state, s.AccessConfig, s.Name, ami, region, *ec2conn.Config.Region, regKeyID) lock.Lock() defer lock.Unlock() amis[region] = id @@ -85,7 +85,7 @@ func (s *StepAMIRegionCopy) Cleanup(state multistep.StateBag) { // amiRegionCopy does a copy for the given AMI to the target region and // returns the resulting ID and snapshot IDs, or error. -func amiRegionCopy(state multistep.StateBag, config *AccessConfig, name string, imageId string, +func amiRegionCopy(ctx context.Context, state multistep.StateBag, config *AccessConfig, name string, imageId string, target string, source string, keyID string) (string, []string, error) { snapshotIds := []string{} isEncrypted := false @@ -117,7 +117,7 @@ func amiRegionCopy(state multistep.StateBag, config *AccessConfig, name string, } // Wait for the image to become ready - if err := WaitUntilAMIAvailable(regionconn, *resp.ImageId); err != nil { + if err := WaitUntilAMIAvailable(ctx, regionconn, *resp.ImageId); err != nil { return "", snapshotIds, fmt.Errorf("Error waiting for AMI (%s) in region (%s): %s", *resp.ImageId, target, err) } diff --git a/builder/amazon/common/step_encrypted_ami.go b/builder/amazon/common/step_encrypted_ami.go index 5125a70b0..0ad8bd5d3 100644 --- a/builder/amazon/common/step_encrypted_ami.go +++ b/builder/amazon/common/step_encrypted_ami.go @@ -19,7 +19,7 @@ type StepCreateEncryptedAMICopy struct { AMIMappings []BlockDevice } -func (s *StepCreateEncryptedAMICopy) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *StepCreateEncryptedAMICopy) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) ui := state.Get("ui").(packer.Ui) kmsKeyId := s.KeyID @@ -66,7 +66,7 @@ func (s *StepCreateEncryptedAMICopy) Run(_ context.Context, state multistep.Stat // Wait for the copy to become ready ui.Say("Waiting for AMI copy to become ready...") - if err := WaitUntilAMIAvailable(ec2conn, *copyResp.ImageId); err != nil { + if err := WaitUntilAMIAvailable(ctx, ec2conn, *copyResp.ImageId); err != nil { err := fmt.Errorf("Error waiting for AMI Copy: %s", err) state.Put("error", err) ui.Error(err.Error()) diff --git a/builder/amazon/common/step_run_source_instance.go b/builder/amazon/common/step_run_source_instance.go index a7fb84076..7c31fa1f8 100644 --- a/builder/amazon/common/step_run_source_instance.go +++ b/builder/amazon/common/step_run_source_instance.go @@ -304,7 +304,7 @@ func (s *StepRunSourceInstance) Cleanup(state multistep.StateBag) { return } - if err := WaitUntilInstanceTerminated(ec2conn, s.instanceId); err != nil { + if err := WaitUntilInstanceTerminated(aws.BackgroundContext(), ec2conn, s.instanceId); err != nil { ui.Error(err.Error()) } } diff --git a/builder/amazon/common/step_run_spot_instance.go b/builder/amazon/common/step_run_spot_instance.go index 4b0dc6005..9e5678f7f 100644 --- a/builder/amazon/common/step_run_spot_instance.go +++ b/builder/amazon/common/step_run_spot_instance.go @@ -202,7 +202,7 @@ func (s *StepRunSpotInstance) Run(ctx context.Context, state multistep.StateBag) spotRequestId := s.spotRequest.SpotInstanceRequestId ui.Message(fmt.Sprintf("Waiting for spot request (%s) to become active...", *spotRequestId)) - err = WaitUntilSpotRequestFulfilled(ec2conn, *spotRequestId) + err = WaitUntilSpotRequestFulfilled(ctx, ec2conn, *spotRequestId) if err != nil { err := fmt.Errorf("Error waiting for spot request (%s) to become ready: %s", *spotRequestId, err) state.Put("error", err) @@ -339,7 +339,7 @@ func (s *StepRunSpotInstance) Cleanup(state multistep.StateBag) { return } - err := WaitUntilSpotRequestFulfilled(ec2conn, *s.spotRequest.SpotInstanceRequestId) + err := WaitUntilSpotRequestFulfilled(aws.BackgroundContext(), ec2conn, *s.spotRequest.SpotInstanceRequestId) if err != nil { ui.Error(err.Error()) } @@ -354,7 +354,7 @@ func (s *StepRunSpotInstance) Cleanup(state multistep.StateBag) { return } - if err := WaitUntilInstanceTerminated(ec2conn, s.instanceId); err != nil { + if err := WaitUntilInstanceTerminated(aws.BackgroundContext(), ec2conn, s.instanceId); err != nil { ui.Error(err.Error()) } } diff --git a/builder/amazon/ebs/step_create_ami.go b/builder/amazon/ebs/step_create_ami.go index cb3329325..1d081db70 100644 --- a/builder/amazon/ebs/step_create_ami.go +++ b/builder/amazon/ebs/step_create_ami.go @@ -15,7 +15,7 @@ type stepCreateAMI struct { image *ec2.Image } -func (s *stepCreateAMI) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *stepCreateAMI) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(Config) ec2conn := state.Get("ec2").(*ec2.EC2) instance := state.Get("instance").(*ec2.Instance) @@ -45,7 +45,7 @@ func (s *stepCreateAMI) Run(_ context.Context, state multistep.StateBag) multist // Wait for the image to become ready ui.Say("Waiting for AMI to become ready...") - if err := awscommon.WaitUntilAMIAvailable(ec2conn, *createResp.ImageId); err != nil { + if err := awscommon.WaitUntilAMIAvailable(ctx, ec2conn, *createResp.ImageId); err != nil { log.Printf("Error waiting for AMI: %s", err) imagesResp, err := ec2conn.DescribeImages(&ec2.DescribeImagesInput{ImageIds: []*string{createResp.ImageId}}) if err != nil { diff --git a/builder/amazon/ebssurrogate/step_register_ami.go b/builder/amazon/ebssurrogate/step_register_ami.go index 4f6a88667..63e0f5581 100644 --- a/builder/amazon/ebssurrogate/step_register_ami.go +++ b/builder/amazon/ebssurrogate/step_register_ami.go @@ -21,7 +21,7 @@ type StepRegisterAMI struct { image *ec2.Image } -func (s *StepRegisterAMI) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *StepRegisterAMI) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) ec2conn := state.Get("ec2").(*ec2.EC2) snapshotIds := state.Get("snapshot_ids").(map[string]string) @@ -64,7 +64,7 @@ func (s *StepRegisterAMI) Run(_ context.Context, state multistep.StateBag) multi // Wait for the image to become ready ui.Say("Waiting for AMI to become ready...") - if err := awscommon.WaitUntilAMIAvailable(ec2conn, *registerResp.ImageId); err != nil { + if err := awscommon.WaitUntilAMIAvailable(ctx, ec2conn, *registerResp.ImageId); err != nil { err := fmt.Errorf("Error waiting for AMI: %s", err) state.Put("error", err) ui.Error(err.Error()) diff --git a/builder/amazon/ebssurrogate/step_snapshot_volumes.go b/builder/amazon/ebssurrogate/step_snapshot_volumes.go index 3beef0a8e..f238815e1 100644 --- a/builder/amazon/ebssurrogate/step_snapshot_volumes.go +++ b/builder/amazon/ebssurrogate/step_snapshot_volumes.go @@ -22,7 +22,7 @@ type StepSnapshotVolumes struct { snapshotIds map[string]string } -func (s *StepSnapshotVolumes) snapshotVolume(deviceName string, state multistep.StateBag) error { +func (s *StepSnapshotVolumes) snapshotVolume(ctx context.Context, deviceName string, state multistep.StateBag) error { ec2conn := state.Get("ec2").(*ec2.EC2) ui := state.Get("ui").(packer.Ui) instance := state.Get("instance").(*ec2.Instance) @@ -52,11 +52,11 @@ func (s *StepSnapshotVolumes) snapshotVolume(deviceName string, state multistep. s.snapshotIds[deviceName] = *createSnapResp.SnapshotId // Wait for snapshot to be created - err = awscommon.WaitUntilSnapshotDone(ec2conn, *createSnapResp.SnapshotId) + err = awscommon.WaitUntilSnapshotDone(ctx, ec2conn, *createSnapResp.SnapshotId) return err } -func (s *StepSnapshotVolumes) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *StepSnapshotVolumes) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) s.snapshotIds = map[string]string{} @@ -67,7 +67,7 @@ func (s *StepSnapshotVolumes) Run(_ context.Context, state multistep.StateBag) m wg.Add(1) go func(device *ec2.BlockDeviceMapping) { defer wg.Done() - if err := s.snapshotVolume(*device.DeviceName, state); err != nil { + if err := s.snapshotVolume(ctx, *device.DeviceName, state); err != nil { errs = multierror.Append(errs, err) } }(device) diff --git a/builder/amazon/instance/step_register_ami.go b/builder/amazon/instance/step_register_ami.go index 7ddb5bd57..20df1f0d4 100644 --- a/builder/amazon/instance/step_register_ami.go +++ b/builder/amazon/instance/step_register_ami.go @@ -16,7 +16,7 @@ type StepRegisterAMI struct { EnableAMISriovNetSupport bool } -func (s *StepRegisterAMI) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *StepRegisterAMI) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) ec2conn := state.Get("ec2").(*ec2.EC2) manifestPath := state.Get("remote_manifest_path").(string) @@ -59,7 +59,7 @@ func (s *StepRegisterAMI) Run(_ context.Context, state multistep.StateBag) multi // Wait for the image to become ready ui.Say("Waiting for AMI to become ready...") - if err := awscommon.WaitUntilAMIAvailable(ec2conn, *registerResp.ImageId); err != nil { + if err := awscommon.WaitUntilAMIAvailable(ctx, ec2conn, *registerResp.ImageId); err != nil { err := fmt.Errorf("Error waiting for AMI: %s", err) state.Put("error", err) ui.Error(err.Error()) diff --git a/post-processor/amazon-import/post-processor.go b/post-processor/amazon-import/post-processor.go index 2dbbcc6c7..ecf72e555 100644 --- a/post-processor/amazon-import/post-processor.go +++ b/post-processor/amazon-import/post-processor.go @@ -186,7 +186,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac // Wait for import process to complete, this takes a while ui.Message(fmt.Sprintf("Waiting for task %s to complete (may take a while)", *import_start.ImportTaskId)) - err = awscommon.WaitUntilImageImported(ec2conn, *import_start.ImportTaskId) + err = awscommon.WaitUntilImageImported(aws.BackgroundContext(), ec2conn, *import_start.ImportTaskId) // Retrieve what the outcome was for the import task import_result, err := ec2conn.DescribeImportImageTasks(&ec2.DescribeImportImageTasksInput{ @@ -226,7 +226,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac ui.Message(fmt.Sprintf("Waiting for AMI rename to complete (may take a while)")) - if err := awscommon.WaitUntilAMIAvailable(ec2conn, *resp.ImageId); err != nil { + if err := awscommon.WaitUntilAMIAvailable(aws.BackgroundContext(), ec2conn, *resp.ImageId); err != nil { return nil, false, fmt.Errorf("Error waiting for AMI (%s): %s", *resp.ImageId, err) } From bfbe3187278a20088a642fdde826a6eb2a2edc6d Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Mon, 4 Jun 2018 15:34:20 -0700 Subject: [PATCH 084/220] fix the homegrown waiters fix image import; issue was with wait options not being evaluated --- builder/amazon/common/state.go | 123 +++++++++--------- .../amazon-import/post-processor.go | 4 + 2 files changed, 69 insertions(+), 58 deletions(-) diff --git a/builder/amazon/common/state.go b/builder/amazon/common/state.go index 7104bc7ab..8d5896c70 100644 --- a/builder/amazon/common/state.go +++ b/builder/amazon/common/state.go @@ -146,15 +146,9 @@ func WaitForVolumeToBeAttached(c *ec2.EC2, ctx aws.Context, input *ec2.DescribeV { State: request.SuccessWaiterState, Matcher: request.PathAllWaiterMatch, - Argument: "Volumes[].State", + Argument: "Volumes[].Attachments[].State", Expected: "attached", }, - { - State: request.FailureWaiterState, - Matcher: request.PathAnyWaiterMatch, - Argument: "Volumes[].State", - Expected: "deleted", - }, }, Logger: c.Config.Logger, NewRequest: func(opts []request.Option) (*request.Request, error) { @@ -181,8 +175,8 @@ func WaitForVolumeToBeDetached(c *ec2.EC2, ctx aws.Context, input *ec2.DescribeV { State: request.SuccessWaiterState, Matcher: request.PathAllWaiterMatch, - Argument: "Volumes[].State", - Expected: "detached", + Argument: "length(Volumes[].Attachments[]) == `0`", + Expected: true, }, }, Logger: c.Config.Logger, @@ -204,20 +198,15 @@ func WaitForVolumeToBeDetached(c *ec2.EC2, ctx aws.Context, input *ec2.DescribeV func WaitForImageToBeImported(c *ec2.EC2, ctx aws.Context, input *ec2.DescribeImportImageTasksInput, opts ...request.WaiterOption) error { w := request.Waiter{ Name: "DescribeImages", - MaxAttempts: 40, + MaxAttempts: 300, Delay: request.ConstantWaiterDelay(5 * time.Second), Acceptors: []request.WaiterAcceptor{ { State: request.SuccessWaiterState, Matcher: request.PathAllWaiterMatch, - Argument: "ImportImageTasks[].State", + Argument: "ImportImageTasks[].Status", Expected: "completed", }, - { - State: request.RetryWaiterState, - Matcher: request.ErrorWaiterMatch, - Expected: "InvalidConversionTaskId", - }, }, Logger: c.Config.Logger, NewRequest: func(opts []request.Option) (*request.Request, error) { @@ -239,57 +228,75 @@ func WaitForImageToBeImported(c *ec2.EC2, ctx aws.Context, input *ec2.DescribeIm // AWS_POLL_DELAY_SECONDS to generate waiter options that can be passed into any // request.Waiter function. These options will control how many times the waiter // will retry the request, as well as how long to wait between the retries. + +// DEFAULTING BEHAVIOR: +// if AWS_POLL_DELAY_SECONDS is set but the others are not, Packer will set this +// poll delay and use the waiter-specific default + +// if AWS_TIMEOUT_SECONDS is set but AWS_MAX_ATTEMPTS is not, Packer will use +// AWS_TIMEOUT_SECONDS and _either_ AWS_POLL_DELAY_SECONDS _or_ 2 if the user has not set AWS_POLL_DELAY_SECONDS, to determine a max number of attempts to make. + +// if AWS_TIMEOUT_SECONDS, _and_ AWS_MAX_ATTEMPTS are both set, +// AWS_TIMEOUT_SECONDS will be ignored. + +// if AWS_MAX_ATTEMPTS is set but AWS_POLL_DELAY_SECONDS is not, then we will +// use waiter-specific defaults. + func getWaiterOptions() []request.WaiterOption { - // use env vars to read in the wait delay and the max amount of time to wait - delay := SleepSeconds() - timeoutSeconds := TimeoutSeconds() - // AWS sdk uses max attempts instead of a timeout; convert timeout into - // max attempts - maxAttempts := timeoutSeconds / delay - delaySeconds := request.ConstantWaiterDelay(time.Duration(delay) * time.Second) + waitOpts := make([]request.WaiterOption, 0) + // If user has set poll delay seconds, overwrite it. If user has NOT, + // default to a poll delay of 2 seconds + delayOverridden, delay := getEnvOverrides(2, "AWS_POLL_DELAY_SECONDS") + if delayOverridden { + delaySeconds := request.ConstantWaiterDelay(time.Duration(delay) * time.Second) + waitOpts = append(waitOpts, request.WithWaiterDelay(delaySeconds)) + } - return []request.WaiterOption{ - request.WithWaiterDelay(delaySeconds), - request.WithWaiterMaxAttempts(maxAttempts)} + // If user has set max attempts, overwrite it. If user hasn't set max + // attempts, default to whatever the waiter has set as a default. + maxAttemptsOverridden, maxAttempts := getEnvOverrides(0, "AWS_MAX_ATTEMPTS") + if maxAttemptsOverridden { + waitOpts = append(waitOpts, request.WithWaiterMaxAttempts(maxAttempts)) + } + + timeoutOverridden, timeoutSeconds := getEnvOverrides(300, "AWS_TIMEOUT_SECONDS") + if maxAttemptsOverridden { + log.Printf("WARNING: AWS_MAX_ATTEMPTS and AWS_TIMEOUT_SECONDS are" + + " both set. Packer will be using AWS_MAX_ATTEMPTS and discarding " + + "AWS_TIMEOUT_SECONDS. If you have not set AWS_POLL_DELAY_SECONDS, " + + "Packer will default to a 2 second poll delay.") + } else if timeoutOverridden { + log.Printf("DEPRECATION WARNING: env var AWS_TIMEOUT_SECONDS is " + + "deprecated in favor of AWS_MAX_ATTEMPTS. If you have not " + + "explicitly set AWS_POLL_DELAY_SECONDS, we are defaulting to a " + + "poll delay of 2 seconds, regardless of the AWS waiter's default.") + maxAttempts := timeoutSeconds / delay + // override the delay so we can get the timeout right + if !delayOverridden { + delaySeconds := request.ConstantWaiterDelay(time.Duration(delay) * time.Second) + waitOpts = append(waitOpts, request.WithWaiterDelay(delaySeconds)) + } + waitOpts = append(waitOpts, request.WithWaiterMaxAttempts(maxAttempts)) + } + + return waitOpts } -// Returns 300 seconds (5 minutes) by default -// Some AWS operations, like copying an AMI to a distant region, take a very long time -// Allow user to override with AWS_TIMEOUT_SECONDS environment variable -func TimeoutSeconds() (seconds int) { - seconds = 300 - - override := os.Getenv("AWS_TIMEOUT_SECONDS") +func getEnvOverrides(defaultValue int, envVarName string) (bool, int) { + // "AWS_POLL_DELAY_SECONDS" + retVal := defaultValue + overridden := false + override := os.Getenv(envVarName) if override != "" { n, err := strconv.Atoi(override) if err != nil { - log.Printf("Invalid timeout seconds '%s', using default", override) + log.Printf("Invalid %s '%s', using default", envVarName, override) } else { - seconds = n + overridden = true + retVal = n } } - log.Printf("Allowing %ds to complete (change with AWS_TIMEOUT_SECONDS)", seconds) - return seconds -} - -// Returns 2 seconds by default -// AWS async operations sometimes takes long times, if there are multiple parallel builds, -// polling at 2 second frequency will exceed the request limit. Allow 2 seconds to be -// overwritten with AWS_POLL_DELAY_SECONDS -func SleepSeconds() (seconds int) { - seconds = 2 - - override := os.Getenv("AWS_POLL_DELAY_SECONDS") - if override != "" { - n, err := strconv.Atoi(override) - if err != nil { - log.Printf("Invalid sleep seconds '%s', using default", override) - } else { - seconds = n - } - } - - log.Printf("Using %ds as polling delay (change with AWS_POLL_DELAY_SECONDS)", seconds) - return seconds + log.Printf("Using %ds for %s", retVal, envVarName) + return overridden, retVal } diff --git a/post-processor/amazon-import/post-processor.go b/post-processor/amazon-import/post-processor.go index ecf72e555..812f6a4d4 100644 --- a/post-processor/amazon-import/post-processor.go +++ b/post-processor/amazon-import/post-processor.go @@ -187,6 +187,9 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac // Wait for import process to complete, this takes a while ui.Message(fmt.Sprintf("Waiting for task %s to complete (may take a while)", *import_start.ImportTaskId)) err = awscommon.WaitUntilImageImported(aws.BackgroundContext(), ec2conn, *import_start.ImportTaskId) + if err != nil { + return nil, false, fmt.Errorf("Import task %s failed with error: %s", *import_start.ImportTaskId, err) + } // Retrieve what the outcome was for the import task import_result, err := ec2conn.DescribeImportImageTasks(&ec2.DescribeImportImageTasksInput{ @@ -200,6 +203,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac } // Check it was actually completed + log.Printf("MEGAN result was %s", *import_result.ImportImageTasks[0].Status) if *import_result.ImportImageTasks[0].Status != "completed" { // The most useful error message is from the job itself return nil, false, fmt.Errorf("Import task %s failed: %s", *import_start.ImportTaskId, *import_result.ImportImageTasks[0].StatusMessage) From 14166fdd99fb21ad13084081d9518c6e2c780cd5 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 7 Jun 2018 09:30:49 -0700 Subject: [PATCH 085/220] update amazon import docs to include the env vars for setting aws waiter delays and timeouts --- builder/amazon/common/state.go | 8 +++ builder/amazon/common/state_test.go | 63 +++++++++++++++++++ website/source/docs/builders/amazon.html.md | 19 +++++- .../post-processors/amazon-import.html.md | 53 +++++++++------- 4 files changed, 121 insertions(+), 22 deletions(-) create mode 100644 builder/amazon/common/state_test.go diff --git a/builder/amazon/common/state.go b/builder/amazon/common/state.go index 8d5896c70..741b5c651 100644 --- a/builder/amazon/common/state.go +++ b/builder/amazon/common/state.go @@ -278,6 +278,14 @@ func getWaiterOptions() []request.WaiterOption { } waitOpts = append(waitOpts, request.WithWaiterMaxAttempts(maxAttempts)) } + if len(waitOpts) == 0 { + log.Printf("No AWS timeout and polling overrides have been set. " + + "Packer will defalt to waiter-specific delays and timeouts. If you would " + + "like to customize the length of time between retries and max " + + "number of retries you may do so by setting the environment " + + "variables AWS_POLL_DELAY_SECONDS and AWS_MAX_ATTEMPTS to your " + + "desired values.") + } return waitOpts } diff --git a/builder/amazon/common/state_test.go b/builder/amazon/common/state_test.go new file mode 100644 index 000000000..638a41ae9 --- /dev/null +++ b/builder/amazon/common/state_test.go @@ -0,0 +1,63 @@ +package common + +import ( + "os" + "reflect" + "testing" + "time" + + "github.com/aws/aws-sdk-go/aws/request" +) + +func clearEnvVars() { + os.Unsetenv("AWS_POLL_DELAY_SECONDS") + os.Unsetenv("AWS_MAX_ATTEMPTS") + os.Unsetenv("AWS_TIMEOUT_SECONDS") +} + +func testGetWaiterOptions(t *testing.T) { + clearEnvVars() + + // no vars are set + options := getWaiterOptions() + if len(options) > 0 { + t.Fatalf("Did not expect any waiter options to be generated; actual: %#v", options) + } + + // all vars are set + os.Setenv("AWS_MAX_ATTEMPTS", "800") + os.Setenv("AWS_TIMEOUT_SECONDS", "20") + os.Setenv("AWS_POLL_DELAY_SECONDS", "1") + options = getWaiterOptions() + expected := []request.WaiterOption{ + request.WithWaiterDelay(request.ConstantWaiterDelay(time.Duration(1) * time.Second)), + request.WithWaiterMaxAttempts(800), + } + if !reflect.DeepEqual(options, expected) { + t.Fatalf("expected != actual!! Expected: %#v; Actual: %#v.", expected, options) + } + clearEnvVars() + + // poll delay is not set + os.Setenv("AWS_MAX_ATTEMPTS", "800") + options = getWaiterOptions() + expected = []request.WaiterOption{ + request.WithWaiterMaxAttempts(800), + } + if !reflect.DeepEqual(options, expected) { + t.Fatalf("expected != actual!! Expected: %#v; Actual: %#v.", expected, options) + } + clearEnvVars() + + // poll delay is not set but timeout seconds is + os.Setenv("AWS_TIMEOUT_SECONDS", "20") + options = getWaiterOptions() + expected = []request.WaiterOption{ + request.WithWaiterDelay(request.ConstantWaiterDelay(time.Duration(2) * time.Second)), + request.WithWaiterMaxAttempts(10), + } + if !reflect.DeepEqual(options, expected) { + t.Fatalf("expected != actual!! Expected: %#v; Actual: %#v.", expected, options) + } + clearEnvVars() +} diff --git a/website/source/docs/builders/amazon.html.md b/website/source/docs/builders/amazon.html.md index 3b1a177a9..b1119f607 100644 --- a/website/source/docs/builders/amazon.html.md +++ b/website/source/docs/builders/amazon.html.md @@ -176,7 +176,7 @@ for Packer to work: "Resource" : "*" }] } -``` +``` Note that if you'd like to create a spot instance, you must also add: @@ -231,3 +231,20 @@ If you suspect your system's date is wrong, you can compare it against . On Linux/OS X, you can run the `date` command to get the current time. If you're on Linux, you can try setting the time with ntp by running `sudo ntpd -q`. + +### `exceeded wait attempts` while waiting for tasks to complete +We use the AWS SDK's built-in waiters to wait for longer-running tasks to +complete. These waiters have default delays between queries and maximum number +of queries that don't always work for our users. + +If you find that you are being rate-limited or have exceeded your max wait +attempts, you can override the defaults by setting the following packer +environment variables (note that these will apply to all aws tasks that we have +to wait for): + +`AWS_MAX_ATTEMPTS` - This is how many times to re-send a status update request. +Excepting tasks that we know can take an extremely long time, this defaults to +40tries. + +`AWS_POLL_DELAY_SECONDS` - How many seconds to wait in between status update +requests. Generally defaults to 2 or 5 seconds, depending on the task. \ No newline at end of file diff --git a/website/source/docs/post-processors/amazon-import.html.md b/website/source/docs/post-processors/amazon-import.html.md index f7f8959a9..836a271c3 100644 --- a/website/source/docs/post-processors/amazon-import.html.md +++ b/website/source/docs/post-processors/amazon-import.html.md @@ -125,31 +125,42 @@ This is an example that uses `vmware-iso` builder and exports the `.ova` file us ``` json "post-processors" : [ [ - { - "type": "shell-local", - "inline": [ "/usr/bin/ovftool /.vmx /.ova" ] - }, - { - "files": [ - "/.ova" - ], - "type": "artifice" - }, - { - "type": "amazon-import", - "access_key": "YOUR KEY HERE", - "secret_key": "YOUR SECRET KEY HERE", - "region": "us-east-1", - "s3_bucket_name": "importbucket", - "license_type": "BYOL", - "tags": { - "Description": "packer amazon-import {{timestamp}}" - } - } + { + "type": "shell-local", + "inline": [ "/usr/bin/ovftool /.vmx /.ova" ] + }, + { + "files": [ + "/.ova" + ], + "type": "artifice" + }, + { + "type": "amazon-import", + "access_key": "YOUR KEY HERE", + "secret_key": "YOUR SECRET KEY HERE", + "region": "us-east-1", + "s3_bucket_name": "importbucket", + "license_type": "BYOL", + "tags": { + "Description": "packer amazon-import {{timestamp}}" + } + } ] ] ``` +## Troubleshooting Timeouts +The amazon-import feature can take a long time to upload and convert your OVAs +into AMIs; if you find that your build is failing because you have exceeded your +max retries or find yourself being rate limited, you can override the max +retries and the delay in between retries by setting the environment variables + `AWS_MAX_ATTEMPTS` and `AWS_POLL_DELAY_SECONDS` on the machine running the + Packer build. By default, the waiter that waits for your image to be imported + from s3 waits retries up to 300 times with a 5 second delay in between retries. + This is dramatically higher than many of our other waiters, to account for how + long this process can take. + -> **Note:** Packer can also read the access key and secret access key from environmental variables. See the configuration reference in the section above for more information on what environmental variables Packer will look for. From f657ca39c9ef5c40e6c3154ab0ba593eeab60966 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Fri, 29 Jun 2018 16:33:26 -0700 Subject: [PATCH 086/220] refactored env var code and tests so that I don't have to set env vars during tests to check logic --- builder/amazon/common/state.go | 82 ++++++++++++------- builder/amazon/common/state_test.go | 45 +++++----- .../amazon-import/post-processor.go | 1 - 3 files changed, 75 insertions(+), 53 deletions(-) diff --git a/builder/amazon/common/state.go b/builder/amazon/common/state.go index 741b5c651..73280afaa 100644 --- a/builder/amazon/common/state.go +++ b/builder/amazon/common/state.go @@ -242,38 +242,77 @@ func WaitForImageToBeImported(c *ec2.EC2, ctx aws.Context, input *ec2.DescribeIm // if AWS_MAX_ATTEMPTS is set but AWS_POLL_DELAY_SECONDS is not, then we will // use waiter-specific defaults. +type envInfo struct { + envKey string + Val int + overridden bool +} + +type overridableWaitVars struct { + awsPollDelaySeconds envInfo + awsMaxAttempts envInfo + awsTimeoutSeconds envInfo +} + func getWaiterOptions() []request.WaiterOption { + envOverrides := getEnvOverrides() + waitOpts := applyEnvOverrides(envOverrides) + return waitOpts +} + +func getEnvOverrides() overridableWaitVars { + // Load env vars from environment, and use them to override defaults + envValues := overridableWaitVars{ + envInfo{"AWS_POLL_DELAY_SECONDS", 2, false}, + envInfo{"AWS_MAX_ATTEMPTS", 0, false}, + envInfo{"AWS_TIMEOUT_SECONDS", 300, false}, + } + + for _, varInfo := range []envInfo{envValues.awsPollDelaySeconds, envValues.awsMaxAttempts, envValues.awsTimeoutSeconds} { + override := os.Getenv(varInfo.envKey) + if override != "" { + n, err := strconv.Atoi(override) + if err != nil { + log.Printf("Invalid %s '%s', using default", varInfo.envKey, override) + } else { + varInfo.overridden = true + varInfo.Val = n + } + } + } + + return envValues +} + +func applyEnvOverrides(envOverrides overridableWaitVars) []request.WaiterOption { waitOpts := make([]request.WaiterOption, 0) // If user has set poll delay seconds, overwrite it. If user has NOT, // default to a poll delay of 2 seconds - delayOverridden, delay := getEnvOverrides(2, "AWS_POLL_DELAY_SECONDS") - if delayOverridden { - delaySeconds := request.ConstantWaiterDelay(time.Duration(delay) * time.Second) + if envOverrides.awsPollDelaySeconds.overridden { + delaySeconds := request.ConstantWaiterDelay(time.Duration(envOverrides.awsPollDelaySeconds.Val) * time.Second) waitOpts = append(waitOpts, request.WithWaiterDelay(delaySeconds)) } // If user has set max attempts, overwrite it. If user hasn't set max // attempts, default to whatever the waiter has set as a default. - maxAttemptsOverridden, maxAttempts := getEnvOverrides(0, "AWS_MAX_ATTEMPTS") - if maxAttemptsOverridden { - waitOpts = append(waitOpts, request.WithWaiterMaxAttempts(maxAttempts)) + if envOverrides.awsMaxAttempts.overridden { + waitOpts = append(waitOpts, request.WithWaiterMaxAttempts(envOverrides.awsMaxAttempts.Val)) } - timeoutOverridden, timeoutSeconds := getEnvOverrides(300, "AWS_TIMEOUT_SECONDS") - if maxAttemptsOverridden { + if envOverrides.awsMaxAttempts.overridden && envOverrides.awsTimeoutSeconds.overridden { log.Printf("WARNING: AWS_MAX_ATTEMPTS and AWS_TIMEOUT_SECONDS are" + " both set. Packer will be using AWS_MAX_ATTEMPTS and discarding " + "AWS_TIMEOUT_SECONDS. If you have not set AWS_POLL_DELAY_SECONDS, " + "Packer will default to a 2 second poll delay.") - } else if timeoutOverridden { + } else if envOverrides.awsTimeoutSeconds.overridden { log.Printf("DEPRECATION WARNING: env var AWS_TIMEOUT_SECONDS is " + "deprecated in favor of AWS_MAX_ATTEMPTS. If you have not " + "explicitly set AWS_POLL_DELAY_SECONDS, we are defaulting to a " + "poll delay of 2 seconds, regardless of the AWS waiter's default.") - maxAttempts := timeoutSeconds / delay + maxAttempts := envOverrides.awsTimeoutSeconds.Val / envOverrides.awsPollDelaySeconds.Val // override the delay so we can get the timeout right - if !delayOverridden { - delaySeconds := request.ConstantWaiterDelay(time.Duration(delay) * time.Second) + if !envOverrides.awsPollDelaySeconds.overridden { + delaySeconds := request.ConstantWaiterDelay(time.Duration(envOverrides.awsPollDelaySeconds.Val) * time.Second) waitOpts = append(waitOpts, request.WithWaiterDelay(delaySeconds)) } waitOpts = append(waitOpts, request.WithWaiterMaxAttempts(maxAttempts)) @@ -289,22 +328,3 @@ func getWaiterOptions() []request.WaiterOption { return waitOpts } - -func getEnvOverrides(defaultValue int, envVarName string) (bool, int) { - // "AWS_POLL_DELAY_SECONDS" - retVal := defaultValue - overridden := false - override := os.Getenv(envVarName) - if override != "" { - n, err := strconv.Atoi(override) - if err != nil { - log.Printf("Invalid %s '%s', using default", envVarName, override) - } else { - overridden = true - retVal = n - } - } - - log.Printf("Using %ds for %s", retVal, envVarName) - return overridden, retVal -} diff --git a/builder/amazon/common/state_test.go b/builder/amazon/common/state_test.go index 638a41ae9..2ef7ae5aa 100644 --- a/builder/amazon/common/state_test.go +++ b/builder/amazon/common/state_test.go @@ -1,7 +1,6 @@ package common import ( - "os" "reflect" "testing" "time" @@ -9,26 +8,25 @@ import ( "github.com/aws/aws-sdk-go/aws/request" ) -func clearEnvVars() { - os.Unsetenv("AWS_POLL_DELAY_SECONDS") - os.Unsetenv("AWS_MAX_ATTEMPTS") - os.Unsetenv("AWS_TIMEOUT_SECONDS") -} - func testGetWaiterOptions(t *testing.T) { - clearEnvVars() - // no vars are set - options := getWaiterOptions() + envValues := overridableWaitVars{ + envInfo{"AWS_POLL_DELAY_SECONDS", 2, false}, + envInfo{"AWS_MAX_ATTEMPTS", 0, false}, + envInfo{"AWS_TIMEOUT_SECONDS", 300, false}, + } + options := applyEnvOverrides(envValues) if len(options) > 0 { t.Fatalf("Did not expect any waiter options to be generated; actual: %#v", options) } // all vars are set - os.Setenv("AWS_MAX_ATTEMPTS", "800") - os.Setenv("AWS_TIMEOUT_SECONDS", "20") - os.Setenv("AWS_POLL_DELAY_SECONDS", "1") - options = getWaiterOptions() + envValues = overridableWaitVars{ + envInfo{"AWS_POLL_DELAY_SECONDS", 1, true}, + envInfo{"AWS_MAX_ATTEMPTS", 800, true}, + envInfo{"AWS_TIMEOUT_SECONDS", 20, true}, + } + options = applyEnvOverrides(envValues) expected := []request.WaiterOption{ request.WithWaiterDelay(request.ConstantWaiterDelay(time.Duration(1) * time.Second)), request.WithWaiterMaxAttempts(800), @@ -36,22 +34,28 @@ func testGetWaiterOptions(t *testing.T) { if !reflect.DeepEqual(options, expected) { t.Fatalf("expected != actual!! Expected: %#v; Actual: %#v.", expected, options) } - clearEnvVars() // poll delay is not set - os.Setenv("AWS_MAX_ATTEMPTS", "800") - options = getWaiterOptions() + envValues = overridableWaitVars{ + envInfo{"AWS_POLL_DELAY_SECONDS", 2, false}, + envInfo{"AWS_MAX_ATTEMPTS", 800, true}, + envInfo{"AWS_TIMEOUT_SECONDS", 300, false}, + } + options = applyEnvOverrides(envValues) expected = []request.WaiterOption{ request.WithWaiterMaxAttempts(800), } if !reflect.DeepEqual(options, expected) { t.Fatalf("expected != actual!! Expected: %#v; Actual: %#v.", expected, options) } - clearEnvVars() // poll delay is not set but timeout seconds is - os.Setenv("AWS_TIMEOUT_SECONDS", "20") - options = getWaiterOptions() + envValues = overridableWaitVars{ + envInfo{"AWS_POLL_DELAY_SECONDS", 2, false}, + envInfo{"AWS_MAX_ATTEMPTS", 0, false}, + envInfo{"AWS_TIMEOUT_SECONDS", 20, true}, + } + options = applyEnvOverrides(envValues) expected = []request.WaiterOption{ request.WithWaiterDelay(request.ConstantWaiterDelay(time.Duration(2) * time.Second)), request.WithWaiterMaxAttempts(10), @@ -59,5 +63,4 @@ func testGetWaiterOptions(t *testing.T) { if !reflect.DeepEqual(options, expected) { t.Fatalf("expected != actual!! Expected: %#v; Actual: %#v.", expected, options) } - clearEnvVars() } diff --git a/post-processor/amazon-import/post-processor.go b/post-processor/amazon-import/post-processor.go index 812f6a4d4..e42fb1ae7 100644 --- a/post-processor/amazon-import/post-processor.go +++ b/post-processor/amazon-import/post-processor.go @@ -203,7 +203,6 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac } // Check it was actually completed - log.Printf("MEGAN result was %s", *import_result.ImportImageTasks[0].Status) if *import_result.ImportImageTasks[0].Status != "completed" { // The most useful error message is from the job itself return nil, false, fmt.Errorf("Import task %s failed: %s", *import_start.ImportTaskId, *import_result.ImportImageTasks[0].StatusMessage) From 8e228030991016ac76740c252b9ca60d8e4e894d Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Wed, 11 Jul 2018 13:10:38 -0700 Subject: [PATCH 087/220] fix loading of environment variables for managing aws waiters --- builder/amazon/common/state.go | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/builder/amazon/common/state.go b/builder/amazon/common/state.go index 73280afaa..c2390d8b1 100644 --- a/builder/amazon/common/state.go +++ b/builder/amazon/common/state.go @@ -260,6 +260,20 @@ func getWaiterOptions() []request.WaiterOption { return waitOpts } +func getOverride(varInfo envInfo) envInfo { + override := os.Getenv(varInfo.envKey) + if override != "" { + n, err := strconv.Atoi(override) + if err != nil { + log.Printf("Invalid %s '%s', using default", varInfo.envKey, override) + } else { + varInfo.overridden = true + varInfo.Val = n + } + } + + return varInfo +} func getEnvOverrides() overridableWaitVars { // Load env vars from environment, and use them to override defaults envValues := overridableWaitVars{ @@ -268,18 +282,9 @@ func getEnvOverrides() overridableWaitVars { envInfo{"AWS_TIMEOUT_SECONDS", 300, false}, } - for _, varInfo := range []envInfo{envValues.awsPollDelaySeconds, envValues.awsMaxAttempts, envValues.awsTimeoutSeconds} { - override := os.Getenv(varInfo.envKey) - if override != "" { - n, err := strconv.Atoi(override) - if err != nil { - log.Printf("Invalid %s '%s', using default", varInfo.envKey, override) - } else { - varInfo.overridden = true - varInfo.Val = n - } - } - } + envValues.awsMaxAttempts = getOverride(envValues.awsMaxAttempts) + envValues.awsPollDelaySeconds = getOverride(envValues.awsPollDelaySeconds) + envValues.awsTimeoutSeconds = getOverride(envValues.awsTimeoutSeconds) return envValues } From 36df317b892c11e4929ae657706aae61a547c4b8 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Wed, 11 Jul 2018 13:30:20 -0700 Subject: [PATCH 088/220] don't try to determine file or folder with winrm communicator; not all systems will have powershell installed on them --- communicator/winrm/communicator.go | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/communicator/winrm/communicator.go b/communicator/winrm/communicator.go index 6cf2bce37..bab2ebde2 100644 --- a/communicator/winrm/communicator.go +++ b/communicator/winrm/communicator.go @@ -122,26 +122,11 @@ func runCommand(shell *winrm.Shell, cmd *winrm.Command, rc *packer.RemoteCmd) { } // Upload implementation of communicator.Communicator interface -func (c *Communicator) Upload(path string, input io.Reader, fi *os.FileInfo) error { +func (c *Communicator) Upload(path string, input io.Reader, _ *os.FileInfo) error { wcp, err := c.newCopyClient() - if err != nil { - return err - } - if err != nil { return fmt.Errorf("Was unable to create winrm client: %s", err) } - client, err := c.newWinRMClient() - stdout, _, _, err := client.RunWithString(fmt.Sprintf("powershell -Command \"(Get-Item %s) -is [System.IO.DirectoryInfo]\"", path), "") - if err != nil { - return fmt.Errorf("Couldn't determine whether destination was a folder or file: %s", err) - } - if strings.Contains(stdout, "True") { - // The path exists and is a directory. - // Upload file into the directory instead of overwriting. - path = filepath.Join(path, filepath.Base((*fi).Name())) - } - log.Printf("Uploading file to '%s'", path) return wcp.Write(path, input) } From b8de835a91ca4646d2a1f00d9d6829748a5d7647 Mon Sep 17 00:00:00 2001 From: Christopher Boumenot Date: Wed, 11 Jul 2018 14:54:57 -0700 Subject: [PATCH 089/220] merge conflicts --- .../2018-04-01/compute/availabilitysets.go | 33 +- .../2018-04-01/compute/containerservices.go | 52 +- .../compute/mgmt/2018-04-01/compute/disks.go | 144 +- .../compute/mgmt/2018-04-01/compute/images.go | 72 +- .../mgmt/2018-04-01/compute/loganalytics.go | 40 +- .../compute/mgmt/2018-04-01/compute/models.go | 2283 ++++--------- .../mgmt/2018-04-01/compute/snapshots.go | 138 +- .../compute/mgmt/2018-04-01/compute/usage.go | 4 +- .../compute/virtualmachineextensionimages.go | 13 +- .../compute/virtualmachineextensions.go | 129 +- .../compute/virtualmachineimages.go | 34 +- .../compute/virtualmachineruncommands.go | 9 +- .../2018-04-01/compute/virtualmachines.go | 333 +- .../virtualmachinescalesetextensions.go | 59 +- .../virtualmachinescalesetrollingupgrades.go | 43 +- .../compute/virtualmachinescalesets.go | 392 ++- .../compute/virtualmachinescalesetvms.go | 236 +- .../2018-04-01/compute/virtualmachinesizes.go | 4 +- .../2018-01-01/network/applicationgateways.go | 137 +- .../network/applicationsecuritygroups.go | 51 +- .../network/availableendpointservices.go | 4 +- .../network/mgmt/2018-01-01/network/client.go | 7 +- .../2018-01-01/network/connectionmonitors.go | 120 +- .../network/defaultsecurityrules.go | 13 +- .../expressroutecircuitauthorizations.go | 57 +- .../network/expressroutecircuitpeerings.go | 61 +- .../network/expressroutecircuits.go | 148 +- .../2018-01-01/network/inboundnatrules.go | 57 +- .../network/interfaceipconfigurations.go | 12 +- .../network/interfaceloadbalancers.go | 5 +- .../mgmt/2018-01-01/network/interfaces.go | 155 +- .../loadbalancerbackendaddresspools.go | 12 +- .../loadbalancerfrontendipconfigurations.go | 12 +- .../network/loadbalancerloadbalancingrules.go | 12 +- .../network/loadbalancernetworkinterfaces.go | 5 +- .../2018-01-01/network/loadbalancerprobes.go | 12 +- .../mgmt/2018-01-01/network/loadbalancers.go | 72 +- .../network/localnetworkgateways.go | 72 +- .../network/mgmt/2018-01-01/network/models.go | 2944 +++-------------- .../mgmt/2018-01-01/network/packetcaptures.go | 99 +- .../2018-01-01/network/publicipaddresses.go | 101 +- .../2018-01-01/network/routefilterrules.go | 79 +- .../mgmt/2018-01-01/network/routefilters.go | 72 +- .../network/mgmt/2018-01-01/network/routes.go | 55 +- .../mgmt/2018-01-01/network/routetables.go | 72 +- .../mgmt/2018-01-01/network/securitygroups.go | 73 +- .../mgmt/2018-01-01/network/securityrules.go | 57 +- .../mgmt/2018-01-01/network/subnets.go | 57 +- .../network/mgmt/2018-01-01/network/usages.go | 4 +- .../virtualnetworkgatewayconnections.go | 126 +- .../network/virtualnetworkgateways.go | 242 +- .../network/virtualnetworkpeerings.go | 57 +- .../2018-01-01/network/virtualnetworks.go | 84 +- .../mgmt/2018-01-01/network/watchers.go | 260 +- .../2016-06-01/subscriptions/subscriptions.go | 8 +- .../resources/deploymentoperations.go | 14 +- .../mgmt/2018-02-01/resources/deployments.go | 87 +- .../mgmt/2018-02-01/resources/groups.go | 50 +- .../mgmt/2018-02-01/resources/models.go | 352 +- .../mgmt/2018-02-01/resources/providers.go | 24 +- .../mgmt/2018-02-01/resources/resources.go | 223 +- .../mgmt/2018-02-01/resources/tags.go | 18 +- .../mgmt/2017-10-01/storage/accounts.go | 106 +- .../storage/mgmt/2017-10-01/storage/models.go | 32 +- .../Azure/azure-sdk-for-go/storage/README.md | 10 +- .../Azure/azure-sdk-for-go/storage/blob.go | 18 +- .../azure-sdk-for-go/storage/blockblob.go | 2 +- .../Azure/azure-sdk-for-go/storage/client.go | 7 + .../azure-sdk-for-go/storage/container.go | 16 +- .../azure-sdk-for-go/storage/copyblob.go | 6 +- .../azure-sdk-for-go/storage/directory.go | 4 +- .../Azure/azure-sdk-for-go/storage/entity.go | 10 +- .../Azure/azure-sdk-for-go/storage/file.go | 8 +- .../storage/fileserviceclient.go | 12 +- .../azure-sdk-for-go/storage/leaseblob.go | 2 +- .../Azure/azure-sdk-for-go/storage/message.go | 6 +- .../azure-sdk-for-go/storage/pageblob.go | 4 +- .../Azure/azure-sdk-for-go/storage/queue.go | 14 +- .../Azure/azure-sdk-for-go/storage/share.go | 4 +- .../storage/storageservice.go | 2 +- .../Azure/azure-sdk-for-go/storage/table.go | 4 +- .../azure-sdk-for-go/storage/table_batch.go | 2 +- .../Azure/azure-sdk-for-go/version/version.go | 2 +- vendor/vendor.json | 72 +- 84 files changed, 4056 insertions(+), 6487 deletions(-) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/availabilitysets.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/availabilitysets.go index 4cafe8d1e..1f0007ff5 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/availabilitysets.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/availabilitysets.go @@ -40,9 +40,10 @@ func NewAvailabilitySetsClientWithBaseURI(baseURI string, subscriptionID string) } // CreateOrUpdate create or update an availability set. -// -// resourceGroupName is the name of the resource group. availabilitySetName is the name of the availability set. -// parameters is parameters supplied to the Create Availability Set operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// availabilitySetName - the name of the availability set. +// parameters - parameters supplied to the Create Availability Set operation. func (client AvailabilitySetsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, availabilitySetName string, parameters AvailabilitySet) (result AvailabilitySet, err error) { req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, availabilitySetName, parameters) if err != nil { @@ -109,8 +110,9 @@ func (client AvailabilitySetsClient) CreateOrUpdateResponder(resp *http.Response } // Delete delete an availability set. -// -// resourceGroupName is the name of the resource group. availabilitySetName is the name of the availability set. +// Parameters: +// resourceGroupName - the name of the resource group. +// availabilitySetName - the name of the availability set. func (client AvailabilitySetsClient) Delete(ctx context.Context, resourceGroupName string, availabilitySetName string) (result OperationStatusResponse, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, availabilitySetName) if err != nil { @@ -175,8 +177,9 @@ func (client AvailabilitySetsClient) DeleteResponder(resp *http.Response) (resul } // Get retrieves information about an availability set. -// -// resourceGroupName is the name of the resource group. availabilitySetName is the name of the availability set. +// Parameters: +// resourceGroupName - the name of the resource group. +// availabilitySetName - the name of the availability set. func (client AvailabilitySetsClient) Get(ctx context.Context, resourceGroupName string, availabilitySetName string) (result AvailabilitySet, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, availabilitySetName) if err != nil { @@ -241,8 +244,8 @@ func (client AvailabilitySetsClient) GetResponder(resp *http.Response) (result A } // List lists all availability sets in a resource group. -// -// resourceGroupName is the name of the resource group. +// Parameters: +// resourceGroupName - the name of the resource group. func (client AvailabilitySetsClient) List(ctx context.Context, resourceGroupName string) (result AvailabilitySetListResult, err error) { req, err := client.ListPreparer(ctx, resourceGroupName) if err != nil { @@ -307,8 +310,9 @@ func (client AvailabilitySetsClient) ListResponder(resp *http.Response) (result // ListAvailableSizes lists all available virtual machine sizes that can be used to create a new virtual machine in an // existing availability set. -// -// resourceGroupName is the name of the resource group. availabilitySetName is the name of the availability set. +// Parameters: +// resourceGroupName - the name of the resource group. +// availabilitySetName - the name of the availability set. func (client AvailabilitySetsClient) ListAvailableSizes(ctx context.Context, resourceGroupName string, availabilitySetName string) (result VirtualMachineSizeListResult, err error) { req, err := client.ListAvailableSizesPreparer(ctx, resourceGroupName, availabilitySetName) if err != nil { @@ -373,9 +377,10 @@ func (client AvailabilitySetsClient) ListAvailableSizesResponder(resp *http.Resp } // Update update an availability set. -// -// resourceGroupName is the name of the resource group. availabilitySetName is the name of the availability set. -// parameters is parameters supplied to the Update Availability Set operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// availabilitySetName - the name of the availability set. +// parameters - parameters supplied to the Update Availability Set operation. func (client AvailabilitySetsClient) Update(ctx context.Context, resourceGroupName string, availabilitySetName string, parameters AvailabilitySetUpdate) (result AvailabilitySet, err error) { req, err := client.UpdatePreparer(ctx, resourceGroupName, availabilitySetName, parameters) if err != nil { diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/containerservices.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/containerservices.go index 99f10b53a..b16788bfa 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/containerservices.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/containerservices.go @@ -42,10 +42,10 @@ func NewContainerServicesClientWithBaseURI(baseURI string, subscriptionID string // CreateOrUpdate creates or updates a container service with the specified configuration of orchestrator, masters, and // agents. -// -// resourceGroupName is the name of the resource group. containerServiceName is the name of the container service -// in the specified subscription and resource group. parameters is parameters supplied to the Create or Update a -// Container Service operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// containerServiceName - the name of the container service in the specified subscription and resource group. +// parameters - parameters supplied to the Create or Update a Container Service operation. func (client ContainerServicesClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, containerServiceName string, parameters ContainerService) (result ContainerServicesCreateOrUpdateFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: parameters, @@ -119,15 +119,17 @@ func (client ContainerServicesClient) CreateOrUpdatePreparer(ctx context.Context // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client ContainerServicesClient) CreateOrUpdateSender(req *http.Request) (future ContainerServicesCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -148,9 +150,9 @@ func (client ContainerServicesClient) CreateOrUpdateResponder(resp *http.Respons // not delete other resources created as part of creating a container service, including storage accounts, VMs, and // availability sets. All the other resources created with the container service are part of the same resource group // and can be deleted individually. -// -// resourceGroupName is the name of the resource group. containerServiceName is the name of the container service -// in the specified subscription and resource group. +// Parameters: +// resourceGroupName - the name of the resource group. +// containerServiceName - the name of the container service in the specified subscription and resource group. func (client ContainerServicesClient) Delete(ctx context.Context, resourceGroupName string, containerServiceName string) (result ContainerServicesDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, containerServiceName) if err != nil { @@ -191,15 +193,17 @@ func (client ContainerServicesClient) DeletePreparer(ctx context.Context, resour // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client ContainerServicesClient) DeleteSender(req *http.Request) (future ContainerServicesDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -218,9 +222,9 @@ func (client ContainerServicesClient) DeleteResponder(resp *http.Response) (resu // Get gets the properties of the specified container service in the specified subscription and resource group. The // operation returns the properties including state, orchestrator, number of masters and agents, and FQDNs of masters // and agents. -// -// resourceGroupName is the name of the resource group. containerServiceName is the name of the container service -// in the specified subscription and resource group. +// Parameters: +// resourceGroupName - the name of the resource group. +// containerServiceName - the name of the container service in the specified subscription and resource group. func (client ContainerServicesClient) Get(ctx context.Context, resourceGroupName string, containerServiceName string) (result ContainerService, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, containerServiceName) if err != nil { @@ -378,8 +382,8 @@ func (client ContainerServicesClient) ListComplete(ctx context.Context) (result // ListByResourceGroup gets a list of container services in the specified subscription and resource group. The // operation returns properties of each container service including state, orchestrator, number of masters and agents, // and FQDNs of masters and agents. -// -// resourceGroupName is the name of the resource group. +// Parameters: +// resourceGroupName - the name of the resource group. func (client ContainerServicesClient) ListByResourceGroup(ctx context.Context, resourceGroupName string) (result ContainerServiceListResultPage, err error) { result.fn = client.listByResourceGroupNextResults req, err := client.ListByResourceGroupPreparer(ctx, resourceGroupName) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/disks.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/disks.go index 32a8eff1a..cdc570377 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/disks.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/disks.go @@ -41,11 +41,12 @@ func NewDisksClientWithBaseURI(baseURI string, subscriptionID string) DisksClien } // CreateOrUpdate creates or updates a disk. -// -// resourceGroupName is the name of the resource group. diskName is the name of the managed disk that is being -// created. The name can't be changed after the disk is created. Supported characters for the name are a-z, A-Z, -// 0-9 and _. The maximum name length is 80 characters. disk is disk object supplied in the body of the Put disk -// operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// diskName - the name of the managed disk that is being created. The name can't be changed after the disk is +// created. Supported characters for the name are a-z, A-Z, 0-9 and _. The maximum name length is 80 +// characters. +// disk - disk object supplied in the body of the Put disk operation. func (client DisksClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, diskName string, disk Disk) (result DisksCreateOrUpdateFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: disk, @@ -109,15 +110,17 @@ func (client DisksClient) CreateOrUpdatePreparer(ctx context.Context, resourceGr // 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) (future DisksCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -135,10 +138,11 @@ func (client DisksClient) CreateOrUpdateResponder(resp *http.Response) (result D } // Delete deletes a disk. -// -// resourceGroupName is the name of the resource group. diskName is the name of the managed disk that is being -// created. The name can't be changed after the disk is created. Supported characters for the name are a-z, A-Z, -// 0-9 and _. The maximum name length is 80 characters. +// Parameters: +// resourceGroupName - the name of the resource group. +// diskName - the name of the managed disk that is being created. The name can't be changed after the disk is +// created. Supported characters for the name are a-z, A-Z, 0-9 and _. The maximum name length is 80 +// characters. func (client DisksClient) Delete(ctx context.Context, resourceGroupName string, diskName string) (result DisksDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, diskName) if err != nil { @@ -179,36 +183,38 @@ func (client DisksClient) DeletePreparer(ctx context.Context, resourceGroupName // 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) (future DisksDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } // 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) { +func (client DisksClient) DeleteResponder(resp *http.Response) (result autorest.Response, 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} + result.Response = resp return } // Get gets information about a disk. -// -// resourceGroupName is the name of the resource group. diskName is the name of the managed disk that is being -// created. The name can't be changed after the disk is created. Supported characters for the name are a-z, A-Z, -// 0-9 and _. The maximum name length is 80 characters. +// Parameters: +// resourceGroupName - the name of the resource group. +// diskName - the name of the managed disk that is being created. The name can't be changed after the disk is +// created. Supported characters for the name are a-z, A-Z, 0-9 and _. The maximum name length is 80 +// characters. func (client DisksClient) Get(ctx context.Context, resourceGroupName string, diskName string) (result Disk, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, diskName) if err != nil { @@ -273,11 +279,12 @@ func (client DisksClient) GetResponder(resp *http.Response) (result Disk, err er } // GrantAccess grants access to a disk. -// -// resourceGroupName is the name of the resource group. diskName is the name of the managed disk that is being -// created. The name can't be changed after the disk is created. Supported characters for the name are a-z, A-Z, -// 0-9 and _. The maximum name length is 80 characters. grantAccessData is access data object supplied in the body -// of the get disk access operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// diskName - the name of the managed disk that is being created. The name can't be changed after the disk is +// created. Supported characters for the name are a-z, A-Z, 0-9 and _. The maximum name length is 80 +// characters. +// grantAccessData - access data object supplied in the body of the get disk access operation. func (client DisksClient) GrantAccess(ctx context.Context, resourceGroupName string, diskName string, grantAccessData GrantAccessData) (result DisksGrantAccessFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: grantAccessData, @@ -326,15 +333,17 @@ func (client DisksClient) GrantAccessPreparer(ctx context.Context, resourceGroup // 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) (future DisksGrantAccessFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -442,8 +451,8 @@ func (client DisksClient) ListComplete(ctx context.Context) (result DiskListIter } // ListByResourceGroup lists all the disks under a resource group. -// -// resourceGroupName is the name of the resource group. +// Parameters: +// resourceGroupName - the name of the resource group. func (client DisksClient) ListByResourceGroup(ctx context.Context, resourceGroupName string) (result DiskListPage, err error) { result.fn = client.listByResourceGroupNextResults req, err := client.ListByResourceGroupPreparer(ctx, resourceGroupName) @@ -535,10 +544,11 @@ func (client DisksClient) ListByResourceGroupComplete(ctx context.Context, resou } // RevokeAccess revokes access to a disk. -// -// resourceGroupName is the name of the resource group. diskName is the name of the managed disk that is being -// created. The name can't be changed after the disk is created. Supported characters for the name are a-z, A-Z, -// 0-9 and _. The maximum name length is 80 characters. +// Parameters: +// resourceGroupName - the name of the resource group. +// diskName - the name of the managed disk that is being created. The name can't be changed after the disk is +// created. Supported characters for the name are a-z, A-Z, 0-9 and _. The maximum name length is 80 +// characters. func (client DisksClient) RevokeAccess(ctx context.Context, resourceGroupName string, diskName string) (result DisksRevokeAccessFuture, err error) { req, err := client.RevokeAccessPreparer(ctx, resourceGroupName, diskName) if err != nil { @@ -579,37 +589,39 @@ func (client DisksClient) RevokeAccessPreparer(ctx context.Context, resourceGrou // 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) (future DisksRevokeAccessFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } // 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) { +func (client DisksClient) RevokeAccessResponder(resp *http.Response) (result autorest.Response, 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} + result.Response = resp return } // Update updates (patches) a disk. -// -// resourceGroupName is the name of the resource group. diskName is the name of the managed disk that is being -// created. The name can't be changed after the disk is created. Supported characters for the name are a-z, A-Z, -// 0-9 and _. The maximum name length is 80 characters. disk is disk object supplied in the body of the Patch disk -// operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// diskName - the name of the managed disk that is being created. The name can't be changed after the disk is +// created. Supported characters for the name are a-z, A-Z, 0-9 and _. The maximum name length is 80 +// characters. +// disk - disk object supplied in the body of the Patch disk operation. func (client DisksClient) Update(ctx context.Context, resourceGroupName string, diskName string, disk DiskUpdate) (result DisksUpdateFuture, err error) { req, err := client.UpdatePreparer(ctx, resourceGroupName, diskName, disk) if err != nil { @@ -652,15 +664,17 @@ func (client DisksClient) UpdatePreparer(ctx context.Context, resourceGroupName // 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) (future DisksUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/images.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/images.go index 5616d69ca..d50a784b7 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/images.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/images.go @@ -40,9 +40,10 @@ func NewImagesClientWithBaseURI(baseURI string, subscriptionID string) ImagesCli } // CreateOrUpdate create or update an image. -// -// resourceGroupName is the name of the resource group. imageName is the name of the image. parameters is -// parameters supplied to the Create Image operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// imageName - the name of the image. +// parameters - parameters supplied to the Create Image operation. func (client ImagesClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, imageName string, parameters Image) (result ImagesCreateOrUpdateFuture, err error) { req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, imageName, parameters) if err != nil { @@ -85,15 +86,17 @@ func (client ImagesClient) CreateOrUpdatePreparer(ctx context.Context, resourceG // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client ImagesClient) CreateOrUpdateSender(req *http.Request) (future ImagesCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -111,8 +114,9 @@ func (client ImagesClient) CreateOrUpdateResponder(resp *http.Response) (result } // Delete deletes an Image. -// -// resourceGroupName is the name of the resource group. imageName is the name of the image. +// Parameters: +// resourceGroupName - the name of the resource group. +// imageName - the name of the image. func (client ImagesClient) Delete(ctx context.Context, resourceGroupName string, imageName string) (result ImagesDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, imageName) if err != nil { @@ -153,15 +157,17 @@ func (client ImagesClient) DeletePreparer(ctx context.Context, resourceGroupName // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client ImagesClient) DeleteSender(req *http.Request) (future ImagesDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -179,9 +185,10 @@ func (client ImagesClient) DeleteResponder(resp *http.Response) (result Operatio } // Get gets an image. -// -// resourceGroupName is the name of the resource group. imageName is the name of the image. expand is the expand -// expression to apply on the operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// imageName - the name of the image. +// expand - the expand expression to apply on the operation. func (client ImagesClient) Get(ctx context.Context, resourceGroupName string, imageName string, expand string) (result Image, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, imageName, expand) if err != nil { @@ -340,8 +347,8 @@ func (client ImagesClient) ListComplete(ctx context.Context) (result ImageListRe } // ListByResourceGroup gets the list of images under a resource group. -// -// resourceGroupName is the name of the resource group. +// Parameters: +// resourceGroupName - the name of the resource group. func (client ImagesClient) ListByResourceGroup(ctx context.Context, resourceGroupName string) (result ImageListResultPage, err error) { result.fn = client.listByResourceGroupNextResults req, err := client.ListByResourceGroupPreparer(ctx, resourceGroupName) @@ -433,9 +440,10 @@ func (client ImagesClient) ListByResourceGroupComplete(ctx context.Context, reso } // Update update an image. -// -// resourceGroupName is the name of the resource group. imageName is the name of the image. parameters is -// parameters supplied to the Update Image operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// imageName - the name of the image. +// parameters - parameters supplied to the Update Image operation. func (client ImagesClient) Update(ctx context.Context, resourceGroupName string, imageName string, parameters ImageUpdate) (result ImagesUpdateFuture, err error) { req, err := client.UpdatePreparer(ctx, resourceGroupName, imageName, parameters) if err != nil { @@ -478,15 +486,17 @@ func (client ImagesClient) UpdatePreparer(ctx context.Context, resourceGroupName // UpdateSender sends the Update request. The method will close the // http.Response Body if it receives an error. func (client ImagesClient) UpdateSender(req *http.Request) (future ImagesUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/loganalytics.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/loganalytics.go index 0be7ada9b..a309e61ab 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/loganalytics.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/loganalytics.go @@ -42,9 +42,9 @@ func NewLogAnalyticsClientWithBaseURI(baseURI string, subscriptionID string) Log // ExportRequestRateByInterval export logs that show Api requests made by this subscription in the given time window to // show throttling activities. -// -// parameters is parameters supplied to the LogAnalytics getRequestRateByInterval Api. location is the location -// upon which virtual-machine-sizes is queried. +// Parameters: +// parameters - parameters supplied to the LogAnalytics getRequestRateByInterval Api. +// location - the location upon which virtual-machine-sizes is queried. func (client LogAnalyticsClient) ExportRequestRateByInterval(ctx context.Context, parameters RequestRateByIntervalInput, location string) (result LogAnalyticsExportRequestRateByIntervalFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: location, @@ -92,15 +92,17 @@ func (client LogAnalyticsClient) ExportRequestRateByIntervalPreparer(ctx context // ExportRequestRateByIntervalSender sends the ExportRequestRateByInterval request. The method will close the // http.Response Body if it receives an error. func (client LogAnalyticsClient) ExportRequestRateByIntervalSender(req *http.Request) (future LogAnalyticsExportRequestRateByIntervalFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -119,9 +121,9 @@ func (client LogAnalyticsClient) ExportRequestRateByIntervalResponder(resp *http // ExportThrottledRequests export logs that show total throttled Api requests for this subscription in the given time // window. -// -// parameters is parameters supplied to the LogAnalytics getThrottledRequests Api. location is the location upon -// which virtual-machine-sizes is queried. +// Parameters: +// parameters - parameters supplied to the LogAnalytics getThrottledRequests Api. +// location - the location upon which virtual-machine-sizes is queried. func (client LogAnalyticsClient) ExportThrottledRequests(ctx context.Context, parameters ThrottledRequestsInput, location string) (result LogAnalyticsExportThrottledRequestsFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: location, @@ -169,15 +171,17 @@ func (client LogAnalyticsClient) ExportThrottledRequestsPreparer(ctx context.Con // ExportThrottledRequestsSender sends the ExportThrottledRequests request. The method will close the // http.Response Body if it receives an error. func (client LogAnalyticsClient) ExportThrottledRequestsSender(req *http.Request) (future LogAnalyticsExportThrottledRequestsFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/models.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/models.go index 4260c63dc..f4efc7509 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/models.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/models.go @@ -540,6 +540,57 @@ func PossibleUpgradeModeValues() []UpgradeMode { return []UpgradeMode{Automatic, Manual, Rolling} } +// UpgradeOperationInvoker enumerates the values for upgrade operation invoker. +type UpgradeOperationInvoker string + +const ( + // Platform ... + Platform UpgradeOperationInvoker = "Platform" + // Unknown ... + Unknown UpgradeOperationInvoker = "Unknown" + // User ... + User UpgradeOperationInvoker = "User" +) + +// PossibleUpgradeOperationInvokerValues returns an array of possible values for the UpgradeOperationInvoker const type. +func PossibleUpgradeOperationInvokerValues() []UpgradeOperationInvoker { + return []UpgradeOperationInvoker{Platform, Unknown, User} +} + +// UpgradeState enumerates the values for upgrade state. +type UpgradeState string + +const ( + // UpgradeStateCancelled ... + UpgradeStateCancelled UpgradeState = "Cancelled" + // UpgradeStateCompleted ... + UpgradeStateCompleted UpgradeState = "Completed" + // UpgradeStateFaulted ... + UpgradeStateFaulted UpgradeState = "Faulted" + // UpgradeStateRollingForward ... + UpgradeStateRollingForward UpgradeState = "RollingForward" +) + +// PossibleUpgradeStateValues returns an array of possible values for the UpgradeState const type. +func PossibleUpgradeStateValues() []UpgradeState { + return []UpgradeState{UpgradeStateCancelled, UpgradeStateCompleted, UpgradeStateFaulted, UpgradeStateRollingForward} +} + +// VirtualMachineEvictionPolicyTypes enumerates the values for virtual machine eviction policy types. +type VirtualMachineEvictionPolicyTypes string + +const ( + // Deallocate ... + Deallocate VirtualMachineEvictionPolicyTypes = "Deallocate" + // Delete ... + Delete VirtualMachineEvictionPolicyTypes = "Delete" +) + +// PossibleVirtualMachineEvictionPolicyTypesValues returns an array of possible values for the VirtualMachineEvictionPolicyTypes const type. +func PossibleVirtualMachineEvictionPolicyTypesValues() []VirtualMachineEvictionPolicyTypes { + return []VirtualMachineEvictionPolicyTypes{Deallocate, Delete} +} + // VirtualMachinePriorityTypes enumerates the values for virtual machine priority types. type VirtualMachinePriorityTypes string @@ -916,84 +967,6 @@ func PossibleVirtualMachineSizeTypesValues() []VirtualMachineSizeTypes { // AccessURI a disk access SAS uri. type AccessURI struct { autorest.Response `json:"-"` - // AccessURIOutput - Operation output data (raw JSON) - *AccessURIOutput `json:"properties,omitempty"` -} - -// MarshalJSON is the custom marshaler for AccessURI. -func (au AccessURI) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]interface{}) - if au.AccessURIOutput != nil { - objectMap["properties"] = au.AccessURIOutput - } - return json.Marshal(objectMap) -} - -// UnmarshalJSON is the custom unmarshaler for AccessURI struct. -func (au *AccessURI) UnmarshalJSON(body []byte) error { - var m map[string]*json.RawMessage - err := json.Unmarshal(body, &m) - if err != nil { - return err - } - for k, v := range m { - switch k { - case "properties": - if v != nil { - var accessURIOutput AccessURIOutput - err = json.Unmarshal(*v, &accessURIOutput) - if err != nil { - return err - } - au.AccessURIOutput = &accessURIOutput - } - } - } - - return nil -} - -// AccessURIOutput azure properties, including output. -type AccessURIOutput struct { - // AccessURIRaw - Operation output data (raw JSON) - *AccessURIRaw `json:"output,omitempty"` -} - -// MarshalJSON is the custom marshaler for AccessURIOutput. -func (auo AccessURIOutput) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]interface{}) - if auo.AccessURIRaw != nil { - objectMap["output"] = auo.AccessURIRaw - } - return json.Marshal(objectMap) -} - -// UnmarshalJSON is the custom unmarshaler for AccessURIOutput struct. -func (auo *AccessURIOutput) UnmarshalJSON(body []byte) error { - var m map[string]*json.RawMessage - err := json.Unmarshal(body, &m) - if err != nil { - return err - } - for k, v := range m { - switch k { - case "output": - if v != nil { - var accessURIRaw AccessURIRaw - err = json.Unmarshal(*v, &accessURIRaw) - if err != nil { - return err - } - auo.AccessURIRaw = &accessURIRaw - } - } - } - - return nil -} - -// AccessURIRaw this object gets 'bubbled up' through flattening. -type AccessURIRaw struct { // AccessSAS - A SAS uri for accessing a disk. AccessSAS *string `json:"accessSAS,omitempty"` } @@ -1042,6 +1015,12 @@ type APIErrorBase struct { Message *string `json:"message,omitempty"` } +// AutoOSUpgradePolicy the configuration parameters used for performing automatic OS upgrade. +type AutoOSUpgradePolicy struct { + // DisableAutoRollback - Whether OS image rollback feature should be disabled. Default value is false. + DisableAutoRollback *bool `json:"disableAutoRollback,omitempty"` +} + // AvailabilitySet specifies information about the availability set that the virtual machine should be assigned to. // Virtual machines specified in the same availability set are allocated to different nodes to maximize // availability. For more information about availability sets, see [Manage the availability of virtual @@ -1192,13 +1171,7 @@ type AvailabilitySetProperties struct { } // AvailabilitySetUpdate specifies information about the availability set that the virtual machine should be -// assigned to. Virtual machines specified in the same availability set are allocated to different nodes to -// maximize availability. For more information about availability sets, see [Manage the availability of virtual -// machines](https://docs.microsoft.com/azure/virtual-machines/virtual-machines-windows-manage-availability?toc=%2fazure%2fvirtual-machines%2fwindows%2ftoc.json). -//

For more information on Azure planned maintainance, see [Planned maintenance for virtual machines in -// Azure](https://docs.microsoft.com/azure/virtual-machines/virtual-machines-windows-planned-maintenance?toc=%2fazure%2fvirtual-machines%2fwindows%2ftoc.json) -//

Currently, a VM can only be added to availability set at creation time. An existing VM cannot be added -// to an availability set. +// assigned to. Only tags may be updated. type AvailabilitySetUpdate struct { *AvailabilitySetProperties `json:"properties,omitempty"` // Sku - Sku of the availability set @@ -1570,12 +1543,11 @@ type ContainerServiceProperties struct { // operation. type ContainerServicesCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ContainerServicesCreateOrUpdateFuture) Result(client ContainerServicesClient) (cs ContainerService, err error) { +func (future *ContainerServicesCreateOrUpdateFuture) Result(client ContainerServicesClient) (cs ContainerService, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -1583,34 +1555,15 @@ func (future ContainerServicesCreateOrUpdateFuture) Result(client ContainerServi return } if !done { - return cs, azure.NewAsyncOpIncompleteError("compute.ContainerServicesCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - cs, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.ContainerServicesCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.ContainerServicesCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if cs.Response.Response, err = future.GetResult(sender); err == nil && cs.Response.Response.StatusCode != http.StatusNoContent { + cs, err = client.CreateOrUpdateResponder(cs.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.ContainerServicesCreateOrUpdateFuture", "Result", cs.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.ContainerServicesCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - cs, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.ContainerServicesCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -1619,12 +1572,11 @@ func (future ContainerServicesCreateOrUpdateFuture) Result(client ContainerServi // operation. type ContainerServicesDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ContainerServicesDeleteFuture) Result(client ContainerServicesClient) (ar autorest.Response, err error) { +func (future *ContainerServicesDeleteFuture) Result(client ContainerServicesClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -1632,35 +1584,10 @@ func (future ContainerServicesDeleteFuture) Result(client ContainerServicesClien return } if !done { - return ar, azure.NewAsyncOpIncompleteError("compute.ContainerServicesDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.ContainerServicesDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.ContainerServicesDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.ContainerServicesDeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.ContainerServicesDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -2040,12 +1967,11 @@ type DiskProperties struct { // DisksCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a long-running operation. type DisksCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future DisksCreateOrUpdateFuture) Result(client DisksClient) (d Disk, err error) { +func (future *DisksCreateOrUpdateFuture) Result(client DisksClient) (d Disk, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -2053,34 +1979,15 @@ func (future DisksCreateOrUpdateFuture) Result(client DisksClient) (d Disk, err return } if !done { - return d, azure.NewAsyncOpIncompleteError("compute.DisksCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - d, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.DisksCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.DisksCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if d.Response.Response, err = future.GetResult(sender); err == nil && d.Response.Response.StatusCode != http.StatusNoContent { + d, err = client.CreateOrUpdateResponder(d.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.DisksCreateOrUpdateFuture", "Result", d.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.DisksCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - d, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.DisksCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -2088,12 +1995,11 @@ func (future DisksCreateOrUpdateFuture) Result(client DisksClient) (d Disk, err // DisksDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation. type DisksDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future DisksDeleteFuture) Result(client DisksClient) (osr OperationStatusResponse, err error) { +func (future *DisksDeleteFuture) Result(client DisksClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -2101,47 +2007,21 @@ func (future DisksDeleteFuture) Result(client DisksClient) (osr OperationStatusR return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.DisksDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.DisksDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.DisksDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.DisksDeleteFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.DisksDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } // DisksGrantAccessFuture an abstraction for monitoring and retrieving the results of a long-running operation. type DisksGrantAccessFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future DisksGrantAccessFuture) Result(client DisksClient) (au AccessURI, err error) { +func (future *DisksGrantAccessFuture) Result(client DisksClient) (au AccessURI, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -2149,34 +2029,15 @@ func (future DisksGrantAccessFuture) Result(client DisksClient) (au AccessURI, e return } if !done { - return au, azure.NewAsyncOpIncompleteError("compute.DisksGrantAccessFuture") - } - if future.PollingMethod() == azure.PollingLocation { - au, err = client.GrantAccessResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.DisksGrantAccessFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.DisksGrantAccessFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if au.Response.Response, err = future.GetResult(sender); err == nil && au.Response.Response.StatusCode != http.StatusNoContent { + au, err = client.GrantAccessResponder(au.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.DisksGrantAccessFuture", "Result", au.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.DisksGrantAccessFuture", "Result", resp, "Failure sending request") - return - } - au, err = client.GrantAccessResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.DisksGrantAccessFuture", "Result", resp, "Failure responding to request") } return } @@ -2192,12 +2053,11 @@ type DiskSku struct { // DisksRevokeAccessFuture an abstraction for monitoring and retrieving the results of a long-running operation. type DisksRevokeAccessFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future DisksRevokeAccessFuture) Result(client DisksClient) (osr OperationStatusResponse, err error) { +func (future *DisksRevokeAccessFuture) Result(client DisksClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -2205,47 +2065,21 @@ func (future DisksRevokeAccessFuture) Result(client DisksClient) (osr OperationS return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.DisksRevokeAccessFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.RevokeAccessResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.DisksRevokeAccessFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.DisksRevokeAccessFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.DisksRevokeAccessFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.RevokeAccessResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.DisksRevokeAccessFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } // DisksUpdateFuture an abstraction for monitoring and retrieving the results of a long-running operation. type DisksUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future DisksUpdateFuture) Result(client DisksClient) (d Disk, err error) { +func (future *DisksUpdateFuture) Result(client DisksClient) (d Disk, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -2253,34 +2087,15 @@ func (future DisksUpdateFuture) Result(client DisksClient) (d Disk, err error) { return } if !done { - return d, azure.NewAsyncOpIncompleteError("compute.DisksUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - d, err = client.UpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.DisksUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.DisksUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if d.Response.Response, err = future.GetResult(sender); err == nil && d.Response.Response.StatusCode != http.StatusNoContent { + d, err = client.UpdateResponder(d.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.DisksUpdateFuture", "Result", d.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.DisksUpdateFuture", "Result", resp, "Failure sending request") - return - } - d, err = client.UpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.DisksUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -2671,12 +2486,11 @@ type ImageReference struct { // ImagesCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a long-running operation. type ImagesCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ImagesCreateOrUpdateFuture) Result(client ImagesClient) (i Image, err error) { +func (future *ImagesCreateOrUpdateFuture) Result(client ImagesClient) (i Image, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -2684,34 +2498,15 @@ func (future ImagesCreateOrUpdateFuture) Result(client ImagesClient) (i Image, e return } if !done { - return i, azure.NewAsyncOpIncompleteError("compute.ImagesCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - i, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.ImagesCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.ImagesCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if i.Response.Response, err = future.GetResult(sender); err == nil && i.Response.Response.StatusCode != http.StatusNoContent { + i, err = client.CreateOrUpdateResponder(i.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.ImagesCreateOrUpdateFuture", "Result", i.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.ImagesCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - i, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.ImagesCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -2719,12 +2514,11 @@ func (future ImagesCreateOrUpdateFuture) Result(client ImagesClient) (i Image, e // ImagesDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation. type ImagesDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ImagesDeleteFuture) Result(client ImagesClient) (osr OperationStatusResponse, err error) { +func (future *ImagesDeleteFuture) Result(client ImagesClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -2732,34 +2526,15 @@ func (future ImagesDeleteFuture) Result(client ImagesClient) (osr OperationStatu return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.ImagesDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.ImagesDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.ImagesDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.DeleteResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.ImagesDeleteFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.ImagesDeleteFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.ImagesDeleteFuture", "Result", resp, "Failure responding to request") } return } @@ -2777,12 +2552,11 @@ type ImageStorageProfile struct { // ImagesUpdateFuture an abstraction for monitoring and retrieving the results of a long-running operation. type ImagesUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ImagesUpdateFuture) Result(client ImagesClient) (i Image, err error) { +func (future *ImagesUpdateFuture) Result(client ImagesClient) (i Image, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -2790,40 +2564,20 @@ func (future ImagesUpdateFuture) Result(client ImagesClient) (i Image, err error return } if !done { - return i, azure.NewAsyncOpIncompleteError("compute.ImagesUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - i, err = client.UpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.ImagesUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.ImagesUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if i.Response.Response, err = future.GetResult(sender); err == nil && i.Response.Response.StatusCode != http.StatusNoContent { + i, err = client.UpdateResponder(i.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.ImagesUpdateFuture", "Result", i.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.ImagesUpdateFuture", "Result", resp, "Failure sending request") - return - } - i, err = client.UpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.ImagesUpdateFuture", "Result", resp, "Failure responding to request") } return } -// ImageUpdate the source user image virtual hard disk. The virtual hard disk will be copied before being attached -// to the virtual machine. If SourceImage is provided, the destination virtual hard drive must not exist. +// ImageUpdate the source user image virtual hard disk. Only tags may be updated. type ImageUpdate struct { *ImageProperties `json:"properties,omitempty"` // Tags - Resource tags @@ -3060,12 +2814,11 @@ type ListVirtualMachineImageResource struct { // long-running operation. type LogAnalyticsExportRequestRateByIntervalFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future LogAnalyticsExportRequestRateByIntervalFuture) Result(client LogAnalyticsClient) (laor LogAnalyticsOperationResult, err error) { +func (future *LogAnalyticsExportRequestRateByIntervalFuture) Result(client LogAnalyticsClient) (laor LogAnalyticsOperationResult, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -3073,34 +2826,15 @@ func (future LogAnalyticsExportRequestRateByIntervalFuture) Result(client LogAna return } if !done { - return laor, azure.NewAsyncOpIncompleteError("compute.LogAnalyticsExportRequestRateByIntervalFuture") - } - if future.PollingMethod() == azure.PollingLocation { - laor, err = client.ExportRequestRateByIntervalResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.LogAnalyticsExportRequestRateByIntervalFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.LogAnalyticsExportRequestRateByIntervalFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if laor.Response.Response, err = future.GetResult(sender); err == nil && laor.Response.Response.StatusCode != http.StatusNoContent { + laor, err = client.ExportRequestRateByIntervalResponder(laor.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.LogAnalyticsExportRequestRateByIntervalFuture", "Result", laor.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.LogAnalyticsExportRequestRateByIntervalFuture", "Result", resp, "Failure sending request") - return - } - laor, err = client.ExportRequestRateByIntervalResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.LogAnalyticsExportRequestRateByIntervalFuture", "Result", resp, "Failure responding to request") } return } @@ -3109,12 +2843,11 @@ func (future LogAnalyticsExportRequestRateByIntervalFuture) Result(client LogAna // long-running operation. type LogAnalyticsExportThrottledRequestsFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future LogAnalyticsExportThrottledRequestsFuture) Result(client LogAnalyticsClient) (laor LogAnalyticsOperationResult, err error) { +func (future *LogAnalyticsExportThrottledRequestsFuture) Result(client LogAnalyticsClient) (laor LogAnalyticsOperationResult, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -3122,34 +2855,15 @@ func (future LogAnalyticsExportThrottledRequestsFuture) Result(client LogAnalyti return } if !done { - return laor, azure.NewAsyncOpIncompleteError("compute.LogAnalyticsExportThrottledRequestsFuture") - } - if future.PollingMethod() == azure.PollingLocation { - laor, err = client.ExportThrottledRequestsResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.LogAnalyticsExportThrottledRequestsFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.LogAnalyticsExportThrottledRequestsFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if laor.Response.Response, err = future.GetResult(sender); err == nil && laor.Response.Response.StatusCode != http.StatusNoContent { + laor, err = client.ExportThrottledRequestsResponder(laor.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.LogAnalyticsExportThrottledRequestsFuture", "Result", laor.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.LogAnalyticsExportThrottledRequestsFuture", "Result", resp, "Failure sending request") - return - } - laor, err = client.ExportThrottledRequestsResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.LogAnalyticsExportThrottledRequestsFuture", "Result", resp, "Failure responding to request") } return } @@ -3716,23 +3430,14 @@ func (page ResourceSkusResultPage) Values() []ResourceSku { return *page.rsr.Value } -// ResourceUpdate the Resource model definition. -type ResourceUpdate struct { - // Tags - Resource tags - Tags map[string]*string `json:"tags"` - Sku *DiskSku `json:"sku,omitempty"` -} - -// MarshalJSON is the custom marshaler for ResourceUpdate. -func (ru ResourceUpdate) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]interface{}) - if ru.Tags != nil { - objectMap["tags"] = ru.Tags - } - if ru.Sku != nil { - objectMap["sku"] = ru.Sku - } - return json.Marshal(objectMap) +// RollbackStatusInfo information about rollback on failed VM instances after a OS Upgrade operation. +type RollbackStatusInfo struct { + // SuccessfullyRolledbackInstanceCount - The number of instances which have been successfully rolled back. + SuccessfullyRolledbackInstanceCount *int32 `json:"successfullyRolledbackInstanceCount,omitempty"` + // FailedRolledbackInstanceCount - The number of instances which failed to rollback. + FailedRolledbackInstanceCount *int32 `json:"failedRolledbackInstanceCount,omitempty"` + // RollbackError - Error details if OS rollback failed. + RollbackError *APIError `json:"rollbackError,omitempty"` } // RollingUpgradePolicy the configuration parameters used while performing a rolling upgrade. @@ -4424,12 +4129,11 @@ func (page SnapshotListPage) Values() []Snapshot { // operation. type SnapshotsCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future SnapshotsCreateOrUpdateFuture) Result(client SnapshotsClient) (s Snapshot, err error) { +func (future *SnapshotsCreateOrUpdateFuture) Result(client SnapshotsClient) (s Snapshot, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -4437,34 +4141,15 @@ func (future SnapshotsCreateOrUpdateFuture) Result(client SnapshotsClient) (s Sn return } if !done { - return s, azure.NewAsyncOpIncompleteError("compute.SnapshotsCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - s, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.SnapshotsCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.SnapshotsCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if s.Response.Response, err = future.GetResult(sender); err == nil && s.Response.Response.StatusCode != http.StatusNoContent { + s, err = client.CreateOrUpdateResponder(s.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.SnapshotsCreateOrUpdateFuture", "Result", s.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.SnapshotsCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - s, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.SnapshotsCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -4472,12 +4157,11 @@ func (future SnapshotsCreateOrUpdateFuture) Result(client SnapshotsClient) (s Sn // SnapshotsDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation. type SnapshotsDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future SnapshotsDeleteFuture) Result(client SnapshotsClient) (osr OperationStatusResponse, err error) { +func (future *SnapshotsDeleteFuture) Result(client SnapshotsClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -4485,47 +4169,21 @@ func (future SnapshotsDeleteFuture) Result(client SnapshotsClient) (osr Operatio return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.SnapshotsDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.SnapshotsDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.SnapshotsDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.SnapshotsDeleteFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.SnapshotsDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } // SnapshotsGrantAccessFuture an abstraction for monitoring and retrieving the results of a long-running operation. type SnapshotsGrantAccessFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future SnapshotsGrantAccessFuture) Result(client SnapshotsClient) (au AccessURI, err error) { +func (future *SnapshotsGrantAccessFuture) Result(client SnapshotsClient) (au AccessURI, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -4533,34 +4191,15 @@ func (future SnapshotsGrantAccessFuture) Result(client SnapshotsClient) (au Acce return } if !done { - return au, azure.NewAsyncOpIncompleteError("compute.SnapshotsGrantAccessFuture") - } - if future.PollingMethod() == azure.PollingLocation { - au, err = client.GrantAccessResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.SnapshotsGrantAccessFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.SnapshotsGrantAccessFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if au.Response.Response, err = future.GetResult(sender); err == nil && au.Response.Response.StatusCode != http.StatusNoContent { + au, err = client.GrantAccessResponder(au.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.SnapshotsGrantAccessFuture", "Result", au.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.SnapshotsGrantAccessFuture", "Result", resp, "Failure sending request") - return - } - au, err = client.GrantAccessResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.SnapshotsGrantAccessFuture", "Result", resp, "Failure responding to request") } return } @@ -4577,12 +4216,11 @@ type SnapshotSku struct { // operation. type SnapshotsRevokeAccessFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future SnapshotsRevokeAccessFuture) Result(client SnapshotsClient) (osr OperationStatusResponse, err error) { +func (future *SnapshotsRevokeAccessFuture) Result(client SnapshotsClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -4590,47 +4228,21 @@ func (future SnapshotsRevokeAccessFuture) Result(client SnapshotsClient) (osr Op return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.SnapshotsRevokeAccessFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.RevokeAccessResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.SnapshotsRevokeAccessFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.SnapshotsRevokeAccessFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.SnapshotsRevokeAccessFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.RevokeAccessResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.SnapshotsRevokeAccessFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } // SnapshotsUpdateFuture an abstraction for monitoring and retrieving the results of a long-running operation. type SnapshotsUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future SnapshotsUpdateFuture) Result(client SnapshotsClient) (s Snapshot, err error) { +func (future *SnapshotsUpdateFuture) Result(client SnapshotsClient) (s Snapshot, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -4638,34 +4250,15 @@ func (future SnapshotsUpdateFuture) Result(client SnapshotsClient) (s Snapshot, return } if !done { - return s, azure.NewAsyncOpIncompleteError("compute.SnapshotsUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - s, err = client.UpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.SnapshotsUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.SnapshotsUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if s.Response.Response, err = future.GetResult(sender); err == nil && s.Response.Response.StatusCode != http.StatusNoContent { + s, err = client.UpdateResponder(s.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.SnapshotsUpdateFuture", "Result", s.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.SnapshotsUpdateFuture", "Result", resp, "Failure sending request") - return - } - s, err = client.UpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.SnapshotsUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -4675,7 +4268,7 @@ type SnapshotUpdate struct { *DiskUpdateProperties `json:"properties,omitempty"` // Tags - Resource tags Tags map[string]*string `json:"tags"` - Sku *DiskSku `json:"sku,omitempty"` + Sku *SnapshotSku `json:"sku,omitempty"` } // MarshalJSON is the custom marshaler for SnapshotUpdate. @@ -4722,7 +4315,7 @@ func (su *SnapshotUpdate) UnmarshalJSON(body []byte) error { } case "sku": if v != nil { - var sku DiskSku + var sku SnapshotSku err = json.Unmarshal(*v, &sku) if err != nil { return err @@ -4810,6 +4403,42 @@ func (ur UpdateResource) MarshalJSON() ([]byte, error) { return json.Marshal(objectMap) } +// UpgradeOperationHistoricalStatusInfo virtual Machine Scale Set OS Upgrade History operation response. +type UpgradeOperationHistoricalStatusInfo struct { + // Properties - Information about the properties of the upgrade operation. + Properties *UpgradeOperationHistoricalStatusInfoProperties `json:"properties,omitempty"` + // Type - Resource type + Type *string `json:"type,omitempty"` + // Location - Resource location + Location *string `json:"location,omitempty"` +} + +// UpgradeOperationHistoricalStatusInfoProperties describes each OS upgrade on the Virtual Machine Scale Set. +type UpgradeOperationHistoricalStatusInfoProperties struct { + // RunningStatus - Information about the overall status of the upgrade operation. + RunningStatus *UpgradeOperationHistoryStatus `json:"runningStatus,omitempty"` + // Progress - Counts of the VM's in each state. + Progress *RollingUpgradeProgressInfo `json:"progress,omitempty"` + // Error - Error Details for this upgrade if there are any. + Error *APIError `json:"error,omitempty"` + // StartedBy - Invoker of the Upgrade Operation. Possible values include: 'Unknown', 'User', 'Platform' + StartedBy UpgradeOperationInvoker `json:"startedBy,omitempty"` + // TargetImageReference - Image Reference details + TargetImageReference *ImageReference `json:"targetImageReference,omitempty"` + // RollbackInfo - Information about OS rollback if performed + RollbackInfo *RollbackStatusInfo `json:"rollbackInfo,omitempty"` +} + +// UpgradeOperationHistoryStatus information about the current running state of the overall upgrade. +type UpgradeOperationHistoryStatus struct { + // Code - Code indicating the current status of the upgrade. Possible values include: 'UpgradeStateRollingForward', 'UpgradeStateCancelled', 'UpgradeStateCompleted', 'UpgradeStateFaulted' + Code UpgradeState `json:"code,omitempty"` + // StartTime - Start time of the upgrade. + StartTime *date.Time `json:"startTime,omitempty"` + // EndTime - End time of the upgrade. + EndTime *date.Time `json:"endTime,omitempty"` +} + // UpgradePolicy describes an upgrade policy - automatic, manual, or rolling. type UpgradePolicy struct { // Mode - Specifies the mode of an upgrade to virtual machines in the scale set.

Possible values are:

**Manual** - You control the application of updates to virtual machines in the scale set. You do this by using the manualUpgrade action.

**Automatic** - All virtual machines in the scale set are automatically updated at the same time. Possible values include: 'Automatic', 'Manual', 'Rolling' @@ -4818,6 +4447,8 @@ type UpgradePolicy struct { RollingUpgradePolicy *RollingUpgradePolicy `json:"rollingUpgradePolicy,omitempty"` // AutomaticOSUpgrade - Whether OS upgrades should automatically be applied to scale set instances in a rolling fashion when a newer version of the image becomes available. AutomaticOSUpgrade *bool `json:"automaticOSUpgrade,omitempty"` + // AutoOSUpgradePolicy - Configuration parameters used for performing automatic OS Upgrade. + AutoOSUpgradePolicy *AutoOSUpgradePolicy `json:"autoOSUpgradePolicy,omitempty"` } // Usage describes Compute Resource Usage. @@ -5389,12 +5020,11 @@ type VirtualMachineExtensionProperties struct { // long-running operation. type VirtualMachineExtensionsCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineExtensionsCreateOrUpdateFuture) Result(client VirtualMachineExtensionsClient) (vme VirtualMachineExtension, err error) { +func (future *VirtualMachineExtensionsCreateOrUpdateFuture) Result(client VirtualMachineExtensionsClient) (vme VirtualMachineExtension, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -5402,34 +5032,15 @@ func (future VirtualMachineExtensionsCreateOrUpdateFuture) Result(client Virtual return } if !done { - return vme, azure.NewAsyncOpIncompleteError("compute.VirtualMachineExtensionsCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - vme, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionsCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineExtensionsCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if vme.Response.Response, err = future.GetResult(sender); err == nil && vme.Response.Response.StatusCode != http.StatusNoContent { + vme, err = client.CreateOrUpdateResponder(vme.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionsCreateOrUpdateFuture", "Result", vme.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionsCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - vme, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionsCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -5438,12 +5049,11 @@ func (future VirtualMachineExtensionsCreateOrUpdateFuture) Result(client Virtual // operation. type VirtualMachineExtensionsDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineExtensionsDeleteFuture) Result(client VirtualMachineExtensionsClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachineExtensionsDeleteFuture) Result(client VirtualMachineExtensionsClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -5451,38 +5061,125 @@ func (future VirtualMachineExtensionsDeleteFuture) Result(client VirtualMachineE return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachineExtensionsDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionsDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineExtensionsDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.DeleteResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionsDeleteFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionsDeleteFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionsDeleteFuture", "Result", resp, "Failure responding to request") } return } +// VirtualMachineExtensionsListResult the List Extension operation response +type VirtualMachineExtensionsListResult struct { + autorest.Response `json:"-"` + // Value - The list of extensions + Value *[]VirtualMachineExtension `json:"value,omitempty"` +} + +// VirtualMachineExtensionsUpdateFuture an abstraction for monitoring and retrieving the results of a long-running +// operation. +type VirtualMachineExtensionsUpdateFuture struct { + azure.Future +} + +// Result returns the result of the asynchronous operation. +// If the operation has not completed it will return an error. +func (future *VirtualMachineExtensionsUpdateFuture) Result(client VirtualMachineExtensionsClient) (vme VirtualMachineExtension, err error) { + var done bool + done, err = future.Done(client) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionsUpdateFuture", "Result", future.Response(), "Polling failure") + return + } + if !done { + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineExtensionsUpdateFuture") + return + } + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if vme.Response.Response, err = future.GetResult(sender); err == nil && vme.Response.Response.StatusCode != http.StatusNoContent { + vme, err = client.UpdateResponder(vme.Response.Response) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionsUpdateFuture", "Result", vme.Response.Response, "Failure responding to request") + } + } + return +} + +// VirtualMachineExtensionUpdate describes a Virtual Machine Extension. +type VirtualMachineExtensionUpdate struct { + *VirtualMachineExtensionUpdateProperties `json:"properties,omitempty"` + // Tags - Resource tags + Tags map[string]*string `json:"tags"` +} + +// MarshalJSON is the custom marshaler for VirtualMachineExtensionUpdate. +func (vmeu VirtualMachineExtensionUpdate) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if vmeu.VirtualMachineExtensionUpdateProperties != nil { + objectMap["properties"] = vmeu.VirtualMachineExtensionUpdateProperties + } + if vmeu.Tags != nil { + objectMap["tags"] = vmeu.Tags + } + return json.Marshal(objectMap) +} + +// UnmarshalJSON is the custom unmarshaler for VirtualMachineExtensionUpdate struct. +func (vmeu *VirtualMachineExtensionUpdate) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + case "properties": + if v != nil { + var virtualMachineExtensionUpdateProperties VirtualMachineExtensionUpdateProperties + err = json.Unmarshal(*v, &virtualMachineExtensionUpdateProperties) + if err != nil { + return err + } + vmeu.VirtualMachineExtensionUpdateProperties = &virtualMachineExtensionUpdateProperties + } + case "tags": + if v != nil { + var tags map[string]*string + err = json.Unmarshal(*v, &tags) + if err != nil { + return err + } + vmeu.Tags = tags + } + } + } + + return nil +} + +// VirtualMachineExtensionUpdateProperties describes the properties of a Virtual Machine Extension. +type VirtualMachineExtensionUpdateProperties struct { + // ForceUpdateTag - How the extension handler should be forced to update even if the extension configuration has not changed. + ForceUpdateTag *string `json:"forceUpdateTag,omitempty"` + // Publisher - The name of the extension handler publisher. + Publisher *string `json:"publisher,omitempty"` + // Type - Specifies the type of the extension; an example is "CustomScriptExtension". + Type *string `json:"type,omitempty"` + // TypeHandlerVersion - Specifies the version of the script handler. + TypeHandlerVersion *string `json:"typeHandlerVersion,omitempty"` + // AutoUpgradeMinorVersion - Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true. + AutoUpgradeMinorVersion *bool `json:"autoUpgradeMinorVersion,omitempty"` + // Settings - Json formatted public settings for the extension. + Settings interface{} `json:"settings,omitempty"` + // ProtectedSettings - The extension can contain either protectedSettings or protectedSettingsFromKeyVault or no protected settings at all. + ProtectedSettings interface{} `json:"protectedSettings,omitempty"` +} + // VirtualMachineHealthStatus the health status of the VM. type VirtualMachineHealthStatus struct { // Status - The health status information for the VM. @@ -6171,12 +5868,11 @@ type VirtualMachineScaleSetExtensionProperties struct { // a long-running operation. type VirtualMachineScaleSetExtensionsCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineScaleSetExtensionsCreateOrUpdateFuture) Result(client VirtualMachineScaleSetExtensionsClient) (vmsse VirtualMachineScaleSetExtension, err error) { +func (future *VirtualMachineScaleSetExtensionsCreateOrUpdateFuture) Result(client VirtualMachineScaleSetExtensionsClient) (vmsse VirtualMachineScaleSetExtension, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -6184,34 +5880,15 @@ func (future VirtualMachineScaleSetExtensionsCreateOrUpdateFuture) Result(client return } if !done { - return vmsse, azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetExtensionsCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - vmsse, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetExtensionsCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetExtensionsCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if vmsse.Response.Response, err = future.GetResult(sender); err == nil && vmsse.Response.Response.StatusCode != http.StatusNoContent { + vmsse, err = client.CreateOrUpdateResponder(vmsse.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetExtensionsCreateOrUpdateFuture", "Result", vmsse.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetExtensionsCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - vmsse, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetExtensionsCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -6220,12 +5897,11 @@ func (future VirtualMachineScaleSetExtensionsCreateOrUpdateFuture) Result(client // long-running operation. type VirtualMachineScaleSetExtensionsDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineScaleSetExtensionsDeleteFuture) Result(client VirtualMachineScaleSetExtensionsClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachineScaleSetExtensionsDeleteFuture) Result(client VirtualMachineScaleSetExtensionsClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -6233,34 +5909,15 @@ func (future VirtualMachineScaleSetExtensionsDeleteFuture) Result(client Virtual return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetExtensionsDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetExtensionsDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetExtensionsDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.DeleteResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetExtensionsDeleteFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetExtensionsDeleteFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetExtensionsDeleteFuture", "Result", resp, "Failure responding to request") } return } @@ -6380,6 +6037,110 @@ type VirtualMachineScaleSetIPConfigurationProperties struct { LoadBalancerInboundNatPools *[]SubResource `json:"loadBalancerInboundNatPools,omitempty"` } +// VirtualMachineScaleSetListOSUpgradeHistory list of Virtual Machine Scale Set OS Upgrade History operation +// response. +type VirtualMachineScaleSetListOSUpgradeHistory struct { + autorest.Response `json:"-"` + // Value - The list of OS upgrades performed on the virtual machine scale set. + Value *[]UpgradeOperationHistoricalStatusInfo `json:"value,omitempty"` + // NextLink - The uri to fetch the next page of OS Upgrade History. Call ListNext() with this to fetch the next page of history of upgrades. + NextLink *string `json:"nextLink,omitempty"` +} + +// VirtualMachineScaleSetListOSUpgradeHistoryIterator provides access to a complete listing of +// UpgradeOperationHistoricalStatusInfo values. +type VirtualMachineScaleSetListOSUpgradeHistoryIterator struct { + i int + page VirtualMachineScaleSetListOSUpgradeHistoryPage +} + +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *VirtualMachineScaleSetListOSUpgradeHistoryIterator) Next() error { + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil + } + err := iter.page.Next() + if err != nil { + iter.i-- + return err + } + iter.i = 0 + return nil +} + +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter VirtualMachineScaleSetListOSUpgradeHistoryIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) +} + +// Response returns the raw server response from the last page request. +func (iter VirtualMachineScaleSetListOSUpgradeHistoryIterator) Response() VirtualMachineScaleSetListOSUpgradeHistory { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter VirtualMachineScaleSetListOSUpgradeHistoryIterator) Value() UpgradeOperationHistoricalStatusInfo { + if !iter.page.NotDone() { + return UpgradeOperationHistoricalStatusInfo{} + } + return iter.page.Values()[iter.i] +} + +// IsEmpty returns true if the ListResult contains no values. +func (vmsslouh VirtualMachineScaleSetListOSUpgradeHistory) IsEmpty() bool { + return vmsslouh.Value == nil || len(*vmsslouh.Value) == 0 +} + +// virtualMachineScaleSetListOSUpgradeHistoryPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (vmsslouh VirtualMachineScaleSetListOSUpgradeHistory) virtualMachineScaleSetListOSUpgradeHistoryPreparer() (*http.Request, error) { + if vmsslouh.NextLink == nil || len(to.String(vmsslouh.NextLink)) < 1 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(vmsslouh.NextLink))) +} + +// VirtualMachineScaleSetListOSUpgradeHistoryPage contains a page of UpgradeOperationHistoricalStatusInfo values. +type VirtualMachineScaleSetListOSUpgradeHistoryPage struct { + fn func(VirtualMachineScaleSetListOSUpgradeHistory) (VirtualMachineScaleSetListOSUpgradeHistory, error) + vmsslouh VirtualMachineScaleSetListOSUpgradeHistory +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *VirtualMachineScaleSetListOSUpgradeHistoryPage) Next() error { + next, err := page.fn(page.vmsslouh) + if err != nil { + return err + } + page.vmsslouh = next + return nil +} + +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page VirtualMachineScaleSetListOSUpgradeHistoryPage) NotDone() bool { + return !page.vmsslouh.IsEmpty() +} + +// Response returns the raw server response from the last page request. +func (page VirtualMachineScaleSetListOSUpgradeHistoryPage) Response() VirtualMachineScaleSetListOSUpgradeHistory { + return page.vmsslouh +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page VirtualMachineScaleSetListOSUpgradeHistoryPage) Values() []UpgradeOperationHistoricalStatusInfo { + if page.vmsslouh.IsEmpty() { + return nil + } + return *page.vmsslouh.Value +} + // VirtualMachineScaleSetListResult the List Virtual Machine operation response. type VirtualMachineScaleSetListResult struct { autorest.Response `json:"-"` @@ -6924,12 +6685,11 @@ type VirtualMachineScaleSetPublicIPAddressConfigurationProperties struct { // long-running operation. type VirtualMachineScaleSetRollingUpgradesCancelFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineScaleSetRollingUpgradesCancelFuture) Result(client VirtualMachineScaleSetRollingUpgradesClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachineScaleSetRollingUpgradesCancelFuture) Result(client VirtualMachineScaleSetRollingUpgradesClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -6937,34 +6697,15 @@ func (future VirtualMachineScaleSetRollingUpgradesCancelFuture) Result(client Vi return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetRollingUpgradesCancelFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.CancelResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetRollingUpgradesCancelFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetRollingUpgradesCancelFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.CancelResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetRollingUpgradesCancelFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetRollingUpgradesCancelFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.CancelResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetRollingUpgradesCancelFuture", "Result", resp, "Failure responding to request") } return } @@ -6973,12 +6714,11 @@ func (future VirtualMachineScaleSetRollingUpgradesCancelFuture) Result(client Vi // results of a long-running operation. type VirtualMachineScaleSetRollingUpgradesStartOSUpgradeFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineScaleSetRollingUpgradesStartOSUpgradeFuture) Result(client VirtualMachineScaleSetRollingUpgradesClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachineScaleSetRollingUpgradesStartOSUpgradeFuture) Result(client VirtualMachineScaleSetRollingUpgradesClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -6986,34 +6726,15 @@ func (future VirtualMachineScaleSetRollingUpgradesStartOSUpgradeFuture) Result(c return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetRollingUpgradesStartOSUpgradeFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.StartOSUpgradeResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetRollingUpgradesStartOSUpgradeFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetRollingUpgradesStartOSUpgradeFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.StartOSUpgradeResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetRollingUpgradesStartOSUpgradeFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetRollingUpgradesStartOSUpgradeFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.StartOSUpgradeResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetRollingUpgradesStartOSUpgradeFuture", "Result", resp, "Failure responding to request") } return } @@ -7022,12 +6743,11 @@ func (future VirtualMachineScaleSetRollingUpgradesStartOSUpgradeFuture) Result(c // long-running operation. type VirtualMachineScaleSetsCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineScaleSetsCreateOrUpdateFuture) Result(client VirtualMachineScaleSetsClient) (vmss VirtualMachineScaleSet, err error) { +func (future *VirtualMachineScaleSetsCreateOrUpdateFuture) Result(client VirtualMachineScaleSetsClient) (vmss VirtualMachineScaleSet, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -7035,34 +6755,15 @@ func (future VirtualMachineScaleSetsCreateOrUpdateFuture) Result(client VirtualM return } if !done { - return vmss, azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetsCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - vmss, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetsCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if vmss.Response.Response, err = future.GetResult(sender); err == nil && vmss.Response.Response.StatusCode != http.StatusNoContent { + vmss, err = client.CreateOrUpdateResponder(vmss.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsCreateOrUpdateFuture", "Result", vmss.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - vmss, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -7071,12 +6772,11 @@ func (future VirtualMachineScaleSetsCreateOrUpdateFuture) Result(client VirtualM // long-running operation. type VirtualMachineScaleSetsDeallocateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineScaleSetsDeallocateFuture) Result(client VirtualMachineScaleSetsClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachineScaleSetsDeallocateFuture) Result(client VirtualMachineScaleSetsClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -7084,34 +6784,15 @@ func (future VirtualMachineScaleSetsDeallocateFuture) Result(client VirtualMachi return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetsDeallocateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.DeallocateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsDeallocateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetsDeallocateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.DeallocateResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsDeallocateFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsDeallocateFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.DeallocateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsDeallocateFuture", "Result", resp, "Failure responding to request") } return } @@ -7120,12 +6801,11 @@ func (future VirtualMachineScaleSetsDeallocateFuture) Result(client VirtualMachi // operation. type VirtualMachineScaleSetsDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineScaleSetsDeleteFuture) Result(client VirtualMachineScaleSetsClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachineScaleSetsDeleteFuture) Result(client VirtualMachineScaleSetsClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -7133,34 +6813,15 @@ func (future VirtualMachineScaleSetsDeleteFuture) Result(client VirtualMachineSc return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetsDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetsDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.DeleteResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsDeleteFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsDeleteFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsDeleteFuture", "Result", resp, "Failure responding to request") } return } @@ -7169,12 +6830,11 @@ func (future VirtualMachineScaleSetsDeleteFuture) Result(client VirtualMachineSc // long-running operation. type VirtualMachineScaleSetsDeleteInstancesFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineScaleSetsDeleteInstancesFuture) Result(client VirtualMachineScaleSetsClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachineScaleSetsDeleteInstancesFuture) Result(client VirtualMachineScaleSetsClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -7182,34 +6842,15 @@ func (future VirtualMachineScaleSetsDeleteInstancesFuture) Result(client Virtual return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetsDeleteInstancesFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.DeleteInstancesResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsDeleteInstancesFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetsDeleteInstancesFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.DeleteInstancesResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsDeleteInstancesFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsDeleteInstancesFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.DeleteInstancesResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsDeleteInstancesFuture", "Result", resp, "Failure responding to request") } return } @@ -7240,12 +6881,11 @@ type VirtualMachineScaleSetSkuCapacity struct { // long-running operation. type VirtualMachineScaleSetsPerformMaintenanceFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineScaleSetsPerformMaintenanceFuture) Result(client VirtualMachineScaleSetsClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachineScaleSetsPerformMaintenanceFuture) Result(client VirtualMachineScaleSetsClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -7253,34 +6893,15 @@ func (future VirtualMachineScaleSetsPerformMaintenanceFuture) Result(client Virt return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetsPerformMaintenanceFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.PerformMaintenanceResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsPerformMaintenanceFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetsPerformMaintenanceFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.PerformMaintenanceResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsPerformMaintenanceFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsPerformMaintenanceFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.PerformMaintenanceResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsPerformMaintenanceFuture", "Result", resp, "Failure responding to request") } return } @@ -7289,12 +6910,11 @@ func (future VirtualMachineScaleSetsPerformMaintenanceFuture) Result(client Virt // operation. type VirtualMachineScaleSetsPowerOffFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineScaleSetsPowerOffFuture) Result(client VirtualMachineScaleSetsClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachineScaleSetsPowerOffFuture) Result(client VirtualMachineScaleSetsClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -7302,34 +6922,15 @@ func (future VirtualMachineScaleSetsPowerOffFuture) Result(client VirtualMachine return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetsPowerOffFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.PowerOffResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsPowerOffFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetsPowerOffFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.PowerOffResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsPowerOffFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsPowerOffFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.PowerOffResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsPowerOffFuture", "Result", resp, "Failure responding to request") } return } @@ -7338,12 +6939,11 @@ func (future VirtualMachineScaleSetsPowerOffFuture) Result(client VirtualMachine // operation. type VirtualMachineScaleSetsRedeployFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineScaleSetsRedeployFuture) Result(client VirtualMachineScaleSetsClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachineScaleSetsRedeployFuture) Result(client VirtualMachineScaleSetsClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -7351,34 +6951,15 @@ func (future VirtualMachineScaleSetsRedeployFuture) Result(client VirtualMachine return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetsRedeployFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.RedeployResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsRedeployFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetsRedeployFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.RedeployResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsRedeployFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsRedeployFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.RedeployResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsRedeployFuture", "Result", resp, "Failure responding to request") } return } @@ -7387,12 +6968,11 @@ func (future VirtualMachineScaleSetsRedeployFuture) Result(client VirtualMachine // long-running operation. type VirtualMachineScaleSetsReimageAllFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineScaleSetsReimageAllFuture) Result(client VirtualMachineScaleSetsClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachineScaleSetsReimageAllFuture) Result(client VirtualMachineScaleSetsClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -7400,34 +6980,15 @@ func (future VirtualMachineScaleSetsReimageAllFuture) Result(client VirtualMachi return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetsReimageAllFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.ReimageAllResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsReimageAllFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetsReimageAllFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.ReimageAllResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsReimageAllFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsReimageAllFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.ReimageAllResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsReimageAllFuture", "Result", resp, "Failure responding to request") } return } @@ -7436,12 +6997,11 @@ func (future VirtualMachineScaleSetsReimageAllFuture) Result(client VirtualMachi // operation. type VirtualMachineScaleSetsReimageFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineScaleSetsReimageFuture) Result(client VirtualMachineScaleSetsClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachineScaleSetsReimageFuture) Result(client VirtualMachineScaleSetsClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -7449,34 +7009,15 @@ func (future VirtualMachineScaleSetsReimageFuture) Result(client VirtualMachineS return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetsReimageFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.ReimageResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsReimageFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetsReimageFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.ReimageResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsReimageFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsReimageFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.ReimageResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsReimageFuture", "Result", resp, "Failure responding to request") } return } @@ -7485,12 +7026,11 @@ func (future VirtualMachineScaleSetsReimageFuture) Result(client VirtualMachineS // operation. type VirtualMachineScaleSetsRestartFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineScaleSetsRestartFuture) Result(client VirtualMachineScaleSetsClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachineScaleSetsRestartFuture) Result(client VirtualMachineScaleSetsClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -7498,34 +7038,15 @@ func (future VirtualMachineScaleSetsRestartFuture) Result(client VirtualMachineS return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetsRestartFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.RestartResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsRestartFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetsRestartFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.RestartResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsRestartFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsRestartFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.RestartResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsRestartFuture", "Result", resp, "Failure responding to request") } return } @@ -7534,12 +7055,11 @@ func (future VirtualMachineScaleSetsRestartFuture) Result(client VirtualMachineS // operation. type VirtualMachineScaleSetsStartFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineScaleSetsStartFuture) Result(client VirtualMachineScaleSetsClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachineScaleSetsStartFuture) Result(client VirtualMachineScaleSetsClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -7547,34 +7067,15 @@ func (future VirtualMachineScaleSetsStartFuture) Result(client VirtualMachineSca return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetsStartFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.StartResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsStartFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetsStartFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.StartResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsStartFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsStartFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.StartResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsStartFuture", "Result", resp, "Failure responding to request") } return } @@ -7593,12 +7094,11 @@ type VirtualMachineScaleSetStorageProfile struct { // operation. type VirtualMachineScaleSetsUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineScaleSetsUpdateFuture) Result(client VirtualMachineScaleSetsClient) (vmss VirtualMachineScaleSet, err error) { +func (future *VirtualMachineScaleSetsUpdateFuture) Result(client VirtualMachineScaleSetsClient) (vmss VirtualMachineScaleSet, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -7606,34 +7106,15 @@ func (future VirtualMachineScaleSetsUpdateFuture) Result(client VirtualMachineSc return } if !done { - return vmss, azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetsUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - vmss, err = client.UpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetsUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if vmss.Response.Response, err = future.GetResult(sender); err == nil && vmss.Response.Response.StatusCode != http.StatusNoContent { + vmss, err = client.UpdateResponder(vmss.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsUpdateFuture", "Result", vmss.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsUpdateFuture", "Result", resp, "Failure sending request") - return - } - vmss, err = client.UpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -7642,12 +7123,11 @@ func (future VirtualMachineScaleSetsUpdateFuture) Result(client VirtualMachineSc // long-running operation. type VirtualMachineScaleSetsUpdateInstancesFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineScaleSetsUpdateInstancesFuture) Result(client VirtualMachineScaleSetsClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachineScaleSetsUpdateInstancesFuture) Result(client VirtualMachineScaleSetsClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -7655,34 +7135,15 @@ func (future VirtualMachineScaleSetsUpdateInstancesFuture) Result(client Virtual return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetsUpdateInstancesFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.UpdateInstancesResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsUpdateInstancesFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetsUpdateInstancesFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.UpdateInstancesResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsUpdateInstancesFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsUpdateInstancesFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.UpdateInstancesResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsUpdateInstancesFuture", "Result", resp, "Failure responding to request") } return } @@ -8417,6 +7878,8 @@ type VirtualMachineScaleSetVMProfile struct { LicenseType *string `json:"licenseType,omitempty"` // Priority - Specifies the priority for the virtual machines in the scale set.

Minimum api-version: 2017-10-30-preview. Possible values include: 'Regular', 'Low' Priority VirtualMachinePriorityTypes `json:"priority,omitempty"` + // EvictionPolicy - Specifies the eviction policy for virtual machines in a low priority scale set.

Minimum api-version: 2017-10-30-preview. Possible values include: 'Deallocate', 'Delete' + EvictionPolicy VirtualMachineEvictionPolicyTypes `json:"evictionPolicy,omitempty"` } // VirtualMachineScaleSetVMProperties describes the properties of a virtual machine scale set virtual machine. @@ -8449,12 +7912,11 @@ type VirtualMachineScaleSetVMProperties struct { // long-running operation. type VirtualMachineScaleSetVMsDeallocateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineScaleSetVMsDeallocateFuture) Result(client VirtualMachineScaleSetVMsClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachineScaleSetVMsDeallocateFuture) Result(client VirtualMachineScaleSetVMsClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -8462,34 +7924,15 @@ func (future VirtualMachineScaleSetVMsDeallocateFuture) Result(client VirtualMac return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetVMsDeallocateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.DeallocateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsDeallocateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetVMsDeallocateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.DeallocateResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsDeallocateFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsDeallocateFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.DeallocateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsDeallocateFuture", "Result", resp, "Failure responding to request") } return } @@ -8498,12 +7941,11 @@ func (future VirtualMachineScaleSetVMsDeallocateFuture) Result(client VirtualMac // operation. type VirtualMachineScaleSetVMsDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineScaleSetVMsDeleteFuture) Result(client VirtualMachineScaleSetVMsClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachineScaleSetVMsDeleteFuture) Result(client VirtualMachineScaleSetVMsClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -8511,34 +7953,15 @@ func (future VirtualMachineScaleSetVMsDeleteFuture) Result(client VirtualMachine return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetVMsDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetVMsDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.DeleteResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsDeleteFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsDeleteFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsDeleteFuture", "Result", resp, "Failure responding to request") } return } @@ -8547,12 +7970,11 @@ func (future VirtualMachineScaleSetVMsDeleteFuture) Result(client VirtualMachine // long-running operation. type VirtualMachineScaleSetVMsPerformMaintenanceFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineScaleSetVMsPerformMaintenanceFuture) Result(client VirtualMachineScaleSetVMsClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachineScaleSetVMsPerformMaintenanceFuture) Result(client VirtualMachineScaleSetVMsClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -8560,34 +7982,15 @@ func (future VirtualMachineScaleSetVMsPerformMaintenanceFuture) Result(client Vi return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetVMsPerformMaintenanceFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.PerformMaintenanceResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsPerformMaintenanceFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetVMsPerformMaintenanceFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.PerformMaintenanceResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsPerformMaintenanceFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsPerformMaintenanceFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.PerformMaintenanceResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsPerformMaintenanceFuture", "Result", resp, "Failure responding to request") } return } @@ -8596,12 +7999,11 @@ func (future VirtualMachineScaleSetVMsPerformMaintenanceFuture) Result(client Vi // long-running operation. type VirtualMachineScaleSetVMsPowerOffFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineScaleSetVMsPowerOffFuture) Result(client VirtualMachineScaleSetVMsClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachineScaleSetVMsPowerOffFuture) Result(client VirtualMachineScaleSetVMsClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -8609,34 +8011,15 @@ func (future VirtualMachineScaleSetVMsPowerOffFuture) Result(client VirtualMachi return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetVMsPowerOffFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.PowerOffResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsPowerOffFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetVMsPowerOffFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.PowerOffResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsPowerOffFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsPowerOffFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.PowerOffResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsPowerOffFuture", "Result", resp, "Failure responding to request") } return } @@ -8645,12 +8028,11 @@ func (future VirtualMachineScaleSetVMsPowerOffFuture) Result(client VirtualMachi // long-running operation. type VirtualMachineScaleSetVMsRedeployFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineScaleSetVMsRedeployFuture) Result(client VirtualMachineScaleSetVMsClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachineScaleSetVMsRedeployFuture) Result(client VirtualMachineScaleSetVMsClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -8658,34 +8040,15 @@ func (future VirtualMachineScaleSetVMsRedeployFuture) Result(client VirtualMachi return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetVMsRedeployFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.RedeployResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsRedeployFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetVMsRedeployFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.RedeployResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsRedeployFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsRedeployFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.RedeployResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsRedeployFuture", "Result", resp, "Failure responding to request") } return } @@ -8694,12 +8057,11 @@ func (future VirtualMachineScaleSetVMsRedeployFuture) Result(client VirtualMachi // long-running operation. type VirtualMachineScaleSetVMsReimageAllFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineScaleSetVMsReimageAllFuture) Result(client VirtualMachineScaleSetVMsClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachineScaleSetVMsReimageAllFuture) Result(client VirtualMachineScaleSetVMsClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -8707,34 +8069,15 @@ func (future VirtualMachineScaleSetVMsReimageAllFuture) Result(client VirtualMac return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetVMsReimageAllFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.ReimageAllResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsReimageAllFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetVMsReimageAllFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.ReimageAllResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsReimageAllFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsReimageAllFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.ReimageAllResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsReimageAllFuture", "Result", resp, "Failure responding to request") } return } @@ -8743,12 +8086,11 @@ func (future VirtualMachineScaleSetVMsReimageAllFuture) Result(client VirtualMac // long-running operation. type VirtualMachineScaleSetVMsReimageFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineScaleSetVMsReimageFuture) Result(client VirtualMachineScaleSetVMsClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachineScaleSetVMsReimageFuture) Result(client VirtualMachineScaleSetVMsClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -8756,34 +8098,15 @@ func (future VirtualMachineScaleSetVMsReimageFuture) Result(client VirtualMachin return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetVMsReimageFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.ReimageResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsReimageFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetVMsReimageFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.ReimageResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsReimageFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsReimageFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.ReimageResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsReimageFuture", "Result", resp, "Failure responding to request") } return } @@ -8792,12 +8115,11 @@ func (future VirtualMachineScaleSetVMsReimageFuture) Result(client VirtualMachin // long-running operation. type VirtualMachineScaleSetVMsRestartFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineScaleSetVMsRestartFuture) Result(client VirtualMachineScaleSetVMsClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachineScaleSetVMsRestartFuture) Result(client VirtualMachineScaleSetVMsClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -8805,34 +8127,15 @@ func (future VirtualMachineScaleSetVMsRestartFuture) Result(client VirtualMachin return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetVMsRestartFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.RestartResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsRestartFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetVMsRestartFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.RestartResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsRestartFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsRestartFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.RestartResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsRestartFuture", "Result", resp, "Failure responding to request") } return } @@ -8841,12 +8144,11 @@ func (future VirtualMachineScaleSetVMsRestartFuture) Result(client VirtualMachin // operation. type VirtualMachineScaleSetVMsStartFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineScaleSetVMsStartFuture) Result(client VirtualMachineScaleSetVMsClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachineScaleSetVMsStartFuture) Result(client VirtualMachineScaleSetVMsClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -8854,34 +8156,15 @@ func (future VirtualMachineScaleSetVMsStartFuture) Result(client VirtualMachineS return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetVMsStartFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.StartResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsStartFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetVMsStartFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.StartResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsStartFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsStartFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.StartResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsStartFuture", "Result", resp, "Failure responding to request") } return } @@ -8890,12 +8173,11 @@ func (future VirtualMachineScaleSetVMsStartFuture) Result(client VirtualMachineS // operation. type VirtualMachineScaleSetVMsUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachineScaleSetVMsUpdateFuture) Result(client VirtualMachineScaleSetVMsClient) (vmssv VirtualMachineScaleSetVM, err error) { +func (future *VirtualMachineScaleSetVMsUpdateFuture) Result(client VirtualMachineScaleSetVMsClient) (vmssv VirtualMachineScaleSetVM, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -8903,34 +8185,15 @@ func (future VirtualMachineScaleSetVMsUpdateFuture) Result(client VirtualMachine return } if !done { - return vmssv, azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetVMsUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - vmssv, err = client.UpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachineScaleSetVMsUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if vmssv.Response.Response, err = future.GetResult(sender); err == nil && vmssv.Response.Response.StatusCode != http.StatusNoContent { + vmssv, err = client.UpdateResponder(vmssv.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsUpdateFuture", "Result", vmssv.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsUpdateFuture", "Result", resp, "Failure sending request") - return - } - vmssv, err = client.UpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetVMsUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -8939,12 +8202,11 @@ func (future VirtualMachineScaleSetVMsUpdateFuture) Result(client VirtualMachine // operation. type VirtualMachinesCaptureFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachinesCaptureFuture) Result(client VirtualMachinesClient) (vmcr VirtualMachineCaptureResult, err error) { +func (future *VirtualMachinesCaptureFuture) Result(client VirtualMachinesClient) (vmcr VirtualMachineCaptureResult, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -8952,34 +8214,15 @@ func (future VirtualMachinesCaptureFuture) Result(client VirtualMachinesClient) return } if !done { - return vmcr, azure.NewAsyncOpIncompleteError("compute.VirtualMachinesCaptureFuture") - } - if future.PollingMethod() == azure.PollingLocation { - vmcr, err = client.CaptureResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesCaptureFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachinesCaptureFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if vmcr.Response.Response, err = future.GetResult(sender); err == nil && vmcr.Response.Response.StatusCode != http.StatusNoContent { + vmcr, err = client.CaptureResponder(vmcr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesCaptureFuture", "Result", vmcr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesCaptureFuture", "Result", resp, "Failure sending request") - return - } - vmcr, err = client.CaptureResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesCaptureFuture", "Result", resp, "Failure responding to request") } return } @@ -8988,12 +8231,11 @@ func (future VirtualMachinesCaptureFuture) Result(client VirtualMachinesClient) // long-running operation. type VirtualMachinesConvertToManagedDisksFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachinesConvertToManagedDisksFuture) Result(client VirtualMachinesClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachinesConvertToManagedDisksFuture) Result(client VirtualMachinesClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -9001,34 +8243,15 @@ func (future VirtualMachinesConvertToManagedDisksFuture) Result(client VirtualMa return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachinesConvertToManagedDisksFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.ConvertToManagedDisksResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesConvertToManagedDisksFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachinesConvertToManagedDisksFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.ConvertToManagedDisksResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesConvertToManagedDisksFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesConvertToManagedDisksFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.ConvertToManagedDisksResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesConvertToManagedDisksFuture", "Result", resp, "Failure responding to request") } return } @@ -9037,12 +8260,11 @@ func (future VirtualMachinesConvertToManagedDisksFuture) Result(client VirtualMa // operation. type VirtualMachinesCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachinesCreateOrUpdateFuture) Result(client VirtualMachinesClient) (VM VirtualMachine, err error) { +func (future *VirtualMachinesCreateOrUpdateFuture) Result(client VirtualMachinesClient) (VM VirtualMachine, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -9050,34 +8272,15 @@ func (future VirtualMachinesCreateOrUpdateFuture) Result(client VirtualMachinesC return } if !done { - return VM, azure.NewAsyncOpIncompleteError("compute.VirtualMachinesCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - VM, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachinesCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if VM.Response.Response, err = future.GetResult(sender); err == nil && VM.Response.Response.StatusCode != http.StatusNoContent { + VM, err = client.CreateOrUpdateResponder(VM.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesCreateOrUpdateFuture", "Result", VM.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - VM, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -9086,12 +8289,11 @@ func (future VirtualMachinesCreateOrUpdateFuture) Result(client VirtualMachinesC // operation. type VirtualMachinesDeallocateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachinesDeallocateFuture) Result(client VirtualMachinesClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachinesDeallocateFuture) Result(client VirtualMachinesClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -9099,34 +8301,15 @@ func (future VirtualMachinesDeallocateFuture) Result(client VirtualMachinesClien return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachinesDeallocateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.DeallocateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesDeallocateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachinesDeallocateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.DeallocateResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesDeallocateFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesDeallocateFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.DeallocateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesDeallocateFuture", "Result", resp, "Failure responding to request") } return } @@ -9135,12 +8318,11 @@ func (future VirtualMachinesDeallocateFuture) Result(client VirtualMachinesClien // operation. type VirtualMachinesDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachinesDeleteFuture) Result(client VirtualMachinesClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachinesDeleteFuture) Result(client VirtualMachinesClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -9148,34 +8330,15 @@ func (future VirtualMachinesDeleteFuture) Result(client VirtualMachinesClient) ( return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachinesDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachinesDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.DeleteResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesDeleteFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesDeleteFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesDeleteFuture", "Result", resp, "Failure responding to request") } return } @@ -9207,12 +8370,11 @@ type VirtualMachineSizeListResult struct { // long-running operation. type VirtualMachinesPerformMaintenanceFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachinesPerformMaintenanceFuture) Result(client VirtualMachinesClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachinesPerformMaintenanceFuture) Result(client VirtualMachinesClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -9220,34 +8382,15 @@ func (future VirtualMachinesPerformMaintenanceFuture) Result(client VirtualMachi return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachinesPerformMaintenanceFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.PerformMaintenanceResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesPerformMaintenanceFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachinesPerformMaintenanceFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.PerformMaintenanceResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesPerformMaintenanceFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesPerformMaintenanceFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.PerformMaintenanceResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesPerformMaintenanceFuture", "Result", resp, "Failure responding to request") } return } @@ -9256,12 +8399,11 @@ func (future VirtualMachinesPerformMaintenanceFuture) Result(client VirtualMachi // operation. type VirtualMachinesPowerOffFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachinesPowerOffFuture) Result(client VirtualMachinesClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachinesPowerOffFuture) Result(client VirtualMachinesClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -9269,34 +8411,15 @@ func (future VirtualMachinesPowerOffFuture) Result(client VirtualMachinesClient) return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachinesPowerOffFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.PowerOffResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesPowerOffFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachinesPowerOffFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.PowerOffResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesPowerOffFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesPowerOffFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.PowerOffResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesPowerOffFuture", "Result", resp, "Failure responding to request") } return } @@ -9305,12 +8428,11 @@ func (future VirtualMachinesPowerOffFuture) Result(client VirtualMachinesClient) // operation. type VirtualMachinesRedeployFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachinesRedeployFuture) Result(client VirtualMachinesClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachinesRedeployFuture) Result(client VirtualMachinesClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -9318,34 +8440,15 @@ func (future VirtualMachinesRedeployFuture) Result(client VirtualMachinesClient) return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachinesRedeployFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.RedeployResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesRedeployFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachinesRedeployFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.RedeployResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesRedeployFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesRedeployFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.RedeployResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesRedeployFuture", "Result", resp, "Failure responding to request") } return } @@ -9354,12 +8457,11 @@ func (future VirtualMachinesRedeployFuture) Result(client VirtualMachinesClient) // operation. type VirtualMachinesRestartFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachinesRestartFuture) Result(client VirtualMachinesClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachinesRestartFuture) Result(client VirtualMachinesClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -9367,34 +8469,15 @@ func (future VirtualMachinesRestartFuture) Result(client VirtualMachinesClient) return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachinesRestartFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.RestartResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesRestartFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachinesRestartFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.RestartResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesRestartFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesRestartFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.RestartResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesRestartFuture", "Result", resp, "Failure responding to request") } return } @@ -9403,12 +8486,11 @@ func (future VirtualMachinesRestartFuture) Result(client VirtualMachinesClient) // operation. type VirtualMachinesRunCommandFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachinesRunCommandFuture) Result(client VirtualMachinesClient) (rcr RunCommandResult, err error) { +func (future *VirtualMachinesRunCommandFuture) Result(client VirtualMachinesClient) (rcr RunCommandResult, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -9416,34 +8498,15 @@ func (future VirtualMachinesRunCommandFuture) Result(client VirtualMachinesClien return } if !done { - return rcr, azure.NewAsyncOpIncompleteError("compute.VirtualMachinesRunCommandFuture") - } - if future.PollingMethod() == azure.PollingLocation { - rcr, err = client.RunCommandResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesRunCommandFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachinesRunCommandFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if rcr.Response.Response, err = future.GetResult(sender); err == nil && rcr.Response.Response.StatusCode != http.StatusNoContent { + rcr, err = client.RunCommandResponder(rcr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesRunCommandFuture", "Result", rcr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesRunCommandFuture", "Result", resp, "Failure sending request") - return - } - rcr, err = client.RunCommandResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesRunCommandFuture", "Result", resp, "Failure responding to request") } return } @@ -9451,12 +8514,11 @@ func (future VirtualMachinesRunCommandFuture) Result(client VirtualMachinesClien // VirtualMachinesStartFuture an abstraction for monitoring and retrieving the results of a long-running operation. type VirtualMachinesStartFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachinesStartFuture) Result(client VirtualMachinesClient) (osr OperationStatusResponse, err error) { +func (future *VirtualMachinesStartFuture) Result(client VirtualMachinesClient) (osr OperationStatusResponse, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -9464,34 +8526,15 @@ func (future VirtualMachinesStartFuture) Result(client VirtualMachinesClient) (o return } if !done { - return osr, azure.NewAsyncOpIncompleteError("compute.VirtualMachinesStartFuture") - } - if future.PollingMethod() == azure.PollingLocation { - osr, err = client.StartResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesStartFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachinesStartFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if osr.Response.Response, err = future.GetResult(sender); err == nil && osr.Response.Response.StatusCode != http.StatusNoContent { + osr, err = client.StartResponder(osr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesStartFuture", "Result", osr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesStartFuture", "Result", resp, "Failure sending request") - return - } - osr, err = client.StartResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesStartFuture", "Result", resp, "Failure responding to request") } return } @@ -9509,12 +8552,11 @@ type VirtualMachineStatusCodeCount struct { // operation. type VirtualMachinesUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualMachinesUpdateFuture) Result(client VirtualMachinesClient) (VM VirtualMachine, err error) { +func (future *VirtualMachinesUpdateFuture) Result(client VirtualMachinesClient) (VM VirtualMachine, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -9522,39 +8564,20 @@ func (future VirtualMachinesUpdateFuture) Result(client VirtualMachinesClient) ( return } if !done { - return VM, azure.NewAsyncOpIncompleteError("compute.VirtualMachinesUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - VM, err = client.UpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("compute.VirtualMachinesUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if VM.Response.Response, err = future.GetResult(sender); err == nil && VM.Response.Response.StatusCode != http.StatusNoContent { + VM, err = client.UpdateResponder(VM.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesUpdateFuture", "Result", VM.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesUpdateFuture", "Result", resp, "Failure sending request") - return - } - VM, err = client.UpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "compute.VirtualMachinesUpdateFuture", "Result", resp, "Failure responding to request") } return } -// VirtualMachineUpdate describes a Virtual Machine. +// VirtualMachineUpdate describes a Virtual Machine Update. type VirtualMachineUpdate struct { // Plan - Specifies information about the marketplace image used to create the virtual machine. This element is only used for marketplace images. Before you can use a marketplace image from an API, you must enable the image for programmatic use. In the Azure portal, find the marketplace image that you want to use and then click **Want to deploy programmatically, Get Started ->**. Enter any required information and then click **Save**. Plan *Plan `json:"plan,omitempty"` diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/snapshots.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/snapshots.go index 0f77e0d82..b87359354 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/snapshots.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/snapshots.go @@ -41,11 +41,11 @@ func NewSnapshotsClientWithBaseURI(baseURI string, subscriptionID string) Snapsh } // CreateOrUpdate creates or updates a snapshot. -// -// resourceGroupName is the name of the resource group. snapshotName is the name of the snapshot that is being -// created. The name can't be changed after the snapshot is created. Supported characters for the name are a-z, -// A-Z, 0-9 and _. The max name length is 80 characters. snapshot is snapshot object supplied in the body of the -// Put disk operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// snapshotName - the name of the snapshot that is being created. The name can't be changed after the snapshot +// is created. Supported characters for the name are a-z, A-Z, 0-9 and _. The max name length is 80 characters. +// snapshot - snapshot object supplied in the body of the Put disk operation. func (client SnapshotsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, snapshotName string, snapshot Snapshot) (result SnapshotsCreateOrUpdateFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: snapshot, @@ -109,15 +109,17 @@ func (client SnapshotsClient) CreateOrUpdatePreparer(ctx context.Context, resour // 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) (future SnapshotsCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -135,10 +137,10 @@ func (client SnapshotsClient) CreateOrUpdateResponder(resp *http.Response) (resu } // Delete deletes a snapshot. -// -// resourceGroupName is the name of the resource group. snapshotName is the name of the snapshot that is being -// created. The name can't be changed after the snapshot is created. Supported characters for the name are a-z, -// A-Z, 0-9 and _. The max name length is 80 characters. +// Parameters: +// resourceGroupName - the name of the resource group. +// snapshotName - the name of the snapshot that is being created. The name can't be changed after the snapshot +// is created. Supported characters for the name are a-z, A-Z, 0-9 and _. The max name length is 80 characters. func (client SnapshotsClient) Delete(ctx context.Context, resourceGroupName string, snapshotName string) (result SnapshotsDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, snapshotName) if err != nil { @@ -179,36 +181,37 @@ func (client SnapshotsClient) DeletePreparer(ctx context.Context, resourceGroupN // 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) (future SnapshotsDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } // 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) { +func (client SnapshotsClient) DeleteResponder(resp *http.Response) (result autorest.Response, 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} + result.Response = resp return } // Get gets information about a snapshot. -// -// resourceGroupName is the name of the resource group. snapshotName is the name of the snapshot that is being -// created. The name can't be changed after the snapshot is created. Supported characters for the name are a-z, -// A-Z, 0-9 and _. The max name length is 80 characters. +// Parameters: +// resourceGroupName - the name of the resource group. +// snapshotName - the name of the snapshot that is being created. The name can't be changed after the snapshot +// is created. Supported characters for the name are a-z, A-Z, 0-9 and _. The max name length is 80 characters. func (client SnapshotsClient) Get(ctx context.Context, resourceGroupName string, snapshotName string) (result Snapshot, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, snapshotName) if err != nil { @@ -273,11 +276,11 @@ func (client SnapshotsClient) GetResponder(resp *http.Response) (result Snapshot } // GrantAccess grants access to a snapshot. -// -// resourceGroupName is the name of the resource group. snapshotName is the name of the snapshot that is being -// created. The name can't be changed after the snapshot is created. Supported characters for the name are a-z, -// A-Z, 0-9 and _. The max name length is 80 characters. grantAccessData is access data object supplied in the body -// of the get snapshot access operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// snapshotName - the name of the snapshot that is being created. The name can't be changed after the snapshot +// is created. Supported characters for the name are a-z, A-Z, 0-9 and _. The max name length is 80 characters. +// grantAccessData - access data object supplied in the body of the get snapshot access operation. func (client SnapshotsClient) GrantAccess(ctx context.Context, resourceGroupName string, snapshotName string, grantAccessData GrantAccessData) (result SnapshotsGrantAccessFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: grantAccessData, @@ -326,15 +329,17 @@ func (client SnapshotsClient) GrantAccessPreparer(ctx context.Context, resourceG // 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) (future SnapshotsGrantAccessFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -442,8 +447,8 @@ func (client SnapshotsClient) ListComplete(ctx context.Context) (result Snapshot } // ListByResourceGroup lists snapshots under a resource group. -// -// resourceGroupName is the name of the resource group. +// Parameters: +// resourceGroupName - the name of the resource group. func (client SnapshotsClient) ListByResourceGroup(ctx context.Context, resourceGroupName string) (result SnapshotListPage, err error) { result.fn = client.listByResourceGroupNextResults req, err := client.ListByResourceGroupPreparer(ctx, resourceGroupName) @@ -535,10 +540,10 @@ func (client SnapshotsClient) ListByResourceGroupComplete(ctx context.Context, r } // RevokeAccess revokes access to a snapshot. -// -// resourceGroupName is the name of the resource group. snapshotName is the name of the snapshot that is being -// created. The name can't be changed after the snapshot is created. Supported characters for the name are a-z, -// A-Z, 0-9 and _. The max name length is 80 characters. +// Parameters: +// resourceGroupName - the name of the resource group. +// snapshotName - the name of the snapshot that is being created. The name can't be changed after the snapshot +// is created. Supported characters for the name are a-z, A-Z, 0-9 and _. The max name length is 80 characters. func (client SnapshotsClient) RevokeAccess(ctx context.Context, resourceGroupName string, snapshotName string) (result SnapshotsRevokeAccessFuture, err error) { req, err := client.RevokeAccessPreparer(ctx, resourceGroupName, snapshotName) if err != nil { @@ -579,37 +584,38 @@ func (client SnapshotsClient) RevokeAccessPreparer(ctx context.Context, resource // 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) (future SnapshotsRevokeAccessFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } // 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) { +func (client SnapshotsClient) RevokeAccessResponder(resp *http.Response) (result autorest.Response, 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} + result.Response = resp return } // Update updates (patches) a snapshot. -// -// resourceGroupName is the name of the resource group. snapshotName is the name of the snapshot that is being -// created. The name can't be changed after the snapshot is created. Supported characters for the name are a-z, -// A-Z, 0-9 and _. The max name length is 80 characters. snapshot is snapshot object supplied in the body of the -// Patch snapshot operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// snapshotName - the name of the snapshot that is being created. The name can't be changed after the snapshot +// is created. Supported characters for the name are a-z, A-Z, 0-9 and _. The max name length is 80 characters. +// snapshot - snapshot object supplied in the body of the Patch snapshot operation. func (client SnapshotsClient) Update(ctx context.Context, resourceGroupName string, snapshotName string, snapshot SnapshotUpdate) (result SnapshotsUpdateFuture, err error) { req, err := client.UpdatePreparer(ctx, resourceGroupName, snapshotName, snapshot) if err != nil { @@ -652,15 +658,17 @@ func (client SnapshotsClient) UpdatePreparer(ctx context.Context, resourceGroupN // 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) (future SnapshotsUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/usage.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/usage.go index 688781d48..e4bcd72b4 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/usage.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/usage.go @@ -42,8 +42,8 @@ func NewUsageClientWithBaseURI(baseURI string, subscriptionID string) UsageClien // List gets, for the specified location, the current compute resource usage information as well as the limits for // compute resources under the subscription. -// -// location is the location for which resource usage is queried. +// Parameters: +// location - the location for which resource usage is queried. func (client UsageClient) List(ctx context.Context, location string) (result ListUsagesResultPage, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: location, diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineextensionimages.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineextensionimages.go index 1573aa734..ca8bf91f7 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineextensionimages.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineextensionimages.go @@ -41,8 +41,8 @@ func NewVirtualMachineExtensionImagesClientWithBaseURI(baseURI string, subscript } // Get gets a virtual machine extension image. -// -// location is the name of a supported Azure region. +// Parameters: +// location - the name of a supported Azure region. func (client VirtualMachineExtensionImagesClient) Get(ctx context.Context, location string, publisherName string, typeParameter string, version string) (result VirtualMachineExtensionImage, err error) { req, err := client.GetPreparer(ctx, location, publisherName, typeParameter, version) if err != nil { @@ -109,8 +109,8 @@ func (client VirtualMachineExtensionImagesClient) GetResponder(resp *http.Respon } // ListTypes gets a list of virtual machine extension image types. -// -// location is the name of a supported Azure region. +// Parameters: +// location - the name of a supported Azure region. func (client VirtualMachineExtensionImagesClient) ListTypes(ctx context.Context, location string, publisherName string) (result ListVirtualMachineExtensionImage, err error) { req, err := client.ListTypesPreparer(ctx, location, publisherName) if err != nil { @@ -175,8 +175,9 @@ func (client VirtualMachineExtensionImagesClient) ListTypesResponder(resp *http. } // ListVersions gets a list of virtual machine extension image versions. -// -// location is the name of a supported Azure region. filter is the filter to apply on the operation. +// Parameters: +// location - the name of a supported Azure region. +// filter - the filter to apply on the operation. func (client VirtualMachineExtensionImagesClient) ListVersions(ctx context.Context, location string, publisherName string, typeParameter string, filter string, top *int32, orderby string) (result ListVirtualMachineExtensionImage, err error) { req, err := client.ListVersionsPreparer(ctx, location, publisherName, typeParameter, filter, top, orderby) if err != nil { diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineextensions.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineextensions.go index c5cbe664c..8c5d964fe 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineextensions.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineextensions.go @@ -40,10 +40,11 @@ func NewVirtualMachineExtensionsClientWithBaseURI(baseURI string, subscriptionID } // CreateOrUpdate the operation to create or update the extension. -// -// resourceGroupName is the name of the resource group. VMName is the name of the virtual machine where the -// extension should be create or updated. VMExtensionName is the name of the virtual machine extension. -// extensionParameters is parameters supplied to the Create Virtual Machine Extension operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMName - the name of the virtual machine where the extension should be created or updated. +// VMExtensionName - the name of the virtual machine extension. +// extensionParameters - parameters supplied to the Create Virtual Machine Extension operation. func (client VirtualMachineExtensionsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, VMName string, VMExtensionName string, extensionParameters VirtualMachineExtension) (result VirtualMachineExtensionsCreateOrUpdateFuture, err error) { req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, VMName, VMExtensionName, extensionParameters) if err != nil { @@ -87,15 +88,17 @@ func (client VirtualMachineExtensionsClient) CreateOrUpdatePreparer(ctx context. // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineExtensionsClient) CreateOrUpdateSender(req *http.Request) (future VirtualMachineExtensionsCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -113,9 +116,10 @@ func (client VirtualMachineExtensionsClient) CreateOrUpdateResponder(resp *http. } // Delete the operation to delete the extension. -// -// resourceGroupName is the name of the resource group. VMName is the name of the virtual machine where the -// extension should be deleted. VMExtensionName is the name of the virtual machine extension. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMName - the name of the virtual machine where the extension should be deleted. +// VMExtensionName - the name of the virtual machine extension. func (client VirtualMachineExtensionsClient) Delete(ctx context.Context, resourceGroupName string, VMName string, VMExtensionName string) (result VirtualMachineExtensionsDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, VMName, VMExtensionName) if err != nil { @@ -157,15 +161,17 @@ func (client VirtualMachineExtensionsClient) DeletePreparer(ctx context.Context, // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineExtensionsClient) DeleteSender(req *http.Request) (future VirtualMachineExtensionsDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -183,10 +189,11 @@ func (client VirtualMachineExtensionsClient) DeleteResponder(resp *http.Response } // Get the operation to get the extension. -// -// resourceGroupName is the name of the resource group. VMName is the name of the virtual machine containing the -// extension. VMExtensionName is the name of the virtual machine extension. expand is the expand expression to -// apply on the operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMName - the name of the virtual machine containing the extension. +// VMExtensionName - the name of the virtual machine extension. +// expand - the expand expression to apply on the operation. func (client VirtualMachineExtensionsClient) Get(ctx context.Context, resourceGroupName string, VMName string, VMExtensionName string, expand string) (result VirtualMachineExtension, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, VMName, VMExtensionName, expand) if err != nil { @@ -253,3 +260,79 @@ func (client VirtualMachineExtensionsClient) GetResponder(resp *http.Response) ( result.Response = autorest.Response{Response: resp} return } + +// Update the operation to update the extension. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMName - the name of the virtual machine where the extension should be updated. +// VMExtensionName - the name of the virtual machine extension. +// extensionParameters - parameters supplied to the Update Virtual Machine Extension operation. +func (client VirtualMachineExtensionsClient) Update(ctx context.Context, resourceGroupName string, VMName string, VMExtensionName string, extensionParameters VirtualMachineExtensionUpdate) (result VirtualMachineExtensionsUpdateFuture, err error) { + req, err := client.UpdatePreparer(ctx, resourceGroupName, VMName, VMExtensionName, extensionParameters) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionsClient", "Update", nil, "Failure preparing request") + return + } + + result, err = client.UpdateSender(req) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineExtensionsClient", "Update", result.Response(), "Failure sending request") + return + } + + return +} + +// UpdatePreparer prepares the Update request. +func (client VirtualMachineExtensionsClient) UpdatePreparer(ctx context.Context, resourceGroupName string, VMName string, VMExtensionName string, extensionParameters VirtualMachineExtensionUpdate) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmExtensionName": autorest.Encode("path", VMExtensionName), + "vmName": autorest.Encode("path", VMName), + } + + const APIVersion = "2017-12-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName}/extensions/{vmExtensionName}", pathParameters), + autorest.WithJSON(extensionParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// UpdateSender sends the Update request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineExtensionsClient) UpdateSender(req *http.Request) (future VirtualMachineExtensionsUpdateFuture, err error) { + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) + if err != nil { + return + } + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) + return +} + +// UpdateResponder handles the response to the Update request. The method always +// closes the http.Response Body. +func (client VirtualMachineExtensionsClient) UpdateResponder(resp *http.Response) (result VirtualMachineExtension, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineimages.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineimages.go index e8643d065..946a3ab49 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineimages.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineimages.go @@ -40,9 +40,12 @@ func NewVirtualMachineImagesClientWithBaseURI(baseURI string, subscriptionID str } // Get gets a virtual machine image. -// -// location is the name of a supported Azure region. publisherName is a valid image publisher. offer is a valid -// image publisher offer. skus is a valid image SKU. version is a valid image SKU version. +// Parameters: +// location - the name of a supported Azure region. +// publisherName - a valid image publisher. +// offer - a valid image publisher offer. +// skus - a valid image SKU. +// version - a valid image SKU version. func (client VirtualMachineImagesClient) Get(ctx context.Context, location string, publisherName string, offer string, skus string, version string) (result VirtualMachineImage, err error) { req, err := client.GetPreparer(ctx, location, publisherName, offer, skus, version) if err != nil { @@ -110,9 +113,12 @@ func (client VirtualMachineImagesClient) GetResponder(resp *http.Response) (resu } // List gets a list of all virtual machine image versions for the specified location, publisher, offer, and SKU. -// -// location is the name of a supported Azure region. publisherName is a valid image publisher. offer is a valid -// image publisher offer. skus is a valid image SKU. filter is the filter to apply on the operation. +// Parameters: +// location - the name of a supported Azure region. +// publisherName - a valid image publisher. +// offer - a valid image publisher offer. +// skus - a valid image SKU. +// filter - the filter to apply on the operation. func (client VirtualMachineImagesClient) List(ctx context.Context, location string, publisherName string, offer string, skus string, filter string, top *int32, orderby string) (result ListVirtualMachineImageResource, err error) { req, err := client.ListPreparer(ctx, location, publisherName, offer, skus, filter, top, orderby) if err != nil { @@ -188,8 +194,9 @@ func (client VirtualMachineImagesClient) ListResponder(resp *http.Response) (res } // ListOffers gets a list of virtual machine image offers for the specified location and publisher. -// -// location is the name of a supported Azure region. publisherName is a valid image publisher. +// Parameters: +// location - the name of a supported Azure region. +// publisherName - a valid image publisher. func (client VirtualMachineImagesClient) ListOffers(ctx context.Context, location string, publisherName string) (result ListVirtualMachineImageResource, err error) { req, err := client.ListOffersPreparer(ctx, location, publisherName) if err != nil { @@ -254,8 +261,8 @@ func (client VirtualMachineImagesClient) ListOffersResponder(resp *http.Response } // ListPublishers gets a list of virtual machine image publishers for the specified Azure location. -// -// location is the name of a supported Azure region. +// Parameters: +// location - the name of a supported Azure region. func (client VirtualMachineImagesClient) ListPublishers(ctx context.Context, location string) (result ListVirtualMachineImageResource, err error) { req, err := client.ListPublishersPreparer(ctx, location) if err != nil { @@ -319,9 +326,10 @@ func (client VirtualMachineImagesClient) ListPublishersResponder(resp *http.Resp } // ListSkus gets a list of virtual machine image SKUs for the specified location, publisher, and offer. -// -// location is the name of a supported Azure region. publisherName is a valid image publisher. offer is a valid -// image publisher offer. +// Parameters: +// location - the name of a supported Azure region. +// publisherName - a valid image publisher. +// offer - a valid image publisher offer. func (client VirtualMachineImagesClient) ListSkus(ctx context.Context, location string, publisherName string, offer string) (result ListVirtualMachineImageResource, err error) { req, err := client.ListSkusPreparer(ctx, location, publisherName, offer) if err != nil { diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineruncommands.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineruncommands.go index 6c38888d6..26d2a3377 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineruncommands.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachineruncommands.go @@ -41,8 +41,9 @@ func NewVirtualMachineRunCommandsClientWithBaseURI(baseURI string, subscriptionI } // Get gets specific run command for a subscription in a location. -// -// location is the location upon which run commands is queried. commandID is the command id. +// Parameters: +// location - the location upon which run commands is queried. +// commandID - the command id. func (client VirtualMachineRunCommandsClient) Get(ctx context.Context, location string, commandID string) (result RunCommandDocument, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: location, @@ -113,8 +114,8 @@ func (client VirtualMachineRunCommandsClient) GetResponder(resp *http.Response) } // List lists all available run commands for a subscription in a location. -// -// location is the location upon which run commands is queried. +// Parameters: +// location - the location upon which run commands is queried. func (client VirtualMachineRunCommandsClient) List(ctx context.Context, location string) (result RunCommandListResultPage, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: location, diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachines.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachines.go index 1a34d205a..ab8234321 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachines.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachines.go @@ -42,9 +42,10 @@ func NewVirtualMachinesClientWithBaseURI(baseURI string, subscriptionID string) // Capture captures the VM by copying virtual hard disks of the VM and outputs a template that can be used to create // similar VMs. -// -// resourceGroupName is the name of the resource group. VMName is the name of the virtual machine. parameters is -// parameters supplied to the Capture Virtual Machine operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMName - the name of the virtual machine. +// parameters - parameters supplied to the Capture Virtual Machine operation. func (client VirtualMachinesClient) Capture(ctx context.Context, resourceGroupName string, VMName string, parameters VirtualMachineCaptureParameters) (result VirtualMachinesCaptureFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: parameters, @@ -95,15 +96,17 @@ func (client VirtualMachinesClient) CapturePreparer(ctx context.Context, resourc // CaptureSender sends the Capture request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachinesClient) CaptureSender(req *http.Request) (future VirtualMachinesCaptureFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -122,8 +125,9 @@ func (client VirtualMachinesClient) CaptureResponder(resp *http.Response) (resul // ConvertToManagedDisks converts virtual machine disks from blob-based to managed disks. Virtual machine must be // stop-deallocated before invoking this operation. -// -// resourceGroupName is the name of the resource group. VMName is the name of the virtual machine. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMName - the name of the virtual machine. func (client VirtualMachinesClient) ConvertToManagedDisks(ctx context.Context, resourceGroupName string, VMName string) (result VirtualMachinesConvertToManagedDisksFuture, err error) { req, err := client.ConvertToManagedDisksPreparer(ctx, resourceGroupName, VMName) if err != nil { @@ -164,15 +168,17 @@ func (client VirtualMachinesClient) ConvertToManagedDisksPreparer(ctx context.Co // ConvertToManagedDisksSender sends the ConvertToManagedDisks request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachinesClient) ConvertToManagedDisksSender(req *http.Request) (future VirtualMachinesConvertToManagedDisksFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -190,9 +196,10 @@ func (client VirtualMachinesClient) ConvertToManagedDisksResponder(resp *http.Re } // CreateOrUpdate the operation to create or update a virtual machine. -// -// resourceGroupName is the name of the resource group. VMName is the name of the virtual machine. parameters is -// parameters supplied to the Create Virtual Machine operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMName - the name of the virtual machine. +// parameters - parameters supplied to the Create Virtual Machine operation. func (client VirtualMachinesClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, VMName string, parameters VirtualMachine) (result VirtualMachinesCreateOrUpdateFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: parameters, @@ -256,15 +263,17 @@ func (client VirtualMachinesClient) CreateOrUpdatePreparer(ctx context.Context, // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachinesClient) CreateOrUpdateSender(req *http.Request) (future VirtualMachinesCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -283,8 +292,9 @@ func (client VirtualMachinesClient) CreateOrUpdateResponder(resp *http.Response) // Deallocate shuts down the virtual machine and releases the compute resources. You are not billed for the compute // resources that this virtual machine uses. -// -// resourceGroupName is the name of the resource group. VMName is the name of the virtual machine. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMName - the name of the virtual machine. func (client VirtualMachinesClient) Deallocate(ctx context.Context, resourceGroupName string, VMName string) (result VirtualMachinesDeallocateFuture, err error) { req, err := client.DeallocatePreparer(ctx, resourceGroupName, VMName) if err != nil { @@ -325,15 +335,17 @@ func (client VirtualMachinesClient) DeallocatePreparer(ctx context.Context, reso // DeallocateSender sends the Deallocate request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachinesClient) DeallocateSender(req *http.Request) (future VirtualMachinesDeallocateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -351,8 +363,9 @@ func (client VirtualMachinesClient) DeallocateResponder(resp *http.Response) (re } // Delete the operation to delete a virtual machine. -// -// resourceGroupName is the name of the resource group. VMName is the name of the virtual machine. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMName - the name of the virtual machine. func (client VirtualMachinesClient) Delete(ctx context.Context, resourceGroupName string, VMName string) (result VirtualMachinesDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, VMName) if err != nil { @@ -393,15 +406,17 @@ func (client VirtualMachinesClient) DeletePreparer(ctx context.Context, resource // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachinesClient) DeleteSender(req *http.Request) (future VirtualMachinesDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -419,8 +434,9 @@ func (client VirtualMachinesClient) DeleteResponder(resp *http.Response) (result } // Generalize sets the state of the virtual machine to generalized. -// -// resourceGroupName is the name of the resource group. VMName is the name of the virtual machine. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMName - the name of the virtual machine. func (client VirtualMachinesClient) Generalize(ctx context.Context, resourceGroupName string, VMName string) (result OperationStatusResponse, err error) { req, err := client.GeneralizePreparer(ctx, resourceGroupName, VMName) if err != nil { @@ -485,9 +501,10 @@ func (client VirtualMachinesClient) GeneralizeResponder(resp *http.Response) (re } // Get retrieves information about the model view or the instance view of a virtual machine. -// -// resourceGroupName is the name of the resource group. VMName is the name of the virtual machine. expand is the -// expand expression to apply on the operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMName - the name of the virtual machine. +// expand - the expand expression to apply on the operation. func (client VirtualMachinesClient) Get(ctx context.Context, resourceGroupName string, VMName string, expand InstanceViewTypes) (result VirtualMachine, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, VMName, expand) if err != nil { @@ -554,9 +571,81 @@ func (client VirtualMachinesClient) GetResponder(resp *http.Response) (result Vi return } +// GetExtensions the operation to get all extensions of a Virtual Machine. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMName - the name of the virtual machine containing the extension. +// expand - the expand expression to apply on the operation. +func (client VirtualMachinesClient) GetExtensions(ctx context.Context, resourceGroupName string, VMName string, expand string) (result VirtualMachineExtensionsListResult, err error) { + req, err := client.GetExtensionsPreparer(ctx, resourceGroupName, VMName, expand) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "GetExtensions", nil, "Failure preparing request") + return + } + + resp, err := client.GetExtensionsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "GetExtensions", resp, "Failure sending request") + return + } + + result, err = client.GetExtensionsResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachinesClient", "GetExtensions", resp, "Failure responding to request") + } + + return +} + +// GetExtensionsPreparer prepares the GetExtensions request. +func (client VirtualMachinesClient) GetExtensionsPreparer(ctx context.Context, resourceGroupName string, VMName string, expand string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmName": autorest.Encode("path", VMName), + } + + const APIVersion = "2017-12-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(expand) > 0 { + queryParameters["$expand"] = autorest.Encode("query", expand) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName}/extensions", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// GetExtensionsSender sends the GetExtensions request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachinesClient) GetExtensionsSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// GetExtensionsResponder handles the response to the GetExtensions request. The method always +// closes the http.Response Body. +func (client VirtualMachinesClient) GetExtensionsResponder(resp *http.Response) (result VirtualMachineExtensionsListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + // InstanceView retrieves information about the run-time state of a virtual machine. -// -// resourceGroupName is the name of the resource group. VMName is the name of the virtual machine. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMName - the name of the virtual machine. func (client VirtualMachinesClient) InstanceView(ctx context.Context, resourceGroupName string, VMName string) (result VirtualMachineInstanceView, err error) { req, err := client.InstanceViewPreparer(ctx, resourceGroupName, VMName) if err != nil { @@ -622,8 +711,8 @@ func (client VirtualMachinesClient) InstanceViewResponder(resp *http.Response) ( // List lists all of the virtual machines in the specified resource group. Use the nextLink property in the response to // get the next page of virtual machines. -// -// resourceGroupName is the name of the resource group. +// Parameters: +// resourceGroupName - the name of the resource group. func (client VirtualMachinesClient) List(ctx context.Context, resourceGroupName string) (result VirtualMachineListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName) @@ -806,8 +895,9 @@ func (client VirtualMachinesClient) ListAllComplete(ctx context.Context) (result } // ListAvailableSizes lists all available virtual machine sizes to which the specified virtual machine can be resized. -// -// resourceGroupName is the name of the resource group. VMName is the name of the virtual machine. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMName - the name of the virtual machine. func (client VirtualMachinesClient) ListAvailableSizes(ctx context.Context, resourceGroupName string, VMName string) (result VirtualMachineSizeListResult, err error) { req, err := client.ListAvailableSizesPreparer(ctx, resourceGroupName, VMName) if err != nil { @@ -872,8 +962,9 @@ func (client VirtualMachinesClient) ListAvailableSizesResponder(resp *http.Respo } // PerformMaintenance the operation to perform maintenance on a virtual machine. -// -// resourceGroupName is the name of the resource group. VMName is the name of the virtual machine. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMName - the name of the virtual machine. func (client VirtualMachinesClient) PerformMaintenance(ctx context.Context, resourceGroupName string, VMName string) (result VirtualMachinesPerformMaintenanceFuture, err error) { req, err := client.PerformMaintenancePreparer(ctx, resourceGroupName, VMName) if err != nil { @@ -914,15 +1005,17 @@ func (client VirtualMachinesClient) PerformMaintenancePreparer(ctx context.Conte // PerformMaintenanceSender sends the PerformMaintenance request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachinesClient) PerformMaintenanceSender(req *http.Request) (future VirtualMachinesPerformMaintenanceFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -941,8 +1034,9 @@ func (client VirtualMachinesClient) PerformMaintenanceResponder(resp *http.Respo // PowerOff the operation to power off (stop) a virtual machine. The virtual machine can be restarted with the same // provisioned resources. You are still charged for this virtual machine. -// -// resourceGroupName is the name of the resource group. VMName is the name of the virtual machine. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMName - the name of the virtual machine. func (client VirtualMachinesClient) PowerOff(ctx context.Context, resourceGroupName string, VMName string) (result VirtualMachinesPowerOffFuture, err error) { req, err := client.PowerOffPreparer(ctx, resourceGroupName, VMName) if err != nil { @@ -983,15 +1077,17 @@ func (client VirtualMachinesClient) PowerOffPreparer(ctx context.Context, resour // PowerOffSender sends the PowerOff request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachinesClient) PowerOffSender(req *http.Request) (future VirtualMachinesPowerOffFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -1009,8 +1105,9 @@ func (client VirtualMachinesClient) PowerOffResponder(resp *http.Response) (resu } // Redeploy the operation to redeploy a virtual machine. -// -// resourceGroupName is the name of the resource group. VMName is the name of the virtual machine. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMName - the name of the virtual machine. func (client VirtualMachinesClient) Redeploy(ctx context.Context, resourceGroupName string, VMName string) (result VirtualMachinesRedeployFuture, err error) { req, err := client.RedeployPreparer(ctx, resourceGroupName, VMName) if err != nil { @@ -1051,15 +1148,17 @@ func (client VirtualMachinesClient) RedeployPreparer(ctx context.Context, resour // RedeploySender sends the Redeploy request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachinesClient) RedeploySender(req *http.Request) (future VirtualMachinesRedeployFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -1077,8 +1176,9 @@ func (client VirtualMachinesClient) RedeployResponder(resp *http.Response) (resu } // Restart the operation to restart a virtual machine. -// -// resourceGroupName is the name of the resource group. VMName is the name of the virtual machine. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMName - the name of the virtual machine. func (client VirtualMachinesClient) Restart(ctx context.Context, resourceGroupName string, VMName string) (result VirtualMachinesRestartFuture, err error) { req, err := client.RestartPreparer(ctx, resourceGroupName, VMName) if err != nil { @@ -1119,15 +1219,17 @@ func (client VirtualMachinesClient) RestartPreparer(ctx context.Context, resourc // RestartSender sends the Restart request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachinesClient) RestartSender(req *http.Request) (future VirtualMachinesRestartFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -1145,9 +1247,10 @@ func (client VirtualMachinesClient) RestartResponder(resp *http.Response) (resul } // RunCommand run command on the VM. -// -// resourceGroupName is the name of the resource group. VMName is the name of the virtual machine. parameters is -// parameters supplied to the Run command operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMName - the name of the virtual machine. +// parameters - parameters supplied to the Run command operation. func (client VirtualMachinesClient) RunCommand(ctx context.Context, resourceGroupName string, VMName string, parameters RunCommandInput) (result VirtualMachinesRunCommandFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: parameters, @@ -1196,15 +1299,17 @@ func (client VirtualMachinesClient) RunCommandPreparer(ctx context.Context, reso // RunCommandSender sends the RunCommand request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachinesClient) RunCommandSender(req *http.Request) (future VirtualMachinesRunCommandFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -1222,8 +1327,9 @@ func (client VirtualMachinesClient) RunCommandResponder(resp *http.Response) (re } // Start the operation to start a virtual machine. -// -// resourceGroupName is the name of the resource group. VMName is the name of the virtual machine. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMName - the name of the virtual machine. func (client VirtualMachinesClient) Start(ctx context.Context, resourceGroupName string, VMName string) (result VirtualMachinesStartFuture, err error) { req, err := client.StartPreparer(ctx, resourceGroupName, VMName) if err != nil { @@ -1264,15 +1370,17 @@ func (client VirtualMachinesClient) StartPreparer(ctx context.Context, resourceG // StartSender sends the Start request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachinesClient) StartSender(req *http.Request) (future VirtualMachinesStartFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -1290,9 +1398,10 @@ func (client VirtualMachinesClient) StartResponder(resp *http.Response) (result } // Update the operation to update a virtual machine. -// -// resourceGroupName is the name of the resource group. VMName is the name of the virtual machine. parameters is -// parameters supplied to the Update Virtual Machine operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMName - the name of the virtual machine. +// parameters - parameters supplied to the Update Virtual Machine operation. func (client VirtualMachinesClient) Update(ctx context.Context, resourceGroupName string, VMName string, parameters VirtualMachineUpdate) (result VirtualMachinesUpdateFuture, err error) { req, err := client.UpdatePreparer(ctx, resourceGroupName, VMName, parameters) if err != nil { @@ -1335,15 +1444,17 @@ func (client VirtualMachinesClient) UpdatePreparer(ctx context.Context, resource // UpdateSender sends the Update request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachinesClient) UpdateSender(req *http.Request) (future VirtualMachinesUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesetextensions.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesetextensions.go index fd630e647..4ebd68c00 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesetextensions.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesetextensions.go @@ -41,10 +41,11 @@ func NewVirtualMachineScaleSetExtensionsClientWithBaseURI(baseURI string, subscr } // CreateOrUpdate the operation to create or update an extension. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set where the -// extension should be create or updated. vmssExtensionName is the name of the VM scale set extension. -// extensionParameters is parameters supplied to the Create VM scale set Extension operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set where the extension should be create or updated. +// vmssExtensionName - the name of the VM scale set extension. +// extensionParameters - parameters supplied to the Create VM scale set Extension operation. func (client VirtualMachineScaleSetExtensionsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, VMScaleSetName string, vmssExtensionName string, extensionParameters VirtualMachineScaleSetExtension) (result VirtualMachineScaleSetExtensionsCreateOrUpdateFuture, err error) { req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, VMScaleSetName, vmssExtensionName, extensionParameters) if err != nil { @@ -88,15 +89,17 @@ func (client VirtualMachineScaleSetExtensionsClient) CreateOrUpdatePreparer(ctx // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineScaleSetExtensionsClient) CreateOrUpdateSender(req *http.Request) (future VirtualMachineScaleSetExtensionsCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -114,9 +117,10 @@ func (client VirtualMachineScaleSetExtensionsClient) CreateOrUpdateResponder(res } // Delete the operation to delete the extension. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set where the -// extension should be deleted. vmssExtensionName is the name of the VM scale set extension. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set where the extension should be deleted. +// vmssExtensionName - the name of the VM scale set extension. func (client VirtualMachineScaleSetExtensionsClient) Delete(ctx context.Context, resourceGroupName string, VMScaleSetName string, vmssExtensionName string) (result VirtualMachineScaleSetExtensionsDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, VMScaleSetName, vmssExtensionName) if err != nil { @@ -158,15 +162,17 @@ func (client VirtualMachineScaleSetExtensionsClient) DeletePreparer(ctx context. // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineScaleSetExtensionsClient) DeleteSender(req *http.Request) (future VirtualMachineScaleSetExtensionsDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -184,10 +190,11 @@ func (client VirtualMachineScaleSetExtensionsClient) DeleteResponder(resp *http. } // Get the operation to get the extension. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set containing -// the extension. vmssExtensionName is the name of the VM scale set extension. expand is the expand expression to -// apply on the operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set containing the extension. +// vmssExtensionName - the name of the VM scale set extension. +// expand - the expand expression to apply on the operation. func (client VirtualMachineScaleSetExtensionsClient) Get(ctx context.Context, resourceGroupName string, VMScaleSetName string, vmssExtensionName string, expand string) (result VirtualMachineScaleSetExtension, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, VMScaleSetName, vmssExtensionName, expand) if err != nil { @@ -256,9 +263,9 @@ func (client VirtualMachineScaleSetExtensionsClient) GetResponder(resp *http.Res } // List gets a list of all extensions in a VM scale set. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set containing -// the extension. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set containing the extension. func (client VirtualMachineScaleSetExtensionsClient) List(ctx context.Context, resourceGroupName string, VMScaleSetName string) (result VirtualMachineScaleSetExtensionListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName, VMScaleSetName) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesetrollingupgrades.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesetrollingupgrades.go index 6e7b66cb0..aa23ddb93 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesetrollingupgrades.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesetrollingupgrades.go @@ -42,8 +42,9 @@ func NewVirtualMachineScaleSetRollingUpgradesClientWithBaseURI(baseURI string, s } // Cancel cancels the current virtual machine scale set rolling upgrade. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. func (client VirtualMachineScaleSetRollingUpgradesClient) Cancel(ctx context.Context, resourceGroupName string, VMScaleSetName string) (result VirtualMachineScaleSetRollingUpgradesCancelFuture, err error) { req, err := client.CancelPreparer(ctx, resourceGroupName, VMScaleSetName) if err != nil { @@ -84,15 +85,17 @@ func (client VirtualMachineScaleSetRollingUpgradesClient) CancelPreparer(ctx con // CancelSender sends the Cancel request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineScaleSetRollingUpgradesClient) CancelSender(req *http.Request) (future VirtualMachineScaleSetRollingUpgradesCancelFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -110,8 +113,9 @@ func (client VirtualMachineScaleSetRollingUpgradesClient) CancelResponder(resp * } // GetLatest gets the status of the latest virtual machine scale set rolling upgrade. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. func (client VirtualMachineScaleSetRollingUpgradesClient) GetLatest(ctx context.Context, resourceGroupName string, VMScaleSetName string) (result RollingUpgradeStatusInfo, err error) { req, err := client.GetLatestPreparer(ctx, resourceGroupName, VMScaleSetName) if err != nil { @@ -177,8 +181,9 @@ func (client VirtualMachineScaleSetRollingUpgradesClient) GetLatestResponder(res // StartOSUpgrade starts a rolling upgrade to move all virtual machine scale set instances to the latest available // Platform Image OS version. Instances which are already running the latest available OS version are not affected. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. func (client VirtualMachineScaleSetRollingUpgradesClient) StartOSUpgrade(ctx context.Context, resourceGroupName string, VMScaleSetName string) (result VirtualMachineScaleSetRollingUpgradesStartOSUpgradeFuture, err error) { req, err := client.StartOSUpgradePreparer(ctx, resourceGroupName, VMScaleSetName) if err != nil { @@ -219,15 +224,17 @@ func (client VirtualMachineScaleSetRollingUpgradesClient) StartOSUpgradePreparer // StartOSUpgradeSender sends the StartOSUpgrade request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineScaleSetRollingUpgradesClient) StartOSUpgradeSender(req *http.Request) (future VirtualMachineScaleSetRollingUpgradesStartOSUpgradeFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesets.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesets.go index 4b157e34c..dc742f64f 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesets.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesets.go @@ -41,9 +41,10 @@ func NewVirtualMachineScaleSetsClientWithBaseURI(baseURI string, subscriptionID } // CreateOrUpdate create or update a VM scale set. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set to create or -// update. parameters is the scale set object. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set to create or update. +// parameters - the scale set object. func (client VirtualMachineScaleSetsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, VMScaleSetName string, parameters VirtualMachineScaleSet) (result VirtualMachineScaleSetsCreateOrUpdateFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: parameters, @@ -109,15 +110,17 @@ func (client VirtualMachineScaleSetsClient) CreateOrUpdatePreparer(ctx context.C // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineScaleSetsClient) CreateOrUpdateSender(req *http.Request) (future VirtualMachineScaleSetsCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -136,9 +139,10 @@ func (client VirtualMachineScaleSetsClient) CreateOrUpdateResponder(resp *http.R // Deallocate deallocates specific virtual machines in a VM scale set. Shuts down the virtual machines and releases the // compute resources. You are not billed for the compute resources that this virtual machine scale set deallocates. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. -// VMInstanceIDs is a list of virtual machine instance IDs from the VM scale set. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. +// VMInstanceIDs - a list of virtual machine instance IDs from the VM scale set. func (client VirtualMachineScaleSetsClient) Deallocate(ctx context.Context, resourceGroupName string, VMScaleSetName string, VMInstanceIDs *VirtualMachineScaleSetVMInstanceIDs) (result VirtualMachineScaleSetsDeallocateFuture, err error) { req, err := client.DeallocatePreparer(ctx, resourceGroupName, VMScaleSetName, VMInstanceIDs) if err != nil { @@ -184,15 +188,17 @@ func (client VirtualMachineScaleSetsClient) DeallocatePreparer(ctx context.Conte // DeallocateSender sends the Deallocate request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineScaleSetsClient) DeallocateSender(req *http.Request) (future VirtualMachineScaleSetsDeallocateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -210,8 +216,9 @@ func (client VirtualMachineScaleSetsClient) DeallocateResponder(resp *http.Respo } // Delete deletes a VM scale set. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. func (client VirtualMachineScaleSetsClient) Delete(ctx context.Context, resourceGroupName string, VMScaleSetName string) (result VirtualMachineScaleSetsDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, VMScaleSetName) if err != nil { @@ -252,15 +259,17 @@ func (client VirtualMachineScaleSetsClient) DeletePreparer(ctx context.Context, // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineScaleSetsClient) DeleteSender(req *http.Request) (future VirtualMachineScaleSetsDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -278,9 +287,10 @@ func (client VirtualMachineScaleSetsClient) DeleteResponder(resp *http.Response) } // DeleteInstances deletes virtual machines in a VM scale set. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. -// VMInstanceIDs is a list of virtual machine instance IDs from the VM scale set. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. +// VMInstanceIDs - a list of virtual machine instance IDs from the VM scale set. func (client VirtualMachineScaleSetsClient) DeleteInstances(ctx context.Context, resourceGroupName string, VMScaleSetName string, VMInstanceIDs VirtualMachineScaleSetVMInstanceRequiredIDs) (result VirtualMachineScaleSetsDeleteInstancesFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: VMInstanceIDs, @@ -329,15 +339,17 @@ func (client VirtualMachineScaleSetsClient) DeleteInstancesPreparer(ctx context. // DeleteInstancesSender sends the DeleteInstances request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineScaleSetsClient) DeleteInstancesSender(req *http.Request) (future VirtualMachineScaleSetsDeleteInstancesFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -356,9 +368,10 @@ func (client VirtualMachineScaleSetsClient) DeleteInstancesResponder(resp *http. // ForceRecoveryServiceFabricPlatformUpdateDomainWalk manual platform update domain walk to update virtual machines in // a service fabric virtual machine scale set. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. -// platformUpdateDomain is the platform update domain for which a manual recovery walk is requested +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. +// platformUpdateDomain - the platform update domain for which a manual recovery walk is requested func (client VirtualMachineScaleSetsClient) ForceRecoveryServiceFabricPlatformUpdateDomainWalk(ctx context.Context, resourceGroupName string, VMScaleSetName string, platformUpdateDomain int32) (result RecoveryWalkResponse, err error) { req, err := client.ForceRecoveryServiceFabricPlatformUpdateDomainWalkPreparer(ctx, resourceGroupName, VMScaleSetName, platformUpdateDomain) if err != nil { @@ -424,8 +437,9 @@ func (client VirtualMachineScaleSetsClient) ForceRecoveryServiceFabricPlatformUp } // Get display information about a virtual machine scale set. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. func (client VirtualMachineScaleSetsClient) Get(ctx context.Context, resourceGroupName string, VMScaleSetName string) (result VirtualMachineScaleSet, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, VMScaleSetName) if err != nil { @@ -490,8 +504,9 @@ func (client VirtualMachineScaleSetsClient) GetResponder(resp *http.Response) (r } // GetInstanceView gets the status of a VM scale set instance. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. func (client VirtualMachineScaleSetsClient) GetInstanceView(ctx context.Context, resourceGroupName string, VMScaleSetName string) (result VirtualMachineScaleSetInstanceView, err error) { req, err := client.GetInstanceViewPreparer(ctx, resourceGroupName, VMScaleSetName) if err != nil { @@ -555,9 +570,104 @@ func (client VirtualMachineScaleSetsClient) GetInstanceViewResponder(resp *http. return } +// GetOSUpgradeHistory gets list of OS upgrades on a VM scale set instance. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. +func (client VirtualMachineScaleSetsClient) GetOSUpgradeHistory(ctx context.Context, resourceGroupName string, VMScaleSetName string) (result VirtualMachineScaleSetListOSUpgradeHistoryPage, err error) { + result.fn = client.getOSUpgradeHistoryNextResults + req, err := client.GetOSUpgradeHistoryPreparer(ctx, resourceGroupName, VMScaleSetName) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "GetOSUpgradeHistory", nil, "Failure preparing request") + return + } + + resp, err := client.GetOSUpgradeHistorySender(req) + if err != nil { + result.vmsslouh.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "GetOSUpgradeHistory", resp, "Failure sending request") + return + } + + result.vmsslouh, err = client.GetOSUpgradeHistoryResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "GetOSUpgradeHistory", resp, "Failure responding to request") + } + + return +} + +// GetOSUpgradeHistoryPreparer prepares the GetOSUpgradeHistory request. +func (client VirtualMachineScaleSetsClient) GetOSUpgradeHistoryPreparer(ctx context.Context, resourceGroupName string, VMScaleSetName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vmScaleSetName": autorest.Encode("path", VMScaleSetName), + } + + const APIVersion = "2017-12-01" + 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/virtualMachineScaleSets/{vmScaleSetName}/osUpgradeHistory", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// GetOSUpgradeHistorySender sends the GetOSUpgradeHistory request. The method will close the +// http.Response Body if it receives an error. +func (client VirtualMachineScaleSetsClient) GetOSUpgradeHistorySender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// GetOSUpgradeHistoryResponder handles the response to the GetOSUpgradeHistory request. The method always +// closes the http.Response Body. +func (client VirtualMachineScaleSetsClient) GetOSUpgradeHistoryResponder(resp *http.Response) (result VirtualMachineScaleSetListOSUpgradeHistory, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// getOSUpgradeHistoryNextResults retrieves the next set of results, if any. +func (client VirtualMachineScaleSetsClient) getOSUpgradeHistoryNextResults(lastResults VirtualMachineScaleSetListOSUpgradeHistory) (result VirtualMachineScaleSetListOSUpgradeHistory, err error) { + req, err := lastResults.virtualMachineScaleSetListOSUpgradeHistoryPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "getOSUpgradeHistoryNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.GetOSUpgradeHistorySender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "getOSUpgradeHistoryNextResults", resp, "Failure sending next results request") + } + result, err = client.GetOSUpgradeHistoryResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "compute.VirtualMachineScaleSetsClient", "getOSUpgradeHistoryNextResults", resp, "Failure responding to next results request") + } + return +} + +// GetOSUpgradeHistoryComplete enumerates all values, automatically crossing page boundaries as required. +func (client VirtualMachineScaleSetsClient) GetOSUpgradeHistoryComplete(ctx context.Context, resourceGroupName string, VMScaleSetName string) (result VirtualMachineScaleSetListOSUpgradeHistoryIterator, err error) { + result.page, err = client.GetOSUpgradeHistory(ctx, resourceGroupName, VMScaleSetName) + return +} + // List gets a list of all VM scale sets under a resource group. -// -// resourceGroupName is the name of the resource group. +// Parameters: +// resourceGroupName - the name of the resource group. func (client VirtualMachineScaleSetsClient) List(ctx context.Context, resourceGroupName string) (result VirtualMachineScaleSetListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName) @@ -742,8 +852,9 @@ func (client VirtualMachineScaleSetsClient) ListAllComplete(ctx context.Context) // ListSkus gets a list of SKUs available for your VM scale set, including the minimum and maximum VM instances allowed // for each SKU. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. func (client VirtualMachineScaleSetsClient) ListSkus(ctx context.Context, resourceGroupName string, VMScaleSetName string) (result VirtualMachineScaleSetListSkusResultPage, err error) { result.fn = client.listSkusNextResults req, err := client.ListSkusPreparer(ctx, resourceGroupName, VMScaleSetName) @@ -836,9 +947,10 @@ func (client VirtualMachineScaleSetsClient) ListSkusComplete(ctx context.Context } // PerformMaintenance perform maintenance on one or more virtual machines in a VM scale set. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. -// VMInstanceIDs is a list of virtual machine instance IDs from the VM scale set. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. +// VMInstanceIDs - a list of virtual machine instance IDs from the VM scale set. func (client VirtualMachineScaleSetsClient) PerformMaintenance(ctx context.Context, resourceGroupName string, VMScaleSetName string, VMInstanceIDs *VirtualMachineScaleSetVMInstanceIDs) (result VirtualMachineScaleSetsPerformMaintenanceFuture, err error) { req, err := client.PerformMaintenancePreparer(ctx, resourceGroupName, VMScaleSetName, VMInstanceIDs) if err != nil { @@ -884,15 +996,17 @@ func (client VirtualMachineScaleSetsClient) PerformMaintenancePreparer(ctx conte // PerformMaintenanceSender sends the PerformMaintenance request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineScaleSetsClient) PerformMaintenanceSender(req *http.Request) (future VirtualMachineScaleSetsPerformMaintenanceFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -911,9 +1025,10 @@ func (client VirtualMachineScaleSetsClient) PerformMaintenanceResponder(resp *ht // PowerOff power off (stop) one or more virtual machines in a VM scale set. Note that resources are still attached and // you are getting charged for the resources. Instead, use deallocate to release resources and avoid charges. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. -// VMInstanceIDs is a list of virtual machine instance IDs from the VM scale set. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. +// VMInstanceIDs - a list of virtual machine instance IDs from the VM scale set. func (client VirtualMachineScaleSetsClient) PowerOff(ctx context.Context, resourceGroupName string, VMScaleSetName string, VMInstanceIDs *VirtualMachineScaleSetVMInstanceIDs) (result VirtualMachineScaleSetsPowerOffFuture, err error) { req, err := client.PowerOffPreparer(ctx, resourceGroupName, VMScaleSetName, VMInstanceIDs) if err != nil { @@ -959,15 +1074,17 @@ func (client VirtualMachineScaleSetsClient) PowerOffPreparer(ctx context.Context // PowerOffSender sends the PowerOff request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineScaleSetsClient) PowerOffSender(req *http.Request) (future VirtualMachineScaleSetsPowerOffFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -985,9 +1102,10 @@ func (client VirtualMachineScaleSetsClient) PowerOffResponder(resp *http.Respons } // Redeploy redeploy one or more virtual machines in a VM scale set. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. -// VMInstanceIDs is a list of virtual machine instance IDs from the VM scale set. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. +// VMInstanceIDs - a list of virtual machine instance IDs from the VM scale set. func (client VirtualMachineScaleSetsClient) Redeploy(ctx context.Context, resourceGroupName string, VMScaleSetName string, VMInstanceIDs *VirtualMachineScaleSetVMInstanceIDs) (result VirtualMachineScaleSetsRedeployFuture, err error) { req, err := client.RedeployPreparer(ctx, resourceGroupName, VMScaleSetName, VMInstanceIDs) if err != nil { @@ -1033,15 +1151,17 @@ func (client VirtualMachineScaleSetsClient) RedeployPreparer(ctx context.Context // RedeploySender sends the Redeploy request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineScaleSetsClient) RedeploySender(req *http.Request) (future VirtualMachineScaleSetsRedeployFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -1059,9 +1179,10 @@ func (client VirtualMachineScaleSetsClient) RedeployResponder(resp *http.Respons } // Reimage reimages (upgrade the operating system) one or more virtual machines in a VM scale set. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. -// VMInstanceIDs is a list of virtual machine instance IDs from the VM scale set. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. +// VMInstanceIDs - a list of virtual machine instance IDs from the VM scale set. func (client VirtualMachineScaleSetsClient) Reimage(ctx context.Context, resourceGroupName string, VMScaleSetName string, VMInstanceIDs *VirtualMachineScaleSetVMInstanceIDs) (result VirtualMachineScaleSetsReimageFuture, err error) { req, err := client.ReimagePreparer(ctx, resourceGroupName, VMScaleSetName, VMInstanceIDs) if err != nil { @@ -1107,15 +1228,17 @@ func (client VirtualMachineScaleSetsClient) ReimagePreparer(ctx context.Context, // ReimageSender sends the Reimage request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineScaleSetsClient) ReimageSender(req *http.Request) (future VirtualMachineScaleSetsReimageFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -1134,9 +1257,10 @@ func (client VirtualMachineScaleSetsClient) ReimageResponder(resp *http.Response // ReimageAll reimages all the disks ( including data disks ) in the virtual machines in a VM scale set. This operation // is only supported for managed disks. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. -// VMInstanceIDs is a list of virtual machine instance IDs from the VM scale set. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. +// VMInstanceIDs - a list of virtual machine instance IDs from the VM scale set. func (client VirtualMachineScaleSetsClient) ReimageAll(ctx context.Context, resourceGroupName string, VMScaleSetName string, VMInstanceIDs *VirtualMachineScaleSetVMInstanceIDs) (result VirtualMachineScaleSetsReimageAllFuture, err error) { req, err := client.ReimageAllPreparer(ctx, resourceGroupName, VMScaleSetName, VMInstanceIDs) if err != nil { @@ -1182,15 +1306,17 @@ func (client VirtualMachineScaleSetsClient) ReimageAllPreparer(ctx context.Conte // ReimageAllSender sends the ReimageAll request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineScaleSetsClient) ReimageAllSender(req *http.Request) (future VirtualMachineScaleSetsReimageAllFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -1208,9 +1334,10 @@ func (client VirtualMachineScaleSetsClient) ReimageAllResponder(resp *http.Respo } // Restart restarts one or more virtual machines in a VM scale set. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. -// VMInstanceIDs is a list of virtual machine instance IDs from the VM scale set. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. +// VMInstanceIDs - a list of virtual machine instance IDs from the VM scale set. func (client VirtualMachineScaleSetsClient) Restart(ctx context.Context, resourceGroupName string, VMScaleSetName string, VMInstanceIDs *VirtualMachineScaleSetVMInstanceIDs) (result VirtualMachineScaleSetsRestartFuture, err error) { req, err := client.RestartPreparer(ctx, resourceGroupName, VMScaleSetName, VMInstanceIDs) if err != nil { @@ -1256,15 +1383,17 @@ func (client VirtualMachineScaleSetsClient) RestartPreparer(ctx context.Context, // RestartSender sends the Restart request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineScaleSetsClient) RestartSender(req *http.Request) (future VirtualMachineScaleSetsRestartFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -1282,9 +1411,10 @@ func (client VirtualMachineScaleSetsClient) RestartResponder(resp *http.Response } // Start starts one or more virtual machines in a VM scale set. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. -// VMInstanceIDs is a list of virtual machine instance IDs from the VM scale set. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. +// VMInstanceIDs - a list of virtual machine instance IDs from the VM scale set. func (client VirtualMachineScaleSetsClient) Start(ctx context.Context, resourceGroupName string, VMScaleSetName string, VMInstanceIDs *VirtualMachineScaleSetVMInstanceIDs) (result VirtualMachineScaleSetsStartFuture, err error) { req, err := client.StartPreparer(ctx, resourceGroupName, VMScaleSetName, VMInstanceIDs) if err != nil { @@ -1330,15 +1460,17 @@ func (client VirtualMachineScaleSetsClient) StartPreparer(ctx context.Context, r // StartSender sends the Start request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineScaleSetsClient) StartSender(req *http.Request) (future VirtualMachineScaleSetsStartFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -1356,9 +1488,10 @@ func (client VirtualMachineScaleSetsClient) StartResponder(resp *http.Response) } // Update update a VM scale set. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set to create or -// update. parameters is the scale set object. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set to create or update. +// parameters - the scale set object. func (client VirtualMachineScaleSetsClient) Update(ctx context.Context, resourceGroupName string, VMScaleSetName string, parameters VirtualMachineScaleSetUpdate) (result VirtualMachineScaleSetsUpdateFuture, err error) { req, err := client.UpdatePreparer(ctx, resourceGroupName, VMScaleSetName, parameters) if err != nil { @@ -1401,15 +1534,17 @@ func (client VirtualMachineScaleSetsClient) UpdatePreparer(ctx context.Context, // UpdateSender sends the Update request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineScaleSetsClient) UpdateSender(req *http.Request) (future VirtualMachineScaleSetsUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -1427,9 +1562,10 @@ func (client VirtualMachineScaleSetsClient) UpdateResponder(resp *http.Response) } // UpdateInstances upgrades one or more virtual machines to the latest SKU set in the VM scale set model. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. -// VMInstanceIDs is a list of virtual machine instance IDs from the VM scale set. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. +// VMInstanceIDs - a list of virtual machine instance IDs from the VM scale set. func (client VirtualMachineScaleSetsClient) UpdateInstances(ctx context.Context, resourceGroupName string, VMScaleSetName string, VMInstanceIDs VirtualMachineScaleSetVMInstanceRequiredIDs) (result VirtualMachineScaleSetsUpdateInstancesFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: VMInstanceIDs, @@ -1478,15 +1614,17 @@ func (client VirtualMachineScaleSetsClient) UpdateInstancesPreparer(ctx context. // UpdateInstancesSender sends the UpdateInstances request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineScaleSetsClient) UpdateInstancesSender(req *http.Request) (future VirtualMachineScaleSetsUpdateInstancesFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesetvms.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesetvms.go index a03124183..e8ec06789 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesetvms.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinescalesetvms.go @@ -43,9 +43,10 @@ func NewVirtualMachineScaleSetVMsClientWithBaseURI(baseURI string, subscriptionI // Deallocate deallocates a specific virtual machine in a VM scale set. Shuts down the virtual machine and releases the // compute resources it uses. You are not billed for the compute resources of this virtual machine once it is // deallocated. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. instanceID -// is the instance ID of the virtual machine. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. +// instanceID - the instance ID of the virtual machine. func (client VirtualMachineScaleSetVMsClient) Deallocate(ctx context.Context, resourceGroupName string, VMScaleSetName string, instanceID string) (result VirtualMachineScaleSetVMsDeallocateFuture, err error) { req, err := client.DeallocatePreparer(ctx, resourceGroupName, VMScaleSetName, instanceID) if err != nil { @@ -87,15 +88,17 @@ func (client VirtualMachineScaleSetVMsClient) DeallocatePreparer(ctx context.Con // DeallocateSender sends the Deallocate request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineScaleSetVMsClient) DeallocateSender(req *http.Request) (future VirtualMachineScaleSetVMsDeallocateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -113,9 +116,10 @@ func (client VirtualMachineScaleSetVMsClient) DeallocateResponder(resp *http.Res } // Delete deletes a virtual machine from a VM scale set. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. instanceID -// is the instance ID of the virtual machine. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. +// instanceID - the instance ID of the virtual machine. func (client VirtualMachineScaleSetVMsClient) Delete(ctx context.Context, resourceGroupName string, VMScaleSetName string, instanceID string) (result VirtualMachineScaleSetVMsDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, VMScaleSetName, instanceID) if err != nil { @@ -157,15 +161,17 @@ func (client VirtualMachineScaleSetVMsClient) DeletePreparer(ctx context.Context // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineScaleSetVMsClient) DeleteSender(req *http.Request) (future VirtualMachineScaleSetVMsDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -183,9 +189,10 @@ func (client VirtualMachineScaleSetVMsClient) DeleteResponder(resp *http.Respons } // Get gets a virtual machine from a VM scale set. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. instanceID -// is the instance ID of the virtual machine. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. +// instanceID - the instance ID of the virtual machine. func (client VirtualMachineScaleSetVMsClient) Get(ctx context.Context, resourceGroupName string, VMScaleSetName string, instanceID string) (result VirtualMachineScaleSetVM, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, VMScaleSetName, instanceID) if err != nil { @@ -251,9 +258,10 @@ func (client VirtualMachineScaleSetVMsClient) GetResponder(resp *http.Response) } // GetInstanceView gets the status of a virtual machine from a VM scale set. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. instanceID -// is the instance ID of the virtual machine. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. +// instanceID - the instance ID of the virtual machine. func (client VirtualMachineScaleSetVMsClient) GetInstanceView(ctx context.Context, resourceGroupName string, VMScaleSetName string, instanceID string) (result VirtualMachineScaleSetVMInstanceView, err error) { req, err := client.GetInstanceViewPreparer(ctx, resourceGroupName, VMScaleSetName, instanceID) if err != nil { @@ -319,10 +327,12 @@ func (client VirtualMachineScaleSetVMsClient) GetInstanceViewResponder(resp *htt } // List gets a list of all virtual machines in a VM scale sets. -// -// resourceGroupName is the name of the resource group. virtualMachineScaleSetName is the name of the VM scale set. -// filter is the filter to apply to the operation. selectParameter is the list parameters. expand is the expand -// expression to apply to the operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualMachineScaleSetName - the name of the VM scale set. +// filter - the filter to apply to the operation. +// selectParameter - the list parameters. +// expand - the expand expression to apply to the operation. func (client VirtualMachineScaleSetVMsClient) List(ctx context.Context, resourceGroupName string, virtualMachineScaleSetName string, filter string, selectParameter string, expand string) (result VirtualMachineScaleSetVMListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName, virtualMachineScaleSetName, filter, selectParameter, expand) @@ -424,9 +434,10 @@ func (client VirtualMachineScaleSetVMsClient) ListComplete(ctx context.Context, } // PerformMaintenance performs maintenance on a virtual machine in a VM scale set. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. instanceID -// is the instance ID of the virtual machine. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. +// instanceID - the instance ID of the virtual machine. func (client VirtualMachineScaleSetVMsClient) PerformMaintenance(ctx context.Context, resourceGroupName string, VMScaleSetName string, instanceID string) (result VirtualMachineScaleSetVMsPerformMaintenanceFuture, err error) { req, err := client.PerformMaintenancePreparer(ctx, resourceGroupName, VMScaleSetName, instanceID) if err != nil { @@ -468,15 +479,17 @@ func (client VirtualMachineScaleSetVMsClient) PerformMaintenancePreparer(ctx con // PerformMaintenanceSender sends the PerformMaintenance request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineScaleSetVMsClient) PerformMaintenanceSender(req *http.Request) (future VirtualMachineScaleSetVMsPerformMaintenanceFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -495,9 +508,10 @@ func (client VirtualMachineScaleSetVMsClient) PerformMaintenanceResponder(resp * // PowerOff power off (stop) a virtual machine in a VM scale set. Note that resources are still attached and you are // getting charged for the resources. Instead, use deallocate to release resources and avoid charges. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. instanceID -// is the instance ID of the virtual machine. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. +// instanceID - the instance ID of the virtual machine. func (client VirtualMachineScaleSetVMsClient) PowerOff(ctx context.Context, resourceGroupName string, VMScaleSetName string, instanceID string) (result VirtualMachineScaleSetVMsPowerOffFuture, err error) { req, err := client.PowerOffPreparer(ctx, resourceGroupName, VMScaleSetName, instanceID) if err != nil { @@ -539,15 +553,17 @@ func (client VirtualMachineScaleSetVMsClient) PowerOffPreparer(ctx context.Conte // PowerOffSender sends the PowerOff request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineScaleSetVMsClient) PowerOffSender(req *http.Request) (future VirtualMachineScaleSetVMsPowerOffFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -565,9 +581,10 @@ func (client VirtualMachineScaleSetVMsClient) PowerOffResponder(resp *http.Respo } // Redeploy redeploys a virtual machine in a VM scale set. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. instanceID -// is the instance ID of the virtual machine. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. +// instanceID - the instance ID of the virtual machine. func (client VirtualMachineScaleSetVMsClient) Redeploy(ctx context.Context, resourceGroupName string, VMScaleSetName string, instanceID string) (result VirtualMachineScaleSetVMsRedeployFuture, err error) { req, err := client.RedeployPreparer(ctx, resourceGroupName, VMScaleSetName, instanceID) if err != nil { @@ -609,15 +626,17 @@ func (client VirtualMachineScaleSetVMsClient) RedeployPreparer(ctx context.Conte // RedeploySender sends the Redeploy request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineScaleSetVMsClient) RedeploySender(req *http.Request) (future VirtualMachineScaleSetVMsRedeployFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -635,9 +654,10 @@ func (client VirtualMachineScaleSetVMsClient) RedeployResponder(resp *http.Respo } // Reimage reimages (upgrade the operating system) a specific virtual machine in a VM scale set. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. instanceID -// is the instance ID of the virtual machine. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. +// instanceID - the instance ID of the virtual machine. func (client VirtualMachineScaleSetVMsClient) Reimage(ctx context.Context, resourceGroupName string, VMScaleSetName string, instanceID string) (result VirtualMachineScaleSetVMsReimageFuture, err error) { req, err := client.ReimagePreparer(ctx, resourceGroupName, VMScaleSetName, instanceID) if err != nil { @@ -679,15 +699,17 @@ func (client VirtualMachineScaleSetVMsClient) ReimagePreparer(ctx context.Contex // ReimageSender sends the Reimage request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineScaleSetVMsClient) ReimageSender(req *http.Request) (future VirtualMachineScaleSetVMsReimageFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -706,9 +728,10 @@ func (client VirtualMachineScaleSetVMsClient) ReimageResponder(resp *http.Respon // ReimageAll allows you to re-image all the disks ( including data disks ) in the a VM scale set instance. This // operation is only supported for managed disks. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. instanceID -// is the instance ID of the virtual machine. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. +// instanceID - the instance ID of the virtual machine. func (client VirtualMachineScaleSetVMsClient) ReimageAll(ctx context.Context, resourceGroupName string, VMScaleSetName string, instanceID string) (result VirtualMachineScaleSetVMsReimageAllFuture, err error) { req, err := client.ReimageAllPreparer(ctx, resourceGroupName, VMScaleSetName, instanceID) if err != nil { @@ -750,15 +773,17 @@ func (client VirtualMachineScaleSetVMsClient) ReimageAllPreparer(ctx context.Con // ReimageAllSender sends the ReimageAll request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineScaleSetVMsClient) ReimageAllSender(req *http.Request) (future VirtualMachineScaleSetVMsReimageAllFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -776,9 +801,10 @@ func (client VirtualMachineScaleSetVMsClient) ReimageAllResponder(resp *http.Res } // Restart restarts a virtual machine in a VM scale set. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. instanceID -// is the instance ID of the virtual machine. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. +// instanceID - the instance ID of the virtual machine. func (client VirtualMachineScaleSetVMsClient) Restart(ctx context.Context, resourceGroupName string, VMScaleSetName string, instanceID string) (result VirtualMachineScaleSetVMsRestartFuture, err error) { req, err := client.RestartPreparer(ctx, resourceGroupName, VMScaleSetName, instanceID) if err != nil { @@ -820,15 +846,17 @@ func (client VirtualMachineScaleSetVMsClient) RestartPreparer(ctx context.Contex // RestartSender sends the Restart request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineScaleSetVMsClient) RestartSender(req *http.Request) (future VirtualMachineScaleSetVMsRestartFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -846,9 +874,10 @@ func (client VirtualMachineScaleSetVMsClient) RestartResponder(resp *http.Respon } // Start starts a virtual machine in a VM scale set. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set. instanceID -// is the instance ID of the virtual machine. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set. +// instanceID - the instance ID of the virtual machine. func (client VirtualMachineScaleSetVMsClient) Start(ctx context.Context, resourceGroupName string, VMScaleSetName string, instanceID string) (result VirtualMachineScaleSetVMsStartFuture, err error) { req, err := client.StartPreparer(ctx, resourceGroupName, VMScaleSetName, instanceID) if err != nil { @@ -890,15 +919,17 @@ func (client VirtualMachineScaleSetVMsClient) StartPreparer(ctx context.Context, // StartSender sends the Start request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineScaleSetVMsClient) StartSender(req *http.Request) (future VirtualMachineScaleSetVMsStartFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -916,10 +947,11 @@ func (client VirtualMachineScaleSetVMsClient) StartResponder(resp *http.Response } // Update updates a virtual machine of a VM scale set. -// -// resourceGroupName is the name of the resource group. VMScaleSetName is the name of the VM scale set where the -// extension should be create or updated. instanceID is the instance ID of the virtual machine. parameters is -// parameters supplied to the Update Virtual Machine Scale Sets VM operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// VMScaleSetName - the name of the VM scale set where the extension should be create or updated. +// instanceID - the instance ID of the virtual machine. +// parameters - parameters supplied to the Update Virtual Machine Scale Sets VM operation. func (client VirtualMachineScaleSetVMsClient) Update(ctx context.Context, resourceGroupName string, VMScaleSetName string, instanceID string, parameters VirtualMachineScaleSetVM) (result VirtualMachineScaleSetVMsUpdateFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: parameters, @@ -984,15 +1016,17 @@ func (client VirtualMachineScaleSetVMsClient) UpdatePreparer(ctx context.Context // UpdateSender sends the Update request. The method will close the // http.Response Body if it receives an error. func (client VirtualMachineScaleSetVMsClient) UpdateSender(req *http.Request) (future VirtualMachineScaleSetVMsUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinesizes.go b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinesizes.go index c091724bb..49f81e550 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinesizes.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/virtualmachinesizes.go @@ -41,8 +41,8 @@ func NewVirtualMachineSizesClientWithBaseURI(baseURI string, subscriptionID stri } // List lists all available virtual machine sizes for a subscription in a location. -// -// location is the location upon which virtual-machine-sizes is queried. +// Parameters: +// location - the location upon which virtual-machine-sizes is queried. func (client VirtualMachineSizesClient) List(ctx context.Context, location string) (result VirtualMachineSizeListResult, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: location, diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/applicationgateways.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/applicationgateways.go index 6423ad115..bee104bec 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/applicationgateways.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/applicationgateways.go @@ -41,9 +41,10 @@ func NewApplicationGatewaysClientWithBaseURI(baseURI string, subscriptionID stri } // BackendHealth gets the backend health of the specified application gateway in a resource group. -// -// resourceGroupName is the name of the resource group. applicationGatewayName is the name of the application -// gateway. expand is expands BackendAddressPool and BackendHttpSettings referenced in backend health. +// Parameters: +// resourceGroupName - the name of the resource group. +// applicationGatewayName - the name of the application gateway. +// expand - expands BackendAddressPool and BackendHttpSettings referenced in backend health. func (client ApplicationGatewaysClient) BackendHealth(ctx context.Context, resourceGroupName string, applicationGatewayName string, expand string) (result ApplicationGatewaysBackendHealthFuture, err error) { req, err := client.BackendHealthPreparer(ctx, resourceGroupName, applicationGatewayName, expand) if err != nil { @@ -87,15 +88,17 @@ func (client ApplicationGatewaysClient) BackendHealthPreparer(ctx context.Contex // BackendHealthSender sends the BackendHealth request. The method will close the // http.Response Body if it receives an error. func (client ApplicationGatewaysClient) BackendHealthSender(req *http.Request) (future ApplicationGatewaysBackendHealthFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -113,9 +116,10 @@ func (client ApplicationGatewaysClient) BackendHealthResponder(resp *http.Respon } // CreateOrUpdate creates or updates the specified application gateway. -// -// resourceGroupName is the name of the resource group. applicationGatewayName is the name of the application -// gateway. parameters is parameters supplied to the create or update application gateway operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// applicationGatewayName - the name of the application gateway. +// parameters - parameters supplied to the create or update application gateway operation. func (client ApplicationGatewaysClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, applicationGatewayName string, parameters ApplicationGateway) (result ApplicationGatewaysCreateOrUpdateFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: parameters, @@ -174,15 +178,17 @@ func (client ApplicationGatewaysClient) CreateOrUpdatePreparer(ctx context.Conte // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client ApplicationGatewaysClient) CreateOrUpdateSender(req *http.Request) (future ApplicationGatewaysCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -200,9 +206,9 @@ func (client ApplicationGatewaysClient) CreateOrUpdateResponder(resp *http.Respo } // Delete deletes the specified application gateway. -// -// resourceGroupName is the name of the resource group. applicationGatewayName is the name of the application -// gateway. +// Parameters: +// resourceGroupName - the name of the resource group. +// applicationGatewayName - the name of the application gateway. func (client ApplicationGatewaysClient) Delete(ctx context.Context, resourceGroupName string, applicationGatewayName string) (result ApplicationGatewaysDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, applicationGatewayName) if err != nil { @@ -243,15 +249,17 @@ func (client ApplicationGatewaysClient) DeletePreparer(ctx context.Context, reso // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client ApplicationGatewaysClient) DeleteSender(req *http.Request) (future ApplicationGatewaysDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -268,9 +276,9 @@ func (client ApplicationGatewaysClient) DeleteResponder(resp *http.Response) (re } // Get gets the specified application gateway. -// -// resourceGroupName is the name of the resource group. applicationGatewayName is the name of the application -// gateway. +// Parameters: +// resourceGroupName - the name of the resource group. +// applicationGatewayName - the name of the application gateway. func (client ApplicationGatewaysClient) Get(ctx context.Context, resourceGroupName string, applicationGatewayName string) (result ApplicationGateway, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, applicationGatewayName) if err != nil { @@ -335,8 +343,8 @@ func (client ApplicationGatewaysClient) GetResponder(resp *http.Response) (resul } // GetSslPredefinedPolicy gets Ssl predefined policy with the specified policy name. -// -// predefinedPolicyName is name of Ssl predefined policy. +// Parameters: +// predefinedPolicyName - name of Ssl predefined policy. func (client ApplicationGatewaysClient) GetSslPredefinedPolicy(ctx context.Context, predefinedPolicyName string) (result ApplicationGatewaySslPredefinedPolicy, err error) { req, err := client.GetSslPredefinedPolicyPreparer(ctx, predefinedPolicyName) if err != nil { @@ -400,8 +408,8 @@ func (client ApplicationGatewaysClient) GetSslPredefinedPolicyResponder(resp *ht } // List lists all application gateways in a resource group. -// -// resourceGroupName is the name of the resource group. +// Parameters: +// resourceGroupName - the name of the resource group. func (client ApplicationGatewaysClient) List(ctx context.Context, resourceGroupName string) (result ApplicationGatewayListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName) @@ -797,9 +805,9 @@ func (client ApplicationGatewaysClient) ListAvailableWafRuleSetsResponder(resp * } // Start starts the specified application gateway. -// -// resourceGroupName is the name of the resource group. applicationGatewayName is the name of the application -// gateway. +// Parameters: +// resourceGroupName - the name of the resource group. +// applicationGatewayName - the name of the application gateway. func (client ApplicationGatewaysClient) Start(ctx context.Context, resourceGroupName string, applicationGatewayName string) (result ApplicationGatewaysStartFuture, err error) { req, err := client.StartPreparer(ctx, resourceGroupName, applicationGatewayName) if err != nil { @@ -840,15 +848,17 @@ func (client ApplicationGatewaysClient) StartPreparer(ctx context.Context, resou // StartSender sends the Start request. The method will close the // http.Response Body if it receives an error. func (client ApplicationGatewaysClient) StartSender(req *http.Request) (future ApplicationGatewaysStartFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -865,9 +875,9 @@ func (client ApplicationGatewaysClient) StartResponder(resp *http.Response) (res } // Stop stops the specified application gateway in a resource group. -// -// resourceGroupName is the name of the resource group. applicationGatewayName is the name of the application -// gateway. +// Parameters: +// resourceGroupName - the name of the resource group. +// applicationGatewayName - the name of the application gateway. func (client ApplicationGatewaysClient) Stop(ctx context.Context, resourceGroupName string, applicationGatewayName string) (result ApplicationGatewaysStopFuture, err error) { req, err := client.StopPreparer(ctx, resourceGroupName, applicationGatewayName) if err != nil { @@ -908,15 +918,17 @@ func (client ApplicationGatewaysClient) StopPreparer(ctx context.Context, resour // StopSender sends the Stop request. The method will close the // http.Response Body if it receives an error. func (client ApplicationGatewaysClient) StopSender(req *http.Request) (future ApplicationGatewaysStopFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -933,9 +945,10 @@ func (client ApplicationGatewaysClient) StopResponder(resp *http.Response) (resu } // UpdateTags updates the specified application gateway tags. -// -// resourceGroupName is the name of the resource group. applicationGatewayName is the name of the application -// gateway. parameters is parameters supplied to update application gateway tags. +// Parameters: +// resourceGroupName - the name of the resource group. +// applicationGatewayName - the name of the application gateway. +// parameters - parameters supplied to update application gateway tags. func (client ApplicationGatewaysClient) UpdateTags(ctx context.Context, resourceGroupName string, applicationGatewayName string, parameters TagsObject) (result ApplicationGatewaysUpdateTagsFuture, err error) { req, err := client.UpdateTagsPreparer(ctx, resourceGroupName, applicationGatewayName, parameters) if err != nil { @@ -978,15 +991,17 @@ func (client ApplicationGatewaysClient) UpdateTagsPreparer(ctx context.Context, // UpdateTagsSender sends the UpdateTags request. The method will close the // http.Response Body if it receives an error. func (client ApplicationGatewaysClient) UpdateTagsSender(req *http.Request) (future ApplicationGatewaysUpdateTagsFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/applicationsecuritygroups.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/applicationsecuritygroups.go index 48acb4e55..727b7b1c1 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/applicationsecuritygroups.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/applicationsecuritygroups.go @@ -40,9 +40,10 @@ func NewApplicationSecurityGroupsClientWithBaseURI(baseURI string, subscriptionI } // CreateOrUpdate creates or updates an application security group. -// -// resourceGroupName is the name of the resource group. applicationSecurityGroupName is the name of the application -// security group. parameters is parameters supplied to the create or update ApplicationSecurityGroup operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// applicationSecurityGroupName - the name of the application security group. +// parameters - parameters supplied to the create or update ApplicationSecurityGroup operation. func (client ApplicationSecurityGroupsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, applicationSecurityGroupName string, parameters ApplicationSecurityGroup) (result ApplicationSecurityGroupsCreateOrUpdateFuture, err error) { req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, applicationSecurityGroupName, parameters) if err != nil { @@ -85,15 +86,17 @@ func (client ApplicationSecurityGroupsClient) CreateOrUpdatePreparer(ctx context // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client ApplicationSecurityGroupsClient) CreateOrUpdateSender(req *http.Request) (future ApplicationSecurityGroupsCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -111,9 +114,9 @@ func (client ApplicationSecurityGroupsClient) CreateOrUpdateResponder(resp *http } // Delete deletes the specified application security group. -// -// resourceGroupName is the name of the resource group. applicationSecurityGroupName is the name of the application -// security group. +// Parameters: +// resourceGroupName - the name of the resource group. +// applicationSecurityGroupName - the name of the application security group. func (client ApplicationSecurityGroupsClient) Delete(ctx context.Context, resourceGroupName string, applicationSecurityGroupName string) (result ApplicationSecurityGroupsDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, applicationSecurityGroupName) if err != nil { @@ -154,15 +157,17 @@ func (client ApplicationSecurityGroupsClient) DeletePreparer(ctx context.Context // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client ApplicationSecurityGroupsClient) DeleteSender(req *http.Request) (future ApplicationSecurityGroupsDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -179,9 +184,9 @@ func (client ApplicationSecurityGroupsClient) DeleteResponder(resp *http.Respons } // Get gets information about the specified application security group. -// -// resourceGroupName is the name of the resource group. applicationSecurityGroupName is the name of the application -// security group. +// Parameters: +// resourceGroupName - the name of the resource group. +// applicationSecurityGroupName - the name of the application security group. func (client ApplicationSecurityGroupsClient) Get(ctx context.Context, resourceGroupName string, applicationSecurityGroupName string) (result ApplicationSecurityGroup, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, applicationSecurityGroupName) if err != nil { @@ -246,8 +251,8 @@ func (client ApplicationSecurityGroupsClient) GetResponder(resp *http.Response) } // List gets all the application security groups in a resource group. -// -// resourceGroupName is the name of the resource group. +// Parameters: +// resourceGroupName - the name of the resource group. func (client ApplicationSecurityGroupsClient) List(ctx context.Context, resourceGroupName string) (result ApplicationSecurityGroupListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/availableendpointservices.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/availableendpointservices.go index 23914cbf8..a386e084b 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/availableendpointservices.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/availableendpointservices.go @@ -40,8 +40,8 @@ func NewAvailableEndpointServicesClientWithBaseURI(baseURI string, subscriptionI } // List list what values of endpoint services are available for use. -// -// location is the location to check available endpoint services. +// Parameters: +// location - the location to check available endpoint services. func (client AvailableEndpointServicesClient) List(ctx context.Context, location string) (result EndpointServicesListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, location) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/client.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/client.go index a69c41e90..3e657b1ab 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/client.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/client.go @@ -54,9 +54,10 @@ func NewWithBaseURI(baseURI string, subscriptionID string) BaseClient { } // CheckDNSNameAvailability checks whether a domain name in the cloudapp.azure.com zone is available for use. -// -// location is the location of the domain name. domainNameLabel is the domain name to be verified. It must conform -// to the following regular expression: ^[a-z][a-z0-9-]{1,61}[a-z0-9]$. +// Parameters: +// location - the location of the domain name. +// domainNameLabel - the domain name to be verified. It must conform to the following regular expression: +// ^[a-z][a-z0-9-]{1,61}[a-z0-9]$. func (client BaseClient) CheckDNSNameAvailability(ctx context.Context, location string, domainNameLabel string) (result DNSNameAvailabilityResult, err error) { req, err := client.CheckDNSNameAvailabilityPreparer(ctx, location, domainNameLabel) if err != nil { diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/connectionmonitors.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/connectionmonitors.go index deae88d9d..d19cbad06 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/connectionmonitors.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/connectionmonitors.go @@ -41,10 +41,11 @@ func NewConnectionMonitorsClientWithBaseURI(baseURI string, subscriptionID strin } // CreateOrUpdate create or update a connection monitor. -// -// resourceGroupName is the name of the resource group containing Network Watcher. networkWatcherName is the name -// of the Network Watcher resource. connectionMonitorName is the name of the connection monitor. parameters is -// parameters that define the operation to create a connection monitor. +// Parameters: +// resourceGroupName - the name of the resource group containing Network Watcher. +// networkWatcherName - the name of the Network Watcher resource. +// connectionMonitorName - the name of the connection monitor. +// parameters - parameters that define the operation to create a connection monitor. func (client ConnectionMonitorsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, networkWatcherName string, connectionMonitorName string, parameters ConnectionMonitor) (result ConnectionMonitorsCreateOrUpdateFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: parameters, @@ -98,15 +99,17 @@ func (client ConnectionMonitorsClient) CreateOrUpdatePreparer(ctx context.Contex // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client ConnectionMonitorsClient) CreateOrUpdateSender(req *http.Request) (future ConnectionMonitorsCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -124,9 +127,10 @@ func (client ConnectionMonitorsClient) CreateOrUpdateResponder(resp *http.Respon } // Delete deletes the specified connection monitor. -// -// resourceGroupName is the name of the resource group containing Network Watcher. networkWatcherName is the name -// of the Network Watcher resource. connectionMonitorName is the name of the connection monitor. +// Parameters: +// resourceGroupName - the name of the resource group containing Network Watcher. +// networkWatcherName - the name of the Network Watcher resource. +// connectionMonitorName - the name of the connection monitor. func (client ConnectionMonitorsClient) Delete(ctx context.Context, resourceGroupName string, networkWatcherName string, connectionMonitorName string) (result ConnectionMonitorsDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, networkWatcherName, connectionMonitorName) if err != nil { @@ -168,15 +172,17 @@ func (client ConnectionMonitorsClient) DeletePreparer(ctx context.Context, resou // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client ConnectionMonitorsClient) DeleteSender(req *http.Request) (future ConnectionMonitorsDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -193,9 +199,10 @@ func (client ConnectionMonitorsClient) DeleteResponder(resp *http.Response) (res } // Get gets a connection monitor by name. -// -// resourceGroupName is the name of the resource group containing Network Watcher. networkWatcherName is the name -// of the Network Watcher resource. connectionMonitorName is the name of the connection monitor. +// Parameters: +// resourceGroupName - the name of the resource group containing Network Watcher. +// networkWatcherName - the name of the Network Watcher resource. +// connectionMonitorName - the name of the connection monitor. func (client ConnectionMonitorsClient) Get(ctx context.Context, resourceGroupName string, networkWatcherName string, connectionMonitorName string) (result ConnectionMonitorResult, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, networkWatcherName, connectionMonitorName) if err != nil { @@ -261,9 +268,9 @@ func (client ConnectionMonitorsClient) GetResponder(resp *http.Response) (result } // List lists all connection monitors for the specified Network Watcher. -// -// resourceGroupName is the name of the resource group containing Network Watcher. networkWatcherName is the name -// of the Network Watcher resource. +// Parameters: +// resourceGroupName - the name of the resource group containing Network Watcher. +// networkWatcherName - the name of the Network Watcher resource. func (client ConnectionMonitorsClient) List(ctx context.Context, resourceGroupName string, networkWatcherName string) (result ConnectionMonitorListResult, err error) { req, err := client.ListPreparer(ctx, resourceGroupName, networkWatcherName) if err != nil { @@ -328,9 +335,10 @@ func (client ConnectionMonitorsClient) ListResponder(resp *http.Response) (resul } // Query query a snapshot of the most recent connection states. -// -// resourceGroupName is the name of the resource group containing Network Watcher. networkWatcherName is the name -// of the Network Watcher resource. connectionMonitorName is the name given to the connection monitor. +// Parameters: +// resourceGroupName - the name of the resource group containing Network Watcher. +// networkWatcherName - the name of the Network Watcher resource. +// connectionMonitorName - the name given to the connection monitor. func (client ConnectionMonitorsClient) Query(ctx context.Context, resourceGroupName string, networkWatcherName string, connectionMonitorName string) (result ConnectionMonitorsQueryFuture, err error) { req, err := client.QueryPreparer(ctx, resourceGroupName, networkWatcherName, connectionMonitorName) if err != nil { @@ -372,15 +380,17 @@ func (client ConnectionMonitorsClient) QueryPreparer(ctx context.Context, resour // QuerySender sends the Query request. The method will close the // http.Response Body if it receives an error. func (client ConnectionMonitorsClient) QuerySender(req *http.Request) (future ConnectionMonitorsQueryFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -398,9 +408,10 @@ func (client ConnectionMonitorsClient) QueryResponder(resp *http.Response) (resu } // Start starts the specified connection monitor. -// -// resourceGroupName is the name of the resource group containing Network Watcher. networkWatcherName is the name -// of the Network Watcher resource. connectionMonitorName is the name of the connection monitor. +// Parameters: +// resourceGroupName - the name of the resource group containing Network Watcher. +// networkWatcherName - the name of the Network Watcher resource. +// connectionMonitorName - the name of the connection monitor. func (client ConnectionMonitorsClient) Start(ctx context.Context, resourceGroupName string, networkWatcherName string, connectionMonitorName string) (result ConnectionMonitorsStartFuture, err error) { req, err := client.StartPreparer(ctx, resourceGroupName, networkWatcherName, connectionMonitorName) if err != nil { @@ -442,15 +453,17 @@ func (client ConnectionMonitorsClient) StartPreparer(ctx context.Context, resour // StartSender sends the Start request. The method will close the // http.Response Body if it receives an error. func (client ConnectionMonitorsClient) StartSender(req *http.Request) (future ConnectionMonitorsStartFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -467,9 +480,10 @@ func (client ConnectionMonitorsClient) StartResponder(resp *http.Response) (resu } // Stop stops the specified connection monitor. -// -// resourceGroupName is the name of the resource group containing Network Watcher. networkWatcherName is the name -// of the Network Watcher resource. connectionMonitorName is the name of the connection monitor. +// Parameters: +// resourceGroupName - the name of the resource group containing Network Watcher. +// networkWatcherName - the name of the Network Watcher resource. +// connectionMonitorName - the name of the connection monitor. func (client ConnectionMonitorsClient) Stop(ctx context.Context, resourceGroupName string, networkWatcherName string, connectionMonitorName string) (result ConnectionMonitorsStopFuture, err error) { req, err := client.StopPreparer(ctx, resourceGroupName, networkWatcherName, connectionMonitorName) if err != nil { @@ -511,15 +525,17 @@ func (client ConnectionMonitorsClient) StopPreparer(ctx context.Context, resourc // StopSender sends the Stop request. The method will close the // http.Response Body if it receives an error. func (client ConnectionMonitorsClient) StopSender(req *http.Request) (future ConnectionMonitorsStopFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/defaultsecurityrules.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/defaultsecurityrules.go index f6c84fdb9..a53a27b3e 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/defaultsecurityrules.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/defaultsecurityrules.go @@ -40,9 +40,10 @@ func NewDefaultSecurityRulesClientWithBaseURI(baseURI string, subscriptionID str } // Get get the specified default network security rule. -// -// resourceGroupName is the name of the resource group. networkSecurityGroupName is the name of the network -// security group. defaultSecurityRuleName is the name of the default security rule. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkSecurityGroupName - the name of the network security group. +// defaultSecurityRuleName - the name of the default security rule. func (client DefaultSecurityRulesClient) Get(ctx context.Context, resourceGroupName string, networkSecurityGroupName string, defaultSecurityRuleName string) (result SecurityRule, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, networkSecurityGroupName, defaultSecurityRuleName) if err != nil { @@ -108,9 +109,9 @@ func (client DefaultSecurityRulesClient) GetResponder(resp *http.Response) (resu } // List gets all default security rules in a network security group. -// -// resourceGroupName is the name of the resource group. networkSecurityGroupName is the name of the network -// security group. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkSecurityGroupName - the name of the network security group. func (client DefaultSecurityRulesClient) List(ctx context.Context, resourceGroupName string, networkSecurityGroupName string) (result SecurityRuleListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName, networkSecurityGroupName) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/expressroutecircuitauthorizations.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/expressroutecircuitauthorizations.go index 74ef33cfb..35f9e2744 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/expressroutecircuitauthorizations.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/expressroutecircuitauthorizations.go @@ -42,10 +42,12 @@ func NewExpressRouteCircuitAuthorizationsClientWithBaseURI(baseURI string, subsc } // CreateOrUpdate creates or updates an authorization in the specified express route circuit. -// -// resourceGroupName is the name of the resource group. circuitName is the name of the express route circuit. -// authorizationName is the name of the authorization. authorizationParameters is parameters supplied to the create -// or update express route circuit authorization operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// circuitName - the name of the express route circuit. +// authorizationName - the name of the authorization. +// authorizationParameters - parameters supplied to the create or update express route circuit authorization +// operation. func (client ExpressRouteCircuitAuthorizationsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, circuitName string, authorizationName string, authorizationParameters ExpressRouteCircuitAuthorization) (result ExpressRouteCircuitAuthorizationsCreateOrUpdateFuture, err error) { req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, circuitName, authorizationName, authorizationParameters) if err != nil { @@ -89,15 +91,17 @@ func (client ExpressRouteCircuitAuthorizationsClient) CreateOrUpdatePreparer(ctx // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client ExpressRouteCircuitAuthorizationsClient) CreateOrUpdateSender(req *http.Request) (future ExpressRouteCircuitAuthorizationsCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -115,9 +119,10 @@ func (client ExpressRouteCircuitAuthorizationsClient) CreateOrUpdateResponder(re } // Delete deletes the specified authorization from the specified express route circuit. -// -// resourceGroupName is the name of the resource group. circuitName is the name of the express route circuit. -// authorizationName is the name of the authorization. +// Parameters: +// resourceGroupName - the name of the resource group. +// circuitName - the name of the express route circuit. +// authorizationName - the name of the authorization. func (client ExpressRouteCircuitAuthorizationsClient) Delete(ctx context.Context, resourceGroupName string, circuitName string, authorizationName string) (result ExpressRouteCircuitAuthorizationsDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, circuitName, authorizationName) if err != nil { @@ -159,15 +164,17 @@ func (client ExpressRouteCircuitAuthorizationsClient) DeletePreparer(ctx context // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client ExpressRouteCircuitAuthorizationsClient) DeleteSender(req *http.Request) (future ExpressRouteCircuitAuthorizationsDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -184,9 +191,10 @@ func (client ExpressRouteCircuitAuthorizationsClient) DeleteResponder(resp *http } // Get gets the specified authorization from the specified express route circuit. -// -// resourceGroupName is the name of the resource group. circuitName is the name of the express route circuit. -// authorizationName is the name of the authorization. +// Parameters: +// resourceGroupName - the name of the resource group. +// circuitName - the name of the express route circuit. +// authorizationName - the name of the authorization. func (client ExpressRouteCircuitAuthorizationsClient) Get(ctx context.Context, resourceGroupName string, circuitName string, authorizationName string) (result ExpressRouteCircuitAuthorization, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, circuitName, authorizationName) if err != nil { @@ -252,8 +260,9 @@ func (client ExpressRouteCircuitAuthorizationsClient) GetResponder(resp *http.Re } // List gets all authorizations in an express route circuit. -// -// resourceGroupName is the name of the resource group. circuitName is the name of the circuit. +// Parameters: +// resourceGroupName - the name of the resource group. +// circuitName - the name of the circuit. func (client ExpressRouteCircuitAuthorizationsClient) List(ctx context.Context, resourceGroupName string, circuitName string) (result AuthorizationListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName, circuitName) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/expressroutecircuitpeerings.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/expressroutecircuitpeerings.go index 2611bf16f..8a33a4337 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/expressroutecircuitpeerings.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/expressroutecircuitpeerings.go @@ -19,10 +19,11 @@ package network import ( "context" + "net/http" + "github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest/azure" "github.com/Azure/go-autorest/autorest/validation" - "net/http" ) // ExpressRouteCircuitPeeringsClient is the network Client @@ -41,16 +42,17 @@ func NewExpressRouteCircuitPeeringsClientWithBaseURI(baseURI string, subscriptio } // CreateOrUpdate creates or updates a peering in the specified express route circuits. -// -// resourceGroupName is the name of the resource group. circuitName is the name of the express route circuit. -// peeringName is the name of the peering. peeringParameters is parameters supplied to the create or update express -// route circuit peering operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// circuitName - the name of the express route circuit. +// peeringName - the name of the peering. +// peeringParameters - parameters supplied to the create or update express route circuit peering operation. func (client ExpressRouteCircuitPeeringsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, circuitName string, peeringName string, peeringParameters ExpressRouteCircuitPeering) (result ExpressRouteCircuitPeeringsCreateOrUpdateFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: peeringParameters, Constraints: []validation.Constraint{{Target: "peeringParameters.ExpressRouteCircuitPeeringPropertiesFormat", Name: validation.Null, Rule: false, Chain: []validation.Constraint{{Target: "peeringParameters.ExpressRouteCircuitPeeringPropertiesFormat.PeerASN", Name: validation.Null, Rule: false, - Chain: []validation.Constraint{{Target: "peeringParameters.ExpressRouteCircuitPeeringPropertiesFormat.PeerASN", Name: validation.InclusiveMaximum, Rule: 4294967295, Chain: nil}, + Chain: []validation.Constraint{{Target: "peeringParameters.ExpressRouteCircuitPeeringPropertiesFormat.PeerASN", Name: validation.InclusiveMaximum, Rule: int64(4294967295), Chain: nil}, {Target: "peeringParameters.ExpressRouteCircuitPeeringPropertiesFormat.PeerASN", Name: validation.InclusiveMinimum, Rule: 1, Chain: nil}, }}, }}}}}); err != nil { @@ -99,15 +101,17 @@ func (client ExpressRouteCircuitPeeringsClient) CreateOrUpdatePreparer(ctx conte // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client ExpressRouteCircuitPeeringsClient) CreateOrUpdateSender(req *http.Request) (future ExpressRouteCircuitPeeringsCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -125,9 +129,10 @@ func (client ExpressRouteCircuitPeeringsClient) CreateOrUpdateResponder(resp *ht } // Delete deletes the specified peering from the specified express route circuit. -// -// resourceGroupName is the name of the resource group. circuitName is the name of the express route circuit. -// peeringName is the name of the peering. +// Parameters: +// resourceGroupName - the name of the resource group. +// circuitName - the name of the express route circuit. +// peeringName - the name of the peering. func (client ExpressRouteCircuitPeeringsClient) Delete(ctx context.Context, resourceGroupName string, circuitName string, peeringName string) (result ExpressRouteCircuitPeeringsDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, circuitName, peeringName) if err != nil { @@ -169,15 +174,17 @@ func (client ExpressRouteCircuitPeeringsClient) DeletePreparer(ctx context.Conte // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client ExpressRouteCircuitPeeringsClient) DeleteSender(req *http.Request) (future ExpressRouteCircuitPeeringsDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -194,9 +201,10 @@ func (client ExpressRouteCircuitPeeringsClient) DeleteResponder(resp *http.Respo } // Get gets the specified authorization from the specified express route circuit. -// -// resourceGroupName is the name of the resource group. circuitName is the name of the express route circuit. -// peeringName is the name of the peering. +// Parameters: +// resourceGroupName - the name of the resource group. +// circuitName - the name of the express route circuit. +// peeringName - the name of the peering. func (client ExpressRouteCircuitPeeringsClient) Get(ctx context.Context, resourceGroupName string, circuitName string, peeringName string) (result ExpressRouteCircuitPeering, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, circuitName, peeringName) if err != nil { @@ -262,8 +270,9 @@ func (client ExpressRouteCircuitPeeringsClient) GetResponder(resp *http.Response } // List gets all peerings in a specified express route circuit. -// -// resourceGroupName is the name of the resource group. circuitName is the name of the express route circuit. +// Parameters: +// resourceGroupName - the name of the resource group. +// circuitName - the name of the express route circuit. func (client ExpressRouteCircuitPeeringsClient) List(ctx context.Context, resourceGroupName string, circuitName string) (result ExpressRouteCircuitPeeringListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName, circuitName) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/expressroutecircuits.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/expressroutecircuits.go index 59aeb4a07..b48f75e10 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/expressroutecircuits.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/expressroutecircuits.go @@ -40,9 +40,10 @@ func NewExpressRouteCircuitsClientWithBaseURI(baseURI string, subscriptionID str } // CreateOrUpdate creates or updates an express route circuit. -// -// resourceGroupName is the name of the resource group. circuitName is the name of the circuit. parameters is -// parameters supplied to the create or update express route circuit operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// circuitName - the name of the circuit. +// parameters - parameters supplied to the create or update express route circuit operation. func (client ExpressRouteCircuitsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, circuitName string, parameters ExpressRouteCircuit) (result ExpressRouteCircuitsCreateOrUpdateFuture, err error) { req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, circuitName, parameters) if err != nil { @@ -85,15 +86,17 @@ func (client ExpressRouteCircuitsClient) CreateOrUpdatePreparer(ctx context.Cont // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client ExpressRouteCircuitsClient) CreateOrUpdateSender(req *http.Request) (future ExpressRouteCircuitsCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -111,8 +114,9 @@ func (client ExpressRouteCircuitsClient) CreateOrUpdateResponder(resp *http.Resp } // Delete deletes the specified express route circuit. -// -// resourceGroupName is the name of the resource group. circuitName is the name of the express route circuit. +// Parameters: +// resourceGroupName - the name of the resource group. +// circuitName - the name of the express route circuit. func (client ExpressRouteCircuitsClient) Delete(ctx context.Context, resourceGroupName string, circuitName string) (result ExpressRouteCircuitsDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, circuitName) if err != nil { @@ -153,15 +157,17 @@ func (client ExpressRouteCircuitsClient) DeletePreparer(ctx context.Context, res // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client ExpressRouteCircuitsClient) DeleteSender(req *http.Request) (future ExpressRouteCircuitsDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -178,8 +184,9 @@ func (client ExpressRouteCircuitsClient) DeleteResponder(resp *http.Response) (r } // Get gets information about the specified express route circuit. -// -// resourceGroupName is the name of the resource group. circuitName is the name of express route circuit. +// Parameters: +// resourceGroupName - the name of the resource group. +// circuitName - the name of express route circuit. func (client ExpressRouteCircuitsClient) Get(ctx context.Context, resourceGroupName string, circuitName string) (result ExpressRouteCircuit, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, circuitName) if err != nil { @@ -244,9 +251,10 @@ func (client ExpressRouteCircuitsClient) GetResponder(resp *http.Response) (resu } // GetPeeringStats gets all stats from an express route circuit in a resource group. -// -// resourceGroupName is the name of the resource group. circuitName is the name of the express route circuit. -// peeringName is the name of the peering. +// Parameters: +// resourceGroupName - the name of the resource group. +// circuitName - the name of the express route circuit. +// peeringName - the name of the peering. func (client ExpressRouteCircuitsClient) GetPeeringStats(ctx context.Context, resourceGroupName string, circuitName string, peeringName string) (result ExpressRouteCircuitStats, err error) { req, err := client.GetPeeringStatsPreparer(ctx, resourceGroupName, circuitName, peeringName) if err != nil { @@ -312,8 +320,9 @@ func (client ExpressRouteCircuitsClient) GetPeeringStatsResponder(resp *http.Res } // GetStats gets all the stats from an express route circuit in a resource group. -// -// resourceGroupName is the name of the resource group. circuitName is the name of the express route circuit. +// Parameters: +// resourceGroupName - the name of the resource group. +// circuitName - the name of the express route circuit. func (client ExpressRouteCircuitsClient) GetStats(ctx context.Context, resourceGroupName string, circuitName string) (result ExpressRouteCircuitStats, err error) { req, err := client.GetStatsPreparer(ctx, resourceGroupName, circuitName) if err != nil { @@ -378,8 +387,8 @@ func (client ExpressRouteCircuitsClient) GetStatsResponder(resp *http.Response) } // List gets all the express route circuits in a resource group. -// -// resourceGroupName is the name of the resource group. +// Parameters: +// resourceGroupName - the name of the resource group. func (client ExpressRouteCircuitsClient) List(ctx context.Context, resourceGroupName string) (result ExpressRouteCircuitListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName) @@ -561,9 +570,11 @@ func (client ExpressRouteCircuitsClient) ListAllComplete(ctx context.Context) (r } // ListArpTable gets the currently advertised ARP table associated with the express route circuit in a resource group. -// -// resourceGroupName is the name of the resource group. circuitName is the name of the express route circuit. -// peeringName is the name of the peering. devicePath is the path of the device. +// Parameters: +// resourceGroupName - the name of the resource group. +// circuitName - the name of the express route circuit. +// peeringName - the name of the peering. +// devicePath - the path of the device. func (client ExpressRouteCircuitsClient) ListArpTable(ctx context.Context, resourceGroupName string, circuitName string, peeringName string, devicePath string) (result ExpressRouteCircuitsListArpTableFuture, err error) { req, err := client.ListArpTablePreparer(ctx, resourceGroupName, circuitName, peeringName, devicePath) if err != nil { @@ -606,15 +617,17 @@ func (client ExpressRouteCircuitsClient) ListArpTablePreparer(ctx context.Contex // ListArpTableSender sends the ListArpTable request. The method will close the // http.Response Body if it receives an error. func (client ExpressRouteCircuitsClient) ListArpTableSender(req *http.Request) (future ExpressRouteCircuitsListArpTableFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -633,9 +646,11 @@ func (client ExpressRouteCircuitsClient) ListArpTableResponder(resp *http.Respon // ListRoutesTable gets the currently advertised routes table associated with the express route circuit in a resource // group. -// -// resourceGroupName is the name of the resource group. circuitName is the name of the express route circuit. -// peeringName is the name of the peering. devicePath is the path of the device. +// Parameters: +// resourceGroupName - the name of the resource group. +// circuitName - the name of the express route circuit. +// peeringName - the name of the peering. +// devicePath - the path of the device. func (client ExpressRouteCircuitsClient) ListRoutesTable(ctx context.Context, resourceGroupName string, circuitName string, peeringName string, devicePath string) (result ExpressRouteCircuitsListRoutesTableFuture, err error) { req, err := client.ListRoutesTablePreparer(ctx, resourceGroupName, circuitName, peeringName, devicePath) if err != nil { @@ -678,15 +693,17 @@ func (client ExpressRouteCircuitsClient) ListRoutesTablePreparer(ctx context.Con // ListRoutesTableSender sends the ListRoutesTable request. The method will close the // http.Response Body if it receives an error. func (client ExpressRouteCircuitsClient) ListRoutesTableSender(req *http.Request) (future ExpressRouteCircuitsListRoutesTableFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -705,9 +722,11 @@ func (client ExpressRouteCircuitsClient) ListRoutesTableResponder(resp *http.Res // ListRoutesTableSummary gets the currently advertised routes table summary associated with the express route circuit // in a resource group. -// -// resourceGroupName is the name of the resource group. circuitName is the name of the express route circuit. -// peeringName is the name of the peering. devicePath is the path of the device. +// Parameters: +// resourceGroupName - the name of the resource group. +// circuitName - the name of the express route circuit. +// peeringName - the name of the peering. +// devicePath - the path of the device. func (client ExpressRouteCircuitsClient) ListRoutesTableSummary(ctx context.Context, resourceGroupName string, circuitName string, peeringName string, devicePath string) (result ExpressRouteCircuitsListRoutesTableSummaryFuture, err error) { req, err := client.ListRoutesTableSummaryPreparer(ctx, resourceGroupName, circuitName, peeringName, devicePath) if err != nil { @@ -750,15 +769,17 @@ func (client ExpressRouteCircuitsClient) ListRoutesTableSummaryPreparer(ctx cont // ListRoutesTableSummarySender sends the ListRoutesTableSummary request. The method will close the // http.Response Body if it receives an error. func (client ExpressRouteCircuitsClient) ListRoutesTableSummarySender(req *http.Request) (future ExpressRouteCircuitsListRoutesTableSummaryFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -776,9 +797,10 @@ func (client ExpressRouteCircuitsClient) ListRoutesTableSummaryResponder(resp *h } // UpdateTags updates an express route circuit tags. -// -// resourceGroupName is the name of the resource group. circuitName is the name of the circuit. parameters is -// parameters supplied to update express route circuit tags. +// Parameters: +// resourceGroupName - the name of the resource group. +// circuitName - the name of the circuit. +// parameters - parameters supplied to update express route circuit tags. func (client ExpressRouteCircuitsClient) UpdateTags(ctx context.Context, resourceGroupName string, circuitName string, parameters TagsObject) (result ExpressRouteCircuitsUpdateTagsFuture, err error) { req, err := client.UpdateTagsPreparer(ctx, resourceGroupName, circuitName, parameters) if err != nil { @@ -821,15 +843,17 @@ func (client ExpressRouteCircuitsClient) UpdateTagsPreparer(ctx context.Context, // UpdateTagsSender sends the UpdateTags request. The method will close the // http.Response Body if it receives an error. func (client ExpressRouteCircuitsClient) UpdateTagsSender(req *http.Request) (future ExpressRouteCircuitsUpdateTagsFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/inboundnatrules.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/inboundnatrules.go index 4cfdbedd7..5e976c919 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/inboundnatrules.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/inboundnatrules.go @@ -41,10 +41,11 @@ func NewInboundNatRulesClientWithBaseURI(baseURI string, subscriptionID string) } // CreateOrUpdate creates or updates a load balancer inbound nat rule. -// -// resourceGroupName is the name of the resource group. loadBalancerName is the name of the load balancer. -// inboundNatRuleName is the name of the inbound nat rule. inboundNatRuleParameters is parameters supplied to the -// create or update inbound nat rule operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// loadBalancerName - the name of the load balancer. +// inboundNatRuleName - the name of the inbound nat rule. +// inboundNatRuleParameters - parameters supplied to the create or update inbound nat rule operation. func (client InboundNatRulesClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, loadBalancerName string, inboundNatRuleName string, inboundNatRuleParameters InboundNatRule) (result InboundNatRulesCreateOrUpdateFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: inboundNatRuleParameters, @@ -107,15 +108,17 @@ func (client InboundNatRulesClient) CreateOrUpdatePreparer(ctx context.Context, // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client InboundNatRulesClient) CreateOrUpdateSender(req *http.Request) (future InboundNatRulesCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -133,9 +136,10 @@ func (client InboundNatRulesClient) CreateOrUpdateResponder(resp *http.Response) } // Delete deletes the specified load balancer inbound nat rule. -// -// resourceGroupName is the name of the resource group. loadBalancerName is the name of the load balancer. -// inboundNatRuleName is the name of the inbound nat rule. +// Parameters: +// resourceGroupName - the name of the resource group. +// loadBalancerName - the name of the load balancer. +// inboundNatRuleName - the name of the inbound nat rule. func (client InboundNatRulesClient) Delete(ctx context.Context, resourceGroupName string, loadBalancerName string, inboundNatRuleName string) (result InboundNatRulesDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, loadBalancerName, inboundNatRuleName) if err != nil { @@ -177,15 +181,17 @@ func (client InboundNatRulesClient) DeletePreparer(ctx context.Context, resource // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client InboundNatRulesClient) DeleteSender(req *http.Request) (future InboundNatRulesDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -202,9 +208,11 @@ func (client InboundNatRulesClient) DeleteResponder(resp *http.Response) (result } // Get gets the specified load balancer inbound nat rule. -// -// resourceGroupName is the name of the resource group. loadBalancerName is the name of the load balancer. -// inboundNatRuleName is the name of the inbound nat rule. expand is expands referenced resources. +// Parameters: +// resourceGroupName - the name of the resource group. +// loadBalancerName - the name of the load balancer. +// inboundNatRuleName - the name of the inbound nat rule. +// expand - expands referenced resources. func (client InboundNatRulesClient) Get(ctx context.Context, resourceGroupName string, loadBalancerName string, inboundNatRuleName string, expand string) (result InboundNatRule, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, loadBalancerName, inboundNatRuleName, expand) if err != nil { @@ -273,8 +281,9 @@ func (client InboundNatRulesClient) GetResponder(resp *http.Response) (result In } // List gets all the inbound nat rules in a load balancer. -// -// resourceGroupName is the name of the resource group. loadBalancerName is the name of the load balancer. +// Parameters: +// resourceGroupName - the name of the resource group. +// loadBalancerName - the name of the load balancer. func (client InboundNatRulesClient) List(ctx context.Context, resourceGroupName string, loadBalancerName string) (result InboundNatRuleListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName, loadBalancerName) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/interfaceipconfigurations.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/interfaceipconfigurations.go index d0abe2515..86807b005 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/interfaceipconfigurations.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/interfaceipconfigurations.go @@ -40,9 +40,10 @@ func NewInterfaceIPConfigurationsClientWithBaseURI(baseURI string, subscriptionI } // Get gets the specified network interface ip configuration. -// -// resourceGroupName is the name of the resource group. networkInterfaceName is the name of the network interface. -// IPConfigurationName is the name of the ip configuration name. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkInterfaceName - the name of the network interface. +// IPConfigurationName - the name of the ip configuration name. func (client InterfaceIPConfigurationsClient) Get(ctx context.Context, resourceGroupName string, networkInterfaceName string, IPConfigurationName string) (result InterfaceIPConfiguration, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, networkInterfaceName, IPConfigurationName) if err != nil { @@ -108,8 +109,9 @@ func (client InterfaceIPConfigurationsClient) GetResponder(resp *http.Response) } // List get all ip configurations in a network interface -// -// resourceGroupName is the name of the resource group. networkInterfaceName is the name of the network interface. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkInterfaceName - the name of the network interface. func (client InterfaceIPConfigurationsClient) List(ctx context.Context, resourceGroupName string, networkInterfaceName string) (result InterfaceIPConfigurationListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName, networkInterfaceName) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/interfaceloadbalancers.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/interfaceloadbalancers.go index 6114519d2..cda30b0f4 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/interfaceloadbalancers.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/interfaceloadbalancers.go @@ -40,8 +40,9 @@ func NewInterfaceLoadBalancersClientWithBaseURI(baseURI string, subscriptionID s } // List list all load balancers in a network interface. -// -// resourceGroupName is the name of the resource group. networkInterfaceName is the name of the network interface. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkInterfaceName - the name of the network interface. func (client InterfaceLoadBalancersClient) List(ctx context.Context, resourceGroupName string, networkInterfaceName string) (result InterfaceLoadBalancerListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName, networkInterfaceName) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/interfaces.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/interfaces.go index 1ea81ce09..6165ccc6d 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/interfaces.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/interfaces.go @@ -40,9 +40,10 @@ func NewInterfacesClientWithBaseURI(baseURI string, subscriptionID string) Inter } // CreateOrUpdate creates or updates a network interface. -// -// resourceGroupName is the name of the resource group. networkInterfaceName is the name of the network interface. -// parameters is parameters supplied to the create or update network interface operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkInterfaceName - the name of the network interface. +// parameters - parameters supplied to the create or update network interface operation. func (client InterfacesClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, networkInterfaceName string, parameters Interface) (result InterfacesCreateOrUpdateFuture, err error) { req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, networkInterfaceName, parameters) if err != nil { @@ -85,15 +86,17 @@ func (client InterfacesClient) CreateOrUpdatePreparer(ctx context.Context, resou // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client InterfacesClient) CreateOrUpdateSender(req *http.Request) (future InterfacesCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -111,8 +114,9 @@ func (client InterfacesClient) CreateOrUpdateResponder(resp *http.Response) (res } // Delete deletes the specified network interface. -// -// resourceGroupName is the name of the resource group. networkInterfaceName is the name of the network interface. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkInterfaceName - the name of the network interface. func (client InterfacesClient) Delete(ctx context.Context, resourceGroupName string, networkInterfaceName string) (result InterfacesDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, networkInterfaceName) if err != nil { @@ -153,15 +157,17 @@ func (client InterfacesClient) DeletePreparer(ctx context.Context, resourceGroup // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client InterfacesClient) DeleteSender(req *http.Request) (future InterfacesDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -178,9 +184,10 @@ func (client InterfacesClient) DeleteResponder(resp *http.Response) (result auto } // Get gets information about the specified network interface. -// -// resourceGroupName is the name of the resource group. networkInterfaceName is the name of the network interface. -// expand is expands referenced resources. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkInterfaceName - the name of the network interface. +// expand - expands referenced resources. func (client InterfacesClient) Get(ctx context.Context, resourceGroupName string, networkInterfaceName string, expand string) (result Interface, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, networkInterfaceName, expand) if err != nil { @@ -248,8 +255,9 @@ func (client InterfacesClient) GetResponder(resp *http.Response) (result Interfa } // GetEffectiveRouteTable gets all route tables applied to a network interface. -// -// resourceGroupName is the name of the resource group. networkInterfaceName is the name of the network interface. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkInterfaceName - the name of the network interface. func (client InterfacesClient) GetEffectiveRouteTable(ctx context.Context, resourceGroupName string, networkInterfaceName string) (result InterfacesGetEffectiveRouteTableFuture, err error) { req, err := client.GetEffectiveRouteTablePreparer(ctx, resourceGroupName, networkInterfaceName) if err != nil { @@ -290,15 +298,17 @@ func (client InterfacesClient) GetEffectiveRouteTablePreparer(ctx context.Contex // GetEffectiveRouteTableSender sends the GetEffectiveRouteTable request. The method will close the // http.Response Body if it receives an error. func (client InterfacesClient) GetEffectiveRouteTableSender(req *http.Request) (future InterfacesGetEffectiveRouteTableFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -317,11 +327,13 @@ func (client InterfacesClient) GetEffectiveRouteTableResponder(resp *http.Respon // GetVirtualMachineScaleSetIPConfiguration get the specified network interface ip configuration in a virtual machine // scale set. -// -// resourceGroupName is the name of the resource group. virtualMachineScaleSetName is the name of the virtual -// machine scale set. virtualmachineIndex is the virtual machine index. networkInterfaceName is the name of the -// network interface. IPConfigurationName is the name of the ip configuration. expand is expands referenced -// resources. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualMachineScaleSetName - the name of the virtual machine scale set. +// virtualmachineIndex - the virtual machine index. +// networkInterfaceName - the name of the network interface. +// IPConfigurationName - the name of the ip configuration. +// expand - expands referenced resources. func (client InterfacesClient) GetVirtualMachineScaleSetIPConfiguration(ctx context.Context, resourceGroupName string, virtualMachineScaleSetName string, virtualmachineIndex string, networkInterfaceName string, IPConfigurationName string, expand string) (result InterfaceIPConfiguration, err error) { req, err := client.GetVirtualMachineScaleSetIPConfigurationPreparer(ctx, resourceGroupName, virtualMachineScaleSetName, virtualmachineIndex, networkInterfaceName, IPConfigurationName, expand) if err != nil { @@ -392,10 +404,12 @@ func (client InterfacesClient) GetVirtualMachineScaleSetIPConfigurationResponder } // GetVirtualMachineScaleSetNetworkInterface get the specified network interface in a virtual machine scale set. -// -// resourceGroupName is the name of the resource group. virtualMachineScaleSetName is the name of the virtual -// machine scale set. virtualmachineIndex is the virtual machine index. networkInterfaceName is the name of the -// network interface. expand is expands referenced resources. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualMachineScaleSetName - the name of the virtual machine scale set. +// virtualmachineIndex - the virtual machine index. +// networkInterfaceName - the name of the network interface. +// expand - expands referenced resources. func (client InterfacesClient) GetVirtualMachineScaleSetNetworkInterface(ctx context.Context, resourceGroupName string, virtualMachineScaleSetName string, virtualmachineIndex string, networkInterfaceName string, expand string) (result Interface, err error) { req, err := client.GetVirtualMachineScaleSetNetworkInterfacePreparer(ctx, resourceGroupName, virtualMachineScaleSetName, virtualmachineIndex, networkInterfaceName, expand) if err != nil { @@ -465,8 +479,8 @@ func (client InterfacesClient) GetVirtualMachineScaleSetNetworkInterfaceResponde } // List gets all network interfaces in a resource group. -// -// resourceGroupName is the name of the resource group. +// Parameters: +// resourceGroupName - the name of the resource group. func (client InterfacesClient) List(ctx context.Context, resourceGroupName string) (result InterfaceListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName) @@ -648,8 +662,9 @@ func (client InterfacesClient) ListAllComplete(ctx context.Context) (result Inte } // ListEffectiveNetworkSecurityGroups gets all network security groups applied to a network interface. -// -// resourceGroupName is the name of the resource group. networkInterfaceName is the name of the network interface. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkInterfaceName - the name of the network interface. func (client InterfacesClient) ListEffectiveNetworkSecurityGroups(ctx context.Context, resourceGroupName string, networkInterfaceName string) (result InterfacesListEffectiveNetworkSecurityGroupsFuture, err error) { req, err := client.ListEffectiveNetworkSecurityGroupsPreparer(ctx, resourceGroupName, networkInterfaceName) if err != nil { @@ -690,15 +705,17 @@ func (client InterfacesClient) ListEffectiveNetworkSecurityGroupsPreparer(ctx co // ListEffectiveNetworkSecurityGroupsSender sends the ListEffectiveNetworkSecurityGroups request. The method will close the // http.Response Body if it receives an error. func (client InterfacesClient) ListEffectiveNetworkSecurityGroupsSender(req *http.Request) (future InterfacesListEffectiveNetworkSecurityGroupsFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -717,10 +734,12 @@ func (client InterfacesClient) ListEffectiveNetworkSecurityGroupsResponder(resp // ListVirtualMachineScaleSetIPConfigurations get the specified network interface ip configuration in a virtual machine // scale set. -// -// resourceGroupName is the name of the resource group. virtualMachineScaleSetName is the name of the virtual -// machine scale set. virtualmachineIndex is the virtual machine index. networkInterfaceName is the name of the -// network interface. expand is expands referenced resources. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualMachineScaleSetName - the name of the virtual machine scale set. +// virtualmachineIndex - the virtual machine index. +// networkInterfaceName - the name of the network interface. +// expand - expands referenced resources. func (client InterfacesClient) ListVirtualMachineScaleSetIPConfigurations(ctx context.Context, resourceGroupName string, virtualMachineScaleSetName string, virtualmachineIndex string, networkInterfaceName string, expand string) (result InterfaceIPConfigurationListResultPage, err error) { result.fn = client.listVirtualMachineScaleSetIPConfigurationsNextResults req, err := client.ListVirtualMachineScaleSetIPConfigurationsPreparer(ctx, resourceGroupName, virtualMachineScaleSetName, virtualmachineIndex, networkInterfaceName, expand) @@ -818,9 +837,9 @@ func (client InterfacesClient) ListVirtualMachineScaleSetIPConfigurationsComplet } // ListVirtualMachineScaleSetNetworkInterfaces gets all network interfaces in a virtual machine scale set. -// -// resourceGroupName is the name of the resource group. virtualMachineScaleSetName is the name of the virtual -// machine scale set. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualMachineScaleSetName - the name of the virtual machine scale set. func (client InterfacesClient) ListVirtualMachineScaleSetNetworkInterfaces(ctx context.Context, resourceGroupName string, virtualMachineScaleSetName string) (result InterfaceListResultPage, err error) { result.fn = client.listVirtualMachineScaleSetNetworkInterfacesNextResults req, err := client.ListVirtualMachineScaleSetNetworkInterfacesPreparer(ctx, resourceGroupName, virtualMachineScaleSetName) @@ -914,9 +933,10 @@ func (client InterfacesClient) ListVirtualMachineScaleSetNetworkInterfacesComple // ListVirtualMachineScaleSetVMNetworkInterfaces gets information about all network interfaces in a virtual machine in // a virtual machine scale set. -// -// resourceGroupName is the name of the resource group. virtualMachineScaleSetName is the name of the virtual -// machine scale set. virtualmachineIndex is the virtual machine index. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualMachineScaleSetName - the name of the virtual machine scale set. +// virtualmachineIndex - the virtual machine index. func (client InterfacesClient) ListVirtualMachineScaleSetVMNetworkInterfaces(ctx context.Context, resourceGroupName string, virtualMachineScaleSetName string, virtualmachineIndex string) (result InterfaceListResultPage, err error) { result.fn = client.listVirtualMachineScaleSetVMNetworkInterfacesNextResults req, err := client.ListVirtualMachineScaleSetVMNetworkInterfacesPreparer(ctx, resourceGroupName, virtualMachineScaleSetName, virtualmachineIndex) @@ -1010,9 +1030,10 @@ func (client InterfacesClient) ListVirtualMachineScaleSetVMNetworkInterfacesComp } // UpdateTags updates a network interface tags. -// -// resourceGroupName is the name of the resource group. networkInterfaceName is the name of the network interface. -// parameters is parameters supplied to update network interface tags. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkInterfaceName - the name of the network interface. +// parameters - parameters supplied to update network interface tags. func (client InterfacesClient) UpdateTags(ctx context.Context, resourceGroupName string, networkInterfaceName string, parameters TagsObject) (result InterfacesUpdateTagsFuture, err error) { req, err := client.UpdateTagsPreparer(ctx, resourceGroupName, networkInterfaceName, parameters) if err != nil { @@ -1055,15 +1076,17 @@ func (client InterfacesClient) UpdateTagsPreparer(ctx context.Context, resourceG // UpdateTagsSender sends the UpdateTags request. The method will close the // http.Response Body if it receives an error. func (client InterfacesClient) UpdateTagsSender(req *http.Request) (future InterfacesUpdateTagsFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/loadbalancerbackendaddresspools.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/loadbalancerbackendaddresspools.go index 5da0822f6..b7b82f3bf 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/loadbalancerbackendaddresspools.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/loadbalancerbackendaddresspools.go @@ -41,9 +41,10 @@ func NewLoadBalancerBackendAddressPoolsClientWithBaseURI(baseURI string, subscri } // Get gets load balancer backend address pool. -// -// resourceGroupName is the name of the resource group. loadBalancerName is the name of the load balancer. -// backendAddressPoolName is the name of the backend address pool. +// Parameters: +// resourceGroupName - the name of the resource group. +// loadBalancerName - the name of the load balancer. +// backendAddressPoolName - the name of the backend address pool. func (client LoadBalancerBackendAddressPoolsClient) Get(ctx context.Context, resourceGroupName string, loadBalancerName string, backendAddressPoolName string) (result BackendAddressPool, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, loadBalancerName, backendAddressPoolName) if err != nil { @@ -109,8 +110,9 @@ func (client LoadBalancerBackendAddressPoolsClient) GetResponder(resp *http.Resp } // List gets all the load balancer backed address pools. -// -// resourceGroupName is the name of the resource group. loadBalancerName is the name of the load balancer. +// Parameters: +// resourceGroupName - the name of the resource group. +// loadBalancerName - the name of the load balancer. func (client LoadBalancerBackendAddressPoolsClient) List(ctx context.Context, resourceGroupName string, loadBalancerName string) (result LoadBalancerBackendAddressPoolListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName, loadBalancerName) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/loadbalancerfrontendipconfigurations.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/loadbalancerfrontendipconfigurations.go index cfc1a2d25..502c9379e 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/loadbalancerfrontendipconfigurations.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/loadbalancerfrontendipconfigurations.go @@ -42,9 +42,10 @@ func NewLoadBalancerFrontendIPConfigurationsClientWithBaseURI(baseURI string, su } // Get gets load balancer frontend IP configuration. -// -// resourceGroupName is the name of the resource group. loadBalancerName is the name of the load balancer. -// frontendIPConfigurationName is the name of the frontend IP configuration. +// Parameters: +// resourceGroupName - the name of the resource group. +// loadBalancerName - the name of the load balancer. +// frontendIPConfigurationName - the name of the frontend IP configuration. func (client LoadBalancerFrontendIPConfigurationsClient) Get(ctx context.Context, resourceGroupName string, loadBalancerName string, frontendIPConfigurationName string) (result FrontendIPConfiguration, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, loadBalancerName, frontendIPConfigurationName) if err != nil { @@ -110,8 +111,9 @@ func (client LoadBalancerFrontendIPConfigurationsClient) GetResponder(resp *http } // List gets all the load balancer frontend IP configurations. -// -// resourceGroupName is the name of the resource group. loadBalancerName is the name of the load balancer. +// Parameters: +// resourceGroupName - the name of the resource group. +// loadBalancerName - the name of the load balancer. func (client LoadBalancerFrontendIPConfigurationsClient) List(ctx context.Context, resourceGroupName string, loadBalancerName string) (result LoadBalancerFrontendIPConfigurationListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName, loadBalancerName) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/loadbalancerloadbalancingrules.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/loadbalancerloadbalancingrules.go index f80ffddcc..c59288447 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/loadbalancerloadbalancingrules.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/loadbalancerloadbalancingrules.go @@ -41,9 +41,10 @@ func NewLoadBalancerLoadBalancingRulesClientWithBaseURI(baseURI string, subscrip } // Get gets the specified load balancer load balancing rule. -// -// resourceGroupName is the name of the resource group. loadBalancerName is the name of the load balancer. -// loadBalancingRuleName is the name of the load balancing rule. +// Parameters: +// resourceGroupName - the name of the resource group. +// loadBalancerName - the name of the load balancer. +// loadBalancingRuleName - the name of the load balancing rule. func (client LoadBalancerLoadBalancingRulesClient) Get(ctx context.Context, resourceGroupName string, loadBalancerName string, loadBalancingRuleName string) (result LoadBalancingRule, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, loadBalancerName, loadBalancingRuleName) if err != nil { @@ -109,8 +110,9 @@ func (client LoadBalancerLoadBalancingRulesClient) GetResponder(resp *http.Respo } // List gets all the load balancing rules in a load balancer. -// -// resourceGroupName is the name of the resource group. loadBalancerName is the name of the load balancer. +// Parameters: +// resourceGroupName - the name of the resource group. +// loadBalancerName - the name of the load balancer. func (client LoadBalancerLoadBalancingRulesClient) List(ctx context.Context, resourceGroupName string, loadBalancerName string) (result LoadBalancerLoadBalancingRuleListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName, loadBalancerName) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/loadbalancernetworkinterfaces.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/loadbalancernetworkinterfaces.go index 42d1f7939..19aff0ee3 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/loadbalancernetworkinterfaces.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/loadbalancernetworkinterfaces.go @@ -41,8 +41,9 @@ func NewLoadBalancerNetworkInterfacesClientWithBaseURI(baseURI string, subscript } // List gets associated load balancer network interfaces. -// -// resourceGroupName is the name of the resource group. loadBalancerName is the name of the load balancer. +// Parameters: +// resourceGroupName - the name of the resource group. +// loadBalancerName - the name of the load balancer. func (client LoadBalancerNetworkInterfacesClient) List(ctx context.Context, resourceGroupName string, loadBalancerName string) (result InterfaceListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName, loadBalancerName) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/loadbalancerprobes.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/loadbalancerprobes.go index 77e8a60ff..a4501d8fa 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/loadbalancerprobes.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/loadbalancerprobes.go @@ -40,9 +40,10 @@ func NewLoadBalancerProbesClientWithBaseURI(baseURI string, subscriptionID strin } // Get gets load balancer probe. -// -// resourceGroupName is the name of the resource group. loadBalancerName is the name of the load balancer. -// probeName is the name of the probe. +// Parameters: +// resourceGroupName - the name of the resource group. +// loadBalancerName - the name of the load balancer. +// probeName - the name of the probe. func (client LoadBalancerProbesClient) Get(ctx context.Context, resourceGroupName string, loadBalancerName string, probeName string) (result Probe, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, loadBalancerName, probeName) if err != nil { @@ -108,8 +109,9 @@ func (client LoadBalancerProbesClient) GetResponder(resp *http.Response) (result } // List gets all the load balancer probes. -// -// resourceGroupName is the name of the resource group. loadBalancerName is the name of the load balancer. +// Parameters: +// resourceGroupName - the name of the resource group. +// loadBalancerName - the name of the load balancer. func (client LoadBalancerProbesClient) List(ctx context.Context, resourceGroupName string, loadBalancerName string) (result LoadBalancerProbeListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName, loadBalancerName) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/loadbalancers.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/loadbalancers.go index 02035242f..7513f9d14 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/loadbalancers.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/loadbalancers.go @@ -40,9 +40,10 @@ func NewLoadBalancersClientWithBaseURI(baseURI string, subscriptionID string) Lo } // CreateOrUpdate creates or updates a load balancer. -// -// resourceGroupName is the name of the resource group. loadBalancerName is the name of the load balancer. -// parameters is parameters supplied to the create or update load balancer operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// loadBalancerName - the name of the load balancer. +// parameters - parameters supplied to the create or update load balancer operation. func (client LoadBalancersClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, loadBalancerName string, parameters LoadBalancer) (result LoadBalancersCreateOrUpdateFuture, err error) { req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, loadBalancerName, parameters) if err != nil { @@ -85,15 +86,17 @@ func (client LoadBalancersClient) CreateOrUpdatePreparer(ctx context.Context, re // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client LoadBalancersClient) CreateOrUpdateSender(req *http.Request) (future LoadBalancersCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -111,8 +114,9 @@ func (client LoadBalancersClient) CreateOrUpdateResponder(resp *http.Response) ( } // Delete deletes the specified load balancer. -// -// resourceGroupName is the name of the resource group. loadBalancerName is the name of the load balancer. +// Parameters: +// resourceGroupName - the name of the resource group. +// loadBalancerName - the name of the load balancer. func (client LoadBalancersClient) Delete(ctx context.Context, resourceGroupName string, loadBalancerName string) (result LoadBalancersDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, loadBalancerName) if err != nil { @@ -153,15 +157,17 @@ func (client LoadBalancersClient) DeletePreparer(ctx context.Context, resourceGr // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client LoadBalancersClient) DeleteSender(req *http.Request) (future LoadBalancersDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -178,9 +184,10 @@ func (client LoadBalancersClient) DeleteResponder(resp *http.Response) (result a } // Get gets the specified load balancer. -// -// resourceGroupName is the name of the resource group. loadBalancerName is the name of the load balancer. expand -// is expands referenced resources. +// Parameters: +// resourceGroupName - the name of the resource group. +// loadBalancerName - the name of the load balancer. +// expand - expands referenced resources. func (client LoadBalancersClient) Get(ctx context.Context, resourceGroupName string, loadBalancerName string, expand string) (result LoadBalancer, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, loadBalancerName, expand) if err != nil { @@ -248,8 +255,8 @@ func (client LoadBalancersClient) GetResponder(resp *http.Response) (result Load } // List gets all the load balancers in a resource group. -// -// resourceGroupName is the name of the resource group. +// Parameters: +// resourceGroupName - the name of the resource group. func (client LoadBalancersClient) List(ctx context.Context, resourceGroupName string) (result LoadBalancerListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName) @@ -431,9 +438,10 @@ func (client LoadBalancersClient) ListAllComplete(ctx context.Context) (result L } // UpdateTags updates a load balancer tags. -// -// resourceGroupName is the name of the resource group. loadBalancerName is the name of the load balancer. -// parameters is parameters supplied to update load balancer tags. +// Parameters: +// resourceGroupName - the name of the resource group. +// loadBalancerName - the name of the load balancer. +// parameters - parameters supplied to update load balancer tags. func (client LoadBalancersClient) UpdateTags(ctx context.Context, resourceGroupName string, loadBalancerName string, parameters TagsObject) (result LoadBalancersUpdateTagsFuture, err error) { req, err := client.UpdateTagsPreparer(ctx, resourceGroupName, loadBalancerName, parameters) if err != nil { @@ -476,15 +484,17 @@ func (client LoadBalancersClient) UpdateTagsPreparer(ctx context.Context, resour // UpdateTagsSender sends the UpdateTags request. The method will close the // http.Response Body if it receives an error. func (client LoadBalancersClient) UpdateTagsSender(req *http.Request) (future LoadBalancersUpdateTagsFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/localnetworkgateways.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/localnetworkgateways.go index 7c94475c4..e43ee6f27 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/localnetworkgateways.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/localnetworkgateways.go @@ -41,9 +41,10 @@ func NewLocalNetworkGatewaysClientWithBaseURI(baseURI string, subscriptionID str } // CreateOrUpdate creates or updates a local network gateway in the specified resource group. -// -// resourceGroupName is the name of the resource group. localNetworkGatewayName is the name of the local network -// gateway. parameters is parameters supplied to the create or update local network gateway operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// localNetworkGatewayName - the name of the local network gateway. +// parameters - parameters supplied to the create or update local network gateway operation. func (client LocalNetworkGatewaysClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, localNetworkGatewayName string, parameters LocalNetworkGateway) (result LocalNetworkGatewaysCreateOrUpdateFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: localNetworkGatewayName, @@ -94,15 +95,17 @@ func (client LocalNetworkGatewaysClient) CreateOrUpdatePreparer(ctx context.Cont // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client LocalNetworkGatewaysClient) CreateOrUpdateSender(req *http.Request) (future LocalNetworkGatewaysCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -120,9 +123,9 @@ func (client LocalNetworkGatewaysClient) CreateOrUpdateResponder(resp *http.Resp } // Delete deletes the specified local network gateway. -// -// resourceGroupName is the name of the resource group. localNetworkGatewayName is the name of the local network -// gateway. +// Parameters: +// resourceGroupName - the name of the resource group. +// localNetworkGatewayName - the name of the local network gateway. func (client LocalNetworkGatewaysClient) Delete(ctx context.Context, resourceGroupName string, localNetworkGatewayName string) (result LocalNetworkGatewaysDeleteFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: localNetworkGatewayName, @@ -169,15 +172,17 @@ func (client LocalNetworkGatewaysClient) DeletePreparer(ctx context.Context, res // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client LocalNetworkGatewaysClient) DeleteSender(req *http.Request) (future LocalNetworkGatewaysDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -194,9 +199,9 @@ func (client LocalNetworkGatewaysClient) DeleteResponder(resp *http.Response) (r } // Get gets the specified local network gateway in a resource group. -// -// resourceGroupName is the name of the resource group. localNetworkGatewayName is the name of the local network -// gateway. +// Parameters: +// resourceGroupName - the name of the resource group. +// localNetworkGatewayName - the name of the local network gateway. func (client LocalNetworkGatewaysClient) Get(ctx context.Context, resourceGroupName string, localNetworkGatewayName string) (result LocalNetworkGateway, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: localNetworkGatewayName, @@ -267,8 +272,8 @@ func (client LocalNetworkGatewaysClient) GetResponder(resp *http.Response) (resu } // List gets all the local network gateways in a resource group. -// -// resourceGroupName is the name of the resource group. +// Parameters: +// resourceGroupName - the name of the resource group. func (client LocalNetworkGatewaysClient) List(ctx context.Context, resourceGroupName string) (result LocalNetworkGatewayListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName) @@ -360,9 +365,10 @@ func (client LocalNetworkGatewaysClient) ListComplete(ctx context.Context, resou } // UpdateTags updates a local network gateway tags. -// -// resourceGroupName is the name of the resource group. localNetworkGatewayName is the name of the local network -// gateway. parameters is parameters supplied to update local network gateway tags. +// Parameters: +// resourceGroupName - the name of the resource group. +// localNetworkGatewayName - the name of the local network gateway. +// parameters - parameters supplied to update local network gateway tags. func (client LocalNetworkGatewaysClient) UpdateTags(ctx context.Context, resourceGroupName string, localNetworkGatewayName string, parameters TagsObject) (result LocalNetworkGatewaysUpdateTagsFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: localNetworkGatewayName, @@ -411,15 +417,17 @@ func (client LocalNetworkGatewaysClient) UpdateTagsPreparer(ctx context.Context, // UpdateTagsSender sends the UpdateTags request. The method will close the // http.Response Body if it receives an error. func (client LocalNetworkGatewaysClient) UpdateTagsSender(req *http.Request) (future LocalNetworkGatewaysUpdateTagsFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/models.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/models.go index 2da829618..994808f03 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/models.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/models.go @@ -3202,12 +3202,11 @@ type ApplicationGatewayRequestRoutingRulePropertiesFormat struct { // long-running operation. type ApplicationGatewaysBackendHealthFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ApplicationGatewaysBackendHealthFuture) Result(client ApplicationGatewaysClient) (agbh ApplicationGatewayBackendHealth, err error) { +func (future *ApplicationGatewaysBackendHealthFuture) Result(client ApplicationGatewaysClient) (agbh ApplicationGatewayBackendHealth, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -3215,34 +3214,15 @@ func (future ApplicationGatewaysBackendHealthFuture) Result(client ApplicationGa return } if !done { - return agbh, azure.NewAsyncOpIncompleteError("network.ApplicationGatewaysBackendHealthFuture") - } - if future.PollingMethod() == azure.PollingLocation { - agbh, err = client.BackendHealthResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysBackendHealthFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.ApplicationGatewaysBackendHealthFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if agbh.Response.Response, err = future.GetResult(sender); err == nil && agbh.Response.Response.StatusCode != http.StatusNoContent { + agbh, err = client.BackendHealthResponder(agbh.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysBackendHealthFuture", "Result", agbh.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysBackendHealthFuture", "Result", resp, "Failure sending request") - return - } - agbh, err = client.BackendHealthResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysBackendHealthFuture", "Result", resp, "Failure responding to request") } return } @@ -3251,12 +3231,11 @@ func (future ApplicationGatewaysBackendHealthFuture) Result(client ApplicationGa // long-running operation. type ApplicationGatewaysCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ApplicationGatewaysCreateOrUpdateFuture) Result(client ApplicationGatewaysClient) (ag ApplicationGateway, err error) { +func (future *ApplicationGatewaysCreateOrUpdateFuture) Result(client ApplicationGatewaysClient) (ag ApplicationGateway, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -3264,34 +3243,15 @@ func (future ApplicationGatewaysCreateOrUpdateFuture) Result(client ApplicationG return } if !done { - return ag, azure.NewAsyncOpIncompleteError("network.ApplicationGatewaysCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ag, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.ApplicationGatewaysCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if ag.Response.Response, err = future.GetResult(sender); err == nil && ag.Response.Response.StatusCode != http.StatusNoContent { + ag, err = client.CreateOrUpdateResponder(ag.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysCreateOrUpdateFuture", "Result", ag.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - ag, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -3300,12 +3260,11 @@ func (future ApplicationGatewaysCreateOrUpdateFuture) Result(client ApplicationG // operation. type ApplicationGatewaysDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ApplicationGatewaysDeleteFuture) Result(client ApplicationGatewaysClient) (ar autorest.Response, err error) { +func (future *ApplicationGatewaysDeleteFuture) Result(client ApplicationGatewaysClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -3313,35 +3272,10 @@ func (future ApplicationGatewaysDeleteFuture) Result(client ApplicationGatewaysC return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.ApplicationGatewaysDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.ApplicationGatewaysDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysDeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -3554,12 +3488,11 @@ type ApplicationGatewaySslPredefinedPolicyPropertiesFormat struct { // operation. type ApplicationGatewaysStartFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ApplicationGatewaysStartFuture) Result(client ApplicationGatewaysClient) (ar autorest.Response, err error) { +func (future *ApplicationGatewaysStartFuture) Result(client ApplicationGatewaysClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -3567,35 +3500,10 @@ func (future ApplicationGatewaysStartFuture) Result(client ApplicationGatewaysCl return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.ApplicationGatewaysStartFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.StartResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysStartFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.ApplicationGatewaysStartFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysStartFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.StartResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysStartFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -3603,12 +3511,11 @@ func (future ApplicationGatewaysStartFuture) Result(client ApplicationGatewaysCl // operation. type ApplicationGatewaysStopFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ApplicationGatewaysStopFuture) Result(client ApplicationGatewaysClient) (ar autorest.Response, err error) { +func (future *ApplicationGatewaysStopFuture) Result(client ApplicationGatewaysClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -3616,35 +3523,10 @@ func (future ApplicationGatewaysStopFuture) Result(client ApplicationGatewaysCli return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.ApplicationGatewaysStopFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.StopResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysStopFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.ApplicationGatewaysStopFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysStopFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.StopResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysStopFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -3652,12 +3534,11 @@ func (future ApplicationGatewaysStopFuture) Result(client ApplicationGatewaysCli // operation. type ApplicationGatewaysUpdateTagsFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ApplicationGatewaysUpdateTagsFuture) Result(client ApplicationGatewaysClient) (ag ApplicationGateway, err error) { +func (future *ApplicationGatewaysUpdateTagsFuture) Result(client ApplicationGatewaysClient) (ag ApplicationGateway, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -3665,34 +3546,15 @@ func (future ApplicationGatewaysUpdateTagsFuture) Result(client ApplicationGatew return } if !done { - return ag, azure.NewAsyncOpIncompleteError("network.ApplicationGatewaysUpdateTagsFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ag, err = client.UpdateTagsResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysUpdateTagsFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.ApplicationGatewaysUpdateTagsFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if ag.Response.Response, err = future.GetResult(sender); err == nil && ag.Response.Response.StatusCode != http.StatusNoContent { + ag, err = client.UpdateTagsResponder(ag.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysUpdateTagsFuture", "Result", ag.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysUpdateTagsFuture", "Result", resp, "Failure sending request") - return - } - ag, err = client.UpdateTagsResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysUpdateTagsFuture", "Result", resp, "Failure responding to request") } return } @@ -4064,12 +3926,11 @@ type ApplicationSecurityGroupPropertiesFormat struct { // long-running operation. type ApplicationSecurityGroupsCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ApplicationSecurityGroupsCreateOrUpdateFuture) Result(client ApplicationSecurityGroupsClient) (asg ApplicationSecurityGroup, err error) { +func (future *ApplicationSecurityGroupsCreateOrUpdateFuture) Result(client ApplicationSecurityGroupsClient) (asg ApplicationSecurityGroup, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -4077,34 +3938,15 @@ func (future ApplicationSecurityGroupsCreateOrUpdateFuture) Result(client Applic return } if !done { - return asg, azure.NewAsyncOpIncompleteError("network.ApplicationSecurityGroupsCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - asg, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ApplicationSecurityGroupsCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.ApplicationSecurityGroupsCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if asg.Response.Response, err = future.GetResult(sender); err == nil && asg.Response.Response.StatusCode != http.StatusNoContent { + asg, err = client.CreateOrUpdateResponder(asg.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.ApplicationSecurityGroupsCreateOrUpdateFuture", "Result", asg.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ApplicationSecurityGroupsCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - asg, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ApplicationSecurityGroupsCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -4113,12 +3955,11 @@ func (future ApplicationSecurityGroupsCreateOrUpdateFuture) Result(client Applic // operation. type ApplicationSecurityGroupsDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ApplicationSecurityGroupsDeleteFuture) Result(client ApplicationSecurityGroupsClient) (ar autorest.Response, err error) { +func (future *ApplicationSecurityGroupsDeleteFuture) Result(client ApplicationSecurityGroupsClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -4126,35 +3967,10 @@ func (future ApplicationSecurityGroupsDeleteFuture) Result(client ApplicationSec return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.ApplicationSecurityGroupsDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ApplicationSecurityGroupsDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.ApplicationSecurityGroupsDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ApplicationSecurityGroupsDeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ApplicationSecurityGroupsDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -4999,12 +4815,11 @@ type ConnectionMonitorResultProperties struct { // long-running operation. type ConnectionMonitorsCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ConnectionMonitorsCreateOrUpdateFuture) Result(client ConnectionMonitorsClient) (cmr ConnectionMonitorResult, err error) { +func (future *ConnectionMonitorsCreateOrUpdateFuture) Result(client ConnectionMonitorsClient) (cmr ConnectionMonitorResult, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -5012,34 +4827,15 @@ func (future ConnectionMonitorsCreateOrUpdateFuture) Result(client ConnectionMon return } if !done { - return cmr, azure.NewAsyncOpIncompleteError("network.ConnectionMonitorsCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - cmr, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ConnectionMonitorsCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.ConnectionMonitorsCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if cmr.Response.Response, err = future.GetResult(sender); err == nil && cmr.Response.Response.StatusCode != http.StatusNoContent { + cmr, err = client.CreateOrUpdateResponder(cmr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.ConnectionMonitorsCreateOrUpdateFuture", "Result", cmr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ConnectionMonitorsCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - cmr, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ConnectionMonitorsCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -5048,12 +4844,11 @@ func (future ConnectionMonitorsCreateOrUpdateFuture) Result(client ConnectionMon // operation. type ConnectionMonitorsDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ConnectionMonitorsDeleteFuture) Result(client ConnectionMonitorsClient) (ar autorest.Response, err error) { +func (future *ConnectionMonitorsDeleteFuture) Result(client ConnectionMonitorsClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -5061,35 +4856,10 @@ func (future ConnectionMonitorsDeleteFuture) Result(client ConnectionMonitorsCli return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.ConnectionMonitorsDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ConnectionMonitorsDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.ConnectionMonitorsDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ConnectionMonitorsDeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ConnectionMonitorsDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -5105,12 +4875,11 @@ type ConnectionMonitorSource struct { // operation. type ConnectionMonitorsQueryFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ConnectionMonitorsQueryFuture) Result(client ConnectionMonitorsClient) (cmqr ConnectionMonitorQueryResult, err error) { +func (future *ConnectionMonitorsQueryFuture) Result(client ConnectionMonitorsClient) (cmqr ConnectionMonitorQueryResult, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -5118,34 +4887,15 @@ func (future ConnectionMonitorsQueryFuture) Result(client ConnectionMonitorsClie return } if !done { - return cmqr, azure.NewAsyncOpIncompleteError("network.ConnectionMonitorsQueryFuture") - } - if future.PollingMethod() == azure.PollingLocation { - cmqr, err = client.QueryResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ConnectionMonitorsQueryFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.ConnectionMonitorsQueryFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if cmqr.Response.Response, err = future.GetResult(sender); err == nil && cmqr.Response.Response.StatusCode != http.StatusNoContent { + cmqr, err = client.QueryResponder(cmqr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.ConnectionMonitorsQueryFuture", "Result", cmqr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ConnectionMonitorsQueryFuture", "Result", resp, "Failure sending request") - return - } - cmqr, err = client.QueryResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ConnectionMonitorsQueryFuture", "Result", resp, "Failure responding to request") } return } @@ -5154,12 +4904,11 @@ func (future ConnectionMonitorsQueryFuture) Result(client ConnectionMonitorsClie // operation. type ConnectionMonitorsStartFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ConnectionMonitorsStartFuture) Result(client ConnectionMonitorsClient) (ar autorest.Response, err error) { +func (future *ConnectionMonitorsStartFuture) Result(client ConnectionMonitorsClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -5167,35 +4916,10 @@ func (future ConnectionMonitorsStartFuture) Result(client ConnectionMonitorsClie return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.ConnectionMonitorsStartFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.StartResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ConnectionMonitorsStartFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.ConnectionMonitorsStartFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ConnectionMonitorsStartFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.StartResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ConnectionMonitorsStartFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -5203,12 +4927,11 @@ func (future ConnectionMonitorsStartFuture) Result(client ConnectionMonitorsClie // operation. type ConnectionMonitorsStopFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ConnectionMonitorsStopFuture) Result(client ConnectionMonitorsClient) (ar autorest.Response, err error) { +func (future *ConnectionMonitorsStopFuture) Result(client ConnectionMonitorsClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -5216,35 +4939,10 @@ func (future ConnectionMonitorsStopFuture) Result(client ConnectionMonitorsClien return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.ConnectionMonitorsStopFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.StopResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ConnectionMonitorsStopFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.ConnectionMonitorsStopFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ConnectionMonitorsStopFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.StopResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ConnectionMonitorsStopFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -5839,12 +5537,11 @@ func (erca *ExpressRouteCircuitAuthorization) UnmarshalJSON(body []byte) error { // of a long-running operation. type ExpressRouteCircuitAuthorizationsCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ExpressRouteCircuitAuthorizationsCreateOrUpdateFuture) Result(client ExpressRouteCircuitAuthorizationsClient) (erca ExpressRouteCircuitAuthorization, err error) { +func (future *ExpressRouteCircuitAuthorizationsCreateOrUpdateFuture) Result(client ExpressRouteCircuitAuthorizationsClient) (erca ExpressRouteCircuitAuthorization, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -5852,34 +5549,15 @@ func (future ExpressRouteCircuitAuthorizationsCreateOrUpdateFuture) Result(clien return } if !done { - return erca, azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitAuthorizationsCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - erca, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitAuthorizationsCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitAuthorizationsCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if erca.Response.Response, err = future.GetResult(sender); err == nil && erca.Response.Response.StatusCode != http.StatusNoContent { + erca, err = client.CreateOrUpdateResponder(erca.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitAuthorizationsCreateOrUpdateFuture", "Result", erca.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitAuthorizationsCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - erca, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitAuthorizationsCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -5888,12 +5566,11 @@ func (future ExpressRouteCircuitAuthorizationsCreateOrUpdateFuture) Result(clien // long-running operation. type ExpressRouteCircuitAuthorizationsDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ExpressRouteCircuitAuthorizationsDeleteFuture) Result(client ExpressRouteCircuitAuthorizationsClient) (ar autorest.Response, err error) { +func (future *ExpressRouteCircuitAuthorizationsDeleteFuture) Result(client ExpressRouteCircuitAuthorizationsClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -5901,35 +5578,10 @@ func (future ExpressRouteCircuitAuthorizationsDeleteFuture) Result(client Expres return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitAuthorizationsDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitAuthorizationsDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitAuthorizationsDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitAuthorizationsDeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitAuthorizationsDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -6278,12 +5930,11 @@ type ExpressRouteCircuitPeeringPropertiesFormat struct { // long-running operation. type ExpressRouteCircuitPeeringsCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ExpressRouteCircuitPeeringsCreateOrUpdateFuture) Result(client ExpressRouteCircuitPeeringsClient) (ercp ExpressRouteCircuitPeering, err error) { +func (future *ExpressRouteCircuitPeeringsCreateOrUpdateFuture) Result(client ExpressRouteCircuitPeeringsClient) (ercp ExpressRouteCircuitPeering, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -6291,34 +5942,15 @@ func (future ExpressRouteCircuitPeeringsCreateOrUpdateFuture) Result(client Expr return } if !done { - return ercp, azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitPeeringsCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ercp, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitPeeringsCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitPeeringsCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if ercp.Response.Response, err = future.GetResult(sender); err == nil && ercp.Response.Response.StatusCode != http.StatusNoContent { + ercp, err = client.CreateOrUpdateResponder(ercp.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitPeeringsCreateOrUpdateFuture", "Result", ercp.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitPeeringsCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - ercp, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitPeeringsCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -6327,12 +5959,11 @@ func (future ExpressRouteCircuitPeeringsCreateOrUpdateFuture) Result(client Expr // long-running operation. type ExpressRouteCircuitPeeringsDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ExpressRouteCircuitPeeringsDeleteFuture) Result(client ExpressRouteCircuitPeeringsClient) (ar autorest.Response, err error) { +func (future *ExpressRouteCircuitPeeringsDeleteFuture) Result(client ExpressRouteCircuitPeeringsClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -6340,35 +5971,10 @@ func (future ExpressRouteCircuitPeeringsDeleteFuture) Result(client ExpressRoute return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitPeeringsDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitPeeringsDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitPeeringsDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitPeeringsDeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitPeeringsDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -6437,12 +6043,11 @@ type ExpressRouteCircuitsArpTableListResult struct { // long-running operation. type ExpressRouteCircuitsCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ExpressRouteCircuitsCreateOrUpdateFuture) Result(client ExpressRouteCircuitsClient) (erc ExpressRouteCircuit, err error) { +func (future *ExpressRouteCircuitsCreateOrUpdateFuture) Result(client ExpressRouteCircuitsClient) (erc ExpressRouteCircuit, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -6450,34 +6055,15 @@ func (future ExpressRouteCircuitsCreateOrUpdateFuture) Result(client ExpressRout return } if !done { - return erc, azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitsCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - erc, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitsCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if erc.Response.Response, err = future.GetResult(sender); err == nil && erc.Response.Response.StatusCode != http.StatusNoContent { + erc, err = client.CreateOrUpdateResponder(erc.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsCreateOrUpdateFuture", "Result", erc.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - erc, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -6486,12 +6072,11 @@ func (future ExpressRouteCircuitsCreateOrUpdateFuture) Result(client ExpressRout // operation. type ExpressRouteCircuitsDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ExpressRouteCircuitsDeleteFuture) Result(client ExpressRouteCircuitsClient) (ar autorest.Response, err error) { +func (future *ExpressRouteCircuitsDeleteFuture) Result(client ExpressRouteCircuitsClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -6499,35 +6084,10 @@ func (future ExpressRouteCircuitsDeleteFuture) Result(client ExpressRouteCircuit return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitsDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitsDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsDeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -6555,12 +6115,11 @@ type ExpressRouteCircuitSku struct { // long-running operation. type ExpressRouteCircuitsListArpTableFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ExpressRouteCircuitsListArpTableFuture) Result(client ExpressRouteCircuitsClient) (ercatlr ExpressRouteCircuitsArpTableListResult, err error) { +func (future *ExpressRouteCircuitsListArpTableFuture) Result(client ExpressRouteCircuitsClient) (ercatlr ExpressRouteCircuitsArpTableListResult, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -6568,34 +6127,15 @@ func (future ExpressRouteCircuitsListArpTableFuture) Result(client ExpressRouteC return } if !done { - return ercatlr, azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitsListArpTableFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ercatlr, err = client.ListArpTableResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsListArpTableFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitsListArpTableFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if ercatlr.Response.Response, err = future.GetResult(sender); err == nil && ercatlr.Response.Response.StatusCode != http.StatusNoContent { + ercatlr, err = client.ListArpTableResponder(ercatlr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsListArpTableFuture", "Result", ercatlr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsListArpTableFuture", "Result", resp, "Failure sending request") - return - } - ercatlr, err = client.ListArpTableResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsListArpTableFuture", "Result", resp, "Failure responding to request") } return } @@ -6604,12 +6144,11 @@ func (future ExpressRouteCircuitsListArpTableFuture) Result(client ExpressRouteC // long-running operation. type ExpressRouteCircuitsListRoutesTableFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ExpressRouteCircuitsListRoutesTableFuture) Result(client ExpressRouteCircuitsClient) (ercrtlr ExpressRouteCircuitsRoutesTableListResult, err error) { +func (future *ExpressRouteCircuitsListRoutesTableFuture) Result(client ExpressRouteCircuitsClient) (ercrtlr ExpressRouteCircuitsRoutesTableListResult, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -6617,34 +6156,15 @@ func (future ExpressRouteCircuitsListRoutesTableFuture) Result(client ExpressRou return } if !done { - return ercrtlr, azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitsListRoutesTableFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ercrtlr, err = client.ListRoutesTableResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsListRoutesTableFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitsListRoutesTableFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if ercrtlr.Response.Response, err = future.GetResult(sender); err == nil && ercrtlr.Response.Response.StatusCode != http.StatusNoContent { + ercrtlr, err = client.ListRoutesTableResponder(ercrtlr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsListRoutesTableFuture", "Result", ercrtlr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsListRoutesTableFuture", "Result", resp, "Failure sending request") - return - } - ercrtlr, err = client.ListRoutesTableResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsListRoutesTableFuture", "Result", resp, "Failure responding to request") } return } @@ -6653,12 +6173,11 @@ func (future ExpressRouteCircuitsListRoutesTableFuture) Result(client ExpressRou // long-running operation. type ExpressRouteCircuitsListRoutesTableSummaryFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ExpressRouteCircuitsListRoutesTableSummaryFuture) Result(client ExpressRouteCircuitsClient) (ercrtslr ExpressRouteCircuitsRoutesTableSummaryListResult, err error) { +func (future *ExpressRouteCircuitsListRoutesTableSummaryFuture) Result(client ExpressRouteCircuitsClient) (ercrtslr ExpressRouteCircuitsRoutesTableSummaryListResult, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -6666,34 +6185,15 @@ func (future ExpressRouteCircuitsListRoutesTableSummaryFuture) Result(client Exp return } if !done { - return ercrtslr, azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitsListRoutesTableSummaryFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ercrtslr, err = client.ListRoutesTableSummaryResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsListRoutesTableSummaryFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitsListRoutesTableSummaryFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if ercrtslr.Response.Response, err = future.GetResult(sender); err == nil && ercrtslr.Response.Response.StatusCode != http.StatusNoContent { + ercrtslr, err = client.ListRoutesTableSummaryResponder(ercrtslr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsListRoutesTableSummaryFuture", "Result", ercrtslr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsListRoutesTableSummaryFuture", "Result", resp, "Failure sending request") - return - } - ercrtslr, err = client.ListRoutesTableSummaryResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsListRoutesTableSummaryFuture", "Result", resp, "Failure responding to request") } return } @@ -6735,12 +6235,11 @@ type ExpressRouteCircuitStats struct { // operation. type ExpressRouteCircuitsUpdateTagsFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ExpressRouteCircuitsUpdateTagsFuture) Result(client ExpressRouteCircuitsClient) (erc ExpressRouteCircuit, err error) { +func (future *ExpressRouteCircuitsUpdateTagsFuture) Result(client ExpressRouteCircuitsClient) (erc ExpressRouteCircuit, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -6748,34 +6247,15 @@ func (future ExpressRouteCircuitsUpdateTagsFuture) Result(client ExpressRouteCir return } if !done { - return erc, azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitsUpdateTagsFuture") - } - if future.PollingMethod() == azure.PollingLocation { - erc, err = client.UpdateTagsResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsUpdateTagsFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitsUpdateTagsFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if erc.Response.Response, err = future.GetResult(sender); err == nil && erc.Response.Response.StatusCode != http.StatusNoContent { + erc, err = client.UpdateTagsResponder(erc.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsUpdateTagsFuture", "Result", erc.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsUpdateTagsFuture", "Result", resp, "Failure sending request") - return - } - erc, err = client.UpdateTagsResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsUpdateTagsFuture", "Result", resp, "Failure responding to request") } return } @@ -7544,12 +7024,11 @@ type InboundNatRulePropertiesFormat struct { // operation. type InboundNatRulesCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future InboundNatRulesCreateOrUpdateFuture) Result(client InboundNatRulesClient) (inr InboundNatRule, err error) { +func (future *InboundNatRulesCreateOrUpdateFuture) Result(client InboundNatRulesClient) (inr InboundNatRule, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -7557,34 +7036,15 @@ func (future InboundNatRulesCreateOrUpdateFuture) Result(client InboundNatRulesC return } if !done { - return inr, azure.NewAsyncOpIncompleteError("network.InboundNatRulesCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - inr, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.InboundNatRulesCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.InboundNatRulesCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if inr.Response.Response, err = future.GetResult(sender); err == nil && inr.Response.Response.StatusCode != http.StatusNoContent { + inr, err = client.CreateOrUpdateResponder(inr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.InboundNatRulesCreateOrUpdateFuture", "Result", inr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.InboundNatRulesCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - inr, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.InboundNatRulesCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -7593,12 +7053,11 @@ func (future InboundNatRulesCreateOrUpdateFuture) Result(client InboundNatRulesC // operation. type InboundNatRulesDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future InboundNatRulesDeleteFuture) Result(client InboundNatRulesClient) (ar autorest.Response, err error) { +func (future *InboundNatRulesDeleteFuture) Result(client InboundNatRulesClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -7606,35 +7065,10 @@ func (future InboundNatRulesDeleteFuture) Result(client InboundNatRulesClient) ( return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.InboundNatRulesDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.InboundNatRulesDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.InboundNatRulesDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.InboundNatRulesDeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.InboundNatRulesDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -8227,12 +7661,11 @@ type InterfacePropertiesFormat struct { // operation. type InterfacesCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future InterfacesCreateOrUpdateFuture) Result(client InterfacesClient) (i Interface, err error) { +func (future *InterfacesCreateOrUpdateFuture) Result(client InterfacesClient) (i Interface, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -8240,34 +7673,15 @@ func (future InterfacesCreateOrUpdateFuture) Result(client InterfacesClient) (i return } if !done { - return i, azure.NewAsyncOpIncompleteError("network.InterfacesCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - i, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.InterfacesCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.InterfacesCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if i.Response.Response, err = future.GetResult(sender); err == nil && i.Response.Response.StatusCode != http.StatusNoContent { + i, err = client.CreateOrUpdateResponder(i.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.InterfacesCreateOrUpdateFuture", "Result", i.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.InterfacesCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - i, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.InterfacesCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -8275,12 +7689,11 @@ func (future InterfacesCreateOrUpdateFuture) Result(client InterfacesClient) (i // InterfacesDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation. type InterfacesDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future InterfacesDeleteFuture) Result(client InterfacesClient) (ar autorest.Response, err error) { +func (future *InterfacesDeleteFuture) Result(client InterfacesClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -8288,35 +7701,10 @@ func (future InterfacesDeleteFuture) Result(client InterfacesClient) (ar autores return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.InterfacesDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.InterfacesDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.InterfacesDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.InterfacesDeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.InterfacesDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -8324,12 +7712,11 @@ func (future InterfacesDeleteFuture) Result(client InterfacesClient) (ar autores // long-running operation. type InterfacesGetEffectiveRouteTableFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future InterfacesGetEffectiveRouteTableFuture) Result(client InterfacesClient) (erlr EffectiveRouteListResult, err error) { +func (future *InterfacesGetEffectiveRouteTableFuture) Result(client InterfacesClient) (erlr EffectiveRouteListResult, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -8337,34 +7724,15 @@ func (future InterfacesGetEffectiveRouteTableFuture) Result(client InterfacesCli return } if !done { - return erlr, azure.NewAsyncOpIncompleteError("network.InterfacesGetEffectiveRouteTableFuture") - } - if future.PollingMethod() == azure.PollingLocation { - erlr, err = client.GetEffectiveRouteTableResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.InterfacesGetEffectiveRouteTableFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.InterfacesGetEffectiveRouteTableFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if erlr.Response.Response, err = future.GetResult(sender); err == nil && erlr.Response.Response.StatusCode != http.StatusNoContent { + erlr, err = client.GetEffectiveRouteTableResponder(erlr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.InterfacesGetEffectiveRouteTableFuture", "Result", erlr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.InterfacesGetEffectiveRouteTableFuture", "Result", resp, "Failure sending request") - return - } - erlr, err = client.GetEffectiveRouteTableResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.InterfacesGetEffectiveRouteTableFuture", "Result", resp, "Failure responding to request") } return } @@ -8373,12 +7741,11 @@ func (future InterfacesGetEffectiveRouteTableFuture) Result(client InterfacesCli // long-running operation. type InterfacesListEffectiveNetworkSecurityGroupsFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future InterfacesListEffectiveNetworkSecurityGroupsFuture) Result(client InterfacesClient) (ensglr EffectiveNetworkSecurityGroupListResult, err error) { +func (future *InterfacesListEffectiveNetworkSecurityGroupsFuture) Result(client InterfacesClient) (ensglr EffectiveNetworkSecurityGroupListResult, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -8386,34 +7753,15 @@ func (future InterfacesListEffectiveNetworkSecurityGroupsFuture) Result(client I return } if !done { - return ensglr, azure.NewAsyncOpIncompleteError("network.InterfacesListEffectiveNetworkSecurityGroupsFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ensglr, err = client.ListEffectiveNetworkSecurityGroupsResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.InterfacesListEffectiveNetworkSecurityGroupsFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.InterfacesListEffectiveNetworkSecurityGroupsFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if ensglr.Response.Response, err = future.GetResult(sender); err == nil && ensglr.Response.Response.StatusCode != http.StatusNoContent { + ensglr, err = client.ListEffectiveNetworkSecurityGroupsResponder(ensglr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.InterfacesListEffectiveNetworkSecurityGroupsFuture", "Result", ensglr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.InterfacesListEffectiveNetworkSecurityGroupsFuture", "Result", resp, "Failure sending request") - return - } - ensglr, err = client.ListEffectiveNetworkSecurityGroupsResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.InterfacesListEffectiveNetworkSecurityGroupsFuture", "Result", resp, "Failure responding to request") } return } @@ -8421,12 +7769,11 @@ func (future InterfacesListEffectiveNetworkSecurityGroupsFuture) Result(client I // InterfacesUpdateTagsFuture an abstraction for monitoring and retrieving the results of a long-running operation. type InterfacesUpdateTagsFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future InterfacesUpdateTagsFuture) Result(client InterfacesClient) (i Interface, err error) { +func (future *InterfacesUpdateTagsFuture) Result(client InterfacesClient) (i Interface, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -8434,34 +7781,15 @@ func (future InterfacesUpdateTagsFuture) Result(client InterfacesClient) (i Inte return } if !done { - return i, azure.NewAsyncOpIncompleteError("network.InterfacesUpdateTagsFuture") - } - if future.PollingMethod() == azure.PollingLocation { - i, err = client.UpdateTagsResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.InterfacesUpdateTagsFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.InterfacesUpdateTagsFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if i.Response.Response, err = future.GetResult(sender); err == nil && i.Response.Response.StatusCode != http.StatusNoContent { + i, err = client.UpdateTagsResponder(i.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.InterfacesUpdateTagsFuture", "Result", i.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.InterfacesUpdateTagsFuture", "Result", resp, "Failure sending request") - return - } - i, err = client.UpdateTagsResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.InterfacesUpdateTagsFuture", "Result", resp, "Failure responding to request") } return } @@ -9289,12 +8617,11 @@ type LoadBalancerPropertiesFormat struct { // operation. type LoadBalancersCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future LoadBalancersCreateOrUpdateFuture) Result(client LoadBalancersClient) (lb LoadBalancer, err error) { +func (future *LoadBalancersCreateOrUpdateFuture) Result(client LoadBalancersClient) (lb LoadBalancer, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -9302,34 +8629,15 @@ func (future LoadBalancersCreateOrUpdateFuture) Result(client LoadBalancersClien return } if !done { - return lb, azure.NewAsyncOpIncompleteError("network.LoadBalancersCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - lb, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.LoadBalancersCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.LoadBalancersCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if lb.Response.Response, err = future.GetResult(sender); err == nil && lb.Response.Response.StatusCode != http.StatusNoContent { + lb, err = client.CreateOrUpdateResponder(lb.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.LoadBalancersCreateOrUpdateFuture", "Result", lb.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.LoadBalancersCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - lb, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.LoadBalancersCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -9337,12 +8645,11 @@ func (future LoadBalancersCreateOrUpdateFuture) Result(client LoadBalancersClien // LoadBalancersDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation. type LoadBalancersDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future LoadBalancersDeleteFuture) Result(client LoadBalancersClient) (ar autorest.Response, err error) { +func (future *LoadBalancersDeleteFuture) Result(client LoadBalancersClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -9350,35 +8657,10 @@ func (future LoadBalancersDeleteFuture) Result(client LoadBalancersClient) (ar a return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.LoadBalancersDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.LoadBalancersDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.LoadBalancersDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.LoadBalancersDeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.LoadBalancersDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -9392,12 +8674,11 @@ type LoadBalancerSku struct { // operation. type LoadBalancersUpdateTagsFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future LoadBalancersUpdateTagsFuture) Result(client LoadBalancersClient) (lb LoadBalancer, err error) { +func (future *LoadBalancersUpdateTagsFuture) Result(client LoadBalancersClient) (lb LoadBalancer, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -9405,34 +8686,15 @@ func (future LoadBalancersUpdateTagsFuture) Result(client LoadBalancersClient) ( return } if !done { - return lb, azure.NewAsyncOpIncompleteError("network.LoadBalancersUpdateTagsFuture") - } - if future.PollingMethod() == azure.PollingLocation { - lb, err = client.UpdateTagsResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.LoadBalancersUpdateTagsFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.LoadBalancersUpdateTagsFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if lb.Response.Response, err = future.GetResult(sender); err == nil && lb.Response.Response.StatusCode != http.StatusNoContent { + lb, err = client.UpdateTagsResponder(lb.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.LoadBalancersUpdateTagsFuture", "Result", lb.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.LoadBalancersUpdateTagsFuture", "Result", resp, "Failure sending request") - return - } - lb, err = client.UpdateTagsResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.LoadBalancersUpdateTagsFuture", "Result", resp, "Failure responding to request") } return } @@ -9789,12 +9051,11 @@ type LocalNetworkGatewayPropertiesFormat struct { // long-running operation. type LocalNetworkGatewaysCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future LocalNetworkGatewaysCreateOrUpdateFuture) Result(client LocalNetworkGatewaysClient) (lng LocalNetworkGateway, err error) { +func (future *LocalNetworkGatewaysCreateOrUpdateFuture) Result(client LocalNetworkGatewaysClient) (lng LocalNetworkGateway, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -9802,34 +9063,15 @@ func (future LocalNetworkGatewaysCreateOrUpdateFuture) Result(client LocalNetwor return } if !done { - return lng, azure.NewAsyncOpIncompleteError("network.LocalNetworkGatewaysCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - lng, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.LocalNetworkGatewaysCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if lng.Response.Response, err = future.GetResult(sender); err == nil && lng.Response.Response.StatusCode != http.StatusNoContent { + lng, err = client.CreateOrUpdateResponder(lng.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysCreateOrUpdateFuture", "Result", lng.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - lng, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -9838,12 +9080,11 @@ func (future LocalNetworkGatewaysCreateOrUpdateFuture) Result(client LocalNetwor // operation. type LocalNetworkGatewaysDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future LocalNetworkGatewaysDeleteFuture) Result(client LocalNetworkGatewaysClient) (ar autorest.Response, err error) { +func (future *LocalNetworkGatewaysDeleteFuture) Result(client LocalNetworkGatewaysClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -9851,35 +9092,10 @@ func (future LocalNetworkGatewaysDeleteFuture) Result(client LocalNetworkGateway return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.LocalNetworkGatewaysDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.LocalNetworkGatewaysDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysDeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -9887,12 +9103,11 @@ func (future LocalNetworkGatewaysDeleteFuture) Result(client LocalNetworkGateway // operation. type LocalNetworkGatewaysUpdateTagsFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future LocalNetworkGatewaysUpdateTagsFuture) Result(client LocalNetworkGatewaysClient) (lng LocalNetworkGateway, err error) { +func (future *LocalNetworkGatewaysUpdateTagsFuture) Result(client LocalNetworkGatewaysClient) (lng LocalNetworkGateway, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -9900,34 +9115,15 @@ func (future LocalNetworkGatewaysUpdateTagsFuture) Result(client LocalNetworkGat return } if !done { - return lng, azure.NewAsyncOpIncompleteError("network.LocalNetworkGatewaysUpdateTagsFuture") - } - if future.PollingMethod() == azure.PollingLocation { - lng, err = client.UpdateTagsResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysUpdateTagsFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.LocalNetworkGatewaysUpdateTagsFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if lng.Response.Response, err = future.GetResult(sender); err == nil && lng.Response.Response.StatusCode != http.StatusNoContent { + lng, err = client.UpdateTagsResponder(lng.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysUpdateTagsFuture", "Result", lng.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysUpdateTagsFuture", "Result", resp, "Failure sending request") - return - } - lng, err = client.UpdateTagsResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysUpdateTagsFuture", "Result", resp, "Failure responding to request") } return } @@ -10545,12 +9741,11 @@ type PacketCaptureResultProperties struct { // PacketCapturesCreateFuture an abstraction for monitoring and retrieving the results of a long-running operation. type PacketCapturesCreateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future PacketCapturesCreateFuture) Result(client PacketCapturesClient) (pcr PacketCaptureResult, err error) { +func (future *PacketCapturesCreateFuture) Result(client PacketCapturesClient) (pcr PacketCaptureResult, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -10558,34 +9753,15 @@ func (future PacketCapturesCreateFuture) Result(client PacketCapturesClient) (pc return } if !done { - return pcr, azure.NewAsyncOpIncompleteError("network.PacketCapturesCreateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - pcr, err = client.CreateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.PacketCapturesCreateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.PacketCapturesCreateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if pcr.Response.Response, err = future.GetResult(sender); err == nil && pcr.Response.Response.StatusCode != http.StatusNoContent { + pcr, err = client.CreateResponder(pcr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.PacketCapturesCreateFuture", "Result", pcr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.PacketCapturesCreateFuture", "Result", resp, "Failure sending request") - return - } - pcr, err = client.CreateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.PacketCapturesCreateFuture", "Result", resp, "Failure responding to request") } return } @@ -10593,12 +9769,11 @@ func (future PacketCapturesCreateFuture) Result(client PacketCapturesClient) (pc // PacketCapturesDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation. type PacketCapturesDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future PacketCapturesDeleteFuture) Result(client PacketCapturesClient) (ar autorest.Response, err error) { +func (future *PacketCapturesDeleteFuture) Result(client PacketCapturesClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -10606,35 +9781,10 @@ func (future PacketCapturesDeleteFuture) Result(client PacketCapturesClient) (ar return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.PacketCapturesDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.PacketCapturesDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.PacketCapturesDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.PacketCapturesDeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.PacketCapturesDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -10642,12 +9792,11 @@ func (future PacketCapturesDeleteFuture) Result(client PacketCapturesClient) (ar // operation. type PacketCapturesGetStatusFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future PacketCapturesGetStatusFuture) Result(client PacketCapturesClient) (pcqsr PacketCaptureQueryStatusResult, err error) { +func (future *PacketCapturesGetStatusFuture) Result(client PacketCapturesClient) (pcqsr PacketCaptureQueryStatusResult, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -10655,34 +9804,15 @@ func (future PacketCapturesGetStatusFuture) Result(client PacketCapturesClient) return } if !done { - return pcqsr, azure.NewAsyncOpIncompleteError("network.PacketCapturesGetStatusFuture") - } - if future.PollingMethod() == azure.PollingLocation { - pcqsr, err = client.GetStatusResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.PacketCapturesGetStatusFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.PacketCapturesGetStatusFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if pcqsr.Response.Response, err = future.GetResult(sender); err == nil && pcqsr.Response.Response.StatusCode != http.StatusNoContent { + pcqsr, err = client.GetStatusResponder(pcqsr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.PacketCapturesGetStatusFuture", "Result", pcqsr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.PacketCapturesGetStatusFuture", "Result", resp, "Failure sending request") - return - } - pcqsr, err = client.GetStatusResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.PacketCapturesGetStatusFuture", "Result", resp, "Failure responding to request") } return } @@ -10690,12 +9820,11 @@ func (future PacketCapturesGetStatusFuture) Result(client PacketCapturesClient) // PacketCapturesStopFuture an abstraction for monitoring and retrieving the results of a long-running operation. type PacketCapturesStopFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future PacketCapturesStopFuture) Result(client PacketCapturesClient) (ar autorest.Response, err error) { +func (future *PacketCapturesStopFuture) Result(client PacketCapturesClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -10703,35 +9832,10 @@ func (future PacketCapturesStopFuture) Result(client PacketCapturesClient) (ar a return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.PacketCapturesStopFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.StopResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.PacketCapturesStopFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.PacketCapturesStopFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.PacketCapturesStopFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.StopResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.PacketCapturesStopFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -11199,12 +10303,11 @@ type PublicIPAddressDNSSettings struct { // operation. type PublicIPAddressesCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future PublicIPAddressesCreateOrUpdateFuture) Result(client PublicIPAddressesClient) (pia PublicIPAddress, err error) { +func (future *PublicIPAddressesCreateOrUpdateFuture) Result(client PublicIPAddressesClient) (pia PublicIPAddress, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -11212,34 +10315,15 @@ func (future PublicIPAddressesCreateOrUpdateFuture) Result(client PublicIPAddres return } if !done { - return pia, azure.NewAsyncOpIncompleteError("network.PublicIPAddressesCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - pia, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.PublicIPAddressesCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.PublicIPAddressesCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if pia.Response.Response, err = future.GetResult(sender); err == nil && pia.Response.Response.StatusCode != http.StatusNoContent { + pia, err = client.CreateOrUpdateResponder(pia.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.PublicIPAddressesCreateOrUpdateFuture", "Result", pia.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.PublicIPAddressesCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - pia, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.PublicIPAddressesCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -11248,12 +10332,11 @@ func (future PublicIPAddressesCreateOrUpdateFuture) Result(client PublicIPAddres // operation. type PublicIPAddressesDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future PublicIPAddressesDeleteFuture) Result(client PublicIPAddressesClient) (ar autorest.Response, err error) { +func (future *PublicIPAddressesDeleteFuture) Result(client PublicIPAddressesClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -11261,35 +10344,10 @@ func (future PublicIPAddressesDeleteFuture) Result(client PublicIPAddressesClien return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.PublicIPAddressesDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.PublicIPAddressesDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.PublicIPAddressesDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.PublicIPAddressesDeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.PublicIPAddressesDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -11297,12 +10355,11 @@ func (future PublicIPAddressesDeleteFuture) Result(client PublicIPAddressesClien // operation. type PublicIPAddressesUpdateTagsFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future PublicIPAddressesUpdateTagsFuture) Result(client PublicIPAddressesClient) (pia PublicIPAddress, err error) { +func (future *PublicIPAddressesUpdateTagsFuture) Result(client PublicIPAddressesClient) (pia PublicIPAddress, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -11310,34 +10367,15 @@ func (future PublicIPAddressesUpdateTagsFuture) Result(client PublicIPAddressesC return } if !done { - return pia, azure.NewAsyncOpIncompleteError("network.PublicIPAddressesUpdateTagsFuture") - } - if future.PollingMethod() == azure.PollingLocation { - pia, err = client.UpdateTagsResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.PublicIPAddressesUpdateTagsFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.PublicIPAddressesUpdateTagsFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if pia.Response.Response, err = future.GetResult(sender); err == nil && pia.Response.Response.StatusCode != http.StatusNoContent { + pia, err = client.UpdateTagsResponder(pia.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.PublicIPAddressesUpdateTagsFuture", "Result", pia.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.PublicIPAddressesUpdateTagsFuture", "Result", resp, "Failure sending request") - return - } - pia, err = client.UpdateTagsResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.PublicIPAddressesUpdateTagsFuture", "Result", resp, "Failure responding to request") } return } @@ -12142,12 +11180,11 @@ type RouteFilterRulePropertiesFormat struct { // operation. type RouteFilterRulesCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future RouteFilterRulesCreateOrUpdateFuture) Result(client RouteFilterRulesClient) (rfr RouteFilterRule, err error) { +func (future *RouteFilterRulesCreateOrUpdateFuture) Result(client RouteFilterRulesClient) (rfr RouteFilterRule, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -12155,34 +11192,15 @@ func (future RouteFilterRulesCreateOrUpdateFuture) Result(client RouteFilterRule return } if !done { - return rfr, azure.NewAsyncOpIncompleteError("network.RouteFilterRulesCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - rfr, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RouteFilterRulesCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.RouteFilterRulesCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if rfr.Response.Response, err = future.GetResult(sender); err == nil && rfr.Response.Response.StatusCode != http.StatusNoContent { + rfr, err = client.CreateOrUpdateResponder(rfr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.RouteFilterRulesCreateOrUpdateFuture", "Result", rfr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RouteFilterRulesCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - rfr, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RouteFilterRulesCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -12191,12 +11209,11 @@ func (future RouteFilterRulesCreateOrUpdateFuture) Result(client RouteFilterRule // operation. type RouteFilterRulesDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future RouteFilterRulesDeleteFuture) Result(client RouteFilterRulesClient) (ar autorest.Response, err error) { +func (future *RouteFilterRulesDeleteFuture) Result(client RouteFilterRulesClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -12204,35 +11221,10 @@ func (future RouteFilterRulesDeleteFuture) Result(client RouteFilterRulesClient) return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.RouteFilterRulesDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RouteFilterRulesDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.RouteFilterRulesDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RouteFilterRulesDeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RouteFilterRulesDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -12240,12 +11232,11 @@ func (future RouteFilterRulesDeleteFuture) Result(client RouteFilterRulesClient) // operation. type RouteFilterRulesUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future RouteFilterRulesUpdateFuture) Result(client RouteFilterRulesClient) (rfr RouteFilterRule, err error) { +func (future *RouteFilterRulesUpdateFuture) Result(client RouteFilterRulesClient) (rfr RouteFilterRule, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -12253,34 +11244,15 @@ func (future RouteFilterRulesUpdateFuture) Result(client RouteFilterRulesClient) return } if !done { - return rfr, azure.NewAsyncOpIncompleteError("network.RouteFilterRulesUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - rfr, err = client.UpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RouteFilterRulesUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.RouteFilterRulesUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if rfr.Response.Response, err = future.GetResult(sender); err == nil && rfr.Response.Response.StatusCode != http.StatusNoContent { + rfr, err = client.UpdateResponder(rfr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.RouteFilterRulesUpdateFuture", "Result", rfr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RouteFilterRulesUpdateFuture", "Result", resp, "Failure sending request") - return - } - rfr, err = client.UpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RouteFilterRulesUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -12289,12 +11261,11 @@ func (future RouteFilterRulesUpdateFuture) Result(client RouteFilterRulesClient) // operation. type RouteFiltersCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future RouteFiltersCreateOrUpdateFuture) Result(client RouteFiltersClient) (rf RouteFilter, err error) { +func (future *RouteFiltersCreateOrUpdateFuture) Result(client RouteFiltersClient) (rf RouteFilter, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -12302,34 +11273,15 @@ func (future RouteFiltersCreateOrUpdateFuture) Result(client RouteFiltersClient) return } if !done { - return rf, azure.NewAsyncOpIncompleteError("network.RouteFiltersCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - rf, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RouteFiltersCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.RouteFiltersCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if rf.Response.Response, err = future.GetResult(sender); err == nil && rf.Response.Response.StatusCode != http.StatusNoContent { + rf, err = client.CreateOrUpdateResponder(rf.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.RouteFiltersCreateOrUpdateFuture", "Result", rf.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RouteFiltersCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - rf, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RouteFiltersCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -12337,12 +11289,11 @@ func (future RouteFiltersCreateOrUpdateFuture) Result(client RouteFiltersClient) // RouteFiltersDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation. type RouteFiltersDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future RouteFiltersDeleteFuture) Result(client RouteFiltersClient) (ar autorest.Response, err error) { +func (future *RouteFiltersDeleteFuture) Result(client RouteFiltersClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -12350,47 +11301,21 @@ func (future RouteFiltersDeleteFuture) Result(client RouteFiltersClient) (ar aut return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.RouteFiltersDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RouteFiltersDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.RouteFiltersDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RouteFiltersDeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RouteFiltersDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } // RouteFiltersUpdateFuture an abstraction for monitoring and retrieving the results of a long-running operation. type RouteFiltersUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future RouteFiltersUpdateFuture) Result(client RouteFiltersClient) (rf RouteFilter, err error) { +func (future *RouteFiltersUpdateFuture) Result(client RouteFiltersClient) (rf RouteFilter, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -12398,34 +11323,15 @@ func (future RouteFiltersUpdateFuture) Result(client RouteFiltersClient) (rf Rou return } if !done { - return rf, azure.NewAsyncOpIncompleteError("network.RouteFiltersUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - rf, err = client.UpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RouteFiltersUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.RouteFiltersUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if rf.Response.Response, err = future.GetResult(sender); err == nil && rf.Response.Response.StatusCode != http.StatusNoContent { + rf, err = client.UpdateResponder(rf.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.RouteFiltersUpdateFuture", "Result", rf.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RouteFiltersUpdateFuture", "Result", resp, "Failure sending request") - return - } - rf, err = client.UpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RouteFiltersUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -12547,12 +11453,11 @@ type RoutePropertiesFormat struct { // RoutesCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a long-running operation. type RoutesCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future RoutesCreateOrUpdateFuture) Result(client RoutesClient) (r Route, err error) { +func (future *RoutesCreateOrUpdateFuture) Result(client RoutesClient) (r Route, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -12560,34 +11465,15 @@ func (future RoutesCreateOrUpdateFuture) Result(client RoutesClient) (r Route, e return } if !done { - return r, azure.NewAsyncOpIncompleteError("network.RoutesCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - r, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RoutesCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.RoutesCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if r.Response.Response, err = future.GetResult(sender); err == nil && r.Response.Response.StatusCode != http.StatusNoContent { + r, err = client.CreateOrUpdateResponder(r.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.RoutesCreateOrUpdateFuture", "Result", r.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RoutesCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - r, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RoutesCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -12595,12 +11481,11 @@ func (future RoutesCreateOrUpdateFuture) Result(client RoutesClient) (r Route, e // RoutesDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation. type RoutesDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future RoutesDeleteFuture) Result(client RoutesClient) (ar autorest.Response, err error) { +func (future *RoutesDeleteFuture) Result(client RoutesClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -12608,35 +11493,10 @@ func (future RoutesDeleteFuture) Result(client RoutesClient) (ar autorest.Respon return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.RoutesDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RoutesDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.RoutesDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RoutesDeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RoutesDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -12882,12 +11742,11 @@ type RouteTablePropertiesFormat struct { // operation. type RouteTablesCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future RouteTablesCreateOrUpdateFuture) Result(client RouteTablesClient) (rt RouteTable, err error) { +func (future *RouteTablesCreateOrUpdateFuture) Result(client RouteTablesClient) (rt RouteTable, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -12895,34 +11754,15 @@ func (future RouteTablesCreateOrUpdateFuture) Result(client RouteTablesClient) ( return } if !done { - return rt, azure.NewAsyncOpIncompleteError("network.RouteTablesCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - rt, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RouteTablesCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.RouteTablesCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if rt.Response.Response, err = future.GetResult(sender); err == nil && rt.Response.Response.StatusCode != http.StatusNoContent { + rt, err = client.CreateOrUpdateResponder(rt.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.RouteTablesCreateOrUpdateFuture", "Result", rt.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RouteTablesCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - rt, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RouteTablesCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -12930,12 +11770,11 @@ func (future RouteTablesCreateOrUpdateFuture) Result(client RouteTablesClient) ( // RouteTablesDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation. type RouteTablesDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future RouteTablesDeleteFuture) Result(client RouteTablesClient) (ar autorest.Response, err error) { +func (future *RouteTablesDeleteFuture) Result(client RouteTablesClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -12943,35 +11782,10 @@ func (future RouteTablesDeleteFuture) Result(client RouteTablesClient) (ar autor return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.RouteTablesDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RouteTablesDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.RouteTablesDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RouteTablesDeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RouteTablesDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -12979,12 +11793,11 @@ func (future RouteTablesDeleteFuture) Result(client RouteTablesClient) (ar autor // operation. type RouteTablesUpdateTagsFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future RouteTablesUpdateTagsFuture) Result(client RouteTablesClient) (rt RouteTable, err error) { +func (future *RouteTablesUpdateTagsFuture) Result(client RouteTablesClient) (rt RouteTable, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -12992,34 +11805,15 @@ func (future RouteTablesUpdateTagsFuture) Result(client RouteTablesClient) (rt R return } if !done { - return rt, azure.NewAsyncOpIncompleteError("network.RouteTablesUpdateTagsFuture") - } - if future.PollingMethod() == azure.PollingLocation { - rt, err = client.UpdateTagsResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RouteTablesUpdateTagsFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.RouteTablesUpdateTagsFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if rt.Response.Response, err = future.GetResult(sender); err == nil && rt.Response.Response.StatusCode != http.StatusNoContent { + rt, err = client.UpdateTagsResponder(rt.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.RouteTablesUpdateTagsFuture", "Result", rt.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RouteTablesUpdateTagsFuture", "Result", resp, "Failure sending request") - return - } - rt, err = client.UpdateTagsResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.RouteTablesUpdateTagsFuture", "Result", resp, "Failure responding to request") } return } @@ -13277,12 +12071,11 @@ type SecurityGroupPropertiesFormat struct { // operation. type SecurityGroupsCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future SecurityGroupsCreateOrUpdateFuture) Result(client SecurityGroupsClient) (sg SecurityGroup, err error) { +func (future *SecurityGroupsCreateOrUpdateFuture) Result(client SecurityGroupsClient) (sg SecurityGroup, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -13290,34 +12083,15 @@ func (future SecurityGroupsCreateOrUpdateFuture) Result(client SecurityGroupsCli return } if !done { - return sg, azure.NewAsyncOpIncompleteError("network.SecurityGroupsCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - sg, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.SecurityGroupsCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.SecurityGroupsCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if sg.Response.Response, err = future.GetResult(sender); err == nil && sg.Response.Response.StatusCode != http.StatusNoContent { + sg, err = client.CreateOrUpdateResponder(sg.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.SecurityGroupsCreateOrUpdateFuture", "Result", sg.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.SecurityGroupsCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - sg, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.SecurityGroupsCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -13325,12 +12099,11 @@ func (future SecurityGroupsCreateOrUpdateFuture) Result(client SecurityGroupsCli // SecurityGroupsDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation. type SecurityGroupsDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future SecurityGroupsDeleteFuture) Result(client SecurityGroupsClient) (ar autorest.Response, err error) { +func (future *SecurityGroupsDeleteFuture) Result(client SecurityGroupsClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -13338,35 +12111,10 @@ func (future SecurityGroupsDeleteFuture) Result(client SecurityGroupsClient) (ar return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.SecurityGroupsDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.SecurityGroupsDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.SecurityGroupsDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.SecurityGroupsDeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.SecurityGroupsDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -13374,12 +12122,11 @@ func (future SecurityGroupsDeleteFuture) Result(client SecurityGroupsClient) (ar // operation. type SecurityGroupsUpdateTagsFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future SecurityGroupsUpdateTagsFuture) Result(client SecurityGroupsClient) (sg SecurityGroup, err error) { +func (future *SecurityGroupsUpdateTagsFuture) Result(client SecurityGroupsClient) (sg SecurityGroup, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -13387,34 +12134,15 @@ func (future SecurityGroupsUpdateTagsFuture) Result(client SecurityGroupsClient) return } if !done { - return sg, azure.NewAsyncOpIncompleteError("network.SecurityGroupsUpdateTagsFuture") - } - if future.PollingMethod() == azure.PollingLocation { - sg, err = client.UpdateTagsResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.SecurityGroupsUpdateTagsFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.SecurityGroupsUpdateTagsFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if sg.Response.Response, err = future.GetResult(sender); err == nil && sg.Response.Response.StatusCode != http.StatusNoContent { + sg, err = client.UpdateTagsResponder(sg.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.SecurityGroupsUpdateTagsFuture", "Result", sg.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.SecurityGroupsUpdateTagsFuture", "Result", resp, "Failure sending request") - return - } - sg, err = client.UpdateTagsResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.SecurityGroupsUpdateTagsFuture", "Result", resp, "Failure responding to request") } return } @@ -13667,12 +12395,11 @@ type SecurityRulePropertiesFormat struct { // operation. type SecurityRulesCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future SecurityRulesCreateOrUpdateFuture) Result(client SecurityRulesClient) (sr SecurityRule, err error) { +func (future *SecurityRulesCreateOrUpdateFuture) Result(client SecurityRulesClient) (sr SecurityRule, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -13680,34 +12407,15 @@ func (future SecurityRulesCreateOrUpdateFuture) Result(client SecurityRulesClien return } if !done { - return sr, azure.NewAsyncOpIncompleteError("network.SecurityRulesCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - sr, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.SecurityRulesCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.SecurityRulesCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if sr.Response.Response, err = future.GetResult(sender); err == nil && sr.Response.Response.StatusCode != http.StatusNoContent { + sr, err = client.CreateOrUpdateResponder(sr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.SecurityRulesCreateOrUpdateFuture", "Result", sr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.SecurityRulesCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - sr, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.SecurityRulesCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -13715,12 +12423,11 @@ func (future SecurityRulesCreateOrUpdateFuture) Result(client SecurityRulesClien // SecurityRulesDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation. type SecurityRulesDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future SecurityRulesDeleteFuture) Result(client SecurityRulesClient) (ar autorest.Response, err error) { +func (future *SecurityRulesDeleteFuture) Result(client SecurityRulesClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -13728,35 +12435,10 @@ func (future SecurityRulesDeleteFuture) Result(client SecurityRulesClient) (ar a return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.SecurityRulesDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.SecurityRulesDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.SecurityRulesDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.SecurityRulesDeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.SecurityRulesDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -13990,12 +12672,11 @@ type SubnetPropertiesFormat struct { // operation. type SubnetsCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future SubnetsCreateOrUpdateFuture) Result(client SubnetsClient) (s Subnet, err error) { +func (future *SubnetsCreateOrUpdateFuture) Result(client SubnetsClient) (s Subnet, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -14003,34 +12684,15 @@ func (future SubnetsCreateOrUpdateFuture) Result(client SubnetsClient) (s Subnet return } if !done { - return s, azure.NewAsyncOpIncompleteError("network.SubnetsCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - s, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.SubnetsCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.SubnetsCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if s.Response.Response, err = future.GetResult(sender); err == nil && s.Response.Response.StatusCode != http.StatusNoContent { + s, err = client.CreateOrUpdateResponder(s.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.SubnetsCreateOrUpdateFuture", "Result", s.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.SubnetsCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - s, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.SubnetsCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -14038,12 +12700,11 @@ func (future SubnetsCreateOrUpdateFuture) Result(client SubnetsClient) (s Subnet // SubnetsDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation. type SubnetsDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future SubnetsDeleteFuture) Result(client SubnetsClient) (ar autorest.Response, err error) { +func (future *SubnetsDeleteFuture) Result(client SubnetsClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -14051,35 +12712,10 @@ func (future SubnetsDeleteFuture) Result(client SubnetsClient) (ar autorest.Resp return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.SubnetsDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.SubnetsDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.SubnetsDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.SubnetsDeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.SubnetsDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -15116,12 +13752,11 @@ type VirtualNetworkGatewayConnectionPropertiesFormat struct { // a long-running operation. type VirtualNetworkGatewayConnectionsCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualNetworkGatewayConnectionsCreateOrUpdateFuture) Result(client VirtualNetworkGatewayConnectionsClient) (vngc VirtualNetworkGatewayConnection, err error) { +func (future *VirtualNetworkGatewayConnectionsCreateOrUpdateFuture) Result(client VirtualNetworkGatewayConnectionsClient) (vngc VirtualNetworkGatewayConnection, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -15129,34 +13764,15 @@ func (future VirtualNetworkGatewayConnectionsCreateOrUpdateFuture) Result(client return } if !done { - return vngc, azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewayConnectionsCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - vngc, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewayConnectionsCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if vngc.Response.Response, err = future.GetResult(sender); err == nil && vngc.Response.Response.StatusCode != http.StatusNoContent { + vngc, err = client.CreateOrUpdateResponder(vngc.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsCreateOrUpdateFuture", "Result", vngc.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - vngc, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -15165,12 +13781,11 @@ func (future VirtualNetworkGatewayConnectionsCreateOrUpdateFuture) Result(client // long-running operation. type VirtualNetworkGatewayConnectionsDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualNetworkGatewayConnectionsDeleteFuture) Result(client VirtualNetworkGatewayConnectionsClient) (ar autorest.Response, err error) { +func (future *VirtualNetworkGatewayConnectionsDeleteFuture) Result(client VirtualNetworkGatewayConnectionsClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -15178,35 +13793,10 @@ func (future VirtualNetworkGatewayConnectionsDeleteFuture) Result(client Virtual return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewayConnectionsDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewayConnectionsDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsDeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -15214,12 +13804,11 @@ func (future VirtualNetworkGatewayConnectionsDeleteFuture) Result(client Virtual // a long-running operation. type VirtualNetworkGatewayConnectionsResetSharedKeyFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualNetworkGatewayConnectionsResetSharedKeyFuture) Result(client VirtualNetworkGatewayConnectionsClient) (crsk ConnectionResetSharedKey, err error) { +func (future *VirtualNetworkGatewayConnectionsResetSharedKeyFuture) Result(client VirtualNetworkGatewayConnectionsClient) (crsk ConnectionResetSharedKey, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -15227,34 +13816,15 @@ func (future VirtualNetworkGatewayConnectionsResetSharedKeyFuture) Result(client return } if !done { - return crsk, azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewayConnectionsResetSharedKeyFuture") - } - if future.PollingMethod() == azure.PollingLocation { - crsk, err = client.ResetSharedKeyResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsResetSharedKeyFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewayConnectionsResetSharedKeyFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if crsk.Response.Response, err = future.GetResult(sender); err == nil && crsk.Response.Response.StatusCode != http.StatusNoContent { + crsk, err = client.ResetSharedKeyResponder(crsk.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsResetSharedKeyFuture", "Result", crsk.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsResetSharedKeyFuture", "Result", resp, "Failure sending request") - return - } - crsk, err = client.ResetSharedKeyResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsResetSharedKeyFuture", "Result", resp, "Failure responding to request") } return } @@ -15263,12 +13833,11 @@ func (future VirtualNetworkGatewayConnectionsResetSharedKeyFuture) Result(client // long-running operation. type VirtualNetworkGatewayConnectionsSetSharedKeyFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualNetworkGatewayConnectionsSetSharedKeyFuture) Result(client VirtualNetworkGatewayConnectionsClient) (csk ConnectionSharedKey, err error) { +func (future *VirtualNetworkGatewayConnectionsSetSharedKeyFuture) Result(client VirtualNetworkGatewayConnectionsClient) (csk ConnectionSharedKey, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -15276,34 +13845,15 @@ func (future VirtualNetworkGatewayConnectionsSetSharedKeyFuture) Result(client V return } if !done { - return csk, azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewayConnectionsSetSharedKeyFuture") - } - if future.PollingMethod() == azure.PollingLocation { - csk, err = client.SetSharedKeyResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsSetSharedKeyFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewayConnectionsSetSharedKeyFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if csk.Response.Response, err = future.GetResult(sender); err == nil && csk.Response.Response.StatusCode != http.StatusNoContent { + csk, err = client.SetSharedKeyResponder(csk.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsSetSharedKeyFuture", "Result", csk.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsSetSharedKeyFuture", "Result", resp, "Failure sending request") - return - } - csk, err = client.SetSharedKeyResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsSetSharedKeyFuture", "Result", resp, "Failure responding to request") } return } @@ -15312,12 +13862,11 @@ func (future VirtualNetworkGatewayConnectionsSetSharedKeyFuture) Result(client V // long-running operation. type VirtualNetworkGatewayConnectionsUpdateTagsFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualNetworkGatewayConnectionsUpdateTagsFuture) Result(client VirtualNetworkGatewayConnectionsClient) (vngcle VirtualNetworkGatewayConnectionListEntity, err error) { +func (future *VirtualNetworkGatewayConnectionsUpdateTagsFuture) Result(client VirtualNetworkGatewayConnectionsClient) (vngcle VirtualNetworkGatewayConnectionListEntity, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -15325,34 +13874,15 @@ func (future VirtualNetworkGatewayConnectionsUpdateTagsFuture) Result(client Vir return } if !done { - return vngcle, azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewayConnectionsUpdateTagsFuture") - } - if future.PollingMethod() == azure.PollingLocation { - vngcle, err = client.UpdateTagsResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsUpdateTagsFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewayConnectionsUpdateTagsFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if vngcle.Response.Response, err = future.GetResult(sender); err == nil && vngcle.Response.Response.StatusCode != http.StatusNoContent { + vngcle, err = client.UpdateTagsResponder(vngcle.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsUpdateTagsFuture", "Result", vngcle.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsUpdateTagsFuture", "Result", resp, "Failure sending request") - return - } - vngcle, err = client.UpdateTagsResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsUpdateTagsFuture", "Result", resp, "Failure responding to request") } return } @@ -15687,12 +14217,11 @@ type VirtualNetworkGatewayPropertiesFormat struct { // long-running operation. type VirtualNetworkGatewaysCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualNetworkGatewaysCreateOrUpdateFuture) Result(client VirtualNetworkGatewaysClient) (vng VirtualNetworkGateway, err error) { +func (future *VirtualNetworkGatewaysCreateOrUpdateFuture) Result(client VirtualNetworkGatewaysClient) (vng VirtualNetworkGateway, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -15700,34 +14229,15 @@ func (future VirtualNetworkGatewaysCreateOrUpdateFuture) Result(client VirtualNe return } if !done { - return vng, azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - vng, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if vng.Response.Response, err = future.GetResult(sender); err == nil && vng.Response.Response.StatusCode != http.StatusNoContent { + vng, err = client.CreateOrUpdateResponder(vng.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysCreateOrUpdateFuture", "Result", vng.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - vng, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -15736,12 +14246,11 @@ func (future VirtualNetworkGatewaysCreateOrUpdateFuture) Result(client VirtualNe // operation. type VirtualNetworkGatewaysDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualNetworkGatewaysDeleteFuture) Result(client VirtualNetworkGatewaysClient) (ar autorest.Response, err error) { +func (future *VirtualNetworkGatewaysDeleteFuture) Result(client VirtualNetworkGatewaysClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -15749,35 +14258,10 @@ func (future VirtualNetworkGatewaysDeleteFuture) Result(client VirtualNetworkGat return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysDeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -15785,12 +14269,11 @@ func (future VirtualNetworkGatewaysDeleteFuture) Result(client VirtualNetworkGat // a long-running operation. type VirtualNetworkGatewaysGeneratevpnclientpackageFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualNetworkGatewaysGeneratevpnclientpackageFuture) Result(client VirtualNetworkGatewaysClient) (s String, err error) { +func (future *VirtualNetworkGatewaysGeneratevpnclientpackageFuture) Result(client VirtualNetworkGatewaysClient) (s String, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -15798,34 +14281,15 @@ func (future VirtualNetworkGatewaysGeneratevpnclientpackageFuture) Result(client return } if !done { - return s, azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysGeneratevpnclientpackageFuture") - } - if future.PollingMethod() == azure.PollingLocation { - s, err = client.GeneratevpnclientpackageResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGeneratevpnclientpackageFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysGeneratevpnclientpackageFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if s.Response.Response, err = future.GetResult(sender); err == nil && s.Response.Response.StatusCode != http.StatusNoContent { + s, err = client.GeneratevpnclientpackageResponder(s.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGeneratevpnclientpackageFuture", "Result", s.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGeneratevpnclientpackageFuture", "Result", resp, "Failure sending request") - return - } - s, err = client.GeneratevpnclientpackageResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGeneratevpnclientpackageFuture", "Result", resp, "Failure responding to request") } return } @@ -15834,12 +14298,11 @@ func (future VirtualNetworkGatewaysGeneratevpnclientpackageFuture) Result(client // long-running operation. type VirtualNetworkGatewaysGenerateVpnProfileFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualNetworkGatewaysGenerateVpnProfileFuture) Result(client VirtualNetworkGatewaysClient) (s String, err error) { +func (future *VirtualNetworkGatewaysGenerateVpnProfileFuture) Result(client VirtualNetworkGatewaysClient) (s String, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -15847,34 +14310,15 @@ func (future VirtualNetworkGatewaysGenerateVpnProfileFuture) Result(client Virtu return } if !done { - return s, azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysGenerateVpnProfileFuture") - } - if future.PollingMethod() == azure.PollingLocation { - s, err = client.GenerateVpnProfileResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGenerateVpnProfileFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysGenerateVpnProfileFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if s.Response.Response, err = future.GetResult(sender); err == nil && s.Response.Response.StatusCode != http.StatusNoContent { + s, err = client.GenerateVpnProfileResponder(s.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGenerateVpnProfileFuture", "Result", s.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGenerateVpnProfileFuture", "Result", resp, "Failure sending request") - return - } - s, err = client.GenerateVpnProfileResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGenerateVpnProfileFuture", "Result", resp, "Failure responding to request") } return } @@ -15883,12 +14327,11 @@ func (future VirtualNetworkGatewaysGenerateVpnProfileFuture) Result(client Virtu // long-running operation. type VirtualNetworkGatewaysGetAdvertisedRoutesFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualNetworkGatewaysGetAdvertisedRoutesFuture) Result(client VirtualNetworkGatewaysClient) (grlr GatewayRouteListResult, err error) { +func (future *VirtualNetworkGatewaysGetAdvertisedRoutesFuture) Result(client VirtualNetworkGatewaysClient) (grlr GatewayRouteListResult, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -15896,34 +14339,15 @@ func (future VirtualNetworkGatewaysGetAdvertisedRoutesFuture) Result(client Virt return } if !done { - return grlr, azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysGetAdvertisedRoutesFuture") - } - if future.PollingMethod() == azure.PollingLocation { - grlr, err = client.GetAdvertisedRoutesResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGetAdvertisedRoutesFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysGetAdvertisedRoutesFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if grlr.Response.Response, err = future.GetResult(sender); err == nil && grlr.Response.Response.StatusCode != http.StatusNoContent { + grlr, err = client.GetAdvertisedRoutesResponder(grlr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGetAdvertisedRoutesFuture", "Result", grlr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGetAdvertisedRoutesFuture", "Result", resp, "Failure sending request") - return - } - grlr, err = client.GetAdvertisedRoutesResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGetAdvertisedRoutesFuture", "Result", resp, "Failure responding to request") } return } @@ -15932,12 +14356,11 @@ func (future VirtualNetworkGatewaysGetAdvertisedRoutesFuture) Result(client Virt // long-running operation. type VirtualNetworkGatewaysGetBgpPeerStatusFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualNetworkGatewaysGetBgpPeerStatusFuture) Result(client VirtualNetworkGatewaysClient) (bpslr BgpPeerStatusListResult, err error) { +func (future *VirtualNetworkGatewaysGetBgpPeerStatusFuture) Result(client VirtualNetworkGatewaysClient) (bpslr BgpPeerStatusListResult, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -15945,34 +14368,15 @@ func (future VirtualNetworkGatewaysGetBgpPeerStatusFuture) Result(client Virtual return } if !done { - return bpslr, azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysGetBgpPeerStatusFuture") - } - if future.PollingMethod() == azure.PollingLocation { - bpslr, err = client.GetBgpPeerStatusResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGetBgpPeerStatusFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysGetBgpPeerStatusFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if bpslr.Response.Response, err = future.GetResult(sender); err == nil && bpslr.Response.Response.StatusCode != http.StatusNoContent { + bpslr, err = client.GetBgpPeerStatusResponder(bpslr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGetBgpPeerStatusFuture", "Result", bpslr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGetBgpPeerStatusFuture", "Result", resp, "Failure sending request") - return - } - bpslr, err = client.GetBgpPeerStatusResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGetBgpPeerStatusFuture", "Result", resp, "Failure responding to request") } return } @@ -15981,12 +14385,11 @@ func (future VirtualNetworkGatewaysGetBgpPeerStatusFuture) Result(client Virtual // long-running operation. type VirtualNetworkGatewaysGetLearnedRoutesFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualNetworkGatewaysGetLearnedRoutesFuture) Result(client VirtualNetworkGatewaysClient) (grlr GatewayRouteListResult, err error) { +func (future *VirtualNetworkGatewaysGetLearnedRoutesFuture) Result(client VirtualNetworkGatewaysClient) (grlr GatewayRouteListResult, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -15994,34 +14397,15 @@ func (future VirtualNetworkGatewaysGetLearnedRoutesFuture) Result(client Virtual return } if !done { - return grlr, azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysGetLearnedRoutesFuture") - } - if future.PollingMethod() == azure.PollingLocation { - grlr, err = client.GetLearnedRoutesResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGetLearnedRoutesFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysGetLearnedRoutesFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if grlr.Response.Response, err = future.GetResult(sender); err == nil && grlr.Response.Response.StatusCode != http.StatusNoContent { + grlr, err = client.GetLearnedRoutesResponder(grlr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGetLearnedRoutesFuture", "Result", grlr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGetLearnedRoutesFuture", "Result", resp, "Failure sending request") - return - } - grlr, err = client.GetLearnedRoutesResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGetLearnedRoutesFuture", "Result", resp, "Failure responding to request") } return } @@ -16030,12 +14414,11 @@ func (future VirtualNetworkGatewaysGetLearnedRoutesFuture) Result(client Virtual // a long-running operation. type VirtualNetworkGatewaysGetVpnProfilePackageURLFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualNetworkGatewaysGetVpnProfilePackageURLFuture) Result(client VirtualNetworkGatewaysClient) (s String, err error) { +func (future *VirtualNetworkGatewaysGetVpnProfilePackageURLFuture) Result(client VirtualNetworkGatewaysClient) (s String, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -16043,34 +14426,15 @@ func (future VirtualNetworkGatewaysGetVpnProfilePackageURLFuture) Result(client return } if !done { - return s, azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysGetVpnProfilePackageURLFuture") - } - if future.PollingMethod() == azure.PollingLocation { - s, err = client.GetVpnProfilePackageURLResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGetVpnProfilePackageURLFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysGetVpnProfilePackageURLFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if s.Response.Response, err = future.GetResult(sender); err == nil && s.Response.Response.StatusCode != http.StatusNoContent { + s, err = client.GetVpnProfilePackageURLResponder(s.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGetVpnProfilePackageURLFuture", "Result", s.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGetVpnProfilePackageURLFuture", "Result", resp, "Failure sending request") - return - } - s, err = client.GetVpnProfilePackageURLResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGetVpnProfilePackageURLFuture", "Result", resp, "Failure responding to request") } return } @@ -16089,12 +14453,11 @@ type VirtualNetworkGatewaySku struct { // operation. type VirtualNetworkGatewaysResetFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualNetworkGatewaysResetFuture) Result(client VirtualNetworkGatewaysClient) (vng VirtualNetworkGateway, err error) { +func (future *VirtualNetworkGatewaysResetFuture) Result(client VirtualNetworkGatewaysClient) (vng VirtualNetworkGateway, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -16102,34 +14465,15 @@ func (future VirtualNetworkGatewaysResetFuture) Result(client VirtualNetworkGate return } if !done { - return vng, azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysResetFuture") - } - if future.PollingMethod() == azure.PollingLocation { - vng, err = client.ResetResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysResetFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysResetFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if vng.Response.Response, err = future.GetResult(sender); err == nil && vng.Response.Response.StatusCode != http.StatusNoContent { + vng, err = client.ResetResponder(vng.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysResetFuture", "Result", vng.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysResetFuture", "Result", resp, "Failure sending request") - return - } - vng, err = client.ResetResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysResetFuture", "Result", resp, "Failure responding to request") } return } @@ -16138,12 +14482,11 @@ func (future VirtualNetworkGatewaysResetFuture) Result(client VirtualNetworkGate // long-running operation. type VirtualNetworkGatewaysUpdateTagsFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualNetworkGatewaysUpdateTagsFuture) Result(client VirtualNetworkGatewaysClient) (vng VirtualNetworkGateway, err error) { +func (future *VirtualNetworkGatewaysUpdateTagsFuture) Result(client VirtualNetworkGatewaysClient) (vng VirtualNetworkGateway, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -16151,34 +14494,15 @@ func (future VirtualNetworkGatewaysUpdateTagsFuture) Result(client VirtualNetwor return } if !done { - return vng, azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysUpdateTagsFuture") - } - if future.PollingMethod() == azure.PollingLocation { - vng, err = client.UpdateTagsResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysUpdateTagsFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysUpdateTagsFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if vng.Response.Response, err = future.GetResult(sender); err == nil && vng.Response.Response.StatusCode != http.StatusNoContent { + vng, err = client.UpdateTagsResponder(vng.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysUpdateTagsFuture", "Result", vng.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysUpdateTagsFuture", "Result", resp, "Failure sending request") - return - } - vng, err = client.UpdateTagsResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysUpdateTagsFuture", "Result", resp, "Failure responding to request") } return } @@ -16596,12 +14920,11 @@ type VirtualNetworkPeeringPropertiesFormat struct { // long-running operation. type VirtualNetworkPeeringsCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualNetworkPeeringsCreateOrUpdateFuture) Result(client VirtualNetworkPeeringsClient) (vnp VirtualNetworkPeering, err error) { +func (future *VirtualNetworkPeeringsCreateOrUpdateFuture) Result(client VirtualNetworkPeeringsClient) (vnp VirtualNetworkPeering, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -16609,34 +14932,15 @@ func (future VirtualNetworkPeeringsCreateOrUpdateFuture) Result(client VirtualNe return } if !done { - return vnp, azure.NewAsyncOpIncompleteError("network.VirtualNetworkPeeringsCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - vnp, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkPeeringsCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkPeeringsCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if vnp.Response.Response, err = future.GetResult(sender); err == nil && vnp.Response.Response.StatusCode != http.StatusNoContent { + vnp, err = client.CreateOrUpdateResponder(vnp.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.VirtualNetworkPeeringsCreateOrUpdateFuture", "Result", vnp.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkPeeringsCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - vnp, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkPeeringsCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -16645,12 +14949,11 @@ func (future VirtualNetworkPeeringsCreateOrUpdateFuture) Result(client VirtualNe // operation. type VirtualNetworkPeeringsDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualNetworkPeeringsDeleteFuture) Result(client VirtualNetworkPeeringsClient) (ar autorest.Response, err error) { +func (future *VirtualNetworkPeeringsDeleteFuture) Result(client VirtualNetworkPeeringsClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -16658,35 +14961,10 @@ func (future VirtualNetworkPeeringsDeleteFuture) Result(client VirtualNetworkPee return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.VirtualNetworkPeeringsDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkPeeringsDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkPeeringsDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkPeeringsDeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworkPeeringsDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -16714,12 +14992,11 @@ type VirtualNetworkPropertiesFormat struct { // operation. type VirtualNetworksCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualNetworksCreateOrUpdateFuture) Result(client VirtualNetworksClient) (vn VirtualNetwork, err error) { +func (future *VirtualNetworksCreateOrUpdateFuture) Result(client VirtualNetworksClient) (vn VirtualNetwork, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -16727,34 +15004,15 @@ func (future VirtualNetworksCreateOrUpdateFuture) Result(client VirtualNetworksC return } if !done { - return vn, azure.NewAsyncOpIncompleteError("network.VirtualNetworksCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - vn, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworksCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.VirtualNetworksCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if vn.Response.Response, err = future.GetResult(sender); err == nil && vn.Response.Response.StatusCode != http.StatusNoContent { + vn, err = client.CreateOrUpdateResponder(vn.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.VirtualNetworksCreateOrUpdateFuture", "Result", vn.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworksCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - vn, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworksCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -16763,12 +15021,11 @@ func (future VirtualNetworksCreateOrUpdateFuture) Result(client VirtualNetworksC // operation. type VirtualNetworksDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualNetworksDeleteFuture) Result(client VirtualNetworksClient) (ar autorest.Response, err error) { +func (future *VirtualNetworksDeleteFuture) Result(client VirtualNetworksClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -16776,35 +15033,10 @@ func (future VirtualNetworksDeleteFuture) Result(client VirtualNetworksClient) ( return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.VirtualNetworksDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworksDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.VirtualNetworksDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworksDeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworksDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -16812,12 +15044,11 @@ func (future VirtualNetworksDeleteFuture) Result(client VirtualNetworksClient) ( // operation. type VirtualNetworksUpdateTagsFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future VirtualNetworksUpdateTagsFuture) Result(client VirtualNetworksClient) (vn VirtualNetwork, err error) { +func (future *VirtualNetworksUpdateTagsFuture) Result(client VirtualNetworksClient) (vn VirtualNetwork, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -16825,34 +15056,15 @@ func (future VirtualNetworksUpdateTagsFuture) Result(client VirtualNetworksClien return } if !done { - return vn, azure.NewAsyncOpIncompleteError("network.VirtualNetworksUpdateTagsFuture") - } - if future.PollingMethod() == azure.PollingLocation { - vn, err = client.UpdateTagsResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworksUpdateTagsFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.VirtualNetworksUpdateTagsFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if vn.Response.Response, err = future.GetResult(sender); err == nil && vn.Response.Response.StatusCode != http.StatusNoContent { + vn, err = client.UpdateTagsResponder(vn.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.VirtualNetworksUpdateTagsFuture", "Result", vn.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworksUpdateTagsFuture", "Result", resp, "Failure sending request") - return - } - vn, err = client.UpdateTagsResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.VirtualNetworksUpdateTagsFuture", "Result", resp, "Failure responding to request") } return } @@ -17234,12 +15446,11 @@ type WatcherPropertiesFormat struct { // operation. type WatchersCheckConnectivityFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future WatchersCheckConnectivityFuture) Result(client WatchersClient) (ci ConnectivityInformation, err error) { +func (future *WatchersCheckConnectivityFuture) Result(client WatchersClient) (ci ConnectivityInformation, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -17247,34 +15458,15 @@ func (future WatchersCheckConnectivityFuture) Result(client WatchersClient) (ci return } if !done { - return ci, azure.NewAsyncOpIncompleteError("network.WatchersCheckConnectivityFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ci, err = client.CheckConnectivityResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersCheckConnectivityFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.WatchersCheckConnectivityFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if ci.Response.Response, err = future.GetResult(sender); err == nil && ci.Response.Response.StatusCode != http.StatusNoContent { + ci, err = client.CheckConnectivityResponder(ci.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.WatchersCheckConnectivityFuture", "Result", ci.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersCheckConnectivityFuture", "Result", resp, "Failure sending request") - return - } - ci, err = client.CheckConnectivityResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersCheckConnectivityFuture", "Result", resp, "Failure responding to request") } return } @@ -17282,12 +15474,11 @@ func (future WatchersCheckConnectivityFuture) Result(client WatchersClient) (ci // WatchersDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation. type WatchersDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future WatchersDeleteFuture) Result(client WatchersClient) (ar autorest.Response, err error) { +func (future *WatchersDeleteFuture) Result(client WatchersClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -17295,35 +15486,10 @@ func (future WatchersDeleteFuture) Result(client WatchersClient) (ar autorest.Re return } if !done { - return ar, azure.NewAsyncOpIncompleteError("network.WatchersDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.WatchersDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersDeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -17331,12 +15497,11 @@ func (future WatchersDeleteFuture) Result(client WatchersClient) (ar autorest.Re // long-running operation. type WatchersGetAzureReachabilityReportFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future WatchersGetAzureReachabilityReportFuture) Result(client WatchersClient) (arr AzureReachabilityReport, err error) { +func (future *WatchersGetAzureReachabilityReportFuture) Result(client WatchersClient) (arr AzureReachabilityReport, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -17344,34 +15509,15 @@ func (future WatchersGetAzureReachabilityReportFuture) Result(client WatchersCli return } if !done { - return arr, azure.NewAsyncOpIncompleteError("network.WatchersGetAzureReachabilityReportFuture") - } - if future.PollingMethod() == azure.PollingLocation { - arr, err = client.GetAzureReachabilityReportResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersGetAzureReachabilityReportFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.WatchersGetAzureReachabilityReportFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if arr.Response.Response, err = future.GetResult(sender); err == nil && arr.Response.Response.StatusCode != http.StatusNoContent { + arr, err = client.GetAzureReachabilityReportResponder(arr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.WatchersGetAzureReachabilityReportFuture", "Result", arr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersGetAzureReachabilityReportFuture", "Result", resp, "Failure sending request") - return - } - arr, err = client.GetAzureReachabilityReportResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersGetAzureReachabilityReportFuture", "Result", resp, "Failure responding to request") } return } @@ -17380,12 +15526,11 @@ func (future WatchersGetAzureReachabilityReportFuture) Result(client WatchersCli // operation. type WatchersGetFlowLogStatusFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future WatchersGetFlowLogStatusFuture) Result(client WatchersClient) (fli FlowLogInformation, err error) { +func (future *WatchersGetFlowLogStatusFuture) Result(client WatchersClient) (fli FlowLogInformation, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -17393,34 +15538,15 @@ func (future WatchersGetFlowLogStatusFuture) Result(client WatchersClient) (fli return } if !done { - return fli, azure.NewAsyncOpIncompleteError("network.WatchersGetFlowLogStatusFuture") - } - if future.PollingMethod() == azure.PollingLocation { - fli, err = client.GetFlowLogStatusResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersGetFlowLogStatusFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.WatchersGetFlowLogStatusFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if fli.Response.Response, err = future.GetResult(sender); err == nil && fli.Response.Response.StatusCode != http.StatusNoContent { + fli, err = client.GetFlowLogStatusResponder(fli.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.WatchersGetFlowLogStatusFuture", "Result", fli.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersGetFlowLogStatusFuture", "Result", resp, "Failure sending request") - return - } - fli, err = client.GetFlowLogStatusResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersGetFlowLogStatusFuture", "Result", resp, "Failure responding to request") } return } @@ -17428,12 +15554,11 @@ func (future WatchersGetFlowLogStatusFuture) Result(client WatchersClient) (fli // WatchersGetNextHopFuture an abstraction for monitoring and retrieving the results of a long-running operation. type WatchersGetNextHopFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future WatchersGetNextHopFuture) Result(client WatchersClient) (nhr NextHopResult, err error) { +func (future *WatchersGetNextHopFuture) Result(client WatchersClient) (nhr NextHopResult, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -17441,34 +15566,15 @@ func (future WatchersGetNextHopFuture) Result(client WatchersClient) (nhr NextHo return } if !done { - return nhr, azure.NewAsyncOpIncompleteError("network.WatchersGetNextHopFuture") - } - if future.PollingMethod() == azure.PollingLocation { - nhr, err = client.GetNextHopResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersGetNextHopFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.WatchersGetNextHopFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if nhr.Response.Response, err = future.GetResult(sender); err == nil && nhr.Response.Response.StatusCode != http.StatusNoContent { + nhr, err = client.GetNextHopResponder(nhr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.WatchersGetNextHopFuture", "Result", nhr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersGetNextHopFuture", "Result", resp, "Failure sending request") - return - } - nhr, err = client.GetNextHopResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersGetNextHopFuture", "Result", resp, "Failure responding to request") } return } @@ -17477,12 +15583,11 @@ func (future WatchersGetNextHopFuture) Result(client WatchersClient) (nhr NextHo // operation. type WatchersGetTroubleshootingFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future WatchersGetTroubleshootingFuture) Result(client WatchersClient) (tr TroubleshootingResult, err error) { +func (future *WatchersGetTroubleshootingFuture) Result(client WatchersClient) (tr TroubleshootingResult, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -17490,34 +15595,15 @@ func (future WatchersGetTroubleshootingFuture) Result(client WatchersClient) (tr return } if !done { - return tr, azure.NewAsyncOpIncompleteError("network.WatchersGetTroubleshootingFuture") - } - if future.PollingMethod() == azure.PollingLocation { - tr, err = client.GetTroubleshootingResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersGetTroubleshootingFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.WatchersGetTroubleshootingFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if tr.Response.Response, err = future.GetResult(sender); err == nil && tr.Response.Response.StatusCode != http.StatusNoContent { + tr, err = client.GetTroubleshootingResponder(tr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.WatchersGetTroubleshootingFuture", "Result", tr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersGetTroubleshootingFuture", "Result", resp, "Failure sending request") - return - } - tr, err = client.GetTroubleshootingResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersGetTroubleshootingFuture", "Result", resp, "Failure responding to request") } return } @@ -17526,12 +15612,11 @@ func (future WatchersGetTroubleshootingFuture) Result(client WatchersClient) (tr // long-running operation. type WatchersGetTroubleshootingResultFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future WatchersGetTroubleshootingResultFuture) Result(client WatchersClient) (tr TroubleshootingResult, err error) { +func (future *WatchersGetTroubleshootingResultFuture) Result(client WatchersClient) (tr TroubleshootingResult, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -17539,34 +15624,15 @@ func (future WatchersGetTroubleshootingResultFuture) Result(client WatchersClien return } if !done { - return tr, azure.NewAsyncOpIncompleteError("network.WatchersGetTroubleshootingResultFuture") - } - if future.PollingMethod() == azure.PollingLocation { - tr, err = client.GetTroubleshootingResultResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersGetTroubleshootingResultFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.WatchersGetTroubleshootingResultFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if tr.Response.Response, err = future.GetResult(sender); err == nil && tr.Response.Response.StatusCode != http.StatusNoContent { + tr, err = client.GetTroubleshootingResultResponder(tr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.WatchersGetTroubleshootingResultFuture", "Result", tr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersGetTroubleshootingResultFuture", "Result", resp, "Failure sending request") - return - } - tr, err = client.GetTroubleshootingResultResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersGetTroubleshootingResultFuture", "Result", resp, "Failure responding to request") } return } @@ -17575,12 +15641,11 @@ func (future WatchersGetTroubleshootingResultFuture) Result(client WatchersClien // operation. type WatchersGetVMSecurityRulesFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future WatchersGetVMSecurityRulesFuture) Result(client WatchersClient) (sgvr SecurityGroupViewResult, err error) { +func (future *WatchersGetVMSecurityRulesFuture) Result(client WatchersClient) (sgvr SecurityGroupViewResult, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -17588,34 +15653,15 @@ func (future WatchersGetVMSecurityRulesFuture) Result(client WatchersClient) (sg return } if !done { - return sgvr, azure.NewAsyncOpIncompleteError("network.WatchersGetVMSecurityRulesFuture") - } - if future.PollingMethod() == azure.PollingLocation { - sgvr, err = client.GetVMSecurityRulesResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersGetVMSecurityRulesFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.WatchersGetVMSecurityRulesFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if sgvr.Response.Response, err = future.GetResult(sender); err == nil && sgvr.Response.Response.StatusCode != http.StatusNoContent { + sgvr, err = client.GetVMSecurityRulesResponder(sgvr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.WatchersGetVMSecurityRulesFuture", "Result", sgvr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersGetVMSecurityRulesFuture", "Result", resp, "Failure sending request") - return - } - sgvr, err = client.GetVMSecurityRulesResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersGetVMSecurityRulesFuture", "Result", resp, "Failure responding to request") } return } @@ -17624,12 +15670,11 @@ func (future WatchersGetVMSecurityRulesFuture) Result(client WatchersClient) (sg // operation. type WatchersListAvailableProvidersFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future WatchersListAvailableProvidersFuture) Result(client WatchersClient) (apl AvailableProvidersList, err error) { +func (future *WatchersListAvailableProvidersFuture) Result(client WatchersClient) (apl AvailableProvidersList, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -17637,34 +15682,15 @@ func (future WatchersListAvailableProvidersFuture) Result(client WatchersClient) return } if !done { - return apl, azure.NewAsyncOpIncompleteError("network.WatchersListAvailableProvidersFuture") - } - if future.PollingMethod() == azure.PollingLocation { - apl, err = client.ListAvailableProvidersResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersListAvailableProvidersFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.WatchersListAvailableProvidersFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if apl.Response.Response, err = future.GetResult(sender); err == nil && apl.Response.Response.StatusCode != http.StatusNoContent { + apl, err = client.ListAvailableProvidersResponder(apl.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.WatchersListAvailableProvidersFuture", "Result", apl.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersListAvailableProvidersFuture", "Result", resp, "Failure sending request") - return - } - apl, err = client.ListAvailableProvidersResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersListAvailableProvidersFuture", "Result", resp, "Failure responding to request") } return } @@ -17673,12 +15699,11 @@ func (future WatchersListAvailableProvidersFuture) Result(client WatchersClient) // operation. type WatchersSetFlowLogConfigurationFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future WatchersSetFlowLogConfigurationFuture) Result(client WatchersClient) (fli FlowLogInformation, err error) { +func (future *WatchersSetFlowLogConfigurationFuture) Result(client WatchersClient) (fli FlowLogInformation, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -17686,34 +15711,15 @@ func (future WatchersSetFlowLogConfigurationFuture) Result(client WatchersClient return } if !done { - return fli, azure.NewAsyncOpIncompleteError("network.WatchersSetFlowLogConfigurationFuture") - } - if future.PollingMethod() == azure.PollingLocation { - fli, err = client.SetFlowLogConfigurationResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersSetFlowLogConfigurationFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.WatchersSetFlowLogConfigurationFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if fli.Response.Response, err = future.GetResult(sender); err == nil && fli.Response.Response.StatusCode != http.StatusNoContent { + fli, err = client.SetFlowLogConfigurationResponder(fli.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.WatchersSetFlowLogConfigurationFuture", "Result", fli.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersSetFlowLogConfigurationFuture", "Result", resp, "Failure sending request") - return - } - fli, err = client.SetFlowLogConfigurationResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersSetFlowLogConfigurationFuture", "Result", resp, "Failure responding to request") } return } @@ -17721,12 +15727,11 @@ func (future WatchersSetFlowLogConfigurationFuture) Result(client WatchersClient // WatchersVerifyIPFlowFuture an abstraction for monitoring and retrieving the results of a long-running operation. type WatchersVerifyIPFlowFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future WatchersVerifyIPFlowFuture) Result(client WatchersClient) (vifr VerificationIPFlowResult, err error) { +func (future *WatchersVerifyIPFlowFuture) Result(client WatchersClient) (vifr VerificationIPFlowResult, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -17734,34 +15739,15 @@ func (future WatchersVerifyIPFlowFuture) Result(client WatchersClient) (vifr Ver return } if !done { - return vifr, azure.NewAsyncOpIncompleteError("network.WatchersVerifyIPFlowFuture") - } - if future.PollingMethod() == azure.PollingLocation { - vifr, err = client.VerifyIPFlowResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersVerifyIPFlowFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("network.WatchersVerifyIPFlowFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if vifr.Response.Response, err = future.GetResult(sender); err == nil && vifr.Response.Response.StatusCode != http.StatusNoContent { + vifr, err = client.VerifyIPFlowResponder(vifr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "network.WatchersVerifyIPFlowFuture", "Result", vifr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersVerifyIPFlowFuture", "Result", resp, "Failure sending request") - return - } - vifr, err = client.VerifyIPFlowResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "network.WatchersVerifyIPFlowFuture", "Result", resp, "Failure responding to request") } return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/packetcaptures.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/packetcaptures.go index d425c6d1c..eb9a1376f 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/packetcaptures.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/packetcaptures.go @@ -41,10 +41,11 @@ func NewPacketCapturesClientWithBaseURI(baseURI string, subscriptionID string) P } // Create create and start a packet capture on the specified VM. -// -// resourceGroupName is the name of the resource group. networkWatcherName is the name of the network watcher. -// packetCaptureName is the name of the packet capture session. parameters is parameters that define the create -// packet capture operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkWatcherName - the name of the network watcher. +// packetCaptureName - the name of the packet capture session. +// parameters - parameters that define the create packet capture operation. func (client PacketCapturesClient) Create(ctx context.Context, resourceGroupName string, networkWatcherName string, packetCaptureName string, parameters PacketCapture) (result PacketCapturesCreateFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: parameters, @@ -97,15 +98,17 @@ func (client PacketCapturesClient) CreatePreparer(ctx context.Context, resourceG // CreateSender sends the Create request. The method will close the // http.Response Body if it receives an error. func (client PacketCapturesClient) CreateSender(req *http.Request) (future PacketCapturesCreateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -123,9 +126,10 @@ func (client PacketCapturesClient) CreateResponder(resp *http.Response) (result } // Delete deletes the specified packet capture session. -// -// resourceGroupName is the name of the resource group. networkWatcherName is the name of the network watcher. -// packetCaptureName is the name of the packet capture session. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkWatcherName - the name of the network watcher. +// packetCaptureName - the name of the packet capture session. func (client PacketCapturesClient) Delete(ctx context.Context, resourceGroupName string, networkWatcherName string, packetCaptureName string) (result PacketCapturesDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, networkWatcherName, packetCaptureName) if err != nil { @@ -167,15 +171,17 @@ func (client PacketCapturesClient) DeletePreparer(ctx context.Context, resourceG // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client PacketCapturesClient) DeleteSender(req *http.Request) (future PacketCapturesDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -192,9 +198,10 @@ func (client PacketCapturesClient) DeleteResponder(resp *http.Response) (result } // Get gets a packet capture session by name. -// -// resourceGroupName is the name of the resource group. networkWatcherName is the name of the network watcher. -// packetCaptureName is the name of the packet capture session. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkWatcherName - the name of the network watcher. +// packetCaptureName - the name of the packet capture session. func (client PacketCapturesClient) Get(ctx context.Context, resourceGroupName string, networkWatcherName string, packetCaptureName string) (result PacketCaptureResult, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, networkWatcherName, packetCaptureName) if err != nil { @@ -260,9 +267,10 @@ func (client PacketCapturesClient) GetResponder(resp *http.Response) (result Pac } // GetStatus query the status of a running packet capture session. -// -// resourceGroupName is the name of the resource group. networkWatcherName is the name of the Network Watcher -// resource. packetCaptureName is the name given to the packet capture session. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkWatcherName - the name of the Network Watcher resource. +// packetCaptureName - the name given to the packet capture session. func (client PacketCapturesClient) GetStatus(ctx context.Context, resourceGroupName string, networkWatcherName string, packetCaptureName string) (result PacketCapturesGetStatusFuture, err error) { req, err := client.GetStatusPreparer(ctx, resourceGroupName, networkWatcherName, packetCaptureName) if err != nil { @@ -304,15 +312,17 @@ func (client PacketCapturesClient) GetStatusPreparer(ctx context.Context, resour // GetStatusSender sends the GetStatus request. The method will close the // http.Response Body if it receives an error. func (client PacketCapturesClient) GetStatusSender(req *http.Request) (future PacketCapturesGetStatusFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -330,9 +340,9 @@ func (client PacketCapturesClient) GetStatusResponder(resp *http.Response) (resu } // List lists all packet capture sessions within the specified resource group. -// -// resourceGroupName is the name of the resource group. networkWatcherName is the name of the Network Watcher -// resource. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkWatcherName - the name of the Network Watcher resource. func (client PacketCapturesClient) List(ctx context.Context, resourceGroupName string, networkWatcherName string) (result PacketCaptureListResult, err error) { req, err := client.ListPreparer(ctx, resourceGroupName, networkWatcherName) if err != nil { @@ -397,9 +407,10 @@ func (client PacketCapturesClient) ListResponder(resp *http.Response) (result Pa } // Stop stops a specified packet capture session. -// -// resourceGroupName is the name of the resource group. networkWatcherName is the name of the network watcher. -// packetCaptureName is the name of the packet capture session. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkWatcherName - the name of the network watcher. +// packetCaptureName - the name of the packet capture session. func (client PacketCapturesClient) Stop(ctx context.Context, resourceGroupName string, networkWatcherName string, packetCaptureName string) (result PacketCapturesStopFuture, err error) { req, err := client.StopPreparer(ctx, resourceGroupName, networkWatcherName, packetCaptureName) if err != nil { @@ -441,15 +452,17 @@ func (client PacketCapturesClient) StopPreparer(ctx context.Context, resourceGro // StopSender sends the Stop request. The method will close the // http.Response Body if it receives an error. func (client PacketCapturesClient) StopSender(req *http.Request) (future PacketCapturesStopFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/publicipaddresses.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/publicipaddresses.go index caf07d247..956756f94 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/publicipaddresses.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/publicipaddresses.go @@ -41,9 +41,10 @@ func NewPublicIPAddressesClientWithBaseURI(baseURI string, subscriptionID string } // CreateOrUpdate creates or updates a static or dynamic public IP address. -// -// resourceGroupName is the name of the resource group. publicIPAddressName is the name of the public IP address. -// parameters is parameters supplied to the create or update public IP address operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// publicIPAddressName - the name of the public IP address. +// parameters - parameters supplied to the create or update public IP address operation. func (client PublicIPAddressesClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, publicIPAddressName string, parameters PublicIPAddress) (result PublicIPAddressesCreateOrUpdateFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: parameters, @@ -97,15 +98,17 @@ func (client PublicIPAddressesClient) CreateOrUpdatePreparer(ctx context.Context // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client PublicIPAddressesClient) CreateOrUpdateSender(req *http.Request) (future PublicIPAddressesCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -123,8 +126,9 @@ func (client PublicIPAddressesClient) CreateOrUpdateResponder(resp *http.Respons } // Delete deletes the specified public IP address. -// -// resourceGroupName is the name of the resource group. publicIPAddressName is the name of the subnet. +// Parameters: +// resourceGroupName - the name of the resource group. +// publicIPAddressName - the name of the subnet. func (client PublicIPAddressesClient) Delete(ctx context.Context, resourceGroupName string, publicIPAddressName string) (result PublicIPAddressesDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, publicIPAddressName) if err != nil { @@ -165,15 +169,17 @@ func (client PublicIPAddressesClient) DeletePreparer(ctx context.Context, resour // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client PublicIPAddressesClient) DeleteSender(req *http.Request) (future PublicIPAddressesDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -190,9 +196,10 @@ func (client PublicIPAddressesClient) DeleteResponder(resp *http.Response) (resu } // Get gets the specified public IP address in a specified resource group. -// -// resourceGroupName is the name of the resource group. publicIPAddressName is the name of the subnet. expand is -// expands referenced resources. +// Parameters: +// resourceGroupName - the name of the resource group. +// publicIPAddressName - the name of the subnet. +// expand - expands referenced resources. func (client PublicIPAddressesClient) Get(ctx context.Context, resourceGroupName string, publicIPAddressName string, expand string) (result PublicIPAddress, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, publicIPAddressName, expand) if err != nil { @@ -260,11 +267,14 @@ func (client PublicIPAddressesClient) GetResponder(resp *http.Response) (result } // GetVirtualMachineScaleSetPublicIPAddress get the specified public IP address in a virtual machine scale set. -// -// resourceGroupName is the name of the resource group. virtualMachineScaleSetName is the name of the virtual -// machine scale set. virtualmachineIndex is the virtual machine index. networkInterfaceName is the name of the -// network interface. IPConfigurationName is the name of the IP configuration. publicIPAddressName is the name of -// the public IP Address. expand is expands referenced resources. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualMachineScaleSetName - the name of the virtual machine scale set. +// virtualmachineIndex - the virtual machine index. +// networkInterfaceName - the name of the network interface. +// IPConfigurationName - the name of the IP configuration. +// publicIPAddressName - the name of the public IP Address. +// expand - expands referenced resources. func (client PublicIPAddressesClient) GetVirtualMachineScaleSetPublicIPAddress(ctx context.Context, resourceGroupName string, virtualMachineScaleSetName string, virtualmachineIndex string, networkInterfaceName string, IPConfigurationName string, publicIPAddressName string, expand string) (result PublicIPAddress, err error) { req, err := client.GetVirtualMachineScaleSetPublicIPAddressPreparer(ctx, resourceGroupName, virtualMachineScaleSetName, virtualmachineIndex, networkInterfaceName, IPConfigurationName, publicIPAddressName, expand) if err != nil { @@ -336,8 +346,8 @@ func (client PublicIPAddressesClient) GetVirtualMachineScaleSetPublicIPAddressRe } // List gets all public IP addresses in a resource group. -// -// resourceGroupName is the name of the resource group. +// Parameters: +// resourceGroupName - the name of the resource group. func (client PublicIPAddressesClient) List(ctx context.Context, resourceGroupName string) (result PublicIPAddressListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName) @@ -520,9 +530,9 @@ func (client PublicIPAddressesClient) ListAllComplete(ctx context.Context) (resu // ListVirtualMachineScaleSetPublicIPAddresses gets information about all public IP addresses on a virtual machine // scale set level. -// -// resourceGroupName is the name of the resource group. virtualMachineScaleSetName is the name of the virtual -// machine scale set. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualMachineScaleSetName - the name of the virtual machine scale set. func (client PublicIPAddressesClient) ListVirtualMachineScaleSetPublicIPAddresses(ctx context.Context, resourceGroupName string, virtualMachineScaleSetName string) (result PublicIPAddressListResultPage, err error) { result.fn = client.listVirtualMachineScaleSetPublicIPAddressesNextResults req, err := client.ListVirtualMachineScaleSetPublicIPAddressesPreparer(ctx, resourceGroupName, virtualMachineScaleSetName) @@ -616,10 +626,12 @@ func (client PublicIPAddressesClient) ListVirtualMachineScaleSetPublicIPAddresse // ListVirtualMachineScaleSetVMPublicIPAddresses gets information about all public IP addresses in a virtual machine IP // configuration in a virtual machine scale set. -// -// resourceGroupName is the name of the resource group. virtualMachineScaleSetName is the name of the virtual -// machine scale set. virtualmachineIndex is the virtual machine index. networkInterfaceName is the network -// interface name. IPConfigurationName is the IP configuration name. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualMachineScaleSetName - the name of the virtual machine scale set. +// virtualmachineIndex - the virtual machine index. +// networkInterfaceName - the network interface name. +// IPConfigurationName - the IP configuration name. func (client PublicIPAddressesClient) ListVirtualMachineScaleSetVMPublicIPAddresses(ctx context.Context, resourceGroupName string, virtualMachineScaleSetName string, virtualmachineIndex string, networkInterfaceName string, IPConfigurationName string) (result PublicIPAddressListResultPage, err error) { result.fn = client.listVirtualMachineScaleSetVMPublicIPAddressesNextResults req, err := client.ListVirtualMachineScaleSetVMPublicIPAddressesPreparer(ctx, resourceGroupName, virtualMachineScaleSetName, virtualmachineIndex, networkInterfaceName, IPConfigurationName) @@ -715,9 +727,10 @@ func (client PublicIPAddressesClient) ListVirtualMachineScaleSetVMPublicIPAddres } // UpdateTags updates public IP address tags. -// -// resourceGroupName is the name of the resource group. publicIPAddressName is the name of the public IP address. -// parameters is parameters supplied to update public IP address tags. +// Parameters: +// resourceGroupName - the name of the resource group. +// publicIPAddressName - the name of the public IP address. +// parameters - parameters supplied to update public IP address tags. func (client PublicIPAddressesClient) UpdateTags(ctx context.Context, resourceGroupName string, publicIPAddressName string, parameters TagsObject) (result PublicIPAddressesUpdateTagsFuture, err error) { req, err := client.UpdateTagsPreparer(ctx, resourceGroupName, publicIPAddressName, parameters) if err != nil { @@ -760,15 +773,17 @@ func (client PublicIPAddressesClient) UpdateTagsPreparer(ctx context.Context, re // UpdateTagsSender sends the UpdateTags request. The method will close the // http.Response Body if it receives an error. func (client PublicIPAddressesClient) UpdateTagsSender(req *http.Request) (future PublicIPAddressesUpdateTagsFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/routefilterrules.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/routefilterrules.go index 0f69934c4..42afb6949 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/routefilterrules.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/routefilterrules.go @@ -41,10 +41,11 @@ func NewRouteFilterRulesClientWithBaseURI(baseURI string, subscriptionID string) } // CreateOrUpdate creates or updates a route in the specified route filter. -// -// resourceGroupName is the name of the resource group. routeFilterName is the name of the route filter. ruleName -// is the name of the route filter rule. routeFilterRuleParameters is parameters supplied to the create or update -// route filter rule operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// routeFilterName - the name of the route filter. +// ruleName - the name of the route filter rule. +// routeFilterRuleParameters - parameters supplied to the create or update route filter rule operation. func (client RouteFilterRulesClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, routeFilterName string, ruleName string, routeFilterRuleParameters RouteFilterRule) (result RouteFilterRulesCreateOrUpdateFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: routeFilterRuleParameters, @@ -97,15 +98,17 @@ func (client RouteFilterRulesClient) CreateOrUpdatePreparer(ctx context.Context, // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client RouteFilterRulesClient) CreateOrUpdateSender(req *http.Request) (future RouteFilterRulesCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -123,9 +126,10 @@ func (client RouteFilterRulesClient) CreateOrUpdateResponder(resp *http.Response } // Delete deletes the specified rule from a route filter. -// -// resourceGroupName is the name of the resource group. routeFilterName is the name of the route filter. ruleName -// is the name of the rule. +// Parameters: +// resourceGroupName - the name of the resource group. +// routeFilterName - the name of the route filter. +// ruleName - the name of the rule. func (client RouteFilterRulesClient) Delete(ctx context.Context, resourceGroupName string, routeFilterName string, ruleName string) (result RouteFilterRulesDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, routeFilterName, ruleName) if err != nil { @@ -167,15 +171,17 @@ func (client RouteFilterRulesClient) DeletePreparer(ctx context.Context, resourc // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client RouteFilterRulesClient) DeleteSender(req *http.Request) (future RouteFilterRulesDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -192,9 +198,10 @@ func (client RouteFilterRulesClient) DeleteResponder(resp *http.Response) (resul } // Get gets the specified rule from a route filter. -// -// resourceGroupName is the name of the resource group. routeFilterName is the name of the route filter. ruleName -// is the name of the rule. +// Parameters: +// resourceGroupName - the name of the resource group. +// routeFilterName - the name of the route filter. +// ruleName - the name of the rule. func (client RouteFilterRulesClient) Get(ctx context.Context, resourceGroupName string, routeFilterName string, ruleName string) (result RouteFilterRule, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, routeFilterName, ruleName) if err != nil { @@ -260,8 +267,9 @@ func (client RouteFilterRulesClient) GetResponder(resp *http.Response) (result R } // ListByRouteFilter gets all RouteFilterRules in a route filter. -// -// resourceGroupName is the name of the resource group. routeFilterName is the name of the route filter. +// Parameters: +// resourceGroupName - the name of the resource group. +// routeFilterName - the name of the route filter. func (client RouteFilterRulesClient) ListByRouteFilter(ctx context.Context, resourceGroupName string, routeFilterName string) (result RouteFilterRuleListResultPage, err error) { result.fn = client.listByRouteFilterNextResults req, err := client.ListByRouteFilterPreparer(ctx, resourceGroupName, routeFilterName) @@ -354,10 +362,11 @@ func (client RouteFilterRulesClient) ListByRouteFilterComplete(ctx context.Conte } // Update updates a route in the specified route filter. -// -// resourceGroupName is the name of the resource group. routeFilterName is the name of the route filter. ruleName -// is the name of the route filter rule. routeFilterRuleParameters is parameters supplied to the update route -// filter rule operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// routeFilterName - the name of the route filter. +// ruleName - the name of the route filter rule. +// routeFilterRuleParameters - parameters supplied to the update route filter rule operation. func (client RouteFilterRulesClient) Update(ctx context.Context, resourceGroupName string, routeFilterName string, ruleName string, routeFilterRuleParameters PatchRouteFilterRule) (result RouteFilterRulesUpdateFuture, err error) { req, err := client.UpdatePreparer(ctx, resourceGroupName, routeFilterName, ruleName, routeFilterRuleParameters) if err != nil { @@ -401,15 +410,17 @@ func (client RouteFilterRulesClient) UpdatePreparer(ctx context.Context, resourc // UpdateSender sends the Update request. The method will close the // http.Response Body if it receives an error. func (client RouteFilterRulesClient) UpdateSender(req *http.Request) (future RouteFilterRulesUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/routefilters.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/routefilters.go index de9d41c34..f2df3875e 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/routefilters.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/routefilters.go @@ -40,9 +40,10 @@ func NewRouteFiltersClientWithBaseURI(baseURI string, subscriptionID string) Rou } // CreateOrUpdate creates or updates a route filter in a specified resource group. -// -// resourceGroupName is the name of the resource group. routeFilterName is the name of the route filter. -// routeFilterParameters is parameters supplied to the create or update route filter operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// routeFilterName - the name of the route filter. +// routeFilterParameters - parameters supplied to the create or update route filter operation. func (client RouteFiltersClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, routeFilterName string, routeFilterParameters RouteFilter) (result RouteFiltersCreateOrUpdateFuture, err error) { req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, routeFilterName, routeFilterParameters) if err != nil { @@ -85,15 +86,17 @@ func (client RouteFiltersClient) CreateOrUpdatePreparer(ctx context.Context, res // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client RouteFiltersClient) CreateOrUpdateSender(req *http.Request) (future RouteFiltersCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -111,8 +114,9 @@ func (client RouteFiltersClient) CreateOrUpdateResponder(resp *http.Response) (r } // Delete deletes the specified route filter. -// -// resourceGroupName is the name of the resource group. routeFilterName is the name of the route filter. +// Parameters: +// resourceGroupName - the name of the resource group. +// routeFilterName - the name of the route filter. func (client RouteFiltersClient) Delete(ctx context.Context, resourceGroupName string, routeFilterName string) (result RouteFiltersDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, routeFilterName) if err != nil { @@ -153,15 +157,17 @@ func (client RouteFiltersClient) DeletePreparer(ctx context.Context, resourceGro // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client RouteFiltersClient) DeleteSender(req *http.Request) (future RouteFiltersDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -178,9 +184,10 @@ func (client RouteFiltersClient) DeleteResponder(resp *http.Response) (result au } // Get gets the specified route filter. -// -// resourceGroupName is the name of the resource group. routeFilterName is the name of the route filter. expand is -// expands referenced express route bgp peering resources. +// Parameters: +// resourceGroupName - the name of the resource group. +// routeFilterName - the name of the route filter. +// expand - expands referenced express route bgp peering resources. func (client RouteFiltersClient) Get(ctx context.Context, resourceGroupName string, routeFilterName string, expand string) (result RouteFilter, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, routeFilterName, expand) if err != nil { @@ -338,8 +345,8 @@ func (client RouteFiltersClient) ListComplete(ctx context.Context) (result Route } // ListByResourceGroup gets all route filters in a resource group. -// -// resourceGroupName is the name of the resource group. +// Parameters: +// resourceGroupName - the name of the resource group. func (client RouteFiltersClient) ListByResourceGroup(ctx context.Context, resourceGroupName string) (result RouteFilterListResultPage, err error) { result.fn = client.listByResourceGroupNextResults req, err := client.ListByResourceGroupPreparer(ctx, resourceGroupName) @@ -431,9 +438,10 @@ func (client RouteFiltersClient) ListByResourceGroupComplete(ctx context.Context } // Update updates a route filter in a specified resource group. -// -// resourceGroupName is the name of the resource group. routeFilterName is the name of the route filter. -// routeFilterParameters is parameters supplied to the update route filter operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// routeFilterName - the name of the route filter. +// routeFilterParameters - parameters supplied to the update route filter operation. func (client RouteFiltersClient) Update(ctx context.Context, resourceGroupName string, routeFilterName string, routeFilterParameters PatchRouteFilter) (result RouteFiltersUpdateFuture, err error) { req, err := client.UpdatePreparer(ctx, resourceGroupName, routeFilterName, routeFilterParameters) if err != nil { @@ -476,15 +484,17 @@ func (client RouteFiltersClient) UpdatePreparer(ctx context.Context, resourceGro // UpdateSender sends the Update request. The method will close the // http.Response Body if it receives an error. func (client RouteFiltersClient) UpdateSender(req *http.Request) (future RouteFiltersUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/routes.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/routes.go index 25ddbb5e3..9a716de45 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/routes.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/routes.go @@ -40,9 +40,11 @@ func NewRoutesClientWithBaseURI(baseURI string, subscriptionID string) RoutesCli } // CreateOrUpdate creates or updates a route in the specified route table. -// -// resourceGroupName is the name of the resource group. routeTableName is the name of the route table. routeName is -// the name of the route. routeParameters is parameters supplied to the create or update route operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// routeTableName - the name of the route table. +// routeName - the name of the route. +// routeParameters - parameters supplied to the create or update route operation. func (client RoutesClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, routeTableName string, routeName string, routeParameters Route) (result RoutesCreateOrUpdateFuture, err error) { req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, routeTableName, routeName, routeParameters) if err != nil { @@ -86,15 +88,17 @@ func (client RoutesClient) CreateOrUpdatePreparer(ctx context.Context, resourceG // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client RoutesClient) CreateOrUpdateSender(req *http.Request) (future RoutesCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -112,9 +116,10 @@ func (client RoutesClient) CreateOrUpdateResponder(resp *http.Response) (result } // Delete deletes the specified route from a route table. -// -// resourceGroupName is the name of the resource group. routeTableName is the name of the route table. routeName is -// the name of the route. +// Parameters: +// resourceGroupName - the name of the resource group. +// routeTableName - the name of the route table. +// routeName - the name of the route. func (client RoutesClient) Delete(ctx context.Context, resourceGroupName string, routeTableName string, routeName string) (result RoutesDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, routeTableName, routeName) if err != nil { @@ -156,15 +161,17 @@ func (client RoutesClient) DeletePreparer(ctx context.Context, resourceGroupName // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client RoutesClient) DeleteSender(req *http.Request) (future RoutesDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -181,9 +188,10 @@ func (client RoutesClient) DeleteResponder(resp *http.Response) (result autorest } // Get gets the specified route from a route table. -// -// resourceGroupName is the name of the resource group. routeTableName is the name of the route table. routeName is -// the name of the route. +// Parameters: +// resourceGroupName - the name of the resource group. +// routeTableName - the name of the route table. +// routeName - the name of the route. func (client RoutesClient) Get(ctx context.Context, resourceGroupName string, routeTableName string, routeName string) (result Route, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, routeTableName, routeName) if err != nil { @@ -249,8 +257,9 @@ func (client RoutesClient) GetResponder(resp *http.Response) (result Route, err } // List gets all routes in a route table. -// -// resourceGroupName is the name of the resource group. routeTableName is the name of the route table. +// Parameters: +// resourceGroupName - the name of the resource group. +// routeTableName - the name of the route table. func (client RoutesClient) List(ctx context.Context, resourceGroupName string, routeTableName string) (result RouteListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName, routeTableName) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/routetables.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/routetables.go index 371200926..21f30e9c9 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/routetables.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/routetables.go @@ -40,9 +40,10 @@ func NewRouteTablesClientWithBaseURI(baseURI string, subscriptionID string) Rout } // CreateOrUpdate create or updates a route table in a specified resource group. -// -// resourceGroupName is the name of the resource group. routeTableName is the name of the route table. parameters -// is parameters supplied to the create or update route table operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// routeTableName - the name of the route table. +// parameters - parameters supplied to the create or update route table operation. func (client RouteTablesClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, routeTableName string, parameters RouteTable) (result RouteTablesCreateOrUpdateFuture, err error) { req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, routeTableName, parameters) if err != nil { @@ -85,15 +86,17 @@ func (client RouteTablesClient) CreateOrUpdatePreparer(ctx context.Context, reso // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client RouteTablesClient) CreateOrUpdateSender(req *http.Request) (future RouteTablesCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -111,8 +114,9 @@ func (client RouteTablesClient) CreateOrUpdateResponder(resp *http.Response) (re } // Delete deletes the specified route table. -// -// resourceGroupName is the name of the resource group. routeTableName is the name of the route table. +// Parameters: +// resourceGroupName - the name of the resource group. +// routeTableName - the name of the route table. func (client RouteTablesClient) Delete(ctx context.Context, resourceGroupName string, routeTableName string) (result RouteTablesDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, routeTableName) if err != nil { @@ -153,15 +157,17 @@ func (client RouteTablesClient) DeletePreparer(ctx context.Context, resourceGrou // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client RouteTablesClient) DeleteSender(req *http.Request) (future RouteTablesDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -178,9 +184,10 @@ func (client RouteTablesClient) DeleteResponder(resp *http.Response) (result aut } // Get gets the specified route table. -// -// resourceGroupName is the name of the resource group. routeTableName is the name of the route table. expand is -// expands referenced resources. +// Parameters: +// resourceGroupName - the name of the resource group. +// routeTableName - the name of the route table. +// expand - expands referenced resources. func (client RouteTablesClient) Get(ctx context.Context, resourceGroupName string, routeTableName string, expand string) (result RouteTable, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, routeTableName, expand) if err != nil { @@ -248,8 +255,8 @@ func (client RouteTablesClient) GetResponder(resp *http.Response) (result RouteT } // List gets all route tables in a resource group. -// -// resourceGroupName is the name of the resource group. +// Parameters: +// resourceGroupName - the name of the resource group. func (client RouteTablesClient) List(ctx context.Context, resourceGroupName string) (result RouteTableListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName) @@ -431,9 +438,10 @@ func (client RouteTablesClient) ListAllComplete(ctx context.Context) (result Rou } // UpdateTags updates a route table tags. -// -// resourceGroupName is the name of the resource group. routeTableName is the name of the route table. parameters -// is parameters supplied to update route table tags. +// Parameters: +// resourceGroupName - the name of the resource group. +// routeTableName - the name of the route table. +// parameters - parameters supplied to update route table tags. func (client RouteTablesClient) UpdateTags(ctx context.Context, resourceGroupName string, routeTableName string, parameters TagsObject) (result RouteTablesUpdateTagsFuture, err error) { req, err := client.UpdateTagsPreparer(ctx, resourceGroupName, routeTableName, parameters) if err != nil { @@ -476,15 +484,17 @@ func (client RouteTablesClient) UpdateTagsPreparer(ctx context.Context, resource // UpdateTagsSender sends the UpdateTags request. The method will close the // http.Response Body if it receives an error. func (client RouteTablesClient) UpdateTagsSender(req *http.Request) (future RouteTablesUpdateTagsFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/securitygroups.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/securitygroups.go index e51ec0c93..0c6d7f78e 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/securitygroups.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/securitygroups.go @@ -40,9 +40,10 @@ func NewSecurityGroupsClientWithBaseURI(baseURI string, subscriptionID string) S } // CreateOrUpdate creates or updates a network security group in the specified resource group. -// -// resourceGroupName is the name of the resource group. networkSecurityGroupName is the name of the network -// security group. parameters is parameters supplied to the create or update network security group operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkSecurityGroupName - the name of the network security group. +// parameters - parameters supplied to the create or update network security group operation. func (client SecurityGroupsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, networkSecurityGroupName string, parameters SecurityGroup) (result SecurityGroupsCreateOrUpdateFuture, err error) { req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, networkSecurityGroupName, parameters) if err != nil { @@ -85,15 +86,17 @@ func (client SecurityGroupsClient) CreateOrUpdatePreparer(ctx context.Context, r // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client SecurityGroupsClient) CreateOrUpdateSender(req *http.Request) (future SecurityGroupsCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -111,9 +114,9 @@ func (client SecurityGroupsClient) CreateOrUpdateResponder(resp *http.Response) } // Delete deletes the specified network security group. -// -// resourceGroupName is the name of the resource group. networkSecurityGroupName is the name of the network -// security group. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkSecurityGroupName - the name of the network security group. func (client SecurityGroupsClient) Delete(ctx context.Context, resourceGroupName string, networkSecurityGroupName string) (result SecurityGroupsDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, networkSecurityGroupName) if err != nil { @@ -154,15 +157,17 @@ func (client SecurityGroupsClient) DeletePreparer(ctx context.Context, resourceG // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client SecurityGroupsClient) DeleteSender(req *http.Request) (future SecurityGroupsDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -179,9 +184,10 @@ func (client SecurityGroupsClient) DeleteResponder(resp *http.Response) (result } // Get gets the specified network security group. -// -// resourceGroupName is the name of the resource group. networkSecurityGroupName is the name of the network -// security group. expand is expands referenced resources. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkSecurityGroupName - the name of the network security group. +// expand - expands referenced resources. func (client SecurityGroupsClient) Get(ctx context.Context, resourceGroupName string, networkSecurityGroupName string, expand string) (result SecurityGroup, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, networkSecurityGroupName, expand) if err != nil { @@ -249,8 +255,8 @@ func (client SecurityGroupsClient) GetResponder(resp *http.Response) (result Sec } // List gets all network security groups in a resource group. -// -// resourceGroupName is the name of the resource group. +// Parameters: +// resourceGroupName - the name of the resource group. func (client SecurityGroupsClient) List(ctx context.Context, resourceGroupName string) (result SecurityGroupListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName) @@ -432,9 +438,10 @@ func (client SecurityGroupsClient) ListAllComplete(ctx context.Context) (result } // UpdateTags updates a network security group tags. -// -// resourceGroupName is the name of the resource group. networkSecurityGroupName is the name of the network -// security group. parameters is parameters supplied to update network security group tags. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkSecurityGroupName - the name of the network security group. +// parameters - parameters supplied to update network security group tags. func (client SecurityGroupsClient) UpdateTags(ctx context.Context, resourceGroupName string, networkSecurityGroupName string, parameters TagsObject) (result SecurityGroupsUpdateTagsFuture, err error) { req, err := client.UpdateTagsPreparer(ctx, resourceGroupName, networkSecurityGroupName, parameters) if err != nil { @@ -477,15 +484,17 @@ func (client SecurityGroupsClient) UpdateTagsPreparer(ctx context.Context, resou // UpdateTagsSender sends the UpdateTags request. The method will close the // http.Response Body if it receives an error. func (client SecurityGroupsClient) UpdateTagsSender(req *http.Request) (future SecurityGroupsUpdateTagsFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/securityrules.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/securityrules.go index 50b60b9dc..942c34def 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/securityrules.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/securityrules.go @@ -40,10 +40,11 @@ func NewSecurityRulesClientWithBaseURI(baseURI string, subscriptionID string) Se } // CreateOrUpdate creates or updates a security rule in the specified network security group. -// -// resourceGroupName is the name of the resource group. networkSecurityGroupName is the name of the network -// security group. securityRuleName is the name of the security rule. securityRuleParameters is parameters supplied -// to the create or update network security rule operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkSecurityGroupName - the name of the network security group. +// securityRuleName - the name of the security rule. +// securityRuleParameters - parameters supplied to the create or update network security rule operation. func (client SecurityRulesClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, networkSecurityGroupName string, securityRuleName string, securityRuleParameters SecurityRule) (result SecurityRulesCreateOrUpdateFuture, err error) { req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, networkSecurityGroupName, securityRuleName, securityRuleParameters) if err != nil { @@ -87,15 +88,17 @@ func (client SecurityRulesClient) CreateOrUpdatePreparer(ctx context.Context, re // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client SecurityRulesClient) CreateOrUpdateSender(req *http.Request) (future SecurityRulesCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -113,9 +116,10 @@ func (client SecurityRulesClient) CreateOrUpdateResponder(resp *http.Response) ( } // Delete deletes the specified network security rule. -// -// resourceGroupName is the name of the resource group. networkSecurityGroupName is the name of the network -// security group. securityRuleName is the name of the security rule. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkSecurityGroupName - the name of the network security group. +// securityRuleName - the name of the security rule. func (client SecurityRulesClient) Delete(ctx context.Context, resourceGroupName string, networkSecurityGroupName string, securityRuleName string) (result SecurityRulesDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, networkSecurityGroupName, securityRuleName) if err != nil { @@ -157,15 +161,17 @@ func (client SecurityRulesClient) DeletePreparer(ctx context.Context, resourceGr // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client SecurityRulesClient) DeleteSender(req *http.Request) (future SecurityRulesDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -182,9 +188,10 @@ func (client SecurityRulesClient) DeleteResponder(resp *http.Response) (result a } // Get get the specified network security rule. -// -// resourceGroupName is the name of the resource group. networkSecurityGroupName is the name of the network -// security group. securityRuleName is the name of the security rule. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkSecurityGroupName - the name of the network security group. +// securityRuleName - the name of the security rule. func (client SecurityRulesClient) Get(ctx context.Context, resourceGroupName string, networkSecurityGroupName string, securityRuleName string) (result SecurityRule, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, networkSecurityGroupName, securityRuleName) if err != nil { @@ -250,9 +257,9 @@ func (client SecurityRulesClient) GetResponder(resp *http.Response) (result Secu } // List gets all security rules in a network security group. -// -// resourceGroupName is the name of the resource group. networkSecurityGroupName is the name of the network -// security group. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkSecurityGroupName - the name of the network security group. func (client SecurityRulesClient) List(ctx context.Context, resourceGroupName string, networkSecurityGroupName string) (result SecurityRuleListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName, networkSecurityGroupName) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/subnets.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/subnets.go index fd7a17bc9..b288b8ba8 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/subnets.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/subnets.go @@ -40,10 +40,11 @@ func NewSubnetsClientWithBaseURI(baseURI string, subscriptionID string) SubnetsC } // CreateOrUpdate creates or updates a subnet in the specified virtual network. -// -// resourceGroupName is the name of the resource group. virtualNetworkName is the name of the virtual network. -// subnetName is the name of the subnet. subnetParameters is parameters supplied to the create or update subnet -// operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkName - the name of the virtual network. +// subnetName - the name of the subnet. +// subnetParameters - parameters supplied to the create or update subnet operation. func (client SubnetsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, virtualNetworkName string, subnetName string, subnetParameters Subnet) (result SubnetsCreateOrUpdateFuture, err error) { req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, virtualNetworkName, subnetName, subnetParameters) if err != nil { @@ -87,15 +88,17 @@ func (client SubnetsClient) CreateOrUpdatePreparer(ctx context.Context, resource // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client SubnetsClient) CreateOrUpdateSender(req *http.Request) (future SubnetsCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -113,9 +116,10 @@ func (client SubnetsClient) CreateOrUpdateResponder(resp *http.Response) (result } // Delete deletes the specified subnet. -// -// resourceGroupName is the name of the resource group. virtualNetworkName is the name of the virtual network. -// subnetName is the name of the subnet. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkName - the name of the virtual network. +// subnetName - the name of the subnet. func (client SubnetsClient) Delete(ctx context.Context, resourceGroupName string, virtualNetworkName string, subnetName string) (result SubnetsDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, virtualNetworkName, subnetName) if err != nil { @@ -157,15 +161,17 @@ func (client SubnetsClient) DeletePreparer(ctx context.Context, resourceGroupNam // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client SubnetsClient) DeleteSender(req *http.Request) (future SubnetsDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -182,9 +188,11 @@ func (client SubnetsClient) DeleteResponder(resp *http.Response) (result autores } // Get gets the specified subnet by virtual network and resource group. -// -// resourceGroupName is the name of the resource group. virtualNetworkName is the name of the virtual network. -// subnetName is the name of the subnet. expand is expands referenced resources. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkName - the name of the virtual network. +// subnetName - the name of the subnet. +// expand - expands referenced resources. func (client SubnetsClient) Get(ctx context.Context, resourceGroupName string, virtualNetworkName string, subnetName string, expand string) (result Subnet, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, virtualNetworkName, subnetName, expand) if err != nil { @@ -253,8 +261,9 @@ func (client SubnetsClient) GetResponder(resp *http.Response) (result Subnet, er } // List gets all subnets in a virtual network. -// -// resourceGroupName is the name of the resource group. virtualNetworkName is the name of the virtual network. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkName - the name of the virtual network. func (client SubnetsClient) List(ctx context.Context, resourceGroupName string, virtualNetworkName string) (result SubnetListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName, virtualNetworkName) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/usages.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/usages.go index da22b0d62..96b8efdd2 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/usages.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/usages.go @@ -41,8 +41,8 @@ func NewUsagesClientWithBaseURI(baseURI string, subscriptionID string) UsagesCli } // List list network usages for a subscription. -// -// location is the location where resource usage is queried. +// Parameters: +// location - the location where resource usage is queried. func (client UsagesClient) List(ctx context.Context, location string) (result UsagesListResultPage, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: location, diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/virtualnetworkgatewayconnections.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/virtualnetworkgatewayconnections.go index ce5e4ba54..d7a1d50a6 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/virtualnetworkgatewayconnections.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/virtualnetworkgatewayconnections.go @@ -42,10 +42,10 @@ func NewVirtualNetworkGatewayConnectionsClientWithBaseURI(baseURI string, subscr } // CreateOrUpdate creates or updates a virtual network gateway connection in the specified resource group. -// -// resourceGroupName is the name of the resource group. virtualNetworkGatewayConnectionName is the name of the -// virtual network gateway connection. parameters is parameters supplied to the create or update virtual network -// gateway connection operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkGatewayConnectionName - the name of the virtual network gateway connection. +// parameters - parameters supplied to the create or update virtual network gateway connection operation. func (client VirtualNetworkGatewayConnectionsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, virtualNetworkGatewayConnectionName string, parameters VirtualNetworkGatewayConnection) (result VirtualNetworkGatewayConnectionsCreateOrUpdateFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: parameters, @@ -101,15 +101,17 @@ func (client VirtualNetworkGatewayConnectionsClient) CreateOrUpdatePreparer(ctx // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client VirtualNetworkGatewayConnectionsClient) CreateOrUpdateSender(req *http.Request) (future VirtualNetworkGatewayConnectionsCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -127,9 +129,9 @@ func (client VirtualNetworkGatewayConnectionsClient) CreateOrUpdateResponder(res } // Delete deletes the specified virtual network Gateway connection. -// -// resourceGroupName is the name of the resource group. virtualNetworkGatewayConnectionName is the name of the -// virtual network gateway connection. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkGatewayConnectionName - the name of the virtual network gateway connection. func (client VirtualNetworkGatewayConnectionsClient) Delete(ctx context.Context, resourceGroupName string, virtualNetworkGatewayConnectionName string) (result VirtualNetworkGatewayConnectionsDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, virtualNetworkGatewayConnectionName) if err != nil { @@ -170,15 +172,17 @@ func (client VirtualNetworkGatewayConnectionsClient) DeletePreparer(ctx context. // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client VirtualNetworkGatewayConnectionsClient) DeleteSender(req *http.Request) (future VirtualNetworkGatewayConnectionsDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -195,9 +199,9 @@ func (client VirtualNetworkGatewayConnectionsClient) DeleteResponder(resp *http. } // Get gets the specified virtual network gateway connection by resource group. -// -// resourceGroupName is the name of the resource group. virtualNetworkGatewayConnectionName is the name of the -// virtual network gateway connection. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkGatewayConnectionName - the name of the virtual network gateway connection. func (client VirtualNetworkGatewayConnectionsClient) Get(ctx context.Context, resourceGroupName string, virtualNetworkGatewayConnectionName string) (result VirtualNetworkGatewayConnection, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, virtualNetworkGatewayConnectionName) if err != nil { @@ -263,9 +267,9 @@ func (client VirtualNetworkGatewayConnectionsClient) GetResponder(resp *http.Res // GetSharedKey the Get VirtualNetworkGatewayConnectionSharedKey operation retrieves information about the specified // virtual network gateway connection shared key through Network resource provider. -// -// resourceGroupName is the name of the resource group. virtualNetworkGatewayConnectionName is the virtual network -// gateway connection shared key name. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkGatewayConnectionName - the virtual network gateway connection shared key name. func (client VirtualNetworkGatewayConnectionsClient) GetSharedKey(ctx context.Context, resourceGroupName string, virtualNetworkGatewayConnectionName string) (result ConnectionSharedKey, err error) { req, err := client.GetSharedKeyPreparer(ctx, resourceGroupName, virtualNetworkGatewayConnectionName) if err != nil { @@ -331,8 +335,8 @@ func (client VirtualNetworkGatewayConnectionsClient) GetSharedKeyResponder(resp // List the List VirtualNetworkGatewayConnections operation retrieves all the virtual network gateways connections // created. -// -// resourceGroupName is the name of the resource group. +// Parameters: +// resourceGroupName - the name of the resource group. func (client VirtualNetworkGatewayConnectionsClient) List(ctx context.Context, resourceGroupName string) (result VirtualNetworkGatewayConnectionListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName) @@ -426,10 +430,11 @@ func (client VirtualNetworkGatewayConnectionsClient) ListComplete(ctx context.Co // ResetSharedKey the VirtualNetworkGatewayConnectionResetSharedKey operation resets the virtual network gateway // connection shared key for passed virtual network gateway connection in the specified resource group through Network // resource provider. -// -// resourceGroupName is the name of the resource group. virtualNetworkGatewayConnectionName is the virtual network -// gateway connection reset shared key Name. parameters is parameters supplied to the begin reset virtual network -// gateway connection shared key operation through network resource provider. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkGatewayConnectionName - the virtual network gateway connection reset shared key Name. +// parameters - parameters supplied to the begin reset virtual network gateway connection shared key operation +// through network resource provider. func (client VirtualNetworkGatewayConnectionsClient) ResetSharedKey(ctx context.Context, resourceGroupName string, virtualNetworkGatewayConnectionName string, parameters ConnectionResetSharedKey) (result VirtualNetworkGatewayConnectionsResetSharedKeyFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: parameters, @@ -481,15 +486,17 @@ func (client VirtualNetworkGatewayConnectionsClient) ResetSharedKeyPreparer(ctx // ResetSharedKeySender sends the ResetSharedKey request. The method will close the // http.Response Body if it receives an error. func (client VirtualNetworkGatewayConnectionsClient) ResetSharedKeySender(req *http.Request) (future VirtualNetworkGatewayConnectionsResetSharedKeyFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -509,10 +516,11 @@ func (client VirtualNetworkGatewayConnectionsClient) ResetSharedKeyResponder(res // SetSharedKey the Put VirtualNetworkGatewayConnectionSharedKey operation sets the virtual network gateway connection // shared key for passed virtual network gateway connection in the specified resource group through Network resource // provider. -// -// resourceGroupName is the name of the resource group. virtualNetworkGatewayConnectionName is the virtual network -// gateway connection name. parameters is parameters supplied to the Begin Set Virtual Network Gateway connection -// Shared key operation throughNetwork resource provider. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkGatewayConnectionName - the virtual network gateway connection name. +// parameters - parameters supplied to the Begin Set Virtual Network Gateway connection Shared key operation +// throughNetwork resource provider. func (client VirtualNetworkGatewayConnectionsClient) SetSharedKey(ctx context.Context, resourceGroupName string, virtualNetworkGatewayConnectionName string, parameters ConnectionSharedKey) (result VirtualNetworkGatewayConnectionsSetSharedKeyFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: parameters, @@ -561,15 +569,17 @@ func (client VirtualNetworkGatewayConnectionsClient) SetSharedKeyPreparer(ctx co // SetSharedKeySender sends the SetSharedKey request. The method will close the // http.Response Body if it receives an error. func (client VirtualNetworkGatewayConnectionsClient) SetSharedKeySender(req *http.Request) (future VirtualNetworkGatewayConnectionsSetSharedKeyFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -587,10 +597,10 @@ func (client VirtualNetworkGatewayConnectionsClient) SetSharedKeyResponder(resp } // UpdateTags updates a virtual network gateway connection tags. -// -// resourceGroupName is the name of the resource group. virtualNetworkGatewayConnectionName is the name of the -// virtual network gateway connection. parameters is parameters supplied to update virtual network gateway -// connection tags. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkGatewayConnectionName - the name of the virtual network gateway connection. +// parameters - parameters supplied to update virtual network gateway connection tags. func (client VirtualNetworkGatewayConnectionsClient) UpdateTags(ctx context.Context, resourceGroupName string, virtualNetworkGatewayConnectionName string, parameters TagsObject) (result VirtualNetworkGatewayConnectionsUpdateTagsFuture, err error) { req, err := client.UpdateTagsPreparer(ctx, resourceGroupName, virtualNetworkGatewayConnectionName, parameters) if err != nil { @@ -633,15 +643,17 @@ func (client VirtualNetworkGatewayConnectionsClient) UpdateTagsPreparer(ctx cont // UpdateTagsSender sends the UpdateTags request. The method will close the // http.Response Body if it receives an error. func (client VirtualNetworkGatewayConnectionsClient) UpdateTagsSender(req *http.Request) (future VirtualNetworkGatewayConnectionsUpdateTagsFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/virtualnetworkgateways.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/virtualnetworkgateways.go index e6f529514..aa314cddf 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/virtualnetworkgateways.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/virtualnetworkgateways.go @@ -41,9 +41,10 @@ func NewVirtualNetworkGatewaysClientWithBaseURI(baseURI string, subscriptionID s } // CreateOrUpdate creates or updates a virtual network gateway in the specified resource group. -// -// resourceGroupName is the name of the resource group. virtualNetworkGatewayName is the name of the virtual -// network gateway. parameters is parameters supplied to create or update virtual network gateway operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkGatewayName - the name of the virtual network gateway. +// parameters - parameters supplied to create or update virtual network gateway operation. func (client VirtualNetworkGatewaysClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, virtualNetworkGatewayName string, parameters VirtualNetworkGateway) (result VirtualNetworkGatewaysCreateOrUpdateFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: parameters, @@ -92,15 +93,17 @@ func (client VirtualNetworkGatewaysClient) CreateOrUpdatePreparer(ctx context.Co // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client VirtualNetworkGatewaysClient) CreateOrUpdateSender(req *http.Request) (future VirtualNetworkGatewaysCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -118,9 +121,9 @@ func (client VirtualNetworkGatewaysClient) CreateOrUpdateResponder(resp *http.Re } // Delete deletes the specified virtual network gateway. -// -// resourceGroupName is the name of the resource group. virtualNetworkGatewayName is the name of the virtual -// network gateway. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkGatewayName - the name of the virtual network gateway. func (client VirtualNetworkGatewaysClient) Delete(ctx context.Context, resourceGroupName string, virtualNetworkGatewayName string) (result VirtualNetworkGatewaysDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, virtualNetworkGatewayName) if err != nil { @@ -161,15 +164,17 @@ func (client VirtualNetworkGatewaysClient) DeletePreparer(ctx context.Context, r // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client VirtualNetworkGatewaysClient) DeleteSender(req *http.Request) (future VirtualNetworkGatewaysDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -187,10 +192,10 @@ func (client VirtualNetworkGatewaysClient) DeleteResponder(resp *http.Response) // Generatevpnclientpackage generates VPN client package for P2S client of the virtual network gateway in the specified // resource group. -// -// resourceGroupName is the name of the resource group. virtualNetworkGatewayName is the name of the virtual -// network gateway. parameters is parameters supplied to the generate virtual network gateway VPN client package -// operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkGatewayName - the name of the virtual network gateway. +// parameters - parameters supplied to the generate virtual network gateway VPN client package operation. func (client VirtualNetworkGatewaysClient) Generatevpnclientpackage(ctx context.Context, resourceGroupName string, virtualNetworkGatewayName string, parameters VpnClientParameters) (result VirtualNetworkGatewaysGeneratevpnclientpackageFuture, err error) { req, err := client.GeneratevpnclientpackagePreparer(ctx, resourceGroupName, virtualNetworkGatewayName, parameters) if err != nil { @@ -233,15 +238,17 @@ func (client VirtualNetworkGatewaysClient) GeneratevpnclientpackagePreparer(ctx // GeneratevpnclientpackageSender sends the Generatevpnclientpackage request. The method will close the // http.Response Body if it receives an error. func (client VirtualNetworkGatewaysClient) GeneratevpnclientpackageSender(req *http.Request) (future VirtualNetworkGatewaysGeneratevpnclientpackageFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -260,10 +267,10 @@ func (client VirtualNetworkGatewaysClient) GeneratevpnclientpackageResponder(res // GenerateVpnProfile generates VPN profile for P2S client of the virtual network gateway in the specified resource // group. Used for IKEV2 and radius based authentication. -// -// resourceGroupName is the name of the resource group. virtualNetworkGatewayName is the name of the virtual -// network gateway. parameters is parameters supplied to the generate virtual network gateway VPN client package -// operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkGatewayName - the name of the virtual network gateway. +// parameters - parameters supplied to the generate virtual network gateway VPN client package operation. func (client VirtualNetworkGatewaysClient) GenerateVpnProfile(ctx context.Context, resourceGroupName string, virtualNetworkGatewayName string, parameters VpnClientParameters) (result VirtualNetworkGatewaysGenerateVpnProfileFuture, err error) { req, err := client.GenerateVpnProfilePreparer(ctx, resourceGroupName, virtualNetworkGatewayName, parameters) if err != nil { @@ -306,15 +313,17 @@ func (client VirtualNetworkGatewaysClient) GenerateVpnProfilePreparer(ctx contex // GenerateVpnProfileSender sends the GenerateVpnProfile request. The method will close the // http.Response Body if it receives an error. func (client VirtualNetworkGatewaysClient) GenerateVpnProfileSender(req *http.Request) (future VirtualNetworkGatewaysGenerateVpnProfileFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -332,9 +341,9 @@ func (client VirtualNetworkGatewaysClient) GenerateVpnProfileResponder(resp *htt } // Get gets the specified virtual network gateway by resource group. -// -// resourceGroupName is the name of the resource group. virtualNetworkGatewayName is the name of the virtual -// network gateway. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkGatewayName - the name of the virtual network gateway. func (client VirtualNetworkGatewaysClient) Get(ctx context.Context, resourceGroupName string, virtualNetworkGatewayName string) (result VirtualNetworkGateway, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, virtualNetworkGatewayName) if err != nil { @@ -400,9 +409,10 @@ func (client VirtualNetworkGatewaysClient) GetResponder(resp *http.Response) (re // GetAdvertisedRoutes this operation retrieves a list of routes the virtual network gateway is advertising to the // specified peer. -// -// resourceGroupName is the name of the resource group. virtualNetworkGatewayName is the name of the virtual -// network gateway. peer is the IP address of the peer +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkGatewayName - the name of the virtual network gateway. +// peer - the IP address of the peer func (client VirtualNetworkGatewaysClient) GetAdvertisedRoutes(ctx context.Context, resourceGroupName string, virtualNetworkGatewayName string, peer string) (result VirtualNetworkGatewaysGetAdvertisedRoutesFuture, err error) { req, err := client.GetAdvertisedRoutesPreparer(ctx, resourceGroupName, virtualNetworkGatewayName, peer) if err != nil { @@ -444,15 +454,17 @@ func (client VirtualNetworkGatewaysClient) GetAdvertisedRoutesPreparer(ctx conte // GetAdvertisedRoutesSender sends the GetAdvertisedRoutes request. The method will close the // http.Response Body if it receives an error. func (client VirtualNetworkGatewaysClient) GetAdvertisedRoutesSender(req *http.Request) (future VirtualNetworkGatewaysGetAdvertisedRoutesFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -470,9 +482,10 @@ func (client VirtualNetworkGatewaysClient) GetAdvertisedRoutesResponder(resp *ht } // GetBgpPeerStatus the GetBgpPeerStatus operation retrieves the status of all BGP peers. -// -// resourceGroupName is the name of the resource group. virtualNetworkGatewayName is the name of the virtual -// network gateway. peer is the IP address of the peer to retrieve the status of. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkGatewayName - the name of the virtual network gateway. +// peer - the IP address of the peer to retrieve the status of. func (client VirtualNetworkGatewaysClient) GetBgpPeerStatus(ctx context.Context, resourceGroupName string, virtualNetworkGatewayName string, peer string) (result VirtualNetworkGatewaysGetBgpPeerStatusFuture, err error) { req, err := client.GetBgpPeerStatusPreparer(ctx, resourceGroupName, virtualNetworkGatewayName, peer) if err != nil { @@ -516,15 +529,17 @@ func (client VirtualNetworkGatewaysClient) GetBgpPeerStatusPreparer(ctx context. // GetBgpPeerStatusSender sends the GetBgpPeerStatus request. The method will close the // http.Response Body if it receives an error. func (client VirtualNetworkGatewaysClient) GetBgpPeerStatusSender(req *http.Request) (future VirtualNetworkGatewaysGetBgpPeerStatusFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -543,9 +558,9 @@ func (client VirtualNetworkGatewaysClient) GetBgpPeerStatusResponder(resp *http. // GetLearnedRoutes this operation retrieves a list of routes the virtual network gateway has learned, including routes // learned from BGP peers. -// -// resourceGroupName is the name of the resource group. virtualNetworkGatewayName is the name of the virtual -// network gateway. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkGatewayName - the name of the virtual network gateway. func (client VirtualNetworkGatewaysClient) GetLearnedRoutes(ctx context.Context, resourceGroupName string, virtualNetworkGatewayName string) (result VirtualNetworkGatewaysGetLearnedRoutesFuture, err error) { req, err := client.GetLearnedRoutesPreparer(ctx, resourceGroupName, virtualNetworkGatewayName) if err != nil { @@ -586,15 +601,17 @@ func (client VirtualNetworkGatewaysClient) GetLearnedRoutesPreparer(ctx context. // GetLearnedRoutesSender sends the GetLearnedRoutes request. The method will close the // http.Response Body if it receives an error. func (client VirtualNetworkGatewaysClient) GetLearnedRoutesSender(req *http.Request) (future VirtualNetworkGatewaysGetLearnedRoutesFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -613,9 +630,9 @@ func (client VirtualNetworkGatewaysClient) GetLearnedRoutesResponder(resp *http. // GetVpnProfilePackageURL gets pre-generated VPN profile for P2S client of the virtual network gateway in the // specified resource group. The profile needs to be generated first using generateVpnProfile. -// -// resourceGroupName is the name of the resource group. virtualNetworkGatewayName is the name of the virtual -// network gateway. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkGatewayName - the name of the virtual network gateway. func (client VirtualNetworkGatewaysClient) GetVpnProfilePackageURL(ctx context.Context, resourceGroupName string, virtualNetworkGatewayName string) (result VirtualNetworkGatewaysGetVpnProfilePackageURLFuture, err error) { req, err := client.GetVpnProfilePackageURLPreparer(ctx, resourceGroupName, virtualNetworkGatewayName) if err != nil { @@ -656,15 +673,17 @@ func (client VirtualNetworkGatewaysClient) GetVpnProfilePackageURLPreparer(ctx c // GetVpnProfilePackageURLSender sends the GetVpnProfilePackageURL request. The method will close the // http.Response Body if it receives an error. func (client VirtualNetworkGatewaysClient) GetVpnProfilePackageURLSender(req *http.Request) (future VirtualNetworkGatewaysGetVpnProfilePackageURLFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -682,8 +701,8 @@ func (client VirtualNetworkGatewaysClient) GetVpnProfilePackageURLResponder(resp } // List gets all virtual network gateways by resource group. -// -// resourceGroupName is the name of the resource group. +// Parameters: +// resourceGroupName - the name of the resource group. func (client VirtualNetworkGatewaysClient) List(ctx context.Context, resourceGroupName string) (result VirtualNetworkGatewayListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName) @@ -775,9 +794,9 @@ func (client VirtualNetworkGatewaysClient) ListComplete(ctx context.Context, res } // ListConnections gets all the connections in a virtual network gateway. -// -// resourceGroupName is the name of the resource group. virtualNetworkGatewayName is the name of the virtual -// network gateway. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkGatewayName - the name of the virtual network gateway. func (client VirtualNetworkGatewaysClient) ListConnections(ctx context.Context, resourceGroupName string, virtualNetworkGatewayName string) (result VirtualNetworkGatewayListConnectionsResultPage, err error) { result.fn = client.listConnectionsNextResults req, err := client.ListConnectionsPreparer(ctx, resourceGroupName, virtualNetworkGatewayName) @@ -870,10 +889,11 @@ func (client VirtualNetworkGatewaysClient) ListConnectionsComplete(ctx context.C } // Reset resets the primary of the virtual network gateway in the specified resource group. -// -// resourceGroupName is the name of the resource group. virtualNetworkGatewayName is the name of the virtual -// network gateway. gatewayVip is virtual network gateway vip address supplied to the begin reset of the -// active-active feature enabled gateway. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkGatewayName - the name of the virtual network gateway. +// gatewayVip - virtual network gateway vip address supplied to the begin reset of the active-active feature +// enabled gateway. func (client VirtualNetworkGatewaysClient) Reset(ctx context.Context, resourceGroupName string, virtualNetworkGatewayName string, gatewayVip string) (result VirtualNetworkGatewaysResetFuture, err error) { req, err := client.ResetPreparer(ctx, resourceGroupName, virtualNetworkGatewayName, gatewayVip) if err != nil { @@ -917,15 +937,17 @@ func (client VirtualNetworkGatewaysClient) ResetPreparer(ctx context.Context, re // ResetSender sends the Reset request. The method will close the // http.Response Body if it receives an error. func (client VirtualNetworkGatewaysClient) ResetSender(req *http.Request) (future VirtualNetworkGatewaysResetFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -943,9 +965,9 @@ func (client VirtualNetworkGatewaysClient) ResetResponder(resp *http.Response) ( } // SupportedVpnDevices gets a xml format representation for supported vpn devices. -// -// resourceGroupName is the name of the resource group. virtualNetworkGatewayName is the name of the virtual -// network gateway. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkGatewayName - the name of the virtual network gateway. func (client VirtualNetworkGatewaysClient) SupportedVpnDevices(ctx context.Context, resourceGroupName string, virtualNetworkGatewayName string) (result String, err error) { req, err := client.SupportedVpnDevicesPreparer(ctx, resourceGroupName, virtualNetworkGatewayName) if err != nil { @@ -1010,9 +1032,10 @@ func (client VirtualNetworkGatewaysClient) SupportedVpnDevicesResponder(resp *ht } // UpdateTags updates a virtual network gateway tags. -// -// resourceGroupName is the name of the resource group. virtualNetworkGatewayName is the name of the virtual -// network gateway. parameters is parameters supplied to update virtual network gateway tags. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkGatewayName - the name of the virtual network gateway. +// parameters - parameters supplied to update virtual network gateway tags. func (client VirtualNetworkGatewaysClient) UpdateTags(ctx context.Context, resourceGroupName string, virtualNetworkGatewayName string, parameters TagsObject) (result VirtualNetworkGatewaysUpdateTagsFuture, err error) { req, err := client.UpdateTagsPreparer(ctx, resourceGroupName, virtualNetworkGatewayName, parameters) if err != nil { @@ -1055,15 +1078,17 @@ func (client VirtualNetworkGatewaysClient) UpdateTagsPreparer(ctx context.Contex // UpdateTagsSender sends the UpdateTags request. The method will close the // http.Response Body if it receives an error. func (client VirtualNetworkGatewaysClient) UpdateTagsSender(req *http.Request) (future VirtualNetworkGatewaysUpdateTagsFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -1081,10 +1106,11 @@ func (client VirtualNetworkGatewaysClient) UpdateTagsResponder(resp *http.Respon } // VpnDeviceConfigurationScript gets a xml format representation for vpn device configuration script. -// -// resourceGroupName is the name of the resource group. virtualNetworkGatewayConnectionName is the name of the -// virtual network gateway connection for which the configuration script is generated. parameters is parameters -// supplied to the generate vpn device script operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkGatewayConnectionName - the name of the virtual network gateway connection for which the +// configuration script is generated. +// parameters - parameters supplied to the generate vpn device script operation. func (client VirtualNetworkGatewaysClient) VpnDeviceConfigurationScript(ctx context.Context, resourceGroupName string, virtualNetworkGatewayConnectionName string, parameters VpnDeviceScriptParameters) (result String, err error) { req, err := client.VpnDeviceConfigurationScriptPreparer(ctx, resourceGroupName, virtualNetworkGatewayConnectionName, parameters) if err != nil { diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/virtualnetworkpeerings.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/virtualnetworkpeerings.go index ee5dcd2db..8b6b0765d 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/virtualnetworkpeerings.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/virtualnetworkpeerings.go @@ -40,10 +40,12 @@ func NewVirtualNetworkPeeringsClientWithBaseURI(baseURI string, subscriptionID s } // CreateOrUpdate creates or updates a peering in the specified virtual network. -// -// resourceGroupName is the name of the resource group. virtualNetworkName is the name of the virtual network. -// virtualNetworkPeeringName is the name of the peering. virtualNetworkPeeringParameters is parameters supplied to -// the create or update virtual network peering operation. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkName - the name of the virtual network. +// virtualNetworkPeeringName - the name of the peering. +// virtualNetworkPeeringParameters - parameters supplied to the create or update virtual network peering +// operation. func (client VirtualNetworkPeeringsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, virtualNetworkName string, virtualNetworkPeeringName string, virtualNetworkPeeringParameters VirtualNetworkPeering) (result VirtualNetworkPeeringsCreateOrUpdateFuture, err error) { req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, virtualNetworkName, virtualNetworkPeeringName, virtualNetworkPeeringParameters) if err != nil { @@ -87,15 +89,17 @@ func (client VirtualNetworkPeeringsClient) CreateOrUpdatePreparer(ctx context.Co // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client VirtualNetworkPeeringsClient) CreateOrUpdateSender(req *http.Request) (future VirtualNetworkPeeringsCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -113,9 +117,10 @@ func (client VirtualNetworkPeeringsClient) CreateOrUpdateResponder(resp *http.Re } // Delete deletes the specified virtual network peering. -// -// resourceGroupName is the name of the resource group. virtualNetworkName is the name of the virtual network. -// virtualNetworkPeeringName is the name of the virtual network peering. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkName - the name of the virtual network. +// virtualNetworkPeeringName - the name of the virtual network peering. func (client VirtualNetworkPeeringsClient) Delete(ctx context.Context, resourceGroupName string, virtualNetworkName string, virtualNetworkPeeringName string) (result VirtualNetworkPeeringsDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, virtualNetworkName, virtualNetworkPeeringName) if err != nil { @@ -157,15 +162,17 @@ func (client VirtualNetworkPeeringsClient) DeletePreparer(ctx context.Context, r // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client VirtualNetworkPeeringsClient) DeleteSender(req *http.Request) (future VirtualNetworkPeeringsDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -182,9 +189,10 @@ func (client VirtualNetworkPeeringsClient) DeleteResponder(resp *http.Response) } // Get gets the specified virtual network peering. -// -// resourceGroupName is the name of the resource group. virtualNetworkName is the name of the virtual network. -// virtualNetworkPeeringName is the name of the virtual network peering. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkName - the name of the virtual network. +// virtualNetworkPeeringName - the name of the virtual network peering. func (client VirtualNetworkPeeringsClient) Get(ctx context.Context, resourceGroupName string, virtualNetworkName string, virtualNetworkPeeringName string) (result VirtualNetworkPeering, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, virtualNetworkName, virtualNetworkPeeringName) if err != nil { @@ -250,8 +258,9 @@ func (client VirtualNetworkPeeringsClient) GetResponder(resp *http.Response) (re } // List gets all virtual network peerings in a virtual network. -// -// resourceGroupName is the name of the resource group. virtualNetworkName is the name of the virtual network. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkName - the name of the virtual network. func (client VirtualNetworkPeeringsClient) List(ctx context.Context, resourceGroupName string, virtualNetworkName string) (result VirtualNetworkPeeringListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName, virtualNetworkName) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/virtualnetworks.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/virtualnetworks.go index 8f947161b..261bdb40d 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/virtualnetworks.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/virtualnetworks.go @@ -40,9 +40,10 @@ func NewVirtualNetworksClientWithBaseURI(baseURI string, subscriptionID string) } // CheckIPAddressAvailability checks whether a private IP address is available for use. -// -// resourceGroupName is the name of the resource group. virtualNetworkName is the name of the virtual network. -// IPAddress is the private IP address to be verified. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkName - the name of the virtual network. +// IPAddress - the private IP address to be verified. func (client VirtualNetworksClient) CheckIPAddressAvailability(ctx context.Context, resourceGroupName string, virtualNetworkName string, IPAddress string) (result IPAddressAvailabilityResult, err error) { req, err := client.CheckIPAddressAvailabilityPreparer(ctx, resourceGroupName, virtualNetworkName, IPAddress) if err != nil { @@ -110,9 +111,10 @@ func (client VirtualNetworksClient) CheckIPAddressAvailabilityResponder(resp *ht } // CreateOrUpdate creates or updates a virtual network in the specified resource group. -// -// resourceGroupName is the name of the resource group. virtualNetworkName is the name of the virtual network. -// parameters is parameters supplied to the create or update virtual network operation +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkName - the name of the virtual network. +// parameters - parameters supplied to the create or update virtual network operation func (client VirtualNetworksClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, virtualNetworkName string, parameters VirtualNetwork) (result VirtualNetworksCreateOrUpdateFuture, err error) { req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, virtualNetworkName, parameters) if err != nil { @@ -155,15 +157,17 @@ func (client VirtualNetworksClient) CreateOrUpdatePreparer(ctx context.Context, // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client VirtualNetworksClient) CreateOrUpdateSender(req *http.Request) (future VirtualNetworksCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -181,8 +185,9 @@ func (client VirtualNetworksClient) CreateOrUpdateResponder(resp *http.Response) } // Delete deletes the specified virtual network. -// -// resourceGroupName is the name of the resource group. virtualNetworkName is the name of the virtual network. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkName - the name of the virtual network. func (client VirtualNetworksClient) Delete(ctx context.Context, resourceGroupName string, virtualNetworkName string) (result VirtualNetworksDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, virtualNetworkName) if err != nil { @@ -223,15 +228,17 @@ func (client VirtualNetworksClient) DeletePreparer(ctx context.Context, resource // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client VirtualNetworksClient) DeleteSender(req *http.Request) (future VirtualNetworksDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -248,9 +255,10 @@ func (client VirtualNetworksClient) DeleteResponder(resp *http.Response) (result } // Get gets the specified virtual network by resource group. -// -// resourceGroupName is the name of the resource group. virtualNetworkName is the name of the virtual network. -// expand is expands referenced resources. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkName - the name of the virtual network. +// expand - expands referenced resources. func (client VirtualNetworksClient) Get(ctx context.Context, resourceGroupName string, virtualNetworkName string, expand string) (result VirtualNetwork, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, virtualNetworkName, expand) if err != nil { @@ -318,8 +326,8 @@ func (client VirtualNetworksClient) GetResponder(resp *http.Response) (result Vi } // List gets all virtual networks in a resource group. -// -// resourceGroupName is the name of the resource group. +// Parameters: +// resourceGroupName - the name of the resource group. func (client VirtualNetworksClient) List(ctx context.Context, resourceGroupName string) (result VirtualNetworkListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, resourceGroupName) @@ -501,8 +509,9 @@ func (client VirtualNetworksClient) ListAllComplete(ctx context.Context) (result } // ListUsage lists usage stats. -// -// resourceGroupName is the name of the resource group. virtualNetworkName is the name of the virtual network. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkName - the name of the virtual network. func (client VirtualNetworksClient) ListUsage(ctx context.Context, resourceGroupName string, virtualNetworkName string) (result VirtualNetworkListUsageResultPage, err error) { result.fn = client.listUsageNextResults req, err := client.ListUsagePreparer(ctx, resourceGroupName, virtualNetworkName) @@ -595,9 +604,10 @@ func (client VirtualNetworksClient) ListUsageComplete(ctx context.Context, resou } // UpdateTags updates a virtual network tags. -// -// resourceGroupName is the name of the resource group. virtualNetworkName is the name of the virtual network. -// parameters is parameters supplied to update virtual network tags. +// Parameters: +// resourceGroupName - the name of the resource group. +// virtualNetworkName - the name of the virtual network. +// parameters - parameters supplied to update virtual network tags. func (client VirtualNetworksClient) UpdateTags(ctx context.Context, resourceGroupName string, virtualNetworkName string, parameters TagsObject) (result VirtualNetworksUpdateTagsFuture, err error) { req, err := client.UpdateTagsPreparer(ctx, resourceGroupName, virtualNetworkName, parameters) if err != nil { @@ -640,15 +650,17 @@ func (client VirtualNetworksClient) UpdateTagsPreparer(ctx context.Context, reso // UpdateTagsSender sends the UpdateTags request. The method will close the // http.Response Body if it receives an error. func (client VirtualNetworksClient) UpdateTagsSender(req *http.Request) (future VirtualNetworksUpdateTagsFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/watchers.go b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/watchers.go index 1d5f6decb..877534e4e 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/watchers.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/watchers.go @@ -42,9 +42,10 @@ func NewWatchersClientWithBaseURI(baseURI string, subscriptionID string) Watcher // CheckConnectivity verifies the possibility of establishing a direct TCP connection from a virtual machine to a given // endpoint including another VM or an arbitrary remote server. -// -// resourceGroupName is the name of the network watcher resource group. networkWatcherName is the name of the -// network watcher resource. parameters is parameters that determine how the connectivity check will be performed. +// Parameters: +// resourceGroupName - the name of the network watcher resource group. +// networkWatcherName - the name of the network watcher resource. +// parameters - parameters that determine how the connectivity check will be performed. func (client WatchersClient) CheckConnectivity(ctx context.Context, resourceGroupName string, networkWatcherName string, parameters ConnectivityParameters) (result WatchersCheckConnectivityFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: parameters, @@ -95,15 +96,17 @@ func (client WatchersClient) CheckConnectivityPreparer(ctx context.Context, reso // CheckConnectivitySender sends the CheckConnectivity request. The method will close the // http.Response Body if it receives an error. func (client WatchersClient) CheckConnectivitySender(req *http.Request) (future WatchersCheckConnectivityFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -121,9 +124,10 @@ func (client WatchersClient) CheckConnectivityResponder(resp *http.Response) (re } // CreateOrUpdate creates or updates a network watcher in the specified resource group. -// -// resourceGroupName is the name of the resource group. networkWatcherName is the name of the network watcher. -// parameters is parameters that define the network watcher resource. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkWatcherName - the name of the network watcher. +// parameters - parameters that define the network watcher resource. func (client WatchersClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, networkWatcherName string, parameters Watcher) (result Watcher, err error) { req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, networkWatcherName, parameters) if err != nil { @@ -190,8 +194,9 @@ func (client WatchersClient) CreateOrUpdateResponder(resp *http.Response) (resul } // Delete deletes the specified network watcher resource. -// -// resourceGroupName is the name of the resource group. networkWatcherName is the name of the network watcher. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkWatcherName - the name of the network watcher. func (client WatchersClient) Delete(ctx context.Context, resourceGroupName string, networkWatcherName string) (result WatchersDeleteFuture, err error) { req, err := client.DeletePreparer(ctx, resourceGroupName, networkWatcherName) if err != nil { @@ -232,15 +237,17 @@ func (client WatchersClient) DeletePreparer(ctx context.Context, resourceGroupNa // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client WatchersClient) DeleteSender(req *http.Request) (future WatchersDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -257,8 +264,9 @@ func (client WatchersClient) DeleteResponder(resp *http.Response) (result autore } // Get gets the specified network watcher by resource group. -// -// resourceGroupName is the name of the resource group. networkWatcherName is the name of the network watcher. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkWatcherName - the name of the network watcher. func (client WatchersClient) Get(ctx context.Context, resourceGroupName string, networkWatcherName string) (result Watcher, err error) { req, err := client.GetPreparer(ctx, resourceGroupName, networkWatcherName) if err != nil { @@ -324,9 +332,10 @@ func (client WatchersClient) GetResponder(resp *http.Response) (result Watcher, // GetAzureReachabilityReport gets the relative latency score for internet service providers from a specified location // to Azure regions. -// -// resourceGroupName is the name of the network watcher resource group. networkWatcherName is the name of the -// network watcher resource. parameters is parameters that determine Azure reachability report configuration. +// Parameters: +// resourceGroupName - the name of the network watcher resource group. +// networkWatcherName - the name of the network watcher resource. +// parameters - parameters that determine Azure reachability report configuration. func (client WatchersClient) GetAzureReachabilityReport(ctx context.Context, resourceGroupName string, networkWatcherName string, parameters AzureReachabilityReportParameters) (result WatchersGetAzureReachabilityReportFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: parameters, @@ -378,15 +387,17 @@ func (client WatchersClient) GetAzureReachabilityReportPreparer(ctx context.Cont // GetAzureReachabilityReportSender sends the GetAzureReachabilityReport request. The method will close the // http.Response Body if it receives an error. func (client WatchersClient) GetAzureReachabilityReportSender(req *http.Request) (future WatchersGetAzureReachabilityReportFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -404,10 +415,10 @@ func (client WatchersClient) GetAzureReachabilityReportResponder(resp *http.Resp } // GetFlowLogStatus queries status of flow log and traffic analytics (optional) on a specified resource. -// -// resourceGroupName is the name of the network watcher resource group. networkWatcherName is the name of the -// network watcher resource. parameters is parameters that define a resource to query flow log and traffic -// analytics (optional) status. +// Parameters: +// resourceGroupName - the name of the network watcher resource group. +// networkWatcherName - the name of the network watcher resource. +// parameters - parameters that define a resource to query flow log and traffic analytics (optional) status. func (client WatchersClient) GetFlowLogStatus(ctx context.Context, resourceGroupName string, networkWatcherName string, parameters FlowLogStatusParameters) (result WatchersGetFlowLogStatusFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: parameters, @@ -456,15 +467,17 @@ func (client WatchersClient) GetFlowLogStatusPreparer(ctx context.Context, resou // GetFlowLogStatusSender sends the GetFlowLogStatus request. The method will close the // http.Response Body if it receives an error. func (client WatchersClient) GetFlowLogStatusSender(req *http.Request) (future WatchersGetFlowLogStatusFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -482,9 +495,10 @@ func (client WatchersClient) GetFlowLogStatusResponder(resp *http.Response) (res } // GetNextHop gets the next hop from the specified VM. -// -// resourceGroupName is the name of the resource group. networkWatcherName is the name of the network watcher. -// parameters is parameters that define the source and destination endpoint. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkWatcherName - the name of the network watcher. +// parameters - parameters that define the source and destination endpoint. func (client WatchersClient) GetNextHop(ctx context.Context, resourceGroupName string, networkWatcherName string, parameters NextHopParameters) (result WatchersGetNextHopFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: parameters, @@ -535,15 +549,17 @@ func (client WatchersClient) GetNextHopPreparer(ctx context.Context, resourceGro // GetNextHopSender sends the GetNextHop request. The method will close the // http.Response Body if it receives an error. func (client WatchersClient) GetNextHopSender(req *http.Request) (future WatchersGetNextHopFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -561,9 +577,10 @@ func (client WatchersClient) GetNextHopResponder(resp *http.Response) (result Ne } // GetTopology gets the current network topology by resource group. -// -// resourceGroupName is the name of the resource group. networkWatcherName is the name of the network watcher. -// parameters is parameters that define the representation of topology. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkWatcherName - the name of the network watcher. +// parameters - parameters that define the representation of topology. func (client WatchersClient) GetTopology(ctx context.Context, resourceGroupName string, networkWatcherName string, parameters TopologyParameters) (result Topology, err error) { req, err := client.GetTopologyPreparer(ctx, resourceGroupName, networkWatcherName, parameters) if err != nil { @@ -630,9 +647,10 @@ func (client WatchersClient) GetTopologyResponder(resp *http.Response) (result T } // GetTroubleshooting initiate troubleshooting on a specified resource -// -// resourceGroupName is the name of the resource group. networkWatcherName is the name of the network watcher -// resource. parameters is parameters that define the resource to troubleshoot. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkWatcherName - the name of the network watcher resource. +// parameters - parameters that define the resource to troubleshoot. func (client WatchersClient) GetTroubleshooting(ctx context.Context, resourceGroupName string, networkWatcherName string, parameters TroubleshootingParameters) (result WatchersGetTroubleshootingFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: parameters, @@ -685,15 +703,17 @@ func (client WatchersClient) GetTroubleshootingPreparer(ctx context.Context, res // GetTroubleshootingSender sends the GetTroubleshooting request. The method will close the // http.Response Body if it receives an error. func (client WatchersClient) GetTroubleshootingSender(req *http.Request) (future WatchersGetTroubleshootingFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -711,9 +731,10 @@ func (client WatchersClient) GetTroubleshootingResponder(resp *http.Response) (r } // GetTroubleshootingResult get the last completed troubleshooting result on a specified resource -// -// resourceGroupName is the name of the resource group. networkWatcherName is the name of the network watcher -// resource. parameters is parameters that define the resource to query the troubleshooting result. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkWatcherName - the name of the network watcher resource. +// parameters - parameters that define the resource to query the troubleshooting result. func (client WatchersClient) GetTroubleshootingResult(ctx context.Context, resourceGroupName string, networkWatcherName string, parameters QueryTroubleshootingParameters) (result WatchersGetTroubleshootingResultFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: parameters, @@ -762,15 +783,17 @@ func (client WatchersClient) GetTroubleshootingResultPreparer(ctx context.Contex // GetTroubleshootingResultSender sends the GetTroubleshootingResult request. The method will close the // http.Response Body if it receives an error. func (client WatchersClient) GetTroubleshootingResultSender(req *http.Request) (future WatchersGetTroubleshootingResultFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -788,9 +811,10 @@ func (client WatchersClient) GetTroubleshootingResultResponder(resp *http.Respon } // GetVMSecurityRules gets the configured and effective security group rules on the specified VM. -// -// resourceGroupName is the name of the resource group. networkWatcherName is the name of the network watcher. -// parameters is parameters that define the VM to check security groups for. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkWatcherName - the name of the network watcher. +// parameters - parameters that define the VM to check security groups for. func (client WatchersClient) GetVMSecurityRules(ctx context.Context, resourceGroupName string, networkWatcherName string, parameters SecurityGroupViewParameters) (result WatchersGetVMSecurityRulesFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: parameters, @@ -839,15 +863,17 @@ func (client WatchersClient) GetVMSecurityRulesPreparer(ctx context.Context, res // GetVMSecurityRulesSender sends the GetVMSecurityRules request. The method will close the // http.Response Body if it receives an error. func (client WatchersClient) GetVMSecurityRulesSender(req *http.Request) (future WatchersGetVMSecurityRulesFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -865,8 +891,8 @@ func (client WatchersClient) GetVMSecurityRulesResponder(resp *http.Response) (r } // List gets all network watchers by resource group. -// -// resourceGroupName is the name of the resource group. +// Parameters: +// resourceGroupName - the name of the resource group. func (client WatchersClient) List(ctx context.Context, resourceGroupName string) (result WatcherListResult, err error) { req, err := client.ListPreparer(ctx, resourceGroupName) if err != nil { @@ -992,9 +1018,10 @@ func (client WatchersClient) ListAllResponder(resp *http.Response) (result Watch } // ListAvailableProviders lists all available internet service providers for a specified Azure region. -// -// resourceGroupName is the name of the network watcher resource group. networkWatcherName is the name of the -// network watcher resource. parameters is parameters that scope the list of available providers. +// Parameters: +// resourceGroupName - the name of the network watcher resource group. +// networkWatcherName - the name of the network watcher resource. +// parameters - parameters that scope the list of available providers. func (client WatchersClient) ListAvailableProviders(ctx context.Context, resourceGroupName string, networkWatcherName string, parameters AvailableProvidersListParameters) (result WatchersListAvailableProvidersFuture, err error) { req, err := client.ListAvailableProvidersPreparer(ctx, resourceGroupName, networkWatcherName, parameters) if err != nil { @@ -1037,15 +1064,17 @@ func (client WatchersClient) ListAvailableProvidersPreparer(ctx context.Context, // ListAvailableProvidersSender sends the ListAvailableProviders request. The method will close the // http.Response Body if it receives an error. func (client WatchersClient) ListAvailableProvidersSender(req *http.Request) (future WatchersListAvailableProvidersFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -1063,9 +1092,10 @@ func (client WatchersClient) ListAvailableProvidersResponder(resp *http.Response } // SetFlowLogConfiguration configures flow log and traffic analytics (optional) on a specified resource. -// -// resourceGroupName is the name of the network watcher resource group. networkWatcherName is the name of the -// network watcher resource. parameters is parameters that define the configuration of flow log. +// Parameters: +// resourceGroupName - the name of the network watcher resource group. +// networkWatcherName - the name of the network watcher resource. +// parameters - parameters that define the configuration of flow log. func (client WatchersClient) SetFlowLogConfiguration(ctx context.Context, resourceGroupName string, networkWatcherName string, parameters FlowLogInformation) (result WatchersSetFlowLogConfigurationFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: parameters, @@ -1126,15 +1156,17 @@ func (client WatchersClient) SetFlowLogConfigurationPreparer(ctx context.Context // SetFlowLogConfigurationSender sends the SetFlowLogConfiguration request. The method will close the // http.Response Body if it receives an error. func (client WatchersClient) SetFlowLogConfigurationSender(req *http.Request) (future WatchersSetFlowLogConfigurationFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -1152,9 +1184,10 @@ func (client WatchersClient) SetFlowLogConfigurationResponder(resp *http.Respons } // UpdateTags updates a network watcher tags. -// -// resourceGroupName is the name of the resource group. networkWatcherName is the name of the network watcher. -// parameters is parameters supplied to update network watcher tags. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkWatcherName - the name of the network watcher. +// parameters - parameters supplied to update network watcher tags. func (client WatchersClient) UpdateTags(ctx context.Context, resourceGroupName string, networkWatcherName string, parameters TagsObject) (result Watcher, err error) { req, err := client.UpdateTagsPreparer(ctx, resourceGroupName, networkWatcherName, parameters) if err != nil { @@ -1221,9 +1254,10 @@ func (client WatchersClient) UpdateTagsResponder(resp *http.Response) (result Wa } // VerifyIPFlow verify IP flow from the specified VM to a location given the currently configured NSG rules. -// -// resourceGroupName is the name of the resource group. networkWatcherName is the name of the network watcher. -// parameters is parameters that define the IP flow to be verified. +// Parameters: +// resourceGroupName - the name of the resource group. +// networkWatcherName - the name of the network watcher. +// parameters - parameters that define the IP flow to be verified. func (client WatchersClient) VerifyIPFlow(ctx context.Context, resourceGroupName string, networkWatcherName string, parameters VerificationIPFlowParameters) (result WatchersVerifyIPFlowFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: parameters, @@ -1276,15 +1310,17 @@ func (client WatchersClient) VerifyIPFlowPreparer(ctx context.Context, resourceG // VerifyIPFlowSender sends the VerifyIPFlow request. The method will close the // http.Response Body if it receives an error. func (client WatchersClient) VerifyIPFlowSender(req *http.Request) (future WatchersVerifyIPFlowFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2016-06-01/subscriptions/subscriptions.go b/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2016-06-01/subscriptions/subscriptions.go index 33474add3..ecbd69126 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2016-06-01/subscriptions/subscriptions.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2016-06-01/subscriptions/subscriptions.go @@ -42,8 +42,8 @@ func NewClientWithBaseURI(baseURI string) Client { } // Get gets details about a specified subscription. -// -// subscriptionID is the ID of the target subscription. +// Parameters: +// subscriptionID - the ID of the target subscription. func (client Client) Get(ctx context.Context, subscriptionID string) (result Subscription, err error) { req, err := client.GetPreparer(ctx, subscriptionID) if err != nil { @@ -193,8 +193,8 @@ func (client Client) ListComplete(ctx context.Context) (result ListResultIterato // ListLocations this operation provides all the locations that are available for resource providers; however, each // resource provider may support a subset of this list. -// -// subscriptionID is the ID of the target subscription. +// Parameters: +// subscriptionID - the ID of the target subscription. func (client Client) ListLocations(ctx context.Context, subscriptionID string) (result LocationListResult, err error) { req, err := client.ListLocationsPreparer(ctx, subscriptionID) if err != nil { diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/deploymentoperations.go b/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/deploymentoperations.go index ce51ed3b2..4b0be23e8 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/deploymentoperations.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/deploymentoperations.go @@ -41,9 +41,10 @@ func NewDeploymentOperationsClientWithBaseURI(baseURI string, subscriptionID str } // Get gets a deployments operation. -// -// resourceGroupName is the name of the resource group. The name is case insensitive. deploymentName is the name of -// the deployment. operationID is the ID of the operation to get. +// Parameters: +// resourceGroupName - the name of the resource group. The name is case insensitive. +// deploymentName - the name of the deployment. +// operationID - the ID of the operation to get. func (client DeploymentOperationsClient) Get(ctx context.Context, resourceGroupName string, deploymentName string, operationID string) (result DeploymentOperation, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, @@ -121,9 +122,10 @@ func (client DeploymentOperationsClient) GetResponder(resp *http.Response) (resu } // List gets all deployments operations for a deployment. -// -// resourceGroupName is the name of the resource group. The name is case insensitive. deploymentName is the name of -// the deployment with the operation to get. top is the number of results to return. +// Parameters: +// resourceGroupName - the name of the resource group. The name is case insensitive. +// deploymentName - the name of the deployment with the operation to get. +// top - the number of results to return. func (client DeploymentOperationsClient) List(ctx context.Context, resourceGroupName string, deploymentName string, top *int32) (result DeploymentOperationsListResultPage, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/deployments.go b/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/deployments.go index 290619838..886129be8 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/deployments.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/deployments.go @@ -43,9 +43,9 @@ func NewDeploymentsClientWithBaseURI(baseURI string, subscriptionID string) Depl // Cancel you can cancel a deployment only if the provisioningState is Accepted or Running. After the deployment is // canceled, the provisioningState is set to Canceled. Canceling a template deployment stops the currently running // template deployment and leaves the resource group partially deployed. -// -// resourceGroupName is the name of the resource group. The name is case insensitive. deploymentName is the name of -// the deployment to cancel. +// Parameters: +// resourceGroupName - the name of the resource group. The name is case insensitive. +// deploymentName - the name of the deployment to cancel. func (client DeploymentsClient) Cancel(ctx context.Context, resourceGroupName string, deploymentName string) (result autorest.Response, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, @@ -121,9 +121,10 @@ func (client DeploymentsClient) CancelResponder(resp *http.Response) (result aut } // CheckExistence checks whether the deployment exists. -// -// resourceGroupName is the name of the resource group with the deployment to check. The name is case insensitive. -// deploymentName is the name of the deployment to check. +// Parameters: +// resourceGroupName - the name of the resource group with the deployment to check. The name is case +// insensitive. +// deploymentName - the name of the deployment to check. func (client DeploymentsClient) CheckExistence(ctx context.Context, resourceGroupName string, deploymentName string) (result autorest.Response, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, @@ -199,10 +200,11 @@ func (client DeploymentsClient) CheckExistenceResponder(resp *http.Response) (re } // CreateOrUpdate you can provide the template and parameters directly in the request or link to JSON files. -// -// resourceGroupName is the name of the resource group to deploy the resources to. The name is case insensitive. -// The resource group must already exist. deploymentName is the name of the deployment. parameters is additional -// parameters supplied to the operation. +// Parameters: +// resourceGroupName - the name of the resource group to deploy the resources to. The name is case insensitive. +// The resource group must already exist. +// deploymentName - the name of the deployment. +// parameters - additional parameters supplied to the operation. func (client DeploymentsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, deploymentName string, parameters Deployment) (result DeploymentsCreateOrUpdateFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, @@ -264,15 +266,17 @@ func (client DeploymentsClient) CreateOrUpdatePreparer(ctx context.Context, reso // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client DeploymentsClient) CreateOrUpdateSender(req *http.Request) (future DeploymentsCreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -296,9 +300,10 @@ func (client DeploymentsClient) CreateOrUpdateResponder(resp *http.Response) (re // process is running, a call to the URI in the Location header returns a status of 202. When the process finishes, the // URI in the Location header returns a status of 204 on success. If the asynchronous request failed, the URI in the // Location header returns an error-level status code. -// -// resourceGroupName is the name of the resource group with the deployment to delete. The name is case insensitive. -// deploymentName is the name of the deployment to delete. +// Parameters: +// resourceGroupName - the name of the resource group with the deployment to delete. The name is case +// insensitive. +// deploymentName - the name of the deployment to delete. func (client DeploymentsClient) Delete(ctx context.Context, resourceGroupName string, deploymentName string) (result DeploymentsDeleteFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, @@ -351,15 +356,17 @@ func (client DeploymentsClient) DeletePreparer(ctx context.Context, resourceGrou // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client DeploymentsClient) DeleteSender(req *http.Request) (future DeploymentsDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -376,9 +383,9 @@ func (client DeploymentsClient) DeleteResponder(resp *http.Response) (result aut } // ExportTemplate exports the template used for specified deployment. -// -// resourceGroupName is the name of the resource group. The name is case insensitive. deploymentName is the name of -// the deployment from which to get the template. +// Parameters: +// resourceGroupName - the name of the resource group. The name is case insensitive. +// deploymentName - the name of the deployment from which to get the template. func (client DeploymentsClient) ExportTemplate(ctx context.Context, resourceGroupName string, deploymentName string) (result DeploymentExportResult, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, @@ -455,9 +462,9 @@ func (client DeploymentsClient) ExportTemplateResponder(resp *http.Response) (re } // Get gets a deployment. -// -// resourceGroupName is the name of the resource group. The name is case insensitive. deploymentName is the name of -// the deployment to get. +// Parameters: +// resourceGroupName - the name of the resource group. The name is case insensitive. +// deploymentName - the name of the deployment to get. func (client DeploymentsClient) Get(ctx context.Context, resourceGroupName string, deploymentName string) (result DeploymentExtended, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, @@ -534,10 +541,12 @@ func (client DeploymentsClient) GetResponder(resp *http.Response) (result Deploy } // ListByResourceGroup get all the deployments for a resource group. -// -// resourceGroupName is the name of the resource group with the deployments to get. The name is case insensitive. -// filter is the filter to apply on the operation. For example, you can use $filter=provisioningState eq '{state}'. -// top is the number of results to get. If null is passed, returns all deployments. +// Parameters: +// resourceGroupName - the name of the resource group with the deployments to get. The name is case +// insensitive. +// filter - the filter to apply on the operation. For example, you can use $filter=provisioningState eq +// '{state}'. +// top - the number of results to get. If null is passed, returns all deployments. func (client DeploymentsClient) ListByResourceGroup(ctx context.Context, resourceGroupName string, filter string, top *int32) (result DeploymentListResultPage, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, @@ -644,9 +653,11 @@ func (client DeploymentsClient) ListByResourceGroupComplete(ctx context.Context, // Validate validates whether the specified template is syntactically correct and will be accepted by Azure Resource // Manager.. -// -// resourceGroupName is the name of the resource group the template will be deployed to. The name is case -// insensitive. deploymentName is the name of the deployment. parameters is parameters to validate. +// Parameters: +// resourceGroupName - the name of the resource group the template will be deployed to. The name is case +// insensitive. +// deploymentName - the name of the deployment. +// parameters - parameters to validate. func (client DeploymentsClient) Validate(ctx context.Context, resourceGroupName string, deploymentName string, parameters Deployment) (result DeploymentValidateResult, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/groups.go b/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/groups.go index d1fd7dda7..1b24ebcbf 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/groups.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/groups.go @@ -41,8 +41,8 @@ func NewGroupsClientWithBaseURI(baseURI string, subscriptionID string) GroupsCli } // CheckExistence checks whether a resource group exists. -// -// resourceGroupName is the name of the resource group to check. The name is case insensitive. +// Parameters: +// resourceGroupName - the name of the resource group to check. The name is case insensitive. func (client GroupsClient) CheckExistence(ctx context.Context, resourceGroupName string) (result autorest.Response, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, @@ -113,9 +113,9 @@ func (client GroupsClient) CheckExistenceResponder(resp *http.Response) (result } // CreateOrUpdate creates or updates a resource group. -// -// resourceGroupName is the name of the resource group to create or update. parameters is parameters supplied to -// the create or update a resource group. +// Parameters: +// resourceGroupName - the name of the resource group to create or update. +// parameters - parameters supplied to the create or update a resource group. func (client GroupsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, parameters Group) (result Group, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, @@ -192,8 +192,8 @@ func (client GroupsClient) CreateOrUpdateResponder(resp *http.Response) (result // Delete when you delete a resource group, all of its resources are also deleted. Deleting a resource group deletes // all of its template deployments and currently stored operations. -// -// resourceGroupName is the name of the resource group to delete. The name is case insensitive. +// Parameters: +// resourceGroupName - the name of the resource group to delete. The name is case insensitive. func (client GroupsClient) Delete(ctx context.Context, resourceGroupName string) (result GroupsDeleteFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, @@ -241,15 +241,17 @@ func (client GroupsClient) DeletePreparer(ctx context.Context, resourceGroupName // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client GroupsClient) DeleteSender(req *http.Request) (future GroupsDeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -266,9 +268,9 @@ func (client GroupsClient) DeleteResponder(resp *http.Response) (result autorest } // ExportTemplate captures the specified resource group as a template. -// -// resourceGroupName is the name of the resource group to export as a template. parameters is parameters for -// exporting the template. +// Parameters: +// resourceGroupName - the name of the resource group to export as a template. +// parameters - parameters for exporting the template. func (client GroupsClient) ExportTemplate(ctx context.Context, resourceGroupName string, parameters ExportTemplateRequest) (result GroupExportResult, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, @@ -342,8 +344,8 @@ func (client GroupsClient) ExportTemplateResponder(resp *http.Response) (result } // Get gets a resource group. -// -// resourceGroupName is the name of the resource group to get. The name is case insensitive. +// Parameters: +// resourceGroupName - the name of the resource group to get. The name is case insensitive. func (client GroupsClient) Get(ctx context.Context, resourceGroupName string) (result Group, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, @@ -415,9 +417,9 @@ func (client GroupsClient) GetResponder(resp *http.Response) (result Group, err } // List gets all the resource groups for a subscription. -// -// filter is the filter to apply on the operation. top is the number of results to return. If null is passed, -// returns all resource groups. +// Parameters: +// filter - the filter to apply on the operation. +// top - the number of results to return. If null is passed, returns all resource groups. func (client GroupsClient) List(ctx context.Context, filter string, top *int32) (result GroupListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, filter, top) @@ -515,9 +517,9 @@ func (client GroupsClient) ListComplete(ctx context.Context, filter string, top // Update resource groups can be updated through a simple PATCH operation to a group address. The format of the request // is the same as that for creating a resource group. If a field is unspecified, the current value is retained. -// -// resourceGroupName is the name of the resource group to update. The name is case insensitive. parameters is -// parameters supplied to update a resource group. +// Parameters: +// resourceGroupName - the name of the resource group to update. The name is case insensitive. +// parameters - parameters supplied to update a resource group. func (client GroupsClient) Update(ctx context.Context, resourceGroupName string, parameters GroupPatchable) (result Group, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/models.go b/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/models.go index 334f2866d..44e1b6102 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/models.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/models.go @@ -104,12 +104,11 @@ type BasicDependency struct { // CreateOrUpdateByIDFuture an abstraction for monitoring and retrieving the results of a long-running operation. type CreateOrUpdateByIDFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future CreateOrUpdateByIDFuture) Result(client Client) (gr GenericResource, err error) { +func (future *CreateOrUpdateByIDFuture) Result(client Client) (gr GenericResource, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -117,34 +116,15 @@ func (future CreateOrUpdateByIDFuture) Result(client Client) (gr GenericResource return } if !done { - return gr, azure.NewAsyncOpIncompleteError("resources.CreateOrUpdateByIDFuture") - } - if future.PollingMethod() == azure.PollingLocation { - gr, err = client.CreateOrUpdateByIDResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.CreateOrUpdateByIDFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("resources.CreateOrUpdateByIDFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if gr.Response.Response, err = future.GetResult(sender); err == nil && gr.Response.Response.StatusCode != http.StatusNoContent { + gr, err = client.CreateOrUpdateByIDResponder(gr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "resources.CreateOrUpdateByIDFuture", "Result", gr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.CreateOrUpdateByIDFuture", "Result", resp, "Failure sending request") - return - } - gr, err = client.CreateOrUpdateByIDResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.CreateOrUpdateByIDFuture", "Result", resp, "Failure responding to request") } return } @@ -152,12 +132,11 @@ func (future CreateOrUpdateByIDFuture) Result(client Client) (gr GenericResource // CreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a long-running operation. type CreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future CreateOrUpdateFuture) Result(client Client) (gr GenericResource, err error) { +func (future *CreateOrUpdateFuture) Result(client Client) (gr GenericResource, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -165,34 +144,15 @@ func (future CreateOrUpdateFuture) Result(client Client) (gr GenericResource, er return } if !done { - return gr, azure.NewAsyncOpIncompleteError("resources.CreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - gr, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.CreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("resources.CreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if gr.Response.Response, err = future.GetResult(sender); err == nil && gr.Response.Response.StatusCode != http.StatusNoContent { + gr, err = client.CreateOrUpdateResponder(gr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "resources.CreateOrUpdateFuture", "Result", gr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.CreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - gr, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.CreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -206,12 +166,11 @@ type DebugSetting struct { // DeleteByIDFuture an abstraction for monitoring and retrieving the results of a long-running operation. type DeleteByIDFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future DeleteByIDFuture) Result(client Client) (ar autorest.Response, err error) { +func (future *DeleteByIDFuture) Result(client Client) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -219,47 +178,21 @@ func (future DeleteByIDFuture) Result(client Client) (ar autorest.Response, err return } if !done { - return ar, azure.NewAsyncOpIncompleteError("resources.DeleteByIDFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteByIDResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.DeleteByIDFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("resources.DeleteByIDFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.DeleteByIDFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteByIDResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.DeleteByIDFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } // DeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation. type DeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future DeleteFuture) Result(client Client) (ar autorest.Response, err error) { +func (future *DeleteFuture) Result(client Client) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -267,35 +200,10 @@ func (future DeleteFuture) Result(client Client) (ar autorest.Response, err erro return } if !done { - return ar, azure.NewAsyncOpIncompleteError("resources.DeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.DeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("resources.DeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.DeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.DeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -628,12 +536,11 @@ type DeploymentPropertiesExtended struct { // operation. type DeploymentsCreateOrUpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future DeploymentsCreateOrUpdateFuture) Result(client DeploymentsClient) (de DeploymentExtended, err error) { +func (future *DeploymentsCreateOrUpdateFuture) Result(client DeploymentsClient) (de DeploymentExtended, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -641,34 +548,15 @@ func (future DeploymentsCreateOrUpdateFuture) Result(client DeploymentsClient) ( return } if !done { - return de, azure.NewAsyncOpIncompleteError("resources.DeploymentsCreateOrUpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - de, err = client.CreateOrUpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.DeploymentsCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("resources.DeploymentsCreateOrUpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if de.Response.Response, err = future.GetResult(sender); err == nil && de.Response.Response.StatusCode != http.StatusNoContent { + de, err = client.CreateOrUpdateResponder(de.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "resources.DeploymentsCreateOrUpdateFuture", "Result", de.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.DeploymentsCreateOrUpdateFuture", "Result", resp, "Failure sending request") - return - } - de, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.DeploymentsCreateOrUpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -676,12 +564,11 @@ func (future DeploymentsCreateOrUpdateFuture) Result(client DeploymentsClient) ( // DeploymentsDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation. type DeploymentsDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future DeploymentsDeleteFuture) Result(client DeploymentsClient) (ar autorest.Response, err error) { +func (future *DeploymentsDeleteFuture) Result(client DeploymentsClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -689,35 +576,10 @@ func (future DeploymentsDeleteFuture) Result(client DeploymentsClient) (ar autor return } if !done { - return ar, azure.NewAsyncOpIncompleteError("resources.DeploymentsDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.DeploymentsDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("resources.DeploymentsDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.DeploymentsDeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.DeploymentsDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -1009,12 +871,11 @@ type GroupProperties struct { // GroupsDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation. type GroupsDeleteFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future GroupsDeleteFuture) Result(client GroupsClient) (ar autorest.Response, err error) { +func (future *GroupsDeleteFuture) Result(client GroupsClient) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -1022,35 +883,10 @@ func (future GroupsDeleteFuture) Result(client GroupsClient) (ar autorest.Respon return } if !done { - return ar, azure.NewAsyncOpIncompleteError("resources.GroupsDeleteFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.DeleteResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.GroupsDeleteFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("resources.GroupsDeleteFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.GroupsDeleteFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.GroupsDeleteFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -1195,12 +1031,11 @@ type MoveInfo struct { // MoveResourcesFuture an abstraction for monitoring and retrieving the results of a long-running operation. type MoveResourcesFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future MoveResourcesFuture) Result(client Client) (ar autorest.Response, err error) { +func (future *MoveResourcesFuture) Result(client Client) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -1208,35 +1043,10 @@ func (future MoveResourcesFuture) Result(client Client) (ar autorest.Response, e return } if !done { - return ar, azure.NewAsyncOpIncompleteError("resources.MoveResourcesFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.MoveResourcesResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.MoveResourcesFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("resources.MoveResourcesFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.MoveResourcesFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.MoveResourcesResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.MoveResourcesFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } @@ -1656,12 +1466,11 @@ type TemplateLink struct { // UpdateByIDFuture an abstraction for monitoring and retrieving the results of a long-running operation. type UpdateByIDFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future UpdateByIDFuture) Result(client Client) (gr GenericResource, err error) { +func (future *UpdateByIDFuture) Result(client Client) (gr GenericResource, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -1669,34 +1478,15 @@ func (future UpdateByIDFuture) Result(client Client) (gr GenericResource, err er return } if !done { - return gr, azure.NewAsyncOpIncompleteError("resources.UpdateByIDFuture") - } - if future.PollingMethod() == azure.PollingLocation { - gr, err = client.UpdateByIDResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.UpdateByIDFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("resources.UpdateByIDFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if gr.Response.Response, err = future.GetResult(sender); err == nil && gr.Response.Response.StatusCode != http.StatusNoContent { + gr, err = client.UpdateByIDResponder(gr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "resources.UpdateByIDFuture", "Result", gr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.UpdateByIDFuture", "Result", resp, "Failure sending request") - return - } - gr, err = client.UpdateByIDResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.UpdateByIDFuture", "Result", resp, "Failure responding to request") } return } @@ -1704,12 +1494,11 @@ func (future UpdateByIDFuture) Result(client Client) (gr GenericResource, err er // UpdateFuture an abstraction for monitoring and retrieving the results of a long-running operation. type UpdateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future UpdateFuture) Result(client Client) (gr GenericResource, err error) { +func (future *UpdateFuture) Result(client Client) (gr GenericResource, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -1717,34 +1506,15 @@ func (future UpdateFuture) Result(client Client) (gr GenericResource, err error) return } if !done { - return gr, azure.NewAsyncOpIncompleteError("resources.UpdateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - gr, err = client.UpdateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.UpdateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("resources.UpdateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if gr.Response.Response, err = future.GetResult(sender); err == nil && gr.Response.Response.StatusCode != http.StatusNoContent { + gr, err = client.UpdateResponder(gr.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "resources.UpdateFuture", "Result", gr.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.UpdateFuture", "Result", resp, "Failure sending request") - return - } - gr, err = client.UpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.UpdateFuture", "Result", resp, "Failure responding to request") } return } @@ -1753,12 +1523,11 @@ func (future UpdateFuture) Result(client Client) (gr GenericResource, err error) // operation. type ValidateMoveResourcesFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future ValidateMoveResourcesFuture) Result(client Client) (ar autorest.Response, err error) { +func (future *ValidateMoveResourcesFuture) Result(client Client) (ar autorest.Response, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -1766,34 +1535,9 @@ func (future ValidateMoveResourcesFuture) Result(client Client) (ar autorest.Res return } if !done { - return ar, azure.NewAsyncOpIncompleteError("resources.ValidateMoveResourcesFuture") - } - if future.PollingMethod() == azure.PollingLocation { - ar, err = client.ValidateMoveResourcesResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.ValidateMoveResourcesFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("resources.ValidateMoveResourcesFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) - if err != nil { - return - } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.ValidateMoveResourcesFuture", "Result", resp, "Failure sending request") - return - } - ar, err = client.ValidateMoveResourcesResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "resources.ValidateMoveResourcesFuture", "Result", resp, "Failure responding to request") - } + ar.Response = future.Response() return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/providers.go b/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/providers.go index a0edd14f7..db8a647f5 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/providers.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/providers.go @@ -40,9 +40,10 @@ func NewProvidersClientWithBaseURI(baseURI string, subscriptionID string) Provid } // Get gets the specified resource provider. -// -// resourceProviderNamespace is the namespace of the resource provider. expand is the $expand query parameter. For -// example, to include property aliases in response, use $expand=resourceTypes/aliases. +// Parameters: +// resourceProviderNamespace - the namespace of the resource provider. +// expand - the $expand query parameter. For example, to include property aliases in response, use +// $expand=resourceTypes/aliases. func (client ProvidersClient) Get(ctx context.Context, resourceProviderNamespace string, expand string) (result Provider, err error) { req, err := client.GetPreparer(ctx, resourceProviderNamespace, expand) if err != nil { @@ -109,10 +110,11 @@ func (client ProvidersClient) GetResponder(resp *http.Response) (result Provider } // List gets all resource providers for a subscription. -// -// top is the number of results to return. If null is passed returns all deployments. expand is the properties to -// include in the results. For example, use &$expand=metadata in the query string to retrieve resource provider -// metadata. To include property aliases in response, use $expand=resourceTypes/aliases. +// Parameters: +// top - the number of results to return. If null is passed returns all deployments. +// expand - the properties to include in the results. For example, use &$expand=metadata in the query string to +// retrieve resource provider metadata. To include property aliases in response, use +// $expand=resourceTypes/aliases. func (client ProvidersClient) List(ctx context.Context, top *int32, expand string) (result ProviderListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, top, expand) @@ -209,8 +211,8 @@ func (client ProvidersClient) ListComplete(ctx context.Context, top *int32, expa } // Register registers a subscription with a resource provider. -// -// resourceProviderNamespace is the namespace of the resource provider to register. +// Parameters: +// resourceProviderNamespace - the namespace of the resource provider to register. func (client ProvidersClient) Register(ctx context.Context, resourceProviderNamespace string) (result Provider, err error) { req, err := client.RegisterPreparer(ctx, resourceProviderNamespace) if err != nil { @@ -274,8 +276,8 @@ func (client ProvidersClient) RegisterResponder(resp *http.Response) (result Pro } // Unregister unregisters a subscription from a resource provider. -// -// resourceProviderNamespace is the namespace of the resource provider to unregister. +// Parameters: +// resourceProviderNamespace - the namespace of the resource provider to unregister. func (client ProvidersClient) Unregister(ctx context.Context, resourceProviderNamespace string) (result Provider, err error) { req, err := client.UnregisterPreparer(ctx, resourceProviderNamespace) if err != nil { diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/resources.go b/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/resources.go index a993eead9..bc7e57190 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/resources.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/resources.go @@ -41,11 +41,13 @@ func NewClientWithBaseURI(baseURI string, subscriptionID string) Client { } // CheckExistence checks whether a resource exists. -// -// resourceGroupName is the name of the resource group containing the resource to check. The name is case -// insensitive. resourceProviderNamespace is the resource provider of the resource to check. parentResourcePath is -// the parent resource identity. resourceType is the resource type. resourceName is the name of the resource to -// check whether it exists. +// Parameters: +// resourceGroupName - the name of the resource group containing the resource to check. The name is case +// insensitive. +// resourceProviderNamespace - the resource provider of the resource to check. +// parentResourcePath - the parent resource identity. +// resourceType - the resource type. +// resourceName - the name of the resource to check whether it exists. func (client Client) CheckExistence(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string) (result autorest.Response, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, @@ -120,8 +122,8 @@ func (client Client) CheckExistenceResponder(resp *http.Response) (result autore } // CheckExistenceByID checks by ID whether a resource exists. -// -// resourceID is the fully qualified ID of the resource, including the resource name and resource type. Use the +// Parameters: +// resourceID - the fully qualified ID of the resource, including the resource name and resource type. Use the // format, // /subscriptions/{guid}/resourceGroups/{resource-group-name}/{resource-provider-namespace}/{resource-type}/{resource-name} func (client Client) CheckExistenceByID(ctx context.Context, resourceID string) (result autorest.Response, err error) { @@ -185,11 +187,13 @@ func (client Client) CheckExistenceByIDResponder(resp *http.Response) (result au } // CreateOrUpdate creates a resource. -// -// resourceGroupName is the name of the resource group for the resource. The name is case insensitive. -// resourceProviderNamespace is the namespace of the resource provider. parentResourcePath is the parent resource -// identity. resourceType is the resource type of the resource to create. resourceName is the name of the resource -// to create. parameters is parameters for creating or updating the resource. +// Parameters: +// resourceGroupName - the name of the resource group for the resource. The name is case insensitive. +// resourceProviderNamespace - the namespace of the resource provider. +// parentResourcePath - the parent resource identity. +// resourceType - the resource type of the resource to create. +// resourceName - the name of the resource to create. +// parameters - parameters for creating or updating the resource. func (client Client) CreateOrUpdate(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, parameters GenericResource) (result CreateOrUpdateFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, @@ -246,15 +250,17 @@ func (client Client) CreateOrUpdatePreparer(ctx context.Context, resourceGroupNa // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client Client) CreateOrUpdateSender(req *http.Request) (future CreateOrUpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -272,11 +278,11 @@ func (client Client) CreateOrUpdateResponder(resp *http.Response) (result Generi } // CreateOrUpdateByID create a resource by ID. -// -// resourceID is the fully qualified ID of the resource, including the resource name and resource type. Use the +// Parameters: +// resourceID - the fully qualified ID of the resource, including the resource name and resource type. Use the // format, // /subscriptions/{guid}/resourceGroups/{resource-group-name}/{resource-provider-namespace}/{resource-type}/{resource-name} -// parameters is create or update resource parameters. +// parameters - create or update resource parameters. func (client Client) CreateOrUpdateByID(ctx context.Context, resourceID string, parameters GenericResource) (result CreateOrUpdateByIDFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: parameters, @@ -324,15 +330,17 @@ func (client Client) CreateOrUpdateByIDPreparer(ctx context.Context, resourceID // CreateOrUpdateByIDSender sends the CreateOrUpdateByID request. The method will close the // http.Response Body if it receives an error. func (client Client) CreateOrUpdateByIDSender(req *http.Request) (future CreateOrUpdateByIDFuture, err error) { - sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -350,10 +358,13 @@ func (client Client) CreateOrUpdateByIDResponder(resp *http.Response) (result Ge } // Delete deletes a resource. -// -// resourceGroupName is the name of the resource group that contains the resource to delete. The name is case -// insensitive. resourceProviderNamespace is the namespace of the resource provider. parentResourcePath is the -// parent resource identity. resourceType is the resource type. resourceName is the name of the resource to delete. +// Parameters: +// resourceGroupName - the name of the resource group that contains the resource to delete. The name is case +// insensitive. +// resourceProviderNamespace - the namespace of the resource provider. +// parentResourcePath - the parent resource identity. +// resourceType - the resource type. +// resourceName - the name of the resource to delete. func (client Client) Delete(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string) (result DeleteFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, @@ -405,15 +416,17 @@ func (client Client) DeletePreparer(ctx context.Context, resourceGroupName strin // DeleteSender sends the Delete request. The method will close the // http.Response Body if it receives an error. func (client Client) DeleteSender(req *http.Request) (future DeleteFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -430,8 +443,8 @@ func (client Client) DeleteResponder(resp *http.Response) (result autorest.Respo } // DeleteByID deletes a resource by ID. -// -// resourceID is the fully qualified ID of the resource, including the resource name and resource type. Use the +// Parameters: +// resourceID - the fully qualified ID of the resource, including the resource name and resource type. Use the // format, // /subscriptions/{guid}/resourceGroups/{resource-group-name}/{resource-provider-namespace}/{resource-type}/{resource-name} func (client Client) DeleteByID(ctx context.Context, resourceID string) (result DeleteByIDFuture, err error) { @@ -472,15 +485,17 @@ func (client Client) DeleteByIDPreparer(ctx context.Context, resourceID string) // DeleteByIDSender sends the DeleteByID request. The method will close the // http.Response Body if it receives an error. func (client Client) DeleteByIDSender(req *http.Request) (future DeleteByIDFuture, err error) { - sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -497,11 +512,13 @@ func (client Client) DeleteByIDResponder(resp *http.Response) (result autorest.R } // Get gets a resource. -// -// resourceGroupName is the name of the resource group containing the resource to get. The name is case -// insensitive. resourceProviderNamespace is the namespace of the resource provider. parentResourcePath is the -// parent resource identity. resourceType is the resource type of the resource. resourceName is the name of the -// resource to get. +// Parameters: +// resourceGroupName - the name of the resource group containing the resource to get. The name is case +// insensitive. +// resourceProviderNamespace - the namespace of the resource provider. +// parentResourcePath - the parent resource identity. +// resourceType - the resource type of the resource. +// resourceName - the name of the resource to get. func (client Client) Get(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string) (result GenericResource, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, @@ -577,8 +594,8 @@ func (client Client) GetResponder(resp *http.Response) (result GenericResource, } // GetByID gets a resource by ID. -// -// resourceID is the fully qualified ID of the resource, including the resource name and resource type. Use the +// Parameters: +// resourceID - the fully qualified ID of the resource, including the resource name and resource type. Use the // format, // /subscriptions/{guid}/resourceGroups/{resource-group-name}/{resource-provider-namespace}/{resource-type}/{resource-name} func (client Client) GetByID(ctx context.Context, resourceID string) (result GenericResource, err error) { @@ -643,9 +660,10 @@ func (client Client) GetByIDResponder(resp *http.Response) (result GenericResour } // List get all the resources in a subscription. -// -// filter is the filter to apply on the operation. expand is the $expand query parameter. top is the number of -// results to return. If null is passed, returns all resource groups. +// Parameters: +// filter - the filter to apply on the operation. +// expand - the $expand query parameter. +// top - the number of results to return. If null is passed, returns all resource groups. func (client Client) List(ctx context.Context, filter string, expand string, top *int32) (result ListResultPage, err error) { result.fn = client.listNextResults req, err := client.ListPreparer(ctx, filter, expand, top) @@ -745,10 +763,11 @@ func (client Client) ListComplete(ctx context.Context, filter string, expand str } // ListByResourceGroup get all the resources for a resource group. -// -// resourceGroupName is the resource group with the resources to get. filter is the filter to apply on the -// operation. expand is the $expand query parameter top is the number of results to return. If null is passed, -// returns all resources. +// Parameters: +// resourceGroupName - the resource group with the resources to get. +// filter - the filter to apply on the operation. +// expand - the $expand query parameter +// top - the number of results to return. If null is passed, returns all resources. func (client Client) ListByResourceGroup(ctx context.Context, resourceGroupName string, filter string, expand string, top *int32) (result ListResultPage, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, @@ -859,9 +878,9 @@ func (client Client) ListByResourceGroupComplete(ctx context.Context, resourceGr // MoveResources the resources to move must be in the same source resource group. The target resource group may be in a // different subscription. When moving resources, both the source group and the target group are locked for the // duration of the operation. Write and delete operations are blocked on the groups until the move completes. -// -// sourceResourceGroupName is the name of the resource group containing the resources to move. parameters is -// parameters for moving resources. +// Parameters: +// sourceResourceGroupName - the name of the resource group containing the resources to move. +// parameters - parameters for moving resources. func (client Client) MoveResources(ctx context.Context, sourceResourceGroupName string, parameters MoveInfo) (result MoveResourcesFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: sourceResourceGroupName, @@ -911,15 +930,17 @@ func (client Client) MoveResourcesPreparer(ctx context.Context, sourceResourceGr // MoveResourcesSender sends the MoveResources request. The method will close the // http.Response Body if it receives an error. func (client Client) MoveResourcesSender(req *http.Request) (future MoveResourcesFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -936,11 +957,13 @@ func (client Client) MoveResourcesResponder(resp *http.Response) (result autores } // Update updates a resource. -// -// resourceGroupName is the name of the resource group for the resource. The name is case insensitive. -// resourceProviderNamespace is the namespace of the resource provider. parentResourcePath is the parent resource -// identity. resourceType is the resource type of the resource to update. resourceName is the name of the resource -// to update. parameters is parameters for updating the resource. +// Parameters: +// resourceGroupName - the name of the resource group for the resource. The name is case insensitive. +// resourceProviderNamespace - the namespace of the resource provider. +// parentResourcePath - the parent resource identity. +// resourceType - the resource type of the resource to update. +// resourceName - the name of the resource to update. +// parameters - parameters for updating the resource. func (client Client) Update(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, parameters GenericResource) (result UpdateFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, @@ -994,15 +1017,17 @@ func (client Client) UpdatePreparer(ctx context.Context, resourceGroupName strin // UpdateSender sends the Update request. The method will close the // http.Response Body if it receives an error. func (client Client) UpdateSender(req *http.Request) (future UpdateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -1020,11 +1045,11 @@ func (client Client) UpdateResponder(resp *http.Response) (result GenericResourc } // UpdateByID updates a resource by ID. -// -// resourceID is the fully qualified ID of the resource, including the resource name and resource type. Use the +// Parameters: +// resourceID - the fully qualified ID of the resource, including the resource name and resource type. Use the // format, // /subscriptions/{guid}/resourceGroups/{resource-group-name}/{resource-provider-namespace}/{resource-type}/{resource-name} -// parameters is update resource parameters. +// parameters - update resource parameters. func (client Client) UpdateByID(ctx context.Context, resourceID string, parameters GenericResource) (result UpdateByIDFuture, err error) { req, err := client.UpdateByIDPreparer(ctx, resourceID, parameters) if err != nil { @@ -1065,15 +1090,17 @@ func (client Client) UpdateByIDPreparer(ctx context.Context, resourceID string, // UpdateByIDSender sends the UpdateByID request. The method will close the // http.Response Body if it receives an error. func (client Client) UpdateByIDSender(req *http.Request) (future UpdateByIDFuture, err error) { - sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -1095,9 +1122,9 @@ func (client Client) UpdateByIDResponder(resp *http.Response) (result GenericRes // subscription. If validation succeeds, it returns HTTP response code 204 (no content). If validation fails, it // returns HTTP response code 409 (Conflict) with an error message. Retrieve the URL in the Location header value to // check the result of the long-running operation. -// -// sourceResourceGroupName is the name of the resource group containing the resources to validate for move. -// parameters is parameters for moving resources. +// Parameters: +// sourceResourceGroupName - the name of the resource group containing the resources to validate for move. +// parameters - parameters for moving resources. func (client Client) ValidateMoveResources(ctx context.Context, sourceResourceGroupName string, parameters MoveInfo) (result ValidateMoveResourcesFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: sourceResourceGroupName, @@ -1147,15 +1174,17 @@ func (client Client) ValidateMoveResourcesPreparer(ctx context.Context, sourceRe // ValidateMoveResourcesSender sends the ValidateMoveResources request. The method will close the // http.Response Body if it receives an error. func (client Client) ValidateMoveResourcesSender(req *http.Request) (future ValidateMoveResourcesFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent, http.StatusConflict)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent, http.StatusConflict)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/tags.go b/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/tags.go index 74daf1e0f..539938125 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/tags.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources/tags.go @@ -41,8 +41,8 @@ func NewTagsClientWithBaseURI(baseURI string, subscriptionID string) TagsClient // CreateOrUpdate the tag name can have a maximum of 512 characters and is case insensitive. Tag names created by Azure // have prefixes of microsoft, azure, or windows. You cannot create tags with one of these prefixes. -// -// tagName is the name of the tag to create. +// Parameters: +// tagName - the name of the tag to create. func (client TagsClient) CreateOrUpdate(ctx context.Context, tagName string) (result TagDetails, err error) { req, err := client.CreateOrUpdatePreparer(ctx, tagName) if err != nil { @@ -106,8 +106,9 @@ func (client TagsClient) CreateOrUpdateResponder(resp *http.Response) (result Ta } // CreateOrUpdateValue creates a tag value. The name of the tag must already exist. -// -// tagName is the name of the tag. tagValue is the value of the tag to create. +// Parameters: +// tagName - the name of the tag. +// tagValue - the value of the tag to create. func (client TagsClient) CreateOrUpdateValue(ctx context.Context, tagName string, tagValue string) (result TagValue, err error) { req, err := client.CreateOrUpdateValuePreparer(ctx, tagName, tagValue) if err != nil { @@ -172,8 +173,8 @@ func (client TagsClient) CreateOrUpdateValueResponder(resp *http.Response) (resu } // Delete you must remove all values from a resource tag before you can delete it. -// -// tagName is the name of the tag. +// Parameters: +// tagName - the name of the tag. func (client TagsClient) Delete(ctx context.Context, tagName string) (result autorest.Response, err error) { req, err := client.DeletePreparer(ctx, tagName) if err != nil { @@ -236,8 +237,9 @@ func (client TagsClient) DeleteResponder(resp *http.Response) (result autorest.R } // DeleteValue deletes a tag value. -// -// tagName is the name of the tag. tagValue is the value of the tag to delete. +// Parameters: +// tagName - the name of the tag. +// tagValue - the value of the tag to delete. func (client TagsClient) DeleteValue(ctx context.Context, tagName string, tagValue string) (result autorest.Response, err error) { req, err := client.DeleteValuePreparer(ctx, tagName, tagValue) if err != nil { diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2017-10-01/storage/accounts.go b/vendor/github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2017-10-01/storage/accounts.go index d5913cdef..56dc300ec 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2017-10-01/storage/accounts.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2017-10-01/storage/accounts.go @@ -41,9 +41,9 @@ func NewAccountsClientWithBaseURI(baseURI string, subscriptionID string) Account } // CheckNameAvailability checks that the storage account name is valid and is not already in use. -// -// accountName is the name of the storage account within the specified resource group. Storage account names must -// be between 3 and 24 characters in length and use numbers and lower-case letters only. +// Parameters: +// accountName - the name of the storage account within the specified resource group. Storage account names +// must be between 3 and 24 characters in length and use numbers and lower-case letters only. func (client AccountsClient) CheckNameAvailability(ctx context.Context, accountName AccountCheckNameAvailabilityParameters) (result CheckNameAvailabilityResult, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: accountName, @@ -118,11 +118,12 @@ func (client AccountsClient) CheckNameAvailabilityResponder(resp *http.Response) // and a subsequent create request is issued with different properties, the account properties will be updated. If an // account is already created and a subsequent create or update request is issued with the exact same set of // properties, the request will succeed. -// -// resourceGroupName is the name of the resource group within the user's subscription. The name is case -// insensitive. accountName is the name of the storage account within the specified resource group. Storage account -// names must be between 3 and 24 characters in length and use numbers and lower-case letters only. parameters is -// the parameters to provide for the created account. +// Parameters: +// resourceGroupName - the name of the resource group within the user's subscription. The name is case +// insensitive. +// accountName - the name of the storage account within the specified resource group. Storage account names +// must be between 3 and 24 characters in length and use numbers and lower-case letters only. +// parameters - the parameters to provide for the created account. func (client AccountsClient) Create(ctx context.Context, resourceGroupName string, accountName string, parameters AccountCreateParameters) (result AccountsCreateFuture, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, @@ -185,15 +186,17 @@ func (client AccountsClient) CreatePreparer(ctx context.Context, resourceGroupNa // CreateSender sends the Create request. The method will close the // http.Response Body if it receives an error. func (client AccountsClient) CreateSender(req *http.Request) (future AccountsCreateFuture, err error) { - sender := autorest.DecorateSender(client, azure.DoRetryWithRegistration(client.Client)) - future.Future = azure.NewFuture(req) - future.req = req - _, err = future.Done(sender) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) if err != nil { return } - err = autorest.Respond(future.Response(), - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) return } @@ -211,10 +214,11 @@ func (client AccountsClient) CreateResponder(resp *http.Response) (result Accoun } // Delete deletes a storage account in Microsoft Azure. -// -// resourceGroupName is the name of the resource group within the user's subscription. The name is case -// insensitive. accountName is the name of the storage account within the specified resource group. Storage account -// names must be between 3 and 24 characters in length and use numbers and lower-case letters only. +// Parameters: +// resourceGroupName - the name of the resource group within the user's subscription. The name is case +// insensitive. +// accountName - the name of the storage account within the specified resource group. Storage account names +// must be between 3 and 24 characters in length and use numbers and lower-case letters only. func (client AccountsClient) Delete(ctx context.Context, resourceGroupName string, accountName string) (result autorest.Response, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, @@ -290,10 +294,11 @@ func (client AccountsClient) DeleteResponder(resp *http.Response) (result autore // GetProperties returns the properties for the specified storage account including but not limited to name, SKU name, // location, and account status. The ListKeys operation should be used to retrieve storage keys. -// -// resourceGroupName is the name of the resource group within the user's subscription. The name is case -// insensitive. accountName is the name of the storage account within the specified resource group. Storage account -// names must be between 3 and 24 characters in length and use numbers and lower-case letters only. +// Parameters: +// resourceGroupName - the name of the resource group within the user's subscription. The name is case +// insensitive. +// accountName - the name of the storage account within the specified resource group. Storage account names +// must be between 3 and 24 characters in length and use numbers and lower-case letters only. func (client AccountsClient) GetProperties(ctx context.Context, resourceGroupName string, accountName string) (result Account, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, @@ -432,11 +437,12 @@ func (client AccountsClient) ListResponder(resp *http.Response) (result AccountL } // ListAccountSAS list SAS credentials of a storage account. -// -// resourceGroupName is the name of the resource group within the user's subscription. The name is case -// insensitive. accountName is the name of the storage account within the specified resource group. Storage account -// names must be between 3 and 24 characters in length and use numbers and lower-case letters only. parameters is -// the parameters to provide to list SAS credentials for the storage account. +// Parameters: +// resourceGroupName - the name of the resource group within the user's subscription. The name is case +// insensitive. +// accountName - the name of the storage account within the specified resource group. Storage account names +// must be between 3 and 24 characters in length and use numbers and lower-case letters only. +// parameters - the parameters to provide to list SAS credentials for the storage account. func (client AccountsClient) ListAccountSAS(ctx context.Context, resourceGroupName string, accountName string, parameters AccountSasParameters) (result ListAccountSasResponse, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, @@ -517,8 +523,8 @@ func (client AccountsClient) ListAccountSASResponder(resp *http.Response) (resul // ListByResourceGroup lists all the storage accounts available under the given resource group. Note that storage keys // are not returned; use the ListKeys operation for this. -// -// resourceGroupName is the name of the resource group within the user's subscription. The name is case +// Parameters: +// resourceGroupName - the name of the resource group within the user's subscription. The name is case // insensitive. func (client AccountsClient) ListByResourceGroup(ctx context.Context, resourceGroupName string) (result AccountListResult, err error) { if err := validation.Validate([]validation.Validation{ @@ -591,10 +597,11 @@ func (client AccountsClient) ListByResourceGroupResponder(resp *http.Response) ( } // ListKeys lists the access keys for the specified storage account. -// -// resourceGroupName is the name of the resource group within the user's subscription. The name is case -// insensitive. accountName is the name of the storage account within the specified resource group. Storage account -// names must be between 3 and 24 characters in length and use numbers and lower-case letters only. +// Parameters: +// resourceGroupName - the name of the resource group within the user's subscription. The name is case +// insensitive. +// accountName - the name of the storage account within the specified resource group. Storage account names +// must be between 3 and 24 characters in length and use numbers and lower-case letters only. func (client AccountsClient) ListKeys(ctx context.Context, resourceGroupName string, accountName string) (result AccountListKeysResult, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, @@ -670,11 +677,12 @@ func (client AccountsClient) ListKeysResponder(resp *http.Response) (result Acco } // ListServiceSAS list service SAS credentials of a specific resource. -// -// resourceGroupName is the name of the resource group within the user's subscription. The name is case -// insensitive. accountName is the name of the storage account within the specified resource group. Storage account -// names must be between 3 and 24 characters in length and use numbers and lower-case letters only. parameters is -// the parameters to provide to list service SAS credentials. +// Parameters: +// resourceGroupName - the name of the resource group within the user's subscription. The name is case +// insensitive. +// accountName - the name of the storage account within the specified resource group. Storage account names +// must be between 3 and 24 characters in length and use numbers and lower-case letters only. +// parameters - the parameters to provide to list service SAS credentials. func (client AccountsClient) ListServiceSAS(ctx context.Context, resourceGroupName string, accountName string, parameters ServiceSasParameters) (result ListServiceSasResponse, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, @@ -756,11 +764,12 @@ func (client AccountsClient) ListServiceSASResponder(resp *http.Response) (resul } // RegenerateKey regenerates one of the access keys for the specified storage account. -// -// resourceGroupName is the name of the resource group within the user's subscription. The name is case -// insensitive. accountName is the name of the storage account within the specified resource group. Storage account -// names must be between 3 and 24 characters in length and use numbers and lower-case letters only. regenerateKey -// is specifies name of the key which should be regenerated -- key1 or key2. +// Parameters: +// resourceGroupName - the name of the resource group within the user's subscription. The name is case +// insensitive. +// accountName - the name of the storage account within the specified resource group. Storage account names +// must be between 3 and 24 characters in length and use numbers and lower-case letters only. +// regenerateKey - specifies name of the key which should be regenerated -- key1 or key2. func (client AccountsClient) RegenerateKey(ctx context.Context, resourceGroupName string, accountName string, regenerateKey AccountRegenerateKeyParameters) (result AccountListKeysResult, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, @@ -845,11 +854,12 @@ func (client AccountsClient) RegenerateKeyResponder(resp *http.Response) (result // must be cleared/unregistered before a new value can be set. The update of multiple properties is supported. This // call does not change the storage keys for the account. If you want to change the storage account keys, use the // regenerate keys operation. The location and name of the storage account cannot be changed after creation. -// -// resourceGroupName is the name of the resource group within the user's subscription. The name is case -// insensitive. accountName is the name of the storage account within the specified resource group. Storage account -// names must be between 3 and 24 characters in length and use numbers and lower-case letters only. parameters is -// the parameters to provide for the updated account. +// Parameters: +// resourceGroupName - the name of the resource group within the user's subscription. The name is case +// insensitive. +// accountName - the name of the storage account within the specified resource group. Storage account names +// must be between 3 and 24 characters in length and use numbers and lower-case letters only. +// parameters - the parameters to provide for the updated account. func (client AccountsClient) Update(ctx context.Context, resourceGroupName string, accountName string, parameters AccountUpdateParameters) (result Account, err error) { if err := validation.Validate([]validation.Validation{ {TargetValue: resourceGroupName, diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2017-10-01/storage/models.go b/vendor/github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2017-10-01/storage/models.go index 9e31bb4e5..c215a75c8 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2017-10-01/storage/models.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2017-10-01/storage/models.go @@ -755,12 +755,11 @@ type AccountSasParameters struct { // AccountsCreateFuture an abstraction for monitoring and retrieving the results of a long-running operation. type AccountsCreateFuture struct { azure.Future - req *http.Request } // Result returns the result of the asynchronous operation. // If the operation has not completed it will return an error. -func (future AccountsCreateFuture) Result(client AccountsClient) (a Account, err error) { +func (future *AccountsCreateFuture) Result(client AccountsClient) (a Account, err error) { var done bool done, err = future.Done(client) if err != nil { @@ -768,34 +767,15 @@ func (future AccountsCreateFuture) Result(client AccountsClient) (a Account, err return } if !done { - return a, azure.NewAsyncOpIncompleteError("storage.AccountsCreateFuture") - } - if future.PollingMethod() == azure.PollingLocation { - a, err = client.CreateResponder(future.Response()) - if err != nil { - err = autorest.NewErrorWithError(err, "storage.AccountsCreateFuture", "Result", future.Response(), "Failure responding to request") - } + err = azure.NewAsyncOpIncompleteError("storage.AccountsCreateFuture") return } - var req *http.Request - var resp *http.Response - if future.PollingURL() != "" { - req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil) + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if a.Response.Response, err = future.GetResult(sender); err == nil && a.Response.Response.StatusCode != http.StatusNoContent { + a, err = client.CreateResponder(a.Response.Response) if err != nil { - return + err = autorest.NewErrorWithError(err, "storage.AccountsCreateFuture", "Result", a.Response.Response, "Failure responding to request") } - } else { - req = autorest.ChangeToGet(future.req) - } - resp, err = autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if err != nil { - err = autorest.NewErrorWithError(err, "storage.AccountsCreateFuture", "Result", resp, "Failure sending request") - return - } - a, err = client.CreateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "storage.AccountsCreateFuture", "Result", resp, "Failure responding to request") } return } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/README.md b/vendor/github.com/Azure/azure-sdk-for-go/storage/README.md index 49e48cdf1..459b45831 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/storage/README.md +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/README.md @@ -1,9 +1,13 @@ # Azure Storage SDK for Go (Preview) :exclamation: IMPORTANT: This package is in maintenance only and will be deprecated in the -future. Consider using the new package for blobs currently in preview at -[github.com/Azure/azure-storage-blob-go](https://github.com/Azure/azure-storage-blob-go). -New Table, Queue and File packages are also in development. +future. Please use one of the following packages instead. + +| Service | Import Path/Repo | +|---------|------------------| +| Storage - Blobs | [github.com/Azure/azure-storage-blob-go](https://github.com/Azure/azure-storage-blob-go) | +| Storage - Files | [github.com/Azure/azure-storage-file-go](https://github.com/Azure/azure-storage-file-go) | +| Storage - Queues | [github.com/Azure/azure-storage-queue-go](https://github.com/Azure/azure-storage-queue-go) | The `github.com/Azure/azure-sdk-for-go/storage` package is used to manage [Azure Storage](https://docs.microsoft.com/en-us/azure/storage/) data plane diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/blob.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/blob.go index 24ee5db6f..1d2248625 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/storage/blob.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/blob.go @@ -140,7 +140,7 @@ func (b *Blob) Exists() (bool, error) { headers := b.Container.bsc.client.getStandardHeaders() resp, err := b.Container.bsc.client.exec(http.MethodHead, uri, headers, nil, b.Container.bsc.auth) if resp != nil { - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) if resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusNotFound { return resp.StatusCode == http.StatusOK, nil } @@ -293,7 +293,7 @@ func (b *Blob) CreateSnapshot(options *SnapshotOptions) (snapshotTimestamp *time if err != nil || resp == nil { return nil, err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) if err := checkRespCode(resp, []int{http.StatusCreated}); err != nil { return nil, err @@ -340,7 +340,7 @@ func (b *Blob) GetProperties(options *GetBlobPropertiesOptions) error { if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) if err = checkRespCode(resp, []int{http.StatusOK}); err != nil { return err @@ -463,7 +463,7 @@ func (b *Blob) SetProperties(options *SetBlobPropertiesOptions) error { if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) return checkRespCode(resp, []int{http.StatusOK}) } @@ -501,7 +501,7 @@ func (b *Blob) SetMetadata(options *SetBlobMetadataOptions) error { if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) return checkRespCode(resp, []int{http.StatusOK}) } @@ -538,7 +538,7 @@ func (b *Blob) GetMetadata(options *GetBlobMetadataOptions) error { if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) if err := checkRespCode(resp, []int{http.StatusOK}); err != nil { return err @@ -574,7 +574,7 @@ func (b *Blob) Delete(options *DeleteBlobOptions) error { if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) return checkRespCode(resp, []int{http.StatusAccepted}) } @@ -585,7 +585,7 @@ func (b *Blob) Delete(options *DeleteBlobOptions) error { func (b *Blob) DeleteIfExists(options *DeleteBlobOptions) (bool, error) { resp, err := b.delete(options) if resp != nil { - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) if resp.StatusCode == http.StatusAccepted || resp.StatusCode == http.StatusNotFound { return resp.StatusCode == http.StatusAccepted, nil } @@ -622,7 +622,7 @@ func pathForResource(container, name string) string { } func (b *Blob) respondCreation(resp *http.Response, bt BlobType) error { - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) err := checkRespCode(resp, []int{http.StatusCreated}) if err != nil { return err diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/blockblob.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/blockblob.go index 5d9467afd..c9c62d799 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/storage/blockblob.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/blockblob.go @@ -229,7 +229,7 @@ func (b *Blob) PutBlockList(blocks []Block, options *PutBlockListOptions) error if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) return checkRespCode(resp, []int{http.StatusCreated}) } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/client.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/client.go index 651ba8722..2930824b2 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/storage/client.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/client.go @@ -120,6 +120,7 @@ func (ds *DefaultSender) Send(c *Client, req *http.Request) (resp *http.Response if err != nil || !autorest.ResponseHasStatusCode(resp, ds.ValidStatusCodes...) { return resp, err } + drainRespBody(resp) autorest.DelayForBackoff(ds.RetryDuration, attempts, req.Cancel) ds.attempts = attempts } @@ -880,6 +881,12 @@ func readAndCloseBody(body io.ReadCloser) ([]byte, error) { return out, err } +// reads the response body then closes it +func drainRespBody(resp *http.Response) { + io.Copy(ioutil.Discard, resp.Body) + resp.Body.Close() +} + func serviceErrFromXML(body []byte, storageErr *AzureStorageServiceError) error { if err := xml.Unmarshal(body, storageErr); err != nil { storageErr.Message = fmt.Sprintf("Response body could no be unmarshaled: %v. Body: %v.", err, string(body)) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/container.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/container.go index bba44db74..056473d49 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/storage/container.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/container.go @@ -258,7 +258,7 @@ func (c *Container) Create(options *CreateContainerOptions) error { if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) return checkRespCode(resp, []int{http.StatusCreated}) } @@ -267,7 +267,7 @@ func (c *Container) Create(options *CreateContainerOptions) error { func (c *Container) CreateIfNotExists(options *CreateContainerOptions) (bool, error) { resp, err := c.create(options) if resp != nil { - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) if resp.StatusCode == http.StatusCreated || resp.StatusCode == http.StatusConflict { return resp.StatusCode == http.StatusCreated, nil } @@ -307,7 +307,7 @@ func (c *Container) Exists() (bool, error) { resp, err := c.bsc.client.exec(http.MethodHead, uri, headers, nil, c.bsc.auth) if resp != nil { - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) if resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusNotFound { return resp.StatusCode == http.StatusOK, nil } @@ -349,7 +349,7 @@ func (c *Container) SetPermissions(permissions ContainerPermissions, options *Se if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) return checkRespCode(resp, []int{http.StatusOK}) } @@ -431,7 +431,7 @@ func (c *Container) Delete(options *DeleteContainerOptions) error { if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) return checkRespCode(resp, []int{http.StatusAccepted}) } @@ -444,7 +444,7 @@ func (c *Container) Delete(options *DeleteContainerOptions) error { func (c *Container) DeleteIfExists(options *DeleteContainerOptions) (bool, error) { resp, err := c.delete(options) if resp != nil { - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) if resp.StatusCode == http.StatusAccepted || resp.StatusCode == http.StatusNotFound { return resp.StatusCode == http.StatusAccepted, nil } @@ -535,7 +535,7 @@ func (c *Container) SetMetadata(options *ContainerMetadataOptions) error { if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) return checkRespCode(resp, []int{http.StatusOK}) } @@ -563,7 +563,7 @@ func (c *Container) GetMetadata(options *ContainerMetadataOptions) error { if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) if err := checkRespCode(resp, []int{http.StatusOK}); err != nil { return err } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/copyblob.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/copyblob.go index 248dfb220..151e9a510 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/storage/copyblob.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/copyblob.go @@ -110,7 +110,7 @@ func (b *Blob) StartCopy(sourceBlob string, options *CopyOptions) (string, error if err != nil { return "", err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) if err := checkRespCode(resp, []int{http.StatusAccepted, http.StatusCreated}); err != nil { return "", err @@ -152,7 +152,7 @@ func (b *Blob) AbortCopy(copyID string, options *AbortCopyOptions) error { if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) return checkRespCode(resp, []int{http.StatusNoContent}) } @@ -223,7 +223,7 @@ func (b *Blob) IncrementalCopyBlob(sourceBlobURL string, snapshotTime time.Time, if err != nil { return "", err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) if err := checkRespCode(resp, []int{http.StatusAccepted}); err != nil { return "", err diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/directory.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/directory.go index 237d10fd1..2e805e7df 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/storage/directory.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/directory.go @@ -107,7 +107,7 @@ func (d *Directory) CreateIfNotExists(options *FileRequestOptions) (bool, error) params := prepareOptions(options) resp, err := d.fsc.createResourceNoClose(d.buildPath(), resourceDirectory, params, nil) if resp != nil { - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) if resp.StatusCode == http.StatusCreated || resp.StatusCode == http.StatusConflict { if resp.StatusCode == http.StatusCreated { d.updateEtagAndLastModified(resp.Header) @@ -135,7 +135,7 @@ func (d *Directory) Delete(options *FileRequestOptions) error { func (d *Directory) DeleteIfExists(options *FileRequestOptions) (bool, error) { resp, err := d.fsc.deleteResourceNoClose(d.buildPath(), resourceDirectory, options) if resp != nil { - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) if resp.StatusCode == http.StatusAccepted || resp.StatusCode == http.StatusNotFound { return resp.StatusCode == http.StatusAccepted, nil } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/entity.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/entity.go index 5af9b1ef3..fbbcb93ba 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/storage/entity.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/entity.go @@ -112,7 +112,7 @@ func (e *Entity) Get(timeout uint, ml MetadataLevel, options *GetEntityOptions) if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) if err = checkRespCode(resp, []int{http.StatusOK}); err != nil { return err @@ -154,7 +154,7 @@ func (e *Entity) Insert(ml MetadataLevel, options *EntityOptions) error { if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) if ml != EmptyPayload { if err = checkRespCode(resp, []int{http.StatusCreated}); err != nil { @@ -212,7 +212,7 @@ func (e *Entity) Delete(force bool, options *EntityOptions) error { } return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) if err = checkRespCode(resp, []int{http.StatusNoContent}); err != nil { return err @@ -399,7 +399,7 @@ func (e *Entity) insertOr(verb string, options *EntityOptions) error { if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) if err = checkRespCode(resp, []int{http.StatusNoContent}); err != nil { return err @@ -428,7 +428,7 @@ func (e *Entity) updateMerge(force bool, verb string, options *EntityOptions) er } return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) if err = checkRespCode(resp, []int{http.StatusNoContent}); err != nil { return err diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/file.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/file.go index 8afc2e233..06bbe4ba0 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/storage/file.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/file.go @@ -187,7 +187,7 @@ func (f *File) Delete(options *FileRequestOptions) error { func (f *File) DeleteIfExists(options *FileRequestOptions) (bool, error) { resp, err := f.fsc.deleteResourceNoClose(f.buildPath(), resourceFile, options) if resp != nil { - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) if resp.StatusCode == http.StatusAccepted || resp.StatusCode == http.StatusNotFound { return resp.StatusCode == http.StatusAccepted, nil } @@ -212,7 +212,7 @@ func (f *File) DownloadToStream(options *FileRequestOptions) (io.ReadCloser, err } if err = checkRespCode(resp, []int{http.StatusOK}); err != nil { - readAndCloseBody(resp.Body) + drainRespBody(resp) return nil, err } return resp.Body, nil @@ -242,7 +242,7 @@ func (f *File) DownloadRangeToStream(fileRange FileRange, options *GetFileOption } if err = checkRespCode(resp, []int{http.StatusOK, http.StatusPartialContent}); err != nil { - readAndCloseBody(resp.Body) + drainRespBody(resp) return fs, err } @@ -375,7 +375,7 @@ func (f *File) modifyRange(bytes io.Reader, fileRange FileRange, timeout *uint, if err != nil { return nil, err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) return resp.Header, checkRespCode(resp, []int{http.StatusCreated}) } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/fileserviceclient.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/fileserviceclient.go index 6467937d2..1db8e7da6 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/storage/fileserviceclient.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/fileserviceclient.go @@ -194,7 +194,7 @@ func (f FileServiceClient) listContent(path string, params url.Values, extraHead } if err = checkRespCode(resp, []int{http.StatusOK}); err != nil { - readAndCloseBody(resp.Body) + drainRespBody(resp) return nil, err } @@ -212,7 +212,7 @@ func (f FileServiceClient) resourceExists(path string, res resourceType) (bool, resp, err := f.client.exec(http.MethodHead, uri, headers, nil, f.auth) if resp != nil { - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) if resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusNotFound { return resp.StatusCode == http.StatusOK, resp.Header, nil } @@ -226,7 +226,7 @@ func (f FileServiceClient) createResource(path string, res resourceType, urlPara if err != nil { return nil, err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) return resp.Header, checkRespCode(resp, expectedResponseCodes) } @@ -251,7 +251,7 @@ func (f FileServiceClient) getResourceHeaders(path string, comp compType, res re if err != nil { return nil, err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) if err = checkRespCode(resp, []int{http.StatusOK}); err != nil { return nil, err @@ -279,7 +279,7 @@ func (f FileServiceClient) deleteResource(path string, res resourceType, options if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) return checkRespCode(resp, []int{http.StatusAccepted}) } @@ -323,7 +323,7 @@ func (f FileServiceClient) setResourceHeaders(path string, comp compType, res re if err != nil { return nil, err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) return resp.Header, checkRespCode(resp, []int{http.StatusOK}) } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/leaseblob.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/leaseblob.go index 22ddbcd65..5b4a65145 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/storage/leaseblob.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/leaseblob.go @@ -53,7 +53,7 @@ func (b *Blob) leaseCommonPut(headers map[string]string, expectedStatus int, opt if err != nil { return nil, err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) if err := checkRespCode(resp, []int{expectedStatus}); err != nil { return nil, err diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/message.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/message.go index ff13704ea..ce33dcb72 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/storage/message.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/message.go @@ -78,7 +78,7 @@ func (m *Message) Put(options *PutMessageOptions) error { if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) err = checkRespCode(resp, []int{http.StatusCreated}) if err != nil { return err @@ -128,7 +128,7 @@ func (m *Message) Update(options *UpdateMessageOptions) error { if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) m.PopReceipt = resp.Header.Get("x-ms-popreceipt") nextTimeStr := resp.Header.Get("x-ms-time-next-visible") @@ -160,7 +160,7 @@ func (m *Message) Delete(options *QueueServiceOptions) error { if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) return checkRespCode(resp, []int{http.StatusNoContent}) } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/pageblob.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/pageblob.go index 007e19e61..7ffd63821 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/storage/pageblob.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/pageblob.go @@ -121,7 +121,7 @@ func (b *Blob) modifyRange(blobRange BlobRange, bytes io.Reader, options *PutPag if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) return checkRespCode(resp, []int{http.StatusCreated}) } @@ -160,7 +160,7 @@ func (b *Blob) GetPageRanges(options *GetPageRangesOptions) (GetPageRangesRespon if err != nil { return out, err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) if err = checkRespCode(resp, []int{http.StatusOK}); err != nil { return out, err diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/queue.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/queue.go index 9a821c56a..55238ab15 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/storage/queue.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/queue.go @@ -91,7 +91,7 @@ func (q *Queue) Create(options *QueueServiceOptions) error { if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) return checkRespCode(resp, []int{http.StatusCreated}) } @@ -111,7 +111,7 @@ func (q *Queue) Delete(options *QueueServiceOptions) error { if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) return checkRespCode(resp, []int{http.StatusNoContent}) } @@ -120,7 +120,7 @@ func (q *Queue) Exists() (bool, error) { uri := q.qsc.client.getEndpoint(queueServiceName, q.buildPath(), url.Values{"comp": {"metadata"}}) resp, err := q.qsc.client.exec(http.MethodGet, uri, q.qsc.client.getStandardHeaders(), nil, q.qsc.auth) if resp != nil { - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) if resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusNotFound { return resp.StatusCode == http.StatusOK, nil } @@ -148,7 +148,7 @@ func (q *Queue) SetMetadata(options *QueueServiceOptions) error { if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) return checkRespCode(resp, []int{http.StatusNoContent}) } @@ -175,7 +175,7 @@ func (q *Queue) GetMetadata(options *QueueServiceOptions) error { if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) if err := checkRespCode(resp, []int{http.StatusOK}); err != nil { return err @@ -314,7 +314,7 @@ func (q *Queue) ClearMessages(options *QueueServiceOptions) error { if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) return checkRespCode(resp, []int{http.StatusNoContent}) } @@ -341,7 +341,7 @@ func (q *Queue) SetPermissions(permissions QueuePermissions, options *SetQueuePe if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) return checkRespCode(resp, []int{http.StatusNoContent}) } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/share.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/share.go index 0ded50107..cf75a2659 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/storage/share.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/share.go @@ -75,7 +75,7 @@ func (s *Share) CreateIfNotExists(options *FileRequestOptions) (bool, error) { params := prepareOptions(options) resp, err := s.fsc.createResourceNoClose(s.buildPath(), resourceShare, params, extraheaders) if resp != nil { - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) if resp.StatusCode == http.StatusCreated || resp.StatusCode == http.StatusConflict { if resp.StatusCode == http.StatusCreated { s.updateEtagAndLastModified(resp.Header) @@ -103,7 +103,7 @@ func (s *Share) Delete(options *FileRequestOptions) error { func (s *Share) DeleteIfExists(options *FileRequestOptions) (bool, error) { resp, err := s.fsc.deleteResourceNoClose(s.buildPath(), resourceShare, options) if resp != nil { - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) if resp.StatusCode == http.StatusAccepted || resp.StatusCode == http.StatusNotFound { return resp.StatusCode == http.StatusAccepted, nil } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/storageservice.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/storageservice.go index a68ad0930..c338975ab 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/storage/storageservice.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/storageservice.go @@ -126,6 +126,6 @@ func (c Client) setServiceProperties(props ServiceProperties, service string, au if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) return checkRespCode(resp, []int{http.StatusAccepted}) } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/table.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/table.go index b96ca6e12..22d9b4f5c 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/storage/table.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/table.go @@ -186,7 +186,7 @@ func (t *Table) Delete(timeout uint, options *TableOptions) error { if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) return checkRespCode(resp, []int{http.StatusNoContent}) } @@ -269,7 +269,7 @@ func (t *Table) SetPermissions(tap []TableAccessPolicy, timeout uint, options *T if err != nil { return err } - defer readAndCloseBody(resp.Body) + defer drainRespBody(resp) return checkRespCode(resp, []int{http.StatusNoContent}) } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/table_batch.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/table_batch.go index 6595fb70f..a2159e296 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/storage/table_batch.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/table_batch.go @@ -163,7 +163,7 @@ func (t *TableBatch) ExecuteBatch() error { if err != nil { return err } - defer readAndCloseBody(resp.resp.Body) + defer drainRespBody(resp.resp) if err = checkRespCode(resp.resp, []int{http.StatusAccepted}); err != nil { diff --git a/vendor/github.com/Azure/azure-sdk-for-go/version/version.go b/vendor/github.com/Azure/azure-sdk-for-go/version/version.go index 9ba20b8a8..0d0677e74 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/version/version.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/version/version.go @@ -18,4 +18,4 @@ package version // Changes may cause incorrect behavior and will be lost if the code is regenerated. // Number contains the semantic version of this SDK. -const Number = "v15.0.0" +const Number = "v17.3.1" diff --git a/vendor/vendor.json b/vendor/vendor.json index 0ae028187..c519a1e0e 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -9,58 +9,60 @@ "revisionTime": "2016-08-11T22:04:02Z" }, { - "checksumSHA1": "cJxhrzJRtddboU3S0TPyvEPBqsc=", + "checksumSHA1": "aspvORKGJoiAwyzot4bsHqt/17Y=", "path": "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute", - "revision": "56332fec5b308fbb6615fa1af6117394cdba186d", - "revisionTime": "2018-03-26T23:29:47Z", - "version": "v15.0.0", - "versionExact": "v15.0.0" + "revision": "ef33a0a23b66ba5e81f699d03dc48b723c1bad50", + "revisionTime": "2018-06-15T22:13:27Z", + "version": "v17.3.1", + "versionExact": "v17.3.1" }, { - "checksumSHA1": "VDwUBYd9RVKy09Y17al0EQ7ivYI=", + "checksumSHA1": "jD1gZ3he4E6iYOZn7D24dKeLG8k=", "path": "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network", - "revision": "56332fec5b308fbb6615fa1af6117394cdba186d", - "revisionTime": "2018-03-26T23:29:47Z", - "version": "v15.0.0", - "versionExact": "v15.0.0" + "revision": "ef33a0a23b66ba5e81f699d03dc48b723c1bad50", + "revisionTime": "2018-06-15T22:13:27Z", + "version": "v17.3.1", + "versionExact": "v17.3.1" }, { - "checksumSHA1": "woz67BK+/NdoZm4GzVYnJwzl61A=", + "checksumSHA1": "pJ2o3U5IZP9z5dKYl69maIBXUOY=", "path": "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2016-06-01/subscriptions", - "revision": "56332fec5b308fbb6615fa1af6117394cdba186d", - "revisionTime": "2018-03-26T23:29:47Z", - "version": "v15.0.0", - "versionExact": "v15.0.0" + "revision": "ef33a0a23b66ba5e81f699d03dc48b723c1bad50", + "revisionTime": "2018-06-15T22:13:27Z", + "version": "v17.3.1", + "versionExact": "v17.3.1" }, { - "checksumSHA1": "1W8UIxg6Rycuzg41FQFu35vkCEU=", + "checksumSHA1": "hnlMpNzAV5mu4PHvyTuBc/BC8aA=", "path": "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources", - "revision": "56332fec5b308fbb6615fa1af6117394cdba186d", - "revisionTime": "2018-03-26T23:29:47Z", - "version": "v15.0.0", - "versionExact": "v15.0.0" + "revision": "ef33a0a23b66ba5e81f699d03dc48b723c1bad50", + "revisionTime": "2018-06-15T22:13:27Z", + "version": "v17.3.1", + "versionExact": "v17.3.1" }, { - "checksumSHA1": "g9eP5AgV9yXRkY36M8h7aDW9oi8=", + "checksumSHA1": "qHMzicMTsihjgKyS/VB8oguXmmc=", "path": "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2017-10-01/storage", - "revision": "56332fec5b308fbb6615fa1af6117394cdba186d", - "revisionTime": "2018-03-26T23:29:47Z", - "version": "v15.0.0", - "versionExact": "v15.0.0" + "revision": "ef33a0a23b66ba5e81f699d03dc48b723c1bad50", + "revisionTime": "2018-06-15T22:13:27Z", + "version": "v17.3.1", + "versionExact": "v17.3.1" }, { - "checksumSHA1": "3N5Et8QnWsHJYN+v/0J/VSQUkJ0=", + "checksumSHA1": "1fQaVn4mDau1rUfyWGitatAvXdM=", "path": "github.com/Azure/azure-sdk-for-go/storage", - "revision": "56332fec5b308fbb6615fa1af6117394cdba186d", - "revisionTime": "2018-03-26T23:29:47Z", - "version": "v15.0.0", - "versionExact": "v15.0.0" + "revision": "ef33a0a23b66ba5e81f699d03dc48b723c1bad50", + "revisionTime": "2018-06-15T22:13:27Z", + "version": "v17.3.1", + "versionExact": "v17.3.1" }, { - "checksumSHA1": "Fb2OanEbwZVaGHYLf9Y4FAajsOM=", + "checksumSHA1": "BeO7/Ld5yP8m32hHNGQBSUvQjaw=", "path": "github.com/Azure/azure-sdk-for-go/version", - "revision": "56332fec5b308fbb6615fa1af6117394cdba186d", - "revisionTime": "2018-03-26T23:29:47Z" + "revision": "ef33a0a23b66ba5e81f699d03dc48b723c1bad50", + "revisionTime": "2018-06-15T22:13:27Z", + "version": "v17.3.1", + "versionExact": "v17.3.1" }, { "checksumSHA1": "+P6HOINDh/n2z4GqEkluzuGP5p0=", @@ -72,7 +74,7 @@ "versionExact": "v10.4.0" }, { - "checksumSHA1": "4Z3yO++uYspufDkuaIydTpT787c=", + "checksumSHA1": "HzA52MbMWnsR31CFrub5biN90/Q=", "path": "github.com/Azure/go-autorest/autorest/adal", "revision": "ed4b7f5bf1ec0c9ede1fda2681d96771282f2862", "revisionTime": "2018-03-26T17:06:54Z", @@ -107,7 +109,7 @@ "versionExact": "v8.0.0" }, { - "checksumSHA1": "5UH4IFIB/98iowPCzzVs4M4MXiQ=", + "checksumSHA1": "CdDkG+J8wqXQVQ0f0xal+eolB1w=", "path": "github.com/Azure/go-autorest/autorest/validation", "revision": "ed4b7f5bf1ec0c9ede1fda2681d96771282f2862", "revisionTime": "2018-03-26T17:06:54Z", From f60921ad4b4f9eceda11474c8f08ff81b9f51cb1 Mon Sep 17 00:00:00 2001 From: Christopher Boumenot Date: Wed, 11 Jul 2018 14:17:56 -0700 Subject: [PATCH 090/220] azure: upgrade Azure/go-autorest to v10.12.0 --- .../Azure/go-autorest/autorest/adal/config.go | 8 +- .../Azure/go-autorest/autorest/adal/msi.go | 20 - .../go-autorest/autorest/adal/msi_windows.go | 25 - .../Azure/go-autorest/autorest/adal/token.go | 541 +++++++-- .../go-autorest/autorest/authorization.go | 22 +- .../Azure/go-autorest/autorest/autorest.go | 18 + .../Azure/go-autorest/autorest/azure/async.go | 1039 ++++++++++++----- .../Azure/go-autorest/autorest/azure/azure.go | 27 +- .../Azure/go-autorest/autorest/azure/rp.go | 12 +- .../Azure/go-autorest/autorest/date/date.go | 14 + .../Azure/go-autorest/autorest/date/time.go | 14 + .../go-autorest/autorest/date/timerfc1123.go | 14 + .../go-autorest/autorest/date/unixtime.go | 14 + .../go-autorest/autorest/date/utility.go | 14 + .../Azure/go-autorest/autorest/sender.go | 22 +- .../Azure/go-autorest/autorest/to/convert.go | 14 + .../Azure/go-autorest/autorest/utility.go | 10 + .../autorest/validation/validation.go | 23 +- .../Azure/go-autorest/autorest/version.go | 2 +- vendor/vendor.json | 60 +- 20 files changed, 1353 insertions(+), 560 deletions(-) delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/adal/msi.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/adal/msi_windows.go diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/config.go b/vendor/github.com/Azure/go-autorest/autorest/adal/config.go index f570d540a..bee5e61dd 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/config.go +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/config.go @@ -26,10 +26,10 @@ const ( // OAuthConfig represents the endpoints needed // in OAuth operations type OAuthConfig struct { - AuthorityEndpoint url.URL - AuthorizeEndpoint url.URL - TokenEndpoint url.URL - DeviceCodeEndpoint url.URL + AuthorityEndpoint url.URL `json:"authorityEndpoint"` + AuthorizeEndpoint url.URL `json:"authorizeEndpoint"` + TokenEndpoint url.URL `json:"tokenEndpoint"` + DeviceCodeEndpoint url.URL `json:"deviceCodeEndpoint"` } // IsZero returns true if the OAuthConfig object is zero-initialized. diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/msi.go b/vendor/github.com/Azure/go-autorest/autorest/adal/msi.go deleted file mode 100644 index 5e02d52ac..000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/msi.go +++ /dev/null @@ -1,20 +0,0 @@ -// +build !windows - -package adal - -// Copyright 2017 Microsoft Corporation -// -// 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. - -// msiPath is the path to the MSI Extension settings file (to discover the endpoint) -var msiPath = "/var/lib/waagent/ManagedIdentity-Settings" diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/msi_windows.go b/vendor/github.com/Azure/go-autorest/autorest/adal/msi_windows.go deleted file mode 100644 index 261b56882..000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/msi_windows.go +++ /dev/null @@ -1,25 +0,0 @@ -// +build windows - -package adal - -// Copyright 2017 Microsoft Corporation -// -// 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. - -import ( - "os" - "strings" -) - -// msiPath is the path to the MSI Extension settings file (to discover the endpoint) -var msiPath = strings.Join([]string{os.Getenv("SystemDrive"), "WindowsAzure/Config/ManagedIdentity-Settings"}, "/") diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/token.go b/vendor/github.com/Azure/go-autorest/autorest/adal/token.go index d98504122..eec4dced7 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/token.go +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/token.go @@ -15,14 +15,18 @@ package adal // limitations under the License. import ( + "context" "crypto/rand" "crypto/rsa" "crypto/sha1" "crypto/x509" "encoding/base64" "encoding/json" + "errors" "fmt" "io/ioutil" + "math" + "net" "net/http" "net/url" "strconv" @@ -54,6 +58,12 @@ const ( // metadataHeader is the header required by MSI extension metadataHeader = "Metadata" + + // msiEndpoint is the well known endpoint for getting MSI authentications tokens + msiEndpoint = "http://169.254.169.254/metadata/identity/oauth2/token" + + // the default number of attempts to refresh an MSI authentication token + defaultMaxMSIRefreshAttempts = 5 ) // OAuthTokenProvider is an interface which should be implemented by an access token retriever @@ -74,6 +84,13 @@ type Refresher interface { EnsureFresh() error } +// RefresherWithContext is an interface for token refresh functionality +type RefresherWithContext interface { + RefreshWithContext(ctx context.Context) error + RefreshExchangeWithContext(ctx context.Context, resource string) error + EnsureFreshWithContext(ctx context.Context) error +} + // TokenRefreshCallback is the type representing callbacks that will be called after // a successful token refresh type TokenRefreshCallback func(Token) error @@ -124,6 +141,12 @@ func (t *Token) OAuthToken() string { return t.AccessToken } +// ServicePrincipalSecret is an interface that allows various secret mechanism to fill the form +// that is submitted when acquiring an oAuth token. +type ServicePrincipalSecret interface { + SetAuthenticationValues(spt *ServicePrincipalToken, values *url.Values) error +} + // ServicePrincipalNoSecret represents a secret type that contains no secret // meaning it is not valid for fetching a fresh token. This is used by Manual type ServicePrincipalNoSecret struct { @@ -135,15 +158,19 @@ func (noSecret *ServicePrincipalNoSecret) SetAuthenticationValues(spt *ServicePr return fmt.Errorf("Manually created ServicePrincipalToken does not contain secret material to retrieve a new access token") } -// ServicePrincipalSecret is an interface that allows various secret mechanism to fill the form -// that is submitted when acquiring an oAuth token. -type ServicePrincipalSecret interface { - SetAuthenticationValues(spt *ServicePrincipalToken, values *url.Values) error +// MarshalJSON implements the json.Marshaler interface. +func (noSecret ServicePrincipalNoSecret) MarshalJSON() ([]byte, error) { + type tokenType struct { + Type string `json:"type"` + } + return json.Marshal(tokenType{ + Type: "ServicePrincipalNoSecret", + }) } // ServicePrincipalTokenSecret implements ServicePrincipalSecret for client_secret type authorization. type ServicePrincipalTokenSecret struct { - ClientSecret string + ClientSecret string `json:"value"` } // SetAuthenticationValues is a method of the interface ServicePrincipalSecret. @@ -153,49 +180,24 @@ func (tokenSecret *ServicePrincipalTokenSecret) SetAuthenticationValues(spt *Ser return nil } +// MarshalJSON implements the json.Marshaler interface. +func (tokenSecret ServicePrincipalTokenSecret) MarshalJSON() ([]byte, error) { + type tokenType struct { + Type string `json:"type"` + Value string `json:"value"` + } + return json.Marshal(tokenType{ + Type: "ServicePrincipalTokenSecret", + Value: tokenSecret.ClientSecret, + }) +} + // ServicePrincipalCertificateSecret implements ServicePrincipalSecret for generic RSA cert auth with signed JWTs. type ServicePrincipalCertificateSecret struct { Certificate *x509.Certificate PrivateKey *rsa.PrivateKey } -// ServicePrincipalMSISecret implements ServicePrincipalSecret for machines running the MSI Extension. -type ServicePrincipalMSISecret struct { -} - -// ServicePrincipalUsernamePasswordSecret implements ServicePrincipalSecret for username and password auth. -type ServicePrincipalUsernamePasswordSecret struct { - Username string - Password string -} - -// ServicePrincipalAuthorizationCodeSecret implements ServicePrincipalSecret for authorization code auth. -type ServicePrincipalAuthorizationCodeSecret struct { - ClientSecret string - AuthorizationCode string - RedirectURI string -} - -// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. -func (secret *ServicePrincipalAuthorizationCodeSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { - v.Set("code", secret.AuthorizationCode) - v.Set("client_secret", secret.ClientSecret) - v.Set("redirect_uri", secret.RedirectURI) - return nil -} - -// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. -func (secret *ServicePrincipalUsernamePasswordSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { - v.Set("username", secret.Username) - v.Set("password", secret.Password) - return nil -} - -// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. -func (msiSecret *ServicePrincipalMSISecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { - return nil -} - // SignJwt returns the JWT signed with the certificate's private key. func (secret *ServicePrincipalCertificateSecret) SignJwt(spt *ServicePrincipalToken) (string, error) { hasher := sha1.New() @@ -216,9 +218,9 @@ func (secret *ServicePrincipalCertificateSecret) SignJwt(spt *ServicePrincipalTo token := jwt.New(jwt.SigningMethodRS256) token.Header["x5t"] = thumbprint token.Claims = jwt.MapClaims{ - "aud": spt.oauthConfig.TokenEndpoint.String(), - "iss": spt.clientID, - "sub": spt.clientID, + "aud": spt.inner.OauthConfig.TokenEndpoint.String(), + "iss": spt.inner.ClientID, + "sub": spt.inner.ClientID, "jti": base64.URLEncoding.EncodeToString(jti), "nbf": time.Now().Unix(), "exp": time.Now().Add(time.Hour * 24).Unix(), @@ -241,19 +243,151 @@ func (secret *ServicePrincipalCertificateSecret) SetAuthenticationValues(spt *Se return nil } +// MarshalJSON implements the json.Marshaler interface. +func (secret ServicePrincipalCertificateSecret) MarshalJSON() ([]byte, error) { + return nil, errors.New("marshalling ServicePrincipalCertificateSecret is not supported") +} + +// ServicePrincipalMSISecret implements ServicePrincipalSecret for machines running the MSI Extension. +type ServicePrincipalMSISecret struct { +} + +// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. +func (msiSecret *ServicePrincipalMSISecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { + return nil +} + +// MarshalJSON implements the json.Marshaler interface. +func (msiSecret ServicePrincipalMSISecret) MarshalJSON() ([]byte, error) { + return nil, errors.New("marshalling ServicePrincipalMSISecret is not supported") +} + +// ServicePrincipalUsernamePasswordSecret implements ServicePrincipalSecret for username and password auth. +type ServicePrincipalUsernamePasswordSecret struct { + Username string `json:"username"` + Password string `json:"password"` +} + +// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. +func (secret *ServicePrincipalUsernamePasswordSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { + v.Set("username", secret.Username) + v.Set("password", secret.Password) + return nil +} + +// MarshalJSON implements the json.Marshaler interface. +func (secret ServicePrincipalUsernamePasswordSecret) MarshalJSON() ([]byte, error) { + type tokenType struct { + Type string `json:"type"` + Username string `json:"username"` + Password string `json:"password"` + } + return json.Marshal(tokenType{ + Type: "ServicePrincipalUsernamePasswordSecret", + Username: secret.Username, + Password: secret.Password, + }) +} + +// ServicePrincipalAuthorizationCodeSecret implements ServicePrincipalSecret for authorization code auth. +type ServicePrincipalAuthorizationCodeSecret struct { + ClientSecret string `json:"value"` + AuthorizationCode string `json:"authCode"` + RedirectURI string `json:"redirect"` +} + +// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. +func (secret *ServicePrincipalAuthorizationCodeSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { + v.Set("code", secret.AuthorizationCode) + v.Set("client_secret", secret.ClientSecret) + v.Set("redirect_uri", secret.RedirectURI) + return nil +} + +// MarshalJSON implements the json.Marshaler interface. +func (secret ServicePrincipalAuthorizationCodeSecret) MarshalJSON() ([]byte, error) { + type tokenType struct { + Type string `json:"type"` + Value string `json:"value"` + AuthCode string `json:"authCode"` + Redirect string `json:"redirect"` + } + return json.Marshal(tokenType{ + Type: "ServicePrincipalAuthorizationCodeSecret", + Value: secret.ClientSecret, + AuthCode: secret.AuthorizationCode, + Redirect: secret.RedirectURI, + }) +} + // ServicePrincipalToken encapsulates a Token created for a Service Principal. type ServicePrincipalToken struct { - token Token - secret ServicePrincipalSecret - oauthConfig OAuthConfig - clientID string - resource string - autoRefresh bool - refreshLock *sync.RWMutex - refreshWithin time.Duration - sender Sender - + inner servicePrincipalToken + refreshLock *sync.RWMutex + sender Sender refreshCallbacks []TokenRefreshCallback + // MaxMSIRefreshAttempts is the maximum number of attempts to refresh an MSI token. + MaxMSIRefreshAttempts int +} + +// MarshalTokenJSON returns the marshalled inner token. +func (spt ServicePrincipalToken) MarshalTokenJSON() ([]byte, error) { + return json.Marshal(spt.inner.Token) +} + +// SetRefreshCallbacks replaces any existing refresh callbacks with the specified callbacks. +func (spt *ServicePrincipalToken) SetRefreshCallbacks(callbacks []TokenRefreshCallback) { + spt.refreshCallbacks = callbacks +} + +// MarshalJSON implements the json.Marshaler interface. +func (spt ServicePrincipalToken) MarshalJSON() ([]byte, error) { + return json.Marshal(spt.inner) +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (spt *ServicePrincipalToken) UnmarshalJSON(data []byte) error { + // need to determine the token type + raw := map[string]interface{}{} + err := json.Unmarshal(data, &raw) + if err != nil { + return err + } + secret := raw["secret"].(map[string]interface{}) + switch secret["type"] { + case "ServicePrincipalNoSecret": + spt.inner.Secret = &ServicePrincipalNoSecret{} + case "ServicePrincipalTokenSecret": + spt.inner.Secret = &ServicePrincipalTokenSecret{} + case "ServicePrincipalCertificateSecret": + return errors.New("unmarshalling ServicePrincipalCertificateSecret is not supported") + case "ServicePrincipalMSISecret": + return errors.New("unmarshalling ServicePrincipalMSISecret is not supported") + case "ServicePrincipalUsernamePasswordSecret": + spt.inner.Secret = &ServicePrincipalUsernamePasswordSecret{} + case "ServicePrincipalAuthorizationCodeSecret": + spt.inner.Secret = &ServicePrincipalAuthorizationCodeSecret{} + default: + return fmt.Errorf("unrecognized token type '%s'", secret["type"]) + } + err = json.Unmarshal(data, &spt.inner) + if err != nil { + return err + } + spt.refreshLock = &sync.RWMutex{} + spt.sender = &http.Client{} + return nil +} + +// internal type used for marshalling/unmarshalling +type servicePrincipalToken struct { + Token Token `json:"token"` + Secret ServicePrincipalSecret `json:"secret"` + OauthConfig OAuthConfig `json:"oauth"` + ClientID string `json:"clientID"` + Resource string `json:"resource"` + AutoRefresh bool `json:"autoRefresh"` + RefreshWithin time.Duration `json:"refreshWithin"` } func validateOAuthConfig(oac OAuthConfig) error { @@ -278,13 +412,15 @@ func NewServicePrincipalTokenWithSecret(oauthConfig OAuthConfig, id string, reso return nil, fmt.Errorf("parameter 'secret' cannot be nil") } spt := &ServicePrincipalToken{ - oauthConfig: oauthConfig, - secret: secret, - clientID: id, - resource: resource, - autoRefresh: true, + inner: servicePrincipalToken{ + OauthConfig: oauthConfig, + Secret: secret, + ClientID: id, + Resource: resource, + AutoRefresh: true, + RefreshWithin: defaultRefresh, + }, refreshLock: &sync.RWMutex{}, - refreshWithin: defaultRefresh, sender: &http.Client{}, refreshCallbacks: callbacks, } @@ -315,7 +451,39 @@ func NewServicePrincipalTokenFromManualToken(oauthConfig OAuthConfig, clientID s return nil, err } - spt.token = token + spt.inner.Token = token + + return spt, nil +} + +// NewServicePrincipalTokenFromManualTokenSecret creates a ServicePrincipalToken using the supplied token and secret +func NewServicePrincipalTokenFromManualTokenSecret(oauthConfig OAuthConfig, clientID string, resource string, token Token, secret ServicePrincipalSecret, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { + if err := validateOAuthConfig(oauthConfig); err != nil { + return nil, err + } + if err := validateStringParam(clientID, "clientID"); err != nil { + return nil, err + } + if err := validateStringParam(resource, "resource"); err != nil { + return nil, err + } + if secret == nil { + return nil, fmt.Errorf("parameter 'secret' cannot be nil") + } + if token.IsZero() { + return nil, fmt.Errorf("parameter 'token' cannot be zero-initialized") + } + spt, err := NewServicePrincipalTokenWithSecret( + oauthConfig, + clientID, + resource, + secret, + callbacks...) + if err != nil { + return nil, err + } + + spt.inner.Token = token return spt, nil } @@ -441,24 +609,7 @@ func NewServicePrincipalTokenFromAuthorizationCode(oauthConfig OAuthConfig, clie // GetMSIVMEndpoint gets the MSI endpoint on Virtual Machines. func GetMSIVMEndpoint() (string, error) { - return getMSIVMEndpoint(msiPath) -} - -func getMSIVMEndpoint(path string) (string, error) { - // Read MSI settings - bytes, err := ioutil.ReadFile(path) - if err != nil { - return "", err - } - msiSettings := struct { - URL string `json:"url"` - }{} - err = json.Unmarshal(bytes, &msiSettings) - if err != nil { - return "", err - } - - return msiSettings.URL, nil + return msiEndpoint, nil } // NewServicePrincipalTokenFromMSI creates a ServicePrincipalToken via the MSI VM Extension. @@ -491,24 +642,32 @@ func newServicePrincipalTokenFromMSI(msiEndpoint, resource string, userAssignedI return nil, err } - oauthConfig, err := NewOAuthConfig(msiEndpointURL.String(), "") - if err != nil { - return nil, err + v := url.Values{} + v.Set("resource", resource) + v.Set("api-version", "2018-02-01") + if userAssignedID != nil { + v.Set("client_id", *userAssignedID) } + msiEndpointURL.RawQuery = v.Encode() spt := &ServicePrincipalToken{ - oauthConfig: *oauthConfig, - secret: &ServicePrincipalMSISecret{}, - resource: resource, - autoRefresh: true, - refreshLock: &sync.RWMutex{}, - refreshWithin: defaultRefresh, - sender: &http.Client{}, - refreshCallbacks: callbacks, + inner: servicePrincipalToken{ + OauthConfig: OAuthConfig{ + TokenEndpoint: *msiEndpointURL, + }, + Secret: &ServicePrincipalMSISecret{}, + Resource: resource, + AutoRefresh: true, + RefreshWithin: defaultRefresh, + }, + refreshLock: &sync.RWMutex{}, + sender: &http.Client{}, + refreshCallbacks: callbacks, + MaxMSIRefreshAttempts: defaultMaxMSIRefreshAttempts, } if userAssignedID != nil { - spt.clientID = *userAssignedID + spt.inner.ClientID = *userAssignedID } return spt, nil @@ -537,12 +696,18 @@ func newTokenRefreshError(message string, resp *http.Response) TokenRefreshError // EnsureFresh will refresh the token if it will expire within the refresh window (as set by // RefreshWithin) and autoRefresh flag is on. This method is safe for concurrent use. func (spt *ServicePrincipalToken) EnsureFresh() error { - if spt.autoRefresh && spt.token.WillExpireIn(spt.refreshWithin) { + return spt.EnsureFreshWithContext(context.Background()) +} + +// EnsureFreshWithContext will refresh the token if it will expire within the refresh window (as set by +// RefreshWithin) and autoRefresh flag is on. This method is safe for concurrent use. +func (spt *ServicePrincipalToken) EnsureFreshWithContext(ctx context.Context) error { + if spt.inner.AutoRefresh && spt.inner.Token.WillExpireIn(spt.inner.RefreshWithin) { // take the write lock then check to see if the token was already refreshed spt.refreshLock.Lock() defer spt.refreshLock.Unlock() - if spt.token.WillExpireIn(spt.refreshWithin) { - return spt.refreshInternal(spt.resource) + if spt.inner.Token.WillExpireIn(spt.inner.RefreshWithin) { + return spt.refreshInternal(ctx, spt.inner.Resource) } } return nil @@ -552,7 +717,7 @@ func (spt *ServicePrincipalToken) EnsureFresh() error { func (spt *ServicePrincipalToken) InvokeRefreshCallbacks(token Token) error { if spt.refreshCallbacks != nil { for _, callback := range spt.refreshCallbacks { - err := callback(spt.token) + err := callback(spt.inner.Token) if err != nil { return fmt.Errorf("adal: TokenRefreshCallback handler failed. Error = '%v'", err) } @@ -564,21 +729,33 @@ func (spt *ServicePrincipalToken) InvokeRefreshCallbacks(token Token) error { // Refresh obtains a fresh token for the Service Principal. // This method is not safe for concurrent use and should be syncrhonized. func (spt *ServicePrincipalToken) Refresh() error { + return spt.RefreshWithContext(context.Background()) +} + +// RefreshWithContext obtains a fresh token for the Service Principal. +// This method is not safe for concurrent use and should be syncrhonized. +func (spt *ServicePrincipalToken) RefreshWithContext(ctx context.Context) error { spt.refreshLock.Lock() defer spt.refreshLock.Unlock() - return spt.refreshInternal(spt.resource) + return spt.refreshInternal(ctx, spt.inner.Resource) } // RefreshExchange refreshes the token, but for a different resource. // This method is not safe for concurrent use and should be syncrhonized. func (spt *ServicePrincipalToken) RefreshExchange(resource string) error { + return spt.RefreshExchangeWithContext(context.Background(), resource) +} + +// RefreshExchangeWithContext refreshes the token, but for a different resource. +// This method is not safe for concurrent use and should be syncrhonized. +func (spt *ServicePrincipalToken) RefreshExchangeWithContext(ctx context.Context, resource string) error { spt.refreshLock.Lock() defer spt.refreshLock.Unlock() - return spt.refreshInternal(resource) + return spt.refreshInternal(ctx, resource) } func (spt *ServicePrincipalToken) getGrantType() string { - switch spt.secret.(type) { + switch spt.inner.Secret.(type) { case *ServicePrincipalUsernamePasswordSecret: return OAuthGrantTypeUserPass case *ServicePrincipalAuthorizationCodeSecret: @@ -588,37 +765,64 @@ func (spt *ServicePrincipalToken) getGrantType() string { } } -func (spt *ServicePrincipalToken) refreshInternal(resource string) error { - v := url.Values{} - v.Set("client_id", spt.clientID) - v.Set("resource", resource) - - if spt.token.RefreshToken != "" { - v.Set("grant_type", OAuthGrantTypeRefreshToken) - v.Set("refresh_token", spt.token.RefreshToken) - } else { - v.Set("grant_type", spt.getGrantType()) - err := spt.secret.SetAuthenticationValues(spt, &v) - if err != nil { - return err - } +func isIMDS(u url.URL) bool { + imds, err := url.Parse(msiEndpoint) + if err != nil { + return false } + return u.Host == imds.Host && u.Path == imds.Path +} - s := v.Encode() - body := ioutil.NopCloser(strings.NewReader(s)) - req, err := http.NewRequest(http.MethodPost, spt.oauthConfig.TokenEndpoint.String(), body) +func (spt *ServicePrincipalToken) refreshInternal(ctx context.Context, resource string) error { + req, err := http.NewRequest(http.MethodPost, spt.inner.OauthConfig.TokenEndpoint.String(), nil) if err != nil { return fmt.Errorf("adal: Failed to build the refresh request. Error = '%v'", err) } + req = req.WithContext(ctx) + if !isIMDS(spt.inner.OauthConfig.TokenEndpoint) { + v := url.Values{} + v.Set("client_id", spt.inner.ClientID) + v.Set("resource", resource) - req.ContentLength = int64(len(s)) - req.Header.Set(contentType, mimeTypeFormPost) - if _, ok := spt.secret.(*ServicePrincipalMSISecret); ok { + if spt.inner.Token.RefreshToken != "" { + v.Set("grant_type", OAuthGrantTypeRefreshToken) + v.Set("refresh_token", spt.inner.Token.RefreshToken) + // web apps must specify client_secret when refreshing tokens + // see https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-code#refreshing-the-access-tokens + if spt.getGrantType() == OAuthGrantTypeAuthorizationCode { + err := spt.inner.Secret.SetAuthenticationValues(spt, &v) + if err != nil { + return err + } + } + } else { + v.Set("grant_type", spt.getGrantType()) + err := spt.inner.Secret.SetAuthenticationValues(spt, &v) + if err != nil { + return err + } + } + + s := v.Encode() + body := ioutil.NopCloser(strings.NewReader(s)) + req.ContentLength = int64(len(s)) + req.Header.Set(contentType, mimeTypeFormPost) + req.Body = body + } + + if _, ok := spt.inner.Secret.(*ServicePrincipalMSISecret); ok { + req.Method = http.MethodGet req.Header.Set(metadataHeader, "true") } - resp, err := spt.sender.Do(req) + + var resp *http.Response + if isIMDS(spt.inner.OauthConfig.TokenEndpoint) { + resp, err = retryForIMDS(spt.sender, req, spt.MaxMSIRefreshAttempts) + } else { + resp, err = spt.sender.Do(req) + } if err != nil { - return fmt.Errorf("adal: Failed to execute the refresh request. Error = '%v'", err) + return newTokenRefreshError(fmt.Sprintf("adal: Failed to execute the refresh request. Error = '%v'", err), nil) } defer resp.Body.Close() @@ -626,11 +830,15 @@ func (spt *ServicePrincipalToken) refreshInternal(resource string) error { if resp.StatusCode != http.StatusOK { if err != nil { - return newTokenRefreshError(fmt.Sprintf("adal: Refresh request failed. Status Code = '%d'. Failed reading response body", resp.StatusCode), resp) + return newTokenRefreshError(fmt.Sprintf("adal: Refresh request failed. Status Code = '%d'. Failed reading response body: %v", resp.StatusCode, err), resp) } return newTokenRefreshError(fmt.Sprintf("adal: Refresh request failed. Status Code = '%d'. Response body: %s", resp.StatusCode, string(rb)), resp) } + // for the following error cases don't return a TokenRefreshError. the operation succeeded + // but some transient failure happened during deserialization. by returning a generic error + // the retry logic will kick in (we don't retry on TokenRefreshError). + if err != nil { return fmt.Errorf("adal: Failed to read a new service principal token during refresh. Error = '%v'", err) } @@ -643,20 +851,99 @@ func (spt *ServicePrincipalToken) refreshInternal(resource string) error { return fmt.Errorf("adal: Failed to unmarshal the service principal token during refresh. Error = '%v' JSON = '%s'", err, string(rb)) } - spt.token = token + spt.inner.Token = token return spt.InvokeRefreshCallbacks(token) } +// retry logic specific to retrieving a token from the IMDS endpoint +func retryForIMDS(sender Sender, req *http.Request, maxAttempts int) (resp *http.Response, err error) { + // copied from client.go due to circular dependency + retries := []int{ + http.StatusRequestTimeout, // 408 + http.StatusTooManyRequests, // 429 + http.StatusInternalServerError, // 500 + http.StatusBadGateway, // 502 + http.StatusServiceUnavailable, // 503 + http.StatusGatewayTimeout, // 504 + } + // extra retry status codes specific to IMDS + retries = append(retries, + http.StatusNotFound, + http.StatusGone, + // all remaining 5xx + http.StatusNotImplemented, + http.StatusHTTPVersionNotSupported, + http.StatusVariantAlsoNegotiates, + http.StatusInsufficientStorage, + http.StatusLoopDetected, + http.StatusNotExtended, + http.StatusNetworkAuthenticationRequired) + + // see https://docs.microsoft.com/en-us/azure/active-directory/managed-service-identity/how-to-use-vm-token#retry-guidance + + const maxDelay time.Duration = 60 * time.Second + + attempt := 0 + delay := time.Duration(0) + + for attempt < maxAttempts { + resp, err = sender.Do(req) + // retry on temporary network errors, e.g. transient network failures. + // if we don't receive a response then assume we can't connect to the + // endpoint so we're likely not running on an Azure VM so don't retry. + if (err != nil && !isTemporaryNetworkError(err)) || resp == nil || resp.StatusCode == http.StatusOK || !containsInt(retries, resp.StatusCode) { + return + } + + // perform exponential backoff with a cap. + // must increment attempt before calculating delay. + attempt++ + // the base value of 2 is the "delta backoff" as specified in the guidance doc + delay += (time.Duration(math.Pow(2, float64(attempt))) * time.Second) + if delay > maxDelay { + delay = maxDelay + } + + select { + case <-time.After(delay): + // intentionally left blank + case <-req.Context().Done(): + err = req.Context().Err() + return + } + } + return +} + +// returns true if the specified error is a temporary network error or false if it's not. +// if the error doesn't implement the net.Error interface the return value is true. +func isTemporaryNetworkError(err error) bool { + if netErr, ok := err.(net.Error); !ok || (ok && netErr.Temporary()) { + return true + } + return false +} + +// returns true if slice ints contains the value n +func containsInt(ints []int, n int) bool { + for _, i := range ints { + if i == n { + return true + } + } + return false +} + // SetAutoRefresh enables or disables automatic refreshing of stale tokens. func (spt *ServicePrincipalToken) SetAutoRefresh(autoRefresh bool) { - spt.autoRefresh = autoRefresh + spt.inner.AutoRefresh = autoRefresh } // SetRefreshWithin sets the interval within which if the token will expire, EnsureFresh will // refresh the token. func (spt *ServicePrincipalToken) SetRefreshWithin(d time.Duration) { - spt.refreshWithin = d + spt.inner.RefreshWithin = d return } @@ -668,12 +955,12 @@ func (spt *ServicePrincipalToken) SetSender(s Sender) { spt.sender = s } func (spt *ServicePrincipalToken) OAuthToken() string { spt.refreshLock.RLock() defer spt.refreshLock.RUnlock() - return spt.token.OAuthToken() + return spt.inner.Token.OAuthToken() } // Token returns a copy of the current token. func (spt *ServicePrincipalToken) Token() Token { spt.refreshLock.RLock() defer spt.refreshLock.RUnlock() - return spt.token + return spt.inner.Token } diff --git a/vendor/github.com/Azure/go-autorest/autorest/authorization.go b/vendor/github.com/Azure/go-autorest/autorest/authorization.go index c51eac0a7..77eff45bd 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/authorization.go +++ b/vendor/github.com/Azure/go-autorest/autorest/authorization.go @@ -113,17 +113,19 @@ func (ba *BearerAuthorizer) WithAuthorization() PrepareDecorator { return PreparerFunc(func(r *http.Request) (*http.Request, error) { r, err := p.Prepare(r) if err == nil { - refresher, ok := ba.tokenProvider.(adal.Refresher) - if ok { - err := refresher.EnsureFresh() - if err != nil { - var resp *http.Response - if tokError, ok := err.(adal.TokenRefreshError); ok { - resp = tokError.Response() - } - return r, NewErrorWithError(err, "azure.BearerAuthorizer", "WithAuthorization", resp, - "Failed to refresh the Token for request to %s", r.URL) + // the ordering is important here, prefer RefresherWithContext if available + if refresher, ok := ba.tokenProvider.(adal.RefresherWithContext); ok { + err = refresher.EnsureFreshWithContext(r.Context()) + } else if refresher, ok := ba.tokenProvider.(adal.Refresher); ok { + err = refresher.EnsureFresh() + } + if err != nil { + var resp *http.Response + if tokError, ok := err.(adal.TokenRefreshError); ok { + resp = tokError.Response() } + return r, NewErrorWithError(err, "azure.BearerAuthorizer", "WithAuthorization", resp, + "Failed to refresh the Token for request to %s", r.URL) } return Prepare(r, WithHeader(headerAuthorization, fmt.Sprintf("Bearer %s", ba.tokenProvider.OAuthToken()))) } diff --git a/vendor/github.com/Azure/go-autorest/autorest/autorest.go b/vendor/github.com/Azure/go-autorest/autorest/autorest.go index f86b66a41..aafdf021f 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/autorest.go +++ b/vendor/github.com/Azure/go-autorest/autorest/autorest.go @@ -72,6 +72,7 @@ package autorest // limitations under the License. import ( + "context" "net/http" "time" ) @@ -130,3 +131,20 @@ func NewPollingRequest(resp *http.Response, cancel <-chan struct{}) (*http.Reque return req, nil } + +// NewPollingRequestWithContext allocates and returns a new http.Request with the specified context to poll for the passed response. +func NewPollingRequestWithContext(ctx context.Context, resp *http.Response) (*http.Request, error) { + location := GetLocation(resp) + if location == "" { + return nil, NewErrorWithResponse("autorest", "NewPollingRequestWithContext", resp, "Location header missing from response that requires polling") + } + + req, err := Prepare((&http.Request{}).WithContext(ctx), + AsGet(), + WithBaseURL(location)) + if err != nil { + return nil, NewErrorWithError(err, "autorest", "NewPollingRequestWithContext", nil, "Failure creating poll request to %s", location) + } + + return req, nil +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/async.go b/vendor/github.com/Azure/go-autorest/autorest/azure/async.go index a18b61041..cda1e180a 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/async.go +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/async.go @@ -21,11 +21,11 @@ import ( "fmt" "io/ioutil" "net/http" + "net/url" "strings" "time" "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/date" ) const ( @@ -44,84 +44,85 @@ var pollingCodes = [...]int{http.StatusNoContent, http.StatusAccepted, http.Stat // Future provides a mechanism to access the status and results of an asynchronous request. // Since futures are stateful they should be passed by value to avoid race conditions. type Future struct { - req *http.Request - resp *http.Response - ps pollingState + req *http.Request // legacy + pt pollingTracker } // NewFuture returns a new Future object initialized with the specified request. +// Deprecated: Please use NewFutureFromResponse instead. func NewFuture(req *http.Request) Future { return Future{req: req} } -// Response returns the last HTTP response or nil if there isn't one. +// NewFutureFromResponse returns a new Future object initialized +// with the initial response from an asynchronous operation. +func NewFutureFromResponse(resp *http.Response) (Future, error) { + pt, err := createPollingTracker(resp) + if err != nil { + return Future{}, err + } + return Future{pt: pt}, nil +} + +// Response returns the last HTTP response. func (f Future) Response() *http.Response { - return f.resp + if f.pt == nil { + return nil + } + return f.pt.latestResponse() } // Status returns the last status message of the operation. func (f Future) Status() string { - if f.ps.State == "" { - return "Unknown" + if f.pt == nil { + return "" } - return f.ps.State + return f.pt.pollingStatus() } // PollingMethod returns the method used to monitor the status of the asynchronous operation. func (f Future) PollingMethod() PollingMethodType { - return f.ps.PollingMethod + if f.pt == nil { + return PollingUnknown + } + return f.pt.pollingMethod() } // Done queries the service to see if the operation has completed. func (f *Future) Done(sender autorest.Sender) (bool, error) { - // exit early if this future has terminated - if f.ps.hasTerminated() { - return true, f.errorInfo() + // support for legacy Future implementation + if f.req != nil { + resp, err := sender.Do(f.req) + if err != nil { + return false, err + } + pt, err := createPollingTracker(resp) + if err != nil { + return false, err + } + f.pt = pt + f.req = nil } - resp, err := sender.Do(f.req) - f.resp = resp - if err != nil { + // end legacy + if f.pt == nil { + return false, autorest.NewError("Future", "Done", "future is not initialized") + } + if f.pt.hasTerminated() { + return true, f.pt.pollingError() + } + if err := f.pt.pollForStatus(sender); err != nil { return false, err } - - if !autorest.ResponseHasStatusCode(resp, pollingCodes[:]...) { - // check response body for error content - if resp.Body != nil { - type respErr struct { - ServiceError ServiceError `json:"error"` - } - re := respErr{} - - defer resp.Body.Close() - b, err := ioutil.ReadAll(resp.Body) - if err != nil { - return false, err - } - err = json.Unmarshal(b, &re) - if err != nil { - return false, err - } - return false, re.ServiceError - } - - // try to return something meaningful - return false, ServiceError{ - Code: fmt.Sprintf("%v", resp.StatusCode), - Message: resp.Status, - } + if err := f.pt.checkForErrors(); err != nil { + return f.pt.hasTerminated(), err } - - err = updatePollingState(resp, &f.ps) - if err != nil { + if err := f.pt.updatePollingState(f.pt.provisioningStateApplicable()); err != nil { return false, err } - - if f.ps.hasTerminated() { - return true, f.errorInfo() + if err := f.pt.updateHeaders(); err != nil { + return false, err } - - f.req, err = newPollingRequest(f.ps) - return false, err + return f.pt.hasTerminated(), f.pt.pollingError() } // GetPollingDelay returns a duration the application should wait before checking @@ -129,11 +130,15 @@ func (f *Future) Done(sender autorest.Sender) (bool, error) { // the service via the Retry-After response header. If the header wasn't returned // then the function returns the zero-value time.Duration and false. func (f Future) GetPollingDelay() (time.Duration, bool) { - if f.resp == nil { + if f.pt == nil { + return 0, false + } + resp := f.pt.latestResponse() + if resp == nil { return 0, false } - retry := f.resp.Header.Get(autorest.HeaderRetryAfter) + retry := resp.Header.Get(autorest.HeaderRetryAfter) if retry == "" { return 0, false } @@ -150,14 +155,22 @@ func (f Future) GetPollingDelay() (time.Duration, bool) { // running operation has completed, the provided context is cancelled, or the client's // polling duration has been exceeded. It will retry failed polling attempts based on // the retry value defined in the client up to the maximum retry attempts. +// Deprecated: Please use WaitForCompletionRef() instead. func (f Future) WaitForCompletion(ctx context.Context, client autorest.Client) error { + return f.WaitForCompletionRef(ctx, client) +} + +// WaitForCompletionRef will return when one of the following conditions is met: the long +// running operation has completed, the provided context is cancelled, or the client's +// polling duration has been exceeded. It will retry failed polling attempts based on +// the retry value defined in the client up to the maximum retry attempts. +func (f *Future) WaitForCompletionRef(ctx context.Context, client autorest.Client) error { ctx, cancel := context.WithTimeout(ctx, client.PollingDuration) defer cancel() - done, err := f.Done(client) for attempts := 0; !done; done, err = f.Done(client) { if attempts >= client.RetryAttempts { - return autorest.NewErrorWithError(err, "azure", "WaitForCompletion", f.resp, "the number of retries has been exceeded") + return autorest.NewErrorWithError(err, "Future", "WaitForCompletion", f.pt.latestResponse(), "the number of retries has been exceeded") } // we want delayAttempt to be zero in the non-error case so // that DelayForBackoff doesn't perform exponential back-off @@ -181,162 +194,692 @@ func (f Future) WaitForCompletion(ctx context.Context, client autorest.Client) e // wait until the delay elapses or the context is cancelled delayElapsed := autorest.DelayForBackoff(delay, delayAttempt, ctx.Done()) if !delayElapsed { - return autorest.NewErrorWithError(ctx.Err(), "azure", "WaitForCompletion", f.resp, "context has been cancelled") + return autorest.NewErrorWithError(ctx.Err(), "Future", "WaitForCompletion", f.pt.latestResponse(), "context has been cancelled") } } return err } -// if the operation failed the polling state will contain -// error information and implements the error interface -func (f *Future) errorInfo() error { - if !f.ps.hasSucceeded() { - return f.ps - } - return nil -} - // MarshalJSON implements the json.Marshaler interface. func (f Future) MarshalJSON() ([]byte, error) { - return json.Marshal(&f.ps) + return json.Marshal(f.pt) } // UnmarshalJSON implements the json.Unmarshaler interface. func (f *Future) UnmarshalJSON(data []byte) error { - err := json.Unmarshal(data, &f.ps) + // unmarshal into JSON object to determine the tracker type + obj := map[string]interface{}{} + err := json.Unmarshal(data, &obj) if err != nil { return err } - f.req, err = newPollingRequest(f.ps) - return err + if obj["method"] == nil { + return autorest.NewError("Future", "UnmarshalJSON", "missing 'method' property") + } + method := obj["method"].(string) + switch strings.ToUpper(method) { + case http.MethodDelete: + f.pt = &pollingTrackerDelete{} + case http.MethodPatch: + f.pt = &pollingTrackerPatch{} + case http.MethodPost: + f.pt = &pollingTrackerPost{} + case http.MethodPut: + f.pt = &pollingTrackerPut{} + default: + return autorest.NewError("Future", "UnmarshalJSON", "unsupoorted method '%s'", method) + } + // now unmarshal into the tracker + return json.Unmarshal(data, &f.pt) } // PollingURL returns the URL used for retrieving the status of the long-running operation. -// For LROs that use the Location header the final URL value is used to retrieve the result. func (f Future) PollingURL() string { - return f.ps.URI + if f.pt == nil { + return "" + } + return f.pt.pollingURL() +} + +// GetResult should be called once polling has completed successfully. +// It makes the final GET call to retrieve the resultant payload. +func (f Future) GetResult(sender autorest.Sender) (*http.Response, error) { + if f.pt.finalGetURL() == "" { + // we can end up in this situation if the async operation returns a 200 + // with no polling URLs. in that case return the response which should + // contain the JSON payload (only do this for successful terminal cases). + if lr := f.pt.latestResponse(); lr != nil && f.pt.hasSucceeded() { + return lr, nil + } + return nil, autorest.NewError("Future", "GetResult", "missing URL for retrieving result") + } + req, err := http.NewRequest(http.MethodGet, f.pt.finalGetURL(), nil) + if err != nil { + return nil, err + } + return sender.Do(req) +} + +type pollingTracker interface { + // these methods can differ per tracker + + // checks the response headers and status code to determine the polling mechanism + updateHeaders() error + + // checks the response for tracker-specific error conditions + checkForErrors() error + + // returns true if provisioning state should be checked + provisioningStateApplicable() bool + + // methods common to all trackers + + // initializes the tracker's internal state, call this when the tracker is created + initializeState() error + + // makes an HTTP request to check the status of the LRO + pollForStatus(sender autorest.Sender) error + + // updates internal tracker state, call this after each call to pollForStatus + updatePollingState(provStateApl bool) error + + // returns the error response from the service, can be nil + pollingError() error + + // returns the polling method being used + pollingMethod() PollingMethodType + + // returns the state of the LRO as returned from the service + pollingStatus() string + + // returns the URL used for polling status + pollingURL() string + + // returns the URL used for the final GET to retrieve the resource + finalGetURL() string + + // returns true if the LRO is in a terminal state + hasTerminated() bool + + // returns true if the LRO is in a failed terminal state + hasFailed() bool + + // returns true if the LRO is in a successful terminal state + hasSucceeded() bool + + // returns the cached HTTP response after a call to pollForStatus(), can be nil + latestResponse() *http.Response +} + +type pollingTrackerBase struct { + // resp is the last response, either from the submission of the LRO or from polling + resp *http.Response + + // method is the HTTP verb, this is needed for deserialization + Method string `json:"method"` + + // rawBody is the raw JSON response body + rawBody map[string]interface{} + + // denotes if polling is using async-operation or location header + Pm PollingMethodType `json:"pollingMethod"` + + // the URL to poll for status + URI string `json:"pollingURI"` + + // the state of the LRO as returned from the service + State string `json:"lroState"` + + // the URL to GET for the final result + FinalGetURI string `json:"resultURI"` + + // used to hold an error object returned from the service + Err *ServiceError `json:"error,omitempty"` +} + +func (pt *pollingTrackerBase) initializeState() error { + // determine the initial polling state based on response body and/or HTTP status + // code. this is applicable to the initial LRO response, not polling responses! + pt.Method = pt.resp.Request.Method + if err := pt.updateRawBody(); err != nil { + return err + } + switch pt.resp.StatusCode { + case http.StatusOK: + if ps := pt.getProvisioningState(); ps != nil { + pt.State = *ps + } else { + pt.State = operationSucceeded + } + case http.StatusCreated: + if ps := pt.getProvisioningState(); ps != nil { + pt.State = *ps + } else { + pt.State = operationInProgress + } + case http.StatusAccepted: + pt.State = operationInProgress + case http.StatusNoContent: + pt.State = operationSucceeded + default: + pt.State = operationFailed + pt.updateErrorFromResponse() + } + return nil +} + +func (pt pollingTrackerBase) getProvisioningState() *string { + if pt.rawBody != nil && pt.rawBody["properties"] != nil { + p := pt.rawBody["properties"].(map[string]interface{}) + if ps := p["provisioningState"]; ps != nil { + s := ps.(string) + return &s + } + } + return nil +} + +func (pt *pollingTrackerBase) updateRawBody() error { + pt.rawBody = map[string]interface{}{} + if pt.resp.ContentLength != 0 { + defer pt.resp.Body.Close() + b, err := ioutil.ReadAll(pt.resp.Body) + if err != nil { + return autorest.NewErrorWithError(err, "pollingTrackerBase", "updateRawBody", nil, "failed to read response body") + } + // put the body back so it's available to other callers + pt.resp.Body = ioutil.NopCloser(bytes.NewReader(b)) + if err = json.Unmarshal(b, &pt.rawBody); err != nil { + return autorest.NewErrorWithError(err, "pollingTrackerBase", "updateRawBody", nil, "failed to unmarshal response body") + } + } + return nil +} + +func (pt *pollingTrackerBase) pollForStatus(sender autorest.Sender) error { + req, err := http.NewRequest(http.MethodGet, pt.URI, nil) + if err != nil { + return autorest.NewErrorWithError(err, "pollingTrackerBase", "pollForStatus", nil, "failed to create HTTP request") + } + // attach the context from the original request if available (it will be absent for deserialized futures) + if pt.resp != nil { + req = req.WithContext(pt.resp.Request.Context()) + } + pt.resp, err = sender.Do(req) + if err != nil { + return autorest.NewErrorWithError(err, "pollingTrackerBase", "pollForStatus", nil, "failed to send HTTP request") + } + if autorest.ResponseHasStatusCode(pt.resp, pollingCodes[:]...) { + // reset the service error on success case + pt.Err = nil + err = pt.updateRawBody() + } else { + // check response body for error content + pt.updateErrorFromResponse() + } + return err +} + +// attempts to unmarshal a ServiceError type from the response body. +// if that fails then make a best attempt at creating something meaningful. +func (pt *pollingTrackerBase) updateErrorFromResponse() { + var err error + if pt.resp.ContentLength != 0 { + type respErr struct { + ServiceError *ServiceError `json:"error"` + } + re := respErr{} + defer pt.resp.Body.Close() + var b []byte + b, err = ioutil.ReadAll(pt.resp.Body) + if err != nil { + goto Default + } + if err = json.Unmarshal(b, &re); err != nil { + goto Default + } + // unmarshalling the error didn't yield anything, try unwrapped error + if re.ServiceError == nil { + err = json.Unmarshal(b, &re.ServiceError) + if err != nil { + goto Default + } + } + if re.ServiceError != nil { + pt.Err = re.ServiceError + return + } + } +Default: + se := &ServiceError{ + Code: fmt.Sprintf("HTTP status code %v", pt.resp.StatusCode), + Message: pt.resp.Status, + } + if err != nil { + se.InnerError = make(map[string]interface{}) + se.InnerError["unmarshalError"] = err.Error() + } + pt.Err = se +} + +func (pt *pollingTrackerBase) updatePollingState(provStateApl bool) error { + if pt.Pm == PollingAsyncOperation && pt.rawBody["status"] != nil { + pt.State = pt.rawBody["status"].(string) + } else { + if pt.resp.StatusCode == http.StatusAccepted { + pt.State = operationInProgress + } else if provStateApl { + if ps := pt.getProvisioningState(); ps != nil { + pt.State = *ps + } else { + pt.State = operationSucceeded + } + } else { + return autorest.NewError("pollingTrackerBase", "updatePollingState", "the response from the async operation has an invalid status code") + } + } + // if the operation has failed update the error state + if pt.hasFailed() { + pt.updateErrorFromResponse() + } + return nil +} + +func (pt pollingTrackerBase) pollingError() error { + if pt.Err == nil { + return nil + } + return pt.Err +} + +func (pt pollingTrackerBase) pollingMethod() PollingMethodType { + return pt.Pm +} + +func (pt pollingTrackerBase) pollingStatus() string { + return pt.State +} + +func (pt pollingTrackerBase) pollingURL() string { + return pt.URI +} + +func (pt pollingTrackerBase) finalGetURL() string { + return pt.FinalGetURI +} + +func (pt pollingTrackerBase) hasTerminated() bool { + return strings.EqualFold(pt.State, operationCanceled) || strings.EqualFold(pt.State, operationFailed) || strings.EqualFold(pt.State, operationSucceeded) +} + +func (pt pollingTrackerBase) hasFailed() bool { + return strings.EqualFold(pt.State, operationCanceled) || strings.EqualFold(pt.State, operationFailed) +} + +func (pt pollingTrackerBase) hasSucceeded() bool { + return strings.EqualFold(pt.State, operationSucceeded) +} + +func (pt pollingTrackerBase) latestResponse() *http.Response { + return pt.resp +} + +// error checking common to all trackers +func (pt pollingTrackerBase) baseCheckForErrors() error { + // for Azure-AsyncOperations the response body cannot be nil or empty + if pt.Pm == PollingAsyncOperation { + if pt.resp.Body == nil || pt.resp.ContentLength == 0 { + return autorest.NewError("pollingTrackerBase", "baseCheckForErrors", "for Azure-AsyncOperation response body cannot be nil") + } + if pt.rawBody["status"] == nil { + return autorest.NewError("pollingTrackerBase", "baseCheckForErrors", "missing status property in Azure-AsyncOperation response body") + } + } + return nil +} + +// DELETE + +type pollingTrackerDelete struct { + pollingTrackerBase +} + +func (pt *pollingTrackerDelete) updateHeaders() error { + // for 201 the Location header is required + if pt.resp.StatusCode == http.StatusCreated { + if lh, err := getURLFromLocationHeader(pt.resp); err != nil { + return err + } else if lh == "" { + return autorest.NewError("pollingTrackerDelete", "updateHeaders", "missing Location header in 201 response") + } else { + pt.URI = lh + } + pt.Pm = PollingLocation + pt.FinalGetURI = pt.URI + } + // for 202 prefer the Azure-AsyncOperation header but fall back to Location if necessary + if pt.resp.StatusCode == http.StatusAccepted { + ao, err := getURLFromAsyncOpHeader(pt.resp) + if err != nil { + return err + } else if ao != "" { + pt.URI = ao + pt.Pm = PollingAsyncOperation + } + // if the Location header is invalid and we already have a polling URL + // then we don't care if the Location header URL is malformed. + if lh, err := getURLFromLocationHeader(pt.resp); err != nil && pt.URI == "" { + return err + } else if lh != "" { + if ao == "" { + pt.URI = lh + pt.Pm = PollingLocation + } + // when both headers are returned we use the value in the Location header for the final GET + pt.FinalGetURI = lh + } + // make sure a polling URL was found + if pt.URI == "" { + return autorest.NewError("pollingTrackerPost", "updateHeaders", "didn't get any suitable polling URLs in 202 response") + } + } + return nil +} + +func (pt pollingTrackerDelete) checkForErrors() error { + return pt.baseCheckForErrors() +} + +func (pt pollingTrackerDelete) provisioningStateApplicable() bool { + return pt.resp.StatusCode == http.StatusOK || pt.resp.StatusCode == http.StatusNoContent +} + +// PATCH + +type pollingTrackerPatch struct { + pollingTrackerBase +} + +func (pt *pollingTrackerPatch) updateHeaders() error { + // by default we can use the original URL for polling and final GET + if pt.URI == "" { + pt.URI = pt.resp.Request.URL.String() + } + if pt.FinalGetURI == "" { + pt.FinalGetURI = pt.resp.Request.URL.String() + } + if pt.Pm == PollingUnknown { + pt.Pm = PollingRequestURI + } + // for 201 it's permissible for no headers to be returned + if pt.resp.StatusCode == http.StatusCreated { + if ao, err := getURLFromAsyncOpHeader(pt.resp); err != nil { + return err + } else if ao != "" { + pt.URI = ao + pt.Pm = PollingAsyncOperation + } + } + // for 202 prefer the Azure-AsyncOperation header but fall back to Location if necessary + // note the absense of the "final GET" mechanism for PATCH + if pt.resp.StatusCode == http.StatusAccepted { + ao, err := getURLFromAsyncOpHeader(pt.resp) + if err != nil { + return err + } else if ao != "" { + pt.URI = ao + pt.Pm = PollingAsyncOperation + } + if ao == "" { + if lh, err := getURLFromLocationHeader(pt.resp); err != nil { + return err + } else if lh == "" { + return autorest.NewError("pollingTrackerPatch", "updateHeaders", "didn't get any suitable polling URLs in 202 response") + } else { + pt.URI = lh + pt.Pm = PollingLocation + } + } + } + return nil +} + +func (pt pollingTrackerPatch) checkForErrors() error { + return pt.baseCheckForErrors() +} + +func (pt pollingTrackerPatch) provisioningStateApplicable() bool { + return pt.resp.StatusCode == http.StatusOK || pt.resp.StatusCode == http.StatusCreated +} + +// POST + +type pollingTrackerPost struct { + pollingTrackerBase +} + +func (pt *pollingTrackerPost) updateHeaders() error { + // 201 requires Location header + if pt.resp.StatusCode == http.StatusCreated { + if lh, err := getURLFromLocationHeader(pt.resp); err != nil { + return err + } else if lh == "" { + return autorest.NewError("pollingTrackerPost", "updateHeaders", "missing Location header in 201 response") + } else { + pt.URI = lh + pt.FinalGetURI = lh + pt.Pm = PollingLocation + } + } + // for 202 prefer the Azure-AsyncOperation header but fall back to Location if necessary + if pt.resp.StatusCode == http.StatusAccepted { + ao, err := getURLFromAsyncOpHeader(pt.resp) + if err != nil { + return err + } else if ao != "" { + pt.URI = ao + pt.Pm = PollingAsyncOperation + } + // if the Location header is invalid and we already have a polling URL + // then we don't care if the Location header URL is malformed. + if lh, err := getURLFromLocationHeader(pt.resp); err != nil && pt.URI == "" { + return err + } else if lh != "" { + if ao == "" { + pt.URI = lh + pt.Pm = PollingLocation + } + // when both headers are returned we use the value in the Location header for the final GET + pt.FinalGetURI = lh + } + // make sure a polling URL was found + if pt.URI == "" { + return autorest.NewError("pollingTrackerPost", "updateHeaders", "didn't get any suitable polling URLs in 202 response") + } + } + return nil +} + +func (pt pollingTrackerPost) checkForErrors() error { + return pt.baseCheckForErrors() +} + +func (pt pollingTrackerPost) provisioningStateApplicable() bool { + return pt.resp.StatusCode == http.StatusOK || pt.resp.StatusCode == http.StatusNoContent +} + +// PUT + +type pollingTrackerPut struct { + pollingTrackerBase +} + +func (pt *pollingTrackerPut) updateHeaders() error { + // by default we can use the original URL for polling and final GET + if pt.URI == "" { + pt.URI = pt.resp.Request.URL.String() + } + if pt.FinalGetURI == "" { + pt.FinalGetURI = pt.resp.Request.URL.String() + } + if pt.Pm == PollingUnknown { + pt.Pm = PollingRequestURI + } + // for 201 it's permissible for no headers to be returned + if pt.resp.StatusCode == http.StatusCreated { + if ao, err := getURLFromAsyncOpHeader(pt.resp); err != nil { + return err + } else if ao != "" { + pt.URI = ao + pt.Pm = PollingAsyncOperation + } + } + // for 202 prefer the Azure-AsyncOperation header but fall back to Location if necessary + if pt.resp.StatusCode == http.StatusAccepted { + ao, err := getURLFromAsyncOpHeader(pt.resp) + if err != nil { + return err + } else if ao != "" { + pt.URI = ao + pt.Pm = PollingAsyncOperation + } + // if the Location header is invalid and we already have a polling URL + // then we don't care if the Location header URL is malformed. + if lh, err := getURLFromLocationHeader(pt.resp); err != nil && pt.URI == "" { + return err + } else if lh != "" { + if ao == "" { + pt.URI = lh + pt.Pm = PollingLocation + } + // when both headers are returned we use the value in the Location header for the final GET + pt.FinalGetURI = lh + } + // make sure a polling URL was found + if pt.URI == "" { + return autorest.NewError("pollingTrackerPut", "updateHeaders", "didn't get any suitable polling URLs in 202 response") + } + } + return nil +} + +func (pt pollingTrackerPut) checkForErrors() error { + err := pt.baseCheckForErrors() + if err != nil { + return err + } + // if there are no LRO headers then the body cannot be empty + ao, err := getURLFromAsyncOpHeader(pt.resp) + if err != nil { + return err + } + lh, err := getURLFromLocationHeader(pt.resp) + if err != nil { + return err + } + if ao == "" && lh == "" && len(pt.rawBody) == 0 { + return autorest.NewError("pollingTrackerPut", "checkForErrors", "the response did not contain a body") + } + return nil +} + +func (pt pollingTrackerPut) provisioningStateApplicable() bool { + return pt.resp.StatusCode == http.StatusOK || pt.resp.StatusCode == http.StatusCreated +} + +// creates a polling tracker based on the verb of the original request +func createPollingTracker(resp *http.Response) (pollingTracker, error) { + var pt pollingTracker + switch strings.ToUpper(resp.Request.Method) { + case http.MethodDelete: + pt = &pollingTrackerDelete{pollingTrackerBase: pollingTrackerBase{resp: resp}} + case http.MethodPatch: + pt = &pollingTrackerPatch{pollingTrackerBase: pollingTrackerBase{resp: resp}} + case http.MethodPost: + pt = &pollingTrackerPost{pollingTrackerBase: pollingTrackerBase{resp: resp}} + case http.MethodPut: + pt = &pollingTrackerPut{pollingTrackerBase: pollingTrackerBase{resp: resp}} + default: + return nil, autorest.NewError("azure", "createPollingTracker", "unsupported HTTP method %s", resp.Request.Method) + } + if err := pt.initializeState(); err != nil { + return pt, err + } + // this initializes the polling header values, we do this during creation in case the + // initial response send us invalid values; this way the API call will return a non-nil + // error (not doing this means the error shows up in Future.Done) + return pt, pt.updateHeaders() +} + +// gets the polling URL from the Azure-AsyncOperation header. +// ensures the URL is well-formed and absolute. +func getURLFromAsyncOpHeader(resp *http.Response) (string, error) { + s := resp.Header.Get(http.CanonicalHeaderKey(headerAsyncOperation)) + if s == "" { + return "", nil + } + if !isValidURL(s) { + return "", autorest.NewError("azure", "getURLFromAsyncOpHeader", "invalid polling URL '%s'", s) + } + return s, nil +} + +// gets the polling URL from the Location header. +// ensures the URL is well-formed and absolute. +func getURLFromLocationHeader(resp *http.Response) (string, error) { + s := resp.Header.Get(http.CanonicalHeaderKey(autorest.HeaderLocation)) + if s == "" { + return "", nil + } + if !isValidURL(s) { + return "", autorest.NewError("azure", "getURLFromLocationHeader", "invalid polling URL '%s'", s) + } + return s, nil +} + +// verify that the URL is valid and absolute +func isValidURL(s string) bool { + u, err := url.Parse(s) + return err == nil && u.IsAbs() } // DoPollForAsynchronous returns a SendDecorator that polls if the http.Response is for an Azure // long-running operation. It will delay between requests for the duration specified in the -// RetryAfter header or, if the header is absent, the passed delay. Polling may be canceled by -// closing the optional channel on the http.Request. +// RetryAfter header or, if the header is absent, the passed delay. Polling may be canceled via +// the context associated with the http.Request. +// Deprecated: Prefer using Futures to allow for non-blocking async operations. func DoPollForAsynchronous(delay time.Duration) autorest.SendDecorator { return func(s autorest.Sender) autorest.Sender { - return autorest.SenderFunc(func(r *http.Request) (resp *http.Response, err error) { - resp, err = s.Do(r) + return autorest.SenderFunc(func(r *http.Request) (*http.Response, error) { + resp, err := s.Do(r) if err != nil { return resp, err } if !autorest.ResponseHasStatusCode(resp, pollingCodes[:]...) { return resp, nil } - - ps := pollingState{} - for err == nil { - err = updatePollingState(resp, &ps) - if err != nil { - break - } - if ps.hasTerminated() { - if !ps.hasSucceeded() { - err = ps - } - break - } - - r, err = newPollingRequest(ps) - if err != nil { - return resp, err - } - r.Cancel = resp.Request.Cancel - - delay = autorest.GetRetryAfter(resp, delay) - resp, err = autorest.SendWithSender(s, r, - autorest.AfterDelay(delay)) + future, err := NewFutureFromResponse(resp) + if err != nil { + return resp, err } - - return resp, err + // retry until either the LRO completes or we receive an error + var done bool + for done, err = future.Done(s); !done && err == nil; done, err = future.Done(s) { + // check for Retry-After delay, if not present use the specified polling delay + if pd, ok := future.GetPollingDelay(); ok { + delay = pd + } + // wait until the delay elapses or the context is cancelled + if delayElapsed := autorest.DelayForBackoff(delay, 0, r.Context().Done()); !delayElapsed { + return future.Response(), + autorest.NewErrorWithError(r.Context().Err(), "azure", "DoPollForAsynchronous", future.Response(), "context has been cancelled") + } + } + return future.Response(), err }) } } -func getAsyncOperation(resp *http.Response) string { - return resp.Header.Get(http.CanonicalHeaderKey(headerAsyncOperation)) -} - -func hasSucceeded(state string) bool { - return strings.EqualFold(state, operationSucceeded) -} - -func hasTerminated(state string) bool { - return strings.EqualFold(state, operationCanceled) || strings.EqualFold(state, operationFailed) || strings.EqualFold(state, operationSucceeded) -} - -func hasFailed(state string) bool { - return strings.EqualFold(state, operationFailed) -} - -type provisioningTracker interface { - state() string - hasSucceeded() bool - hasTerminated() bool -} - -type operationResource struct { - // Note: - // The specification states services should return the "id" field. However some return it as - // "operationId". - ID string `json:"id"` - OperationID string `json:"operationId"` - Name string `json:"name"` - Status string `json:"status"` - Properties map[string]interface{} `json:"properties"` - OperationError ServiceError `json:"error"` - StartTime date.Time `json:"startTime"` - EndTime date.Time `json:"endTime"` - PercentComplete float64 `json:"percentComplete"` -} - -func (or operationResource) state() string { - return or.Status -} - -func (or operationResource) hasSucceeded() bool { - return hasSucceeded(or.state()) -} - -func (or operationResource) hasTerminated() bool { - return hasTerminated(or.state()) -} - -type provisioningProperties struct { - ProvisioningState string `json:"provisioningState"` -} - -type provisioningStatus struct { - Properties provisioningProperties `json:"properties,omitempty"` - ProvisioningError ServiceError `json:"error,omitempty"` -} - -func (ps provisioningStatus) state() string { - return ps.Properties.ProvisioningState -} - -func (ps provisioningStatus) hasSucceeded() bool { - return hasSucceeded(ps.state()) -} - -func (ps provisioningStatus) hasTerminated() bool { - return hasTerminated(ps.state()) -} - -func (ps provisioningStatus) hasProvisioningError() bool { - // code and message are required fields so only check them - return len(ps.ProvisioningError.Code) > 0 || - len(ps.ProvisioningError.Message) > 0 -} - // PollingMethodType defines a type used for enumerating polling mechanisms. type PollingMethodType string @@ -347,151 +890,13 @@ const ( // PollingLocation indicates the polling method uses the Location header. PollingLocation PollingMethodType = "Location" + // PollingRequestURI indicates the polling method uses the original request URI. + PollingRequestURI PollingMethodType = "RequestURI" + // PollingUnknown indicates an unknown polling method and is the default value. PollingUnknown PollingMethodType = "" ) -type pollingState struct { - PollingMethod PollingMethodType `json:"pollingMethod"` - URI string `json:"uri"` - State string `json:"state"` - ServiceError *ServiceError `json:"error,omitempty"` -} - -func (ps pollingState) hasSucceeded() bool { - return hasSucceeded(ps.State) -} - -func (ps pollingState) hasTerminated() bool { - return hasTerminated(ps.State) -} - -func (ps pollingState) hasFailed() bool { - return hasFailed(ps.State) -} - -func (ps pollingState) Error() string { - s := fmt.Sprintf("Long running operation terminated with status '%s'", ps.State) - if ps.ServiceError != nil { - s = fmt.Sprintf("%s: %+v", s, *ps.ServiceError) - } - return s -} - -// updatePollingState maps the operation status -- retrieved from either a provisioningState -// field, the status field of an OperationResource, or inferred from the HTTP status code -- -// into a well-known states. Since the process begins from the initial request, the state -// always comes from either a the provisioningState returned or is inferred from the HTTP -// status code. Subsequent requests will read an Azure OperationResource object if the -// service initially returned the Azure-AsyncOperation header. The responseFormat field notes -// the expected response format. -func updatePollingState(resp *http.Response, ps *pollingState) error { - // Determine the response shape - // -- The first response will always be a provisioningStatus response; only the polling requests, - // depending on the header returned, may be something otherwise. - var pt provisioningTracker - if ps.PollingMethod == PollingAsyncOperation { - pt = &operationResource{} - } else { - pt = &provisioningStatus{} - } - - // If this is the first request (that is, the polling response shape is unknown), determine how - // to poll and what to expect - if ps.PollingMethod == PollingUnknown { - req := resp.Request - if req == nil { - return autorest.NewError("azure", "updatePollingState", "Azure Polling Error - Original HTTP request is missing") - } - - // Prefer the Azure-AsyncOperation header - ps.URI = getAsyncOperation(resp) - if ps.URI != "" { - ps.PollingMethod = PollingAsyncOperation - } else { - ps.PollingMethod = PollingLocation - } - - // Else, use the Location header - if ps.URI == "" { - ps.URI = autorest.GetLocation(resp) - } - - // Lastly, requests against an existing resource, use the last request URI - if ps.URI == "" { - m := strings.ToUpper(req.Method) - if m == http.MethodPatch || m == http.MethodPut || m == http.MethodGet { - ps.URI = req.URL.String() - } - } - } - - // Read and interpret the response (saving the Body in case no polling is necessary) - b := &bytes.Buffer{} - err := autorest.Respond(resp, - autorest.ByCopying(b), - autorest.ByUnmarshallingJSON(pt), - autorest.ByClosing()) - resp.Body = ioutil.NopCloser(b) - if err != nil { - return err - } - - // Interpret the results - // -- Terminal states apply regardless - // -- Unknown states are per-service inprogress states - // -- Otherwise, infer state from HTTP status code - if pt.hasTerminated() { - ps.State = pt.state() - } else if pt.state() != "" { - ps.State = operationInProgress - } else { - switch resp.StatusCode { - case http.StatusAccepted: - ps.State = operationInProgress - - case http.StatusNoContent, http.StatusCreated, http.StatusOK: - ps.State = operationSucceeded - - default: - ps.State = operationFailed - } - } - - if strings.EqualFold(ps.State, operationInProgress) && ps.URI == "" { - return autorest.NewError("azure", "updatePollingState", "Azure Polling Error - Unable to obtain polling URI for %s %s", resp.Request.Method, resp.Request.URL) - } - - // For failed operation, check for error code and message in - // -- Operation resource - // -- Response - // -- Otherwise, Unknown - if ps.hasFailed() { - if or, ok := pt.(*operationResource); ok { - ps.ServiceError = &or.OperationError - } else if p, ok := pt.(*provisioningStatus); ok && p.hasProvisioningError() { - ps.ServiceError = &p.ProvisioningError - } else { - ps.ServiceError = &ServiceError{ - Code: "Unknown", - Message: "None", - } - } - } - return nil -} - -func newPollingRequest(ps pollingState) (*http.Request, error) { - reqPoll, err := autorest.Prepare(&http.Request{}, - autorest.AsGet(), - autorest.WithBaseURL(ps.URI)) - if err != nil { - return nil, autorest.NewErrorWithError(err, "azure", "newPollingRequest", nil, "Failure creating poll request to %s", ps.URI) - } - - return reqPoll, nil -} - // AsyncOpIncompleteError is the type that's returned from a future that has not completed. type AsyncOpIncompleteError struct { // FutureType is the name of the type composed of a azure.Future. diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/azure.go b/vendor/github.com/Azure/go-autorest/autorest/azure/azure.go index 18d029526..a702ffe75 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/azure.go +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/azure.go @@ -279,16 +279,29 @@ func WithErrorUnlessStatusCode(codes ...int) autorest.RespondDecorator { resp.Body = ioutil.NopCloser(&b) if decodeErr != nil { return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b.String(), decodeErr) - } else if e.ServiceError == nil { + } + if e.ServiceError == nil { // Check if error is unwrapped ServiceError - if err := json.Unmarshal(b.Bytes(), &e.ServiceError); err != nil || e.ServiceError.Message == "" { - e.ServiceError = &ServiceError{ - Code: "Unknown", - Message: "Unknown service error", - } + if err := json.Unmarshal(b.Bytes(), &e.ServiceError); err != nil { + return err } } - + if e.ServiceError.Message == "" { + // if we're here it means the returned error wasn't OData v4 compliant. + // try to unmarshal the body as raw JSON in hopes of getting something. + rawBody := map[string]interface{}{} + if err := json.Unmarshal(b.Bytes(), &rawBody); err != nil { + return err + } + e.ServiceError = &ServiceError{ + Code: "Unknown", + Message: "Unknown service error", + } + if len(rawBody) > 0 { + e.ServiceError.Details = []map[string]interface{}{rawBody} + } + } + e.Response = resp e.RequestID = ExtractRequestID(resp) if e.StatusCode == nil { e.StatusCode = resp.StatusCode diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/rp.go b/vendor/github.com/Azure/go-autorest/autorest/azure/rp.go index 2c88d60ba..bd34f0ed5 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/rp.go +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/rp.go @@ -64,7 +64,7 @@ func DoRetryWithRegistration(client autorest.Client) autorest.SendDecorator { } } } - return resp, fmt.Errorf("failed request: %s", err) + return resp, err }) } } @@ -115,7 +115,7 @@ func register(client autorest.Client, originalReq *http.Request, re RequestError if err != nil { return err } - req.Cancel = originalReq.Cancel + req = req.WithContext(originalReq.Context()) resp, err := autorest.SendWithSender(client, req, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...), @@ -154,7 +154,7 @@ func register(client autorest.Client, originalReq *http.Request, re RequestError if err != nil { return err } - req.Cancel = originalReq.Cancel + req = req.WithContext(originalReq.Context()) resp, err := autorest.SendWithSender(client, req, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...), @@ -178,9 +178,9 @@ func register(client autorest.Client, originalReq *http.Request, re RequestError break } - delayed := autorest.DelayWithRetryAfter(resp, originalReq.Cancel) - if !delayed { - autorest.DelayForBackoff(client.PollingDelay, 0, originalReq.Cancel) + delayed := autorest.DelayWithRetryAfter(resp, originalReq.Context().Done()) + if !delayed && !autorest.DelayForBackoff(client.PollingDelay, 0, originalReq.Context().Done()) { + return originalReq.Context().Err() } } if !(time.Since(now) < client.PollingDuration) { diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/date.go b/vendor/github.com/Azure/go-autorest/autorest/date/date.go index 80ca60e9b..c45710656 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/date/date.go +++ b/vendor/github.com/Azure/go-autorest/autorest/date/date.go @@ -5,6 +5,20 @@ time.Time types. And both convert to time.Time through a ToTime method. */ package date +// Copyright 2017 Microsoft Corporation +// +// 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. + import ( "fmt" "time" diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/time.go b/vendor/github.com/Azure/go-autorest/autorest/date/time.go index c1af62963..b453fad04 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/date/time.go +++ b/vendor/github.com/Azure/go-autorest/autorest/date/time.go @@ -1,5 +1,19 @@ package date +// Copyright 2017 Microsoft Corporation +// +// 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. + import ( "regexp" "time" diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go b/vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go index 11995fb9f..48fb39ba9 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go +++ b/vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go @@ -1,5 +1,19 @@ package date +// Copyright 2017 Microsoft Corporation +// +// 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. + import ( "errors" "time" diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go b/vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go index e085c77ee..7073959b2 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go +++ b/vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go @@ -1,5 +1,19 @@ package date +// Copyright 2017 Microsoft Corporation +// +// 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. + import ( "bytes" "encoding/binary" diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/utility.go b/vendor/github.com/Azure/go-autorest/autorest/date/utility.go index 207b1a240..12addf0eb 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/date/utility.go +++ b/vendor/github.com/Azure/go-autorest/autorest/date/utility.go @@ -1,5 +1,19 @@ package date +// Copyright 2017 Microsoft Corporation +// +// 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. + import ( "strings" "time" diff --git a/vendor/github.com/Azure/go-autorest/autorest/sender.go b/vendor/github.com/Azure/go-autorest/autorest/sender.go index c5efd59a2..cacbd8157 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/sender.go +++ b/vendor/github.com/Azure/go-autorest/autorest/sender.go @@ -86,7 +86,7 @@ func SendWithSender(s Sender, r *http.Request, decorators ...SendDecorator) (*ht func AfterDelay(d time.Duration) SendDecorator { return func(s Sender) Sender { return SenderFunc(func(r *http.Request) (*http.Response, error) { - if !DelayForBackoff(d, 0, r.Cancel) { + if !DelayForBackoff(d, 0, r.Context().Done()) { return nil, fmt.Errorf("autorest: AfterDelay canceled before full delay") } return s.Do(r) @@ -165,7 +165,7 @@ func DoPollForStatusCodes(duration time.Duration, delay time.Duration, codes ... resp, err = s.Do(r) if err == nil && ResponseHasStatusCode(resp, codes...) { - r, err = NewPollingRequest(resp, r.Cancel) + r, err = NewPollingRequestWithContext(r.Context(), resp) for err == nil && ResponseHasStatusCode(resp, codes...) { Respond(resp, @@ -198,7 +198,9 @@ func DoRetryForAttempts(attempts int, backoff time.Duration) SendDecorator { if err == nil { return resp, err } - DelayForBackoff(backoff, attempt, r.Cancel) + if !DelayForBackoff(backoff, attempt, r.Context().Done()) { + return nil, r.Context().Err() + } } return resp, err }) @@ -221,14 +223,18 @@ func DoRetryForStatusCodes(attempts int, backoff time.Duration, codes ...int) Se return resp, err } resp, err = s.Do(rr.Request()) + // if the error isn't temporary don't bother retrying + if err != nil && !IsTemporaryNetworkError(err) { + return nil, err + } // we want to retry if err is not nil (e.g. transient network failure). note that for failed authentication // resp and err will both have a value, so in this case we don't want to retry as it will never succeed. if err == nil && !ResponseHasStatusCode(resp, codes...) || IsTokenRefreshError(err) { return resp, err } - delayed := DelayWithRetryAfter(resp, r.Cancel) - if !delayed { - DelayForBackoff(backoff, attempt, r.Cancel) + delayed := DelayWithRetryAfter(resp, r.Context().Done()) + if !delayed && !DelayForBackoff(backoff, attempt, r.Context().Done()) { + return nil, r.Context().Err() } // don't count a 429 against the number of attempts // so that we continue to retry until it succeeds @@ -277,7 +283,9 @@ func DoRetryForDuration(d time.Duration, backoff time.Duration) SendDecorator { if err == nil { return resp, err } - DelayForBackoff(backoff, attempt, r.Cancel) + if !DelayForBackoff(backoff, attempt, r.Context().Done()) { + return nil, r.Context().Err() + } } return resp, err }) diff --git a/vendor/github.com/Azure/go-autorest/autorest/to/convert.go b/vendor/github.com/Azure/go-autorest/autorest/to/convert.go index 7b180b866..fdda2ce1a 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/to/convert.go +++ b/vendor/github.com/Azure/go-autorest/autorest/to/convert.go @@ -3,6 +3,20 @@ Package to provides helpers to ease working with pointer values of marshalled st */ package to +// Copyright 2017 Microsoft Corporation +// +// 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. + // String returns a string value for the passed string pointer. It returns the empty string if the // pointer is nil. func String(s *string) string { diff --git a/vendor/github.com/Azure/go-autorest/autorest/utility.go b/vendor/github.com/Azure/go-autorest/autorest/utility.go index afb3e4e16..bfddd90b5 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/utility.go +++ b/vendor/github.com/Azure/go-autorest/autorest/utility.go @@ -20,6 +20,7 @@ import ( "encoding/xml" "fmt" "io" + "net" "net/http" "net/url" "reflect" @@ -216,3 +217,12 @@ func IsTokenRefreshError(err error) bool { } return false } + +// IsTemporaryNetworkError returns true if the specified error is a temporary network error or false +// if it's not. If the error doesn't implement the net.Error interface the return value is true. +func IsTemporaryNetworkError(err error) bool { + if netErr, ok := err.(net.Error); !ok || (ok && netErr.Temporary()) { + return true + } + return false +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/validation/validation.go b/vendor/github.com/Azure/go-autorest/autorest/validation/validation.go index d886e0b3f..ae987f8fa 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/validation/validation.go +++ b/vendor/github.com/Azure/go-autorest/autorest/validation/validation.go @@ -136,29 +136,29 @@ func validatePtr(x reflect.Value, v Constraint) error { func validateInt(x reflect.Value, v Constraint) error { i := x.Int() - r, ok := v.Rule.(int) + r, ok := toInt64(v.Rule) if !ok { return createError(x, v, fmt.Sprintf("rule must be integer value for %v constraint; got: %v", v.Name, v.Rule)) } switch v.Name { case MultipleOf: - if i%int64(r) != 0 { + if i%r != 0 { return createError(x, v, fmt.Sprintf("value must be a multiple of %v", r)) } case ExclusiveMinimum: - if i <= int64(r) { + if i <= r { return createError(x, v, fmt.Sprintf("value must be greater than %v", r)) } case ExclusiveMaximum: - if i >= int64(r) { + if i >= r { return createError(x, v, fmt.Sprintf("value must be less than %v", r)) } case InclusiveMinimum: - if i < int64(r) { + if i < r { return createError(x, v, fmt.Sprintf("value must be greater than or equal to %v", r)) } case InclusiveMaximum: - if i > int64(r) { + if i > r { return createError(x, v, fmt.Sprintf("value must be less than or equal to %v", r)) } default: @@ -388,6 +388,17 @@ func createError(x reflect.Value, v Constraint, err string) error { v.Target, v.Name, getInterfaceValue(x), err) } +func toInt64(v interface{}) (int64, bool) { + if i64, ok := v.(int64); ok { + return i64, true + } + // older generators emit max constants as int, so if int64 fails fall back to int + if i32, ok := v.(int); ok { + return int64(i32), true + } + return 0, false +} + // NewErrorWithValidationError appends package type and method name in // validation error. // diff --git a/vendor/github.com/Azure/go-autorest/autorest/version.go b/vendor/github.com/Azure/go-autorest/autorest/version.go index f900ef8b5..e32cd68fe 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/version.go +++ b/vendor/github.com/Azure/go-autorest/autorest/version.go @@ -16,5 +16,5 @@ package autorest // Version returns the semantic version (see http://semver.org). func Version() string { - return "v10.3.0" + return "v10.12.0" } diff --git a/vendor/vendor.json b/vendor/vendor.json index c519a1e0e..203593780 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -65,56 +65,56 @@ "versionExact": "v17.3.1" }, { - "checksumSHA1": "+P6HOINDh/n2z4GqEkluzuGP5p0=", + "checksumSHA1": "q3bhLdUVAz5dmDFvfKJJSTd/BaE=", "comment": "v7.0.7", "path": "github.com/Azure/go-autorest/autorest", - "revision": "ed4b7f5bf1ec0c9ede1fda2681d96771282f2862", - "revisionTime": "2018-03-26T17:06:54Z", - "version": "v10.4.0", - "versionExact": "v10.4.0" + "revision": "1f7cd6cfe0adea687ad44a512dfe76140f804318", + "revisionTime": "2018-06-28T21:22:21Z", + "version": "v10.12.0", + "versionExact": "v10.12.0" }, { - "checksumSHA1": "HzA52MbMWnsR31CFrub5biN90/Q=", + "checksumSHA1": "Ygkay0Aq7zeg8A9DSRWI+flRcFk=", "path": "github.com/Azure/go-autorest/autorest/adal", - "revision": "ed4b7f5bf1ec0c9ede1fda2681d96771282f2862", - "revisionTime": "2018-03-26T17:06:54Z", - "version": "v10.4.0", - "versionExact": "v10.4.0" + "revision": "1f7cd6cfe0adea687ad44a512dfe76140f804318", + "revisionTime": "2018-06-28T21:22:21Z", + "version": "v10.12.0", + "versionExact": "v10.12.0" }, { - "checksumSHA1": "bDFbLGwpCT8TRmqEKtPY/U1DAY8=", + "checksumSHA1": "O8hvZ5SZ6o/mGOTivIagc1uPdl4=", "comment": "v7.0.7", "path": "github.com/Azure/go-autorest/autorest/azure", - "revision": "ed4b7f5bf1ec0c9ede1fda2681d96771282f2862", - "revisionTime": "2018-03-26T17:06:54Z", - "version": "v10.4.0", - "versionExact": "v10.4.0" + "revision": "1f7cd6cfe0adea687ad44a512dfe76140f804318", + "revisionTime": "2018-06-28T21:22:21Z", + "version": "v10.12.0", + "versionExact": "v10.12.0" }, { - "checksumSHA1": "LSF/pNrjhIxl6jiS6bKooBFCOxI=", + "checksumSHA1": "KcxXWvXhVIkfqdGR+TQqWyCbgZk=", "comment": "v7.0.7", "path": "github.com/Azure/go-autorest/autorest/date", - "revision": "58f6f26e200fa5dfb40c9cd1c83f3e2c860d779d", - "revisionTime": "2017-04-28T17:52:31Z", - "version": "=v8.0.0", - "versionExact": "v8.0.0" + "revision": "1f7cd6cfe0adea687ad44a512dfe76140f804318", + "revisionTime": "2018-06-28T21:22:21Z", + "version": "v10.12.0", + "versionExact": "v10.12.0" }, { - "checksumSHA1": "Ev8qCsbFjDlMlX0N2tYAhYQFpUc=", + "checksumSHA1": "8XiRKZWE6XGsb0eJfG4P98JwaXw=", "comment": "v7.0.7", "path": "github.com/Azure/go-autorest/autorest/to", - "revision": "58f6f26e200fa5dfb40c9cd1c83f3e2c860d779d", - "revisionTime": "2017-04-28T17:52:31Z", - "version": "=v8.0.0", - "versionExact": "v8.0.0" + "revision": "1f7cd6cfe0adea687ad44a512dfe76140f804318", + "revisionTime": "2018-06-28T21:22:21Z", + "version": "v10.12.0", + "versionExact": "v10.12.0" }, { - "checksumSHA1": "CdDkG+J8wqXQVQ0f0xal+eolB1w=", + "checksumSHA1": "SVU/fTZ9osBm+WPdd5y71RabAzE=", "path": "github.com/Azure/go-autorest/autorest/validation", - "revision": "ed4b7f5bf1ec0c9ede1fda2681d96771282f2862", - "revisionTime": "2018-03-26T17:06:54Z", - "version": "v10.4.0", - "versionExact": "v10.4.0" + "revision": "1f7cd6cfe0adea687ad44a512dfe76140f804318", + "revisionTime": "2018-06-28T21:22:21Z", + "version": "v10.12.0", + "versionExact": "v10.12.0" }, { "checksumSHA1": "TgrN0l/E16deTlLYNt8wf66urSU=", From fa7f54cb55041e23b914d7ab0ab3a3bdcdbebee9 Mon Sep 17 00:00:00 2001 From: Christopher Boumenot Date: Wed, 11 Jul 2018 15:32:45 -0700 Subject: [PATCH 091/220] azure: satisfy Azure password requirements --- builder/azure/arm/tempname.go | 41 +++++++++++++++++++++++++++--- builder/azure/arm/tempname_test.go | 14 ++++++++++ 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/builder/azure/arm/tempname.go b/builder/azure/arm/tempname.go index bf0cb6552..501dfda65 100644 --- a/builder/azure/arm/tempname.go +++ b/builder/azure/arm/tempname.go @@ -2,13 +2,19 @@ package arm import ( "fmt" + "strings" "github.com/hashicorp/packer/builder/azure/common" ) const ( - TempNameAlphabet = "0123456789bcdfghjklmnpqrstvwxyz" - TempPasswordAlphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + TempNameAlphabet = "0123456789bcdfghjklmnpqrstvwxyz" + + numbers = "0123456789" + lowerCase = "abcdefghijklmnopqrstuvwxyz" + upperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + + TempPasswordAlphabet = numbers + lowerCase + upperCase ) type TempName struct { @@ -39,8 +45,37 @@ func NewTempName() *TempName { tempName.VirtualNetworkName = fmt.Sprintf("pkrvn%s", suffix) tempName.ResourceGroupName = fmt.Sprintf("packer-Resource-Group-%s", suffix) - tempName.AdminPassword = common.RandomString(TempPasswordAlphabet, 32) + tempName.AdminPassword = generatePassword() tempName.CertificatePassword = common.RandomString(TempPasswordAlphabet, 32) return tempName } + +// generate a password that is acceptable to Azure +// Three of the four items must be met. +// 1. Contains an uppercase character +// 2. Contains a lowercase character +// 3. Contains a numeric digit +// 4. Contains a special character +func generatePassword() string { + var s string + for i := 0; i < 100; i++ { + s := common.RandomString(TempPasswordAlphabet, 32) + if !strings.ContainsAny(s, numbers) { + continue + } + + if !strings.ContainsAny(s, lowerCase) { + continue + } + + if !strings.ContainsAny(s, upperCase) { + continue + } + + return s + } + + // if an acceptable password cannot be generated in 100 tries, give up + return s +} diff --git a/builder/azure/arm/tempname_test.go b/builder/azure/arm/tempname_test.go index 4c09f8c46..120df3ea1 100644 --- a/builder/azure/arm/tempname_test.go +++ b/builder/azure/arm/tempname_test.go @@ -41,6 +41,20 @@ func TestTempNameShouldCreatePrefixedRandomNames(t *testing.T) { } } +func TestTempAdminPassword(t *testing.T) { + tempName := NewTempName() + + if !strings.ContainsAny(tempName.AdminPassword, numbers) { + t.Errorf("Expected AdminPassword to contain at least one of '%s'!", numbers) + } + if !strings.ContainsAny(tempName.AdminPassword, lowerCase) { + t.Errorf("Expected AdminPassword to contain at least one of '%s'!", lowerCase) + } + if !strings.ContainsAny(tempName.AdminPassword, upperCase) { + t.Errorf("Expected AdminPassword to contain at least one of '%s'!", upperCase) + } +} + func TestTempNameShouldHaveSameSuffix(t *testing.T) { tempName := NewTempName() suffix := tempName.ComputeName[5:] From 00eba7e8944f2b0108e935e9aa2096e06f2d4d4c Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Wed, 11 Jul 2018 19:01:45 -0700 Subject: [PATCH 092/220] make trailing slash still work --- communicator/winrm/communicator.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/communicator/winrm/communicator.go b/communicator/winrm/communicator.go index bab2ebde2..fc639ccb0 100644 --- a/communicator/winrm/communicator.go +++ b/communicator/winrm/communicator.go @@ -122,11 +122,15 @@ func runCommand(shell *winrm.Shell, cmd *winrm.Command, rc *packer.RemoteCmd) { } // Upload implementation of communicator.Communicator interface -func (c *Communicator) Upload(path string, input io.Reader, _ *os.FileInfo) error { +func (c *Communicator) Upload(path string, input io.Reader, fi *os.FileInfo) error { wcp, err := c.newCopyClient() if err != nil { return fmt.Errorf("Was unable to create winrm client: %s", err) } + if strings.HasSuffix(path, `\`) { + // path is a directory + path += filepath.Base((*fi).Name()) + } log.Printf("Uploading file to '%s'", path) return wcp.Write(path, input) } From da277a440c83efff7b575e5ff261a640ed4e2b0c Mon Sep 17 00:00:00 2001 From: Adam Robinson Date: Fri, 13 Jul 2018 09:13:58 -0400 Subject: [PATCH 093/220] fix reversed logic in disable_vnc documentation --- website/source/docs/builders/vmware-iso.html.md.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/builders/vmware-iso.html.md.erb b/website/source/docs/builders/vmware-iso.html.md.erb index ee47b5a47..ab1a29f0d 100644 --- a/website/source/docs/builders/vmware-iso.html.md.erb +++ b/website/source/docs/builders/vmware-iso.html.md.erb @@ -105,7 +105,7 @@ builder. this logic. This field can be specified as either `ide`, `sata`, or `scsi`. - `disable_vnc` (boolean) - Whether to create a VNC connection or not. - A `boot_command` cannot be used when this is `false`. Defaults to `false`. + A `boot_command` cannot be used when this is `true`. Defaults to `false`. - `disk_adapter_type` (string) - The adapter type of the VMware virtual disk to create. This option is for advanced usage, modify only if you know what From 2496e09d75db905fd2e7db87ea77990140e40cd7 Mon Sep 17 00:00:00 2001 From: Adam Robinson Date: Fri, 13 Jul 2018 09:26:02 -0400 Subject: [PATCH 094/220] Document vnc_disable_password=true requirement for ESXi 6.5+ --- website/source/docs/builders/vmware-iso.html.md.erb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/website/source/docs/builders/vmware-iso.html.md.erb b/website/source/docs/builders/vmware-iso.html.md.erb index ab1a29f0d..b42259ee8 100644 --- a/website/source/docs/builders/vmware-iso.html.md.erb +++ b/website/source/docs/builders/vmware-iso.html.md.erb @@ -412,7 +412,9 @@ builder. wish to bind to all interfaces use `0.0.0.0`. - `vnc_disable_password` (boolean) - Don't auto-generate a VNC password that - is used to secure the VNC communication with the VM. + is used to secure the VNC communication with the VM. This must be set to + `true` if building on ESXi 6.5 and 6.7 with VNC enabled. Defaults to + `false`. - `vnc_port_min` and `vnc_port_max` (number) - The minimum and maximum port to use for VNC access to the virtual machine. The builder uses VNC to type @@ -553,6 +555,8 @@ modify as well: Since ovftool is only capable of password based authentication `remote_password` must be set when exporting the VM. +- `vnc_disable_password` - This must be set to "true" when using VNC with + ESXi 6.5 or 6.7. ### VNC port discovery From eae0556dc518d97c80408477781d398d36cd090a Mon Sep 17 00:00:00 2001 From: Sergio Millan Rodriguez Date: Fri, 13 Jul 2018 17:56:04 +0200 Subject: [PATCH 095/220] Add option to enable/disable create firewall/acl rules --- builder/cloudstack/config.go | 2 ++ builder/cloudstack/step_configure_networking.go | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/builder/cloudstack/config.go b/builder/cloudstack/config.go index 7a617c6cd..b0c338272 100644 --- a/builder/cloudstack/config.go +++ b/builder/cloudstack/config.go @@ -40,6 +40,8 @@ type Config struct { PublicIPAddress string `mapstructure:"public_ip_address"` SecurityGroups []string `mapstructure:"security_groups"` ServiceOffering string `mapstructure:"service_offering"` + CreateNetworkACL bool `mapstructure:"create_network_acl"` + CreateFirewallRule bool `mapstructure:"create_firewall_rule"` SourceISO string `mapstructure:"source_iso"` SourceTemplate string `mapstructure:"source_template"` TemporaryKeypairName string `mapstructure:"temporary_keypair_name"` diff --git a/builder/cloudstack/step_configure_networking.go b/builder/cloudstack/step_configure_networking.go index 4dba63ef7..ccda39107 100644 --- a/builder/cloudstack/step_configure_networking.go +++ b/builder/cloudstack/step_configure_networking.go @@ -117,7 +117,7 @@ func (s *stepSetupNetworking) Run(_ context.Context, state multistep.StateBag) m // Store the port forward ID. state.Put("port_forward_id", forward.Id) - if network.Vpcid != "" { + if network.Vpcid != "" && config.CreateNetworkACL { ui.Message("Creating network ACL rule...") if network.Aclid == "" { @@ -149,7 +149,7 @@ func (s *stepSetupNetworking) Run(_ context.Context, state multistep.StateBag) m // Store the network ACL rule ID. state.Put("network_acl_rule_id", aclRule.Id) - } else { + } else if config.CreateFirewallRule { ui.Message("Creating firewall rule...") // Create a new parameter struct. From a41a4658ee6da942534389f6e6d57361e4bd7f4b Mon Sep 17 00:00:00 2001 From: Sergio Millan Rodriguez Date: Fri, 13 Jul 2018 17:56:27 +0200 Subject: [PATCH 096/220] make packer builder honour projectid setting if provided --- builder/cloudstack/step_create_instance.go | 5 ++++- builder/cloudstack/step_create_template.go | 7 +++++-- builder/cloudstack/step_keypair.go | 16 +++++++++++++--- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/builder/cloudstack/step_create_instance.go b/builder/cloudstack/step_create_instance.go index 343d36c35..49c728f66 100644 --- a/builder/cloudstack/step_create_instance.go +++ b/builder/cloudstack/step_create_instance.go @@ -47,7 +47,9 @@ func (s *stepCreateInstance) Run(_ context.Context, state multistep.StateBag) mu p.SetDisplayname("Created by Packer") if keypair, ok := state.GetOk("keypair"); ok { - p.SetKeypair(keypair.(string)) + kp := keypair.(string) + ui.Message(fmt.Sprintf("Found keypair: %s", kp)) + p.SetKeypair(kp) } if securitygroups, ok := state.GetOk("security_groups"); ok { @@ -120,6 +122,7 @@ func (s *stepCreateInstance) Run(_ context.Context, state multistep.StateBag) mu } ui.Message("Instance has been created!") + ui.Message(fmt.Sprintf("Instance ID: %s", instance.Id)) // In debug-mode, we output the password if s.Debug { diff --git a/builder/cloudstack/step_create_template.go b/builder/cloudstack/step_create_template.go index 4afba8699..0a51e3cc4 100644 --- a/builder/cloudstack/step_create_template.go +++ b/builder/cloudstack/step_create_template.go @@ -51,7 +51,7 @@ func (s *stepCreateTemplate) Run(_ context.Context, state multistep.StateBag) mu } ui.Message("Retrieving the ROOT volume ID...") - volumeID, err := getRootVolumeID(client, instanceID) + volumeID, err := getRootVolumeID(client, instanceID, config) if err != nil { state.Put("error", err) ui.Error(err.Error()) @@ -89,13 +89,16 @@ func (s *stepCreateTemplate) Cleanup(state multistep.StateBag) { // Nothing to cleanup for this step. } -func getRootVolumeID(client *cloudstack.CloudStackClient, instanceID string) (string, error) { +func getRootVolumeID(client *cloudstack.CloudStackClient, instanceID string, config *Config) (string, error) { // Retrieve the virtual machine object. p := client.Volume.NewListVolumesParams() // Set the type and virtual machine ID p.SetType("ROOT") p.SetVirtualmachineid(instanceID) + if config.Project != "" { + p.SetProjectid(config.Project) + } volumes, err := client.Volume.ListVolumes(p) if err != nil { diff --git a/builder/cloudstack/step_keypair.go b/builder/cloudstack/step_keypair.go index e1f002b76..89e7e4d1f 100644 --- a/builder/cloudstack/step_keypair.go +++ b/builder/cloudstack/step_keypair.go @@ -60,6 +60,12 @@ func (s *stepKeypair) Run(_ context.Context, state multistep.StateBag) multistep ui.Say(fmt.Sprintf("Creating temporary keypair: %s ...", s.TemporaryKeyPairName)) p := client.SSH.NewCreateSSHKeyPairParams(s.TemporaryKeyPairName) + + cfg := state.Get("config").(*Config) + if cfg.Project != "" { + p.SetProjectid(cfg.Project) + } + keypair, err := client.SSH.CreateSSHKeyPair(p) if err != nil { err := fmt.Errorf("Error creating temporary keypair: %s", err) @@ -120,12 +126,16 @@ func (s *stepKeypair) Cleanup(state multistep.StateBag) { ui := state.Get("ui").(packer.Ui) client := state.Get("client").(*cloudstack.CloudStackClient) + cfg := state.Get("config").(*Config) + + p := client.SSH.NewDeleteSSHKeyPairParams(s.TemporaryKeyPairName) + if cfg.Project != "" { + p.SetProjectid(cfg.Project) + } ui.Say(fmt.Sprintf("Deleting temporary keypair: %s ...", s.TemporaryKeyPairName)) - _, err := client.SSH.DeleteSSHKeyPair(client.SSH.NewDeleteSSHKeyPairParams( - s.TemporaryKeyPairName, - )) + _, err := client.SSH.DeleteSSHKeyPair(p) if err != nil { ui.Error(err.Error()) ui.Error(fmt.Sprintf( From d0f0da6626c322352a5f06e55d31d6bba1a81fa0 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Fri, 13 Jul 2018 09:14:59 -0700 Subject: [PATCH 097/220] allow absolute paths to isos in checksum files --- common/iso_config.go | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/common/iso_config.go b/common/iso_config.go index e5a1e4e90..2836cbcc9 100644 --- a/common/iso_config.go +++ b/common/iso_config.go @@ -95,7 +95,6 @@ func (c *ISOConfig) Prepare(ctx *interpolate.Context) (warnings []string, errs [ errs = append(errs, err) return warnings, errs } - case "": break default: @@ -153,7 +152,8 @@ func (c *ISOConfig) parseCheckSumFile(rd *bufio.Reader) error { filename := filepath.Base(u.Path) - errNotFound := fmt.Errorf("No checksum for %q or %q found at: %s", filename, relpath, c.ISOChecksumURL) + errNotFound := fmt.Errorf("No checksum for %q, %q or %q found at: %s", + filename, relpath, u.Path, c.ISOChecksumURL) for { line, err := rd.ReadString('\n') if err != nil && line == "" { @@ -163,12 +163,14 @@ func (c *ISOConfig) parseCheckSumFile(rd *bufio.Reader) error { if len(parts) < 2 { continue } + options := []string{filename, relpath, "./" + relpath, u.Path} if strings.ToLower(parts[0]) == c.ISOChecksumType { // BSD-style checksum - if parts[1] == fmt.Sprintf("(%s)", filename) || parts[1] == fmt.Sprintf("(%s)", relpath) || - parts[1] == fmt.Sprintf("(./%s)", relpath) { - c.ISOChecksum = parts[3] - return nil + for _, match := range options { + if parts[1] == fmt.Sprintf("(%s)", match) { + c.ISOChecksum = parts[3] + return nil + } } } else { // Standard checksum @@ -176,9 +178,11 @@ func (c *ISOConfig) parseCheckSumFile(rd *bufio.Reader) error { // Binary mode parts[1] = parts[1][1:] } - if parts[1] == filename || parts[1] == relpath || parts[1] == "./"+relpath { - c.ISOChecksum = parts[0] - return nil + for _, match := range options { + if parts[1] == match { + c.ISOChecksum = parts[0] + return nil + } } } } From 0df33cd0326eb2d0930de861bc835e012627a1ee Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Fri, 13 Jul 2018 09:21:04 -0700 Subject: [PATCH 098/220] fix relative pathing versus iso checksum dir to work even if user has provided a relative path for the iso_url which is relative to the directory where Packer is run. --- common/iso_config.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/common/iso_config.go b/common/iso_config.go index 2836cbcc9..857c13f57 100644 --- a/common/iso_config.go +++ b/common/iso_config.go @@ -145,7 +145,12 @@ func (c *ISOConfig) parseCheckSumFile(rd *bufio.Reader) error { return err } - relpath, err := filepath.Rel(filepath.Dir(checksumurl.Path), u.Path) + absPath, err := filepath.Abs(u.Path) + if err != nil { + return fmt.Errorf("Unable to generate absolute path from provided iso_url: %s", err) + } + + relpath, err := filepath.Rel(filepath.Dir(checksumurl.Path), absPath) if err != nil { return err } @@ -163,7 +168,7 @@ func (c *ISOConfig) parseCheckSumFile(rd *bufio.Reader) error { if len(parts) < 2 { continue } - options := []string{filename, relpath, "./" + relpath, u.Path} + options := []string{filename, relpath, "./" + relpath, absPath} if strings.ToLower(parts[0]) == c.ISOChecksumType { // BSD-style checksum for _, match := range options { From b6b907f523d366693442eac169982e50ee884d66 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 12 Jul 2018 14:30:44 -0700 Subject: [PATCH 099/220] read in the environment variables that government wait time and polling time for the AWS wait in step_stop_ebs_volume --- builder/amazon/common/step_stop_ebs_instance.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/builder/amazon/common/step_stop_ebs_instance.go b/builder/amazon/common/step_stop_ebs_instance.go index 184430b91..aee29b432 100644 --- a/builder/amazon/common/step_stop_ebs_instance.go +++ b/builder/amazon/common/step_stop_ebs_instance.go @@ -78,9 +78,11 @@ func (s *StepStopEBSBackedInstance) Run(ctx context.Context, state multistep.Sta // Wait for the instance to actually stop ui.Say("Waiting for the instance to stop...") - err = ec2conn.WaitUntilInstanceStoppedWithContext(ctx, &ec2.DescribeInstancesInput{ - InstanceIds: []*string{instance.InstanceId}, - }) + err = ec2conn.WaitUntilInstanceStoppedWithContext(ctx, + &ec2.DescribeInstancesInput{ + InstanceIds: []*string{instance.InstanceId}, + }, + getWaiterOptions()...) if err != nil { err := fmt.Errorf("Error waiting for instance to stop: %s", err) From 2fec76ea8703ded3ad819db2eb37356016244fd2 Mon Sep 17 00:00:00 2001 From: Mark Meyer Date: Fri, 13 Oct 2017 08:22:15 +0200 Subject: [PATCH 100/220] Check if spot price is empty, when spot_tags is set --- builder/amazon/common/run_config.go | 11 +++++++---- website/source/docs/builders/amazon-ebs.html.md | 2 +- .../source/docs/builders/amazon-ebssurrogate.html.md | 2 +- website/source/docs/builders/amazon-ebsvolume.html.md | 2 +- website/source/docs/builders/amazon-instance.html.md | 2 +- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/builder/amazon/common/run_config.go b/builder/amazon/common/run_config.go index b6e13dcc0..9467d42bd 100644 --- a/builder/amazon/common/run_config.go +++ b/builder/amazon/common/run_config.go @@ -77,10 +77,6 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { c.RunTags = make(map[string]string) } - if c.SpotTags == nil { - c.SpotTags = make(map[string]string) - } - // Validation errs := c.Comm.Prepare(ctx) @@ -123,6 +119,13 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { } } + if c.SpotTags != nil { + if c.SpotPrice == "" || c.SpotPrice == "0" { + errs = append(errs, fmt.Errorf( + "spot_tags should not be set when not requesting a spot instance")) + } + } + if c.UserData != "" && c.UserDataFile != "" { errs = append(errs, fmt.Errorf("Only one of user_data or user_data_file can be specified.")) } else if c.UserDataFile != "" { diff --git a/website/source/docs/builders/amazon-ebs.html.md b/website/source/docs/builders/amazon-ebs.html.md index 2db8c6d9f..c09591768 100644 --- a/website/source/docs/builders/amazon-ebs.html.md +++ b/website/source/docs/builders/amazon-ebs.html.md @@ -344,7 +344,7 @@ builder. `Linux/UNIX (Amazon VPC)`, `SUSE Linux (Amazon VPC)`, `Windows (Amazon VPC)` - `spot_tags` (object of key/value strings) - Requires `spot_price` to - be set. This tells Packer to aplly tags to the spot request that is + be set. This tells Packer to apply tags to the spot request that is issued. - `sriov_support` (boolean) - Enable enhanced networking (SriovNetSupport but not ENA) diff --git a/website/source/docs/builders/amazon-ebssurrogate.html.md b/website/source/docs/builders/amazon-ebssurrogate.html.md index f29eb6507..881cce45e 100644 --- a/website/source/docs/builders/amazon-ebssurrogate.html.md +++ b/website/source/docs/builders/amazon-ebssurrogate.html.md @@ -337,7 +337,7 @@ builder. `Linux/UNIX (Amazon VPC)`, `SUSE Linux (Amazon VPC)`, `Windows (Amazon VPC)` - `spot_tags` (object of key/value strings) - Requires `spot_price` to - be set. This tells Packer to aplly tags to the spot request that is + be set. This tells Packer to apply tags to the spot request that is issued. - `sriov_support` (boolean) - Enable enhanced networking (SriovNetSupport but not ENA) diff --git a/website/source/docs/builders/amazon-ebsvolume.html.md b/website/source/docs/builders/amazon-ebsvolume.html.md index 880d8b49f..a3ff74785 100644 --- a/website/source/docs/builders/amazon-ebsvolume.html.md +++ b/website/source/docs/builders/amazon-ebsvolume.html.md @@ -265,7 +265,7 @@ builder. `Linux/UNIX (Amazon VPC)`, `SUSE Linux (Amazon VPC)` or `Windows (Amazon VPC)` - `spot_tags` (object of key/value strings) - Requires `spot_price` to - be set. This tells Packer to aplly tags to the spot request that is + be set. This tells Packer to apply tags to the spot request that is issued. - `sriov_support` (boolean) - Enable enhanced networking (SriovNetSupport but not ENA) diff --git a/website/source/docs/builders/amazon-instance.html.md b/website/source/docs/builders/amazon-instance.html.md index c3f3d76b8..00700dfb5 100644 --- a/website/source/docs/builders/amazon-instance.html.md +++ b/website/source/docs/builders/amazon-instance.html.md @@ -340,7 +340,7 @@ builder. `Linux/UNIX (Amazon VPC)`, `SUSE Linux (Amazon VPC)`, `Windows (Amazon VPC)` - `spot_tags` (object of key/value strings) - Requires `spot_price` to - be set. This tells Packer to aplly tags to the spot request that is + be set. This tells Packer to apply tags to the spot request that is issued. - `sriov_support` (boolean) - Enable enhanced networking (SriovNetSupport but not ENA) From 1b967e60f91c35786cd6fd1e56ef7e364e33e29b Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Fri, 13 Jul 2018 16:48:21 -0700 Subject: [PATCH 101/220] update changelog for v. 1.2.5 --- CHANGELOG.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49cf377a8..a160717b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,36 @@ +## 1.2.5 (July 16, 2018) + +### BUG FIXES: +* core: Fix bug in parsing of iso checksum files that arose when setting iso_url to a relative filepath. [GH-6488] +* communicator/winrm: Revert an attempt to determine whether remote upload destinations were files or directories, as this broke uploads on systems without Powershell installed. [GH-6481] +* builder/amazon: Replace packer's waiters with those from the AWS sdk, solving several timeout bugs. [GH-6332] +* builder/azure: update the max length of managed_image_resource_group to match new increased length of 90 characters. [GH-6477] +* builder/vmware: Fix bug where we couldn't discover IP if vm_name differed from the vmx displayName. [GH-6448] +* fix: Fix bug where fixer for ssh_private_ip that failed when boolean values are passed as strings. [GH-6458] +* builder/qemu: vnc_bind_address was not being passed to qemu. [GH-6467] +* builder/qemu: Fix error race condition in qemu builder that caused convert to fail on ubuntu 18.x [GH-6437] +* builder/vmware: Fix validation to prevent hang when remopte_password is not sent but vmware is building on esxi. [GH-6424] +* builder/virtualbox: Allow iso_url to be a symlink. [GH-6370] +* builder/vmware: Don't fail on DHCP lease files that cannot be read, fixing bug where builder failed on NAT networks that don't serve DHCP. [GH-6415] +* builder/hyper-v: Fix secure boot template feature so that it properly passes the temolate for MicrosoftUEFICertificateAuthority. [GH-6415] +* builder/alicloud: Fix an issue with VPC cleanup. [GH-6418] +* builder/alickoud: Fix issue where internet_max_bandwidth_out template option was not being passed to builder. [GH-6416] +* builder/hyperv: Fix bug in HyperV IP lookups that was causing breakages in FreeBSD/OpenBSD builds. [GH-6416] +* core: Fix Packer crash caused by improper error handling in the downloader. [GH-6381] +* provisioner/powershell: Make upload of powershell variables retryable, in case of system restarts. [GH-6388] +* builder/amazon-chroot: Fix communicator bug that broke chroot builds. [GH-6363] +* builder/vmware:Correctly default the vm export format to ovf; this is what the docs claimed we already did, but we didn't. [GH-4538] + +### IMPROVEMENTS: +* post-processor/googlecompute-import: Added new googlecompute-import post-processor [GH-6451] +* builder/scaleway: Add new "bootscript" parameter, allowing the user to not use the default local bootscript [GH-6439] +* builder/vmware: Add support for linked clones to vmware-vmx. [GH-6394] +* builder/oracle-oci: Add new "instance_name" template option. [GH-6408] +* builder/amazon: Add the ap-northeast-3 region. [GH-6385] +* debug: The -debug flag will now cause Packer to pause between provisioner scripts in addition to Packer steps. [GH-4663] +* provisioner/ansible: Add new "playbook_files" option to execute multiple playbooks within one provisioner call. [GH-5086] +* builder/openstack: Add support for token authorization and cloud.yaml. [GH-6362] + ## 1.2.4 (May 29, 2018) ### BUG FIXES: From 37fd50995fbcac28a085e51a49cd98bef337f4e9 Mon Sep 17 00:00:00 2001 From: Levi Date: Mon, 2 Jul 2018 20:09:38 -0400 Subject: [PATCH 102/220] added parameter for setting packer password as env variable --- provisioner/ansible/provisioner.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/provisioner/ansible/provisioner.go b/provisioner/ansible/provisioner.go index d6e785c70..0f92c9ef4 100644 --- a/provisioner/ansible/provisioner.go +++ b/provisioner/ansible/provisioner.go @@ -57,6 +57,7 @@ type Config struct { UseSFTP bool `mapstructure:"use_sftp"` InventoryDirectory string `mapstructure:"inventory_directory"` InventoryFile string `mapstructure:"inventory_file"` + SetPackerPasswd bool `mapstructure:"set_packer_passwd"` } type Provisioner struct { @@ -118,6 +119,10 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { p.config.AnsibleEnvVars = append(p.config.AnsibleEnvVars, "ANSIBLE_SCP_IF_SSH=True") } + if p.config.SetPackerPasswd { + p.config.AnsibleEnvVars = append(p.config.AnsibleEnvVars, "PACKER_RANDOM_PASSWORD=TEST") + } + if len(p.config.LocalPort) > 0 { if _, err := strconv.ParseUint(p.config.LocalPort, 10, 16); err != nil { errs = packer.MultiErrorAppend(errs, fmt.Errorf("local_port: %s must be a valid port", p.config.LocalPort)) From 636cec8f2bebf9b2b202678d779f0f4ab3e268ab Mon Sep 17 00:00:00 2001 From: Levi Date: Mon, 2 Jul 2018 20:10:06 -0400 Subject: [PATCH 103/220] added commonhelper import --- provisioner/ansible/provisioner.go | 1 + 1 file changed, 1 insertion(+) diff --git a/provisioner/ansible/provisioner.go b/provisioner/ansible/provisioner.go index 0f92c9ef4..fd037c6ce 100644 --- a/provisioner/ansible/provisioner.go +++ b/provisioner/ansible/provisioner.go @@ -26,6 +26,7 @@ import ( "golang.org/x/crypto/ssh" "github.com/hashicorp/packer/common" + commonhelper "github.com/hashicorp/packer/helper/common" "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" From 68ec630fde9f20ec27d22d11496a03289be1d6bc Mon Sep 17 00:00:00 2001 From: Levi Date: Mon, 2 Jul 2018 20:12:04 -0400 Subject: [PATCH 104/220] added function to retreive winrm password from commonhelper --- provisioner/ansible/provisioner.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/provisioner/ansible/provisioner.go b/provisioner/ansible/provisioner.go index fd037c6ce..a01d3f4cb 100644 --- a/provisioner/ansible/provisioner.go +++ b/provisioner/ansible/provisioner.go @@ -121,7 +121,8 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { } if p.config.SetPackerPasswd { - p.config.AnsibleEnvVars = append(p.config.AnsibleEnvVars, "PACKER_RANDOM_PASSWORD=TEST") + var PackerEnvVar string = fmt.Sprintf("PACKER_RANDOM_PASSWORD=%s", getWinRMPassword()) + p.config.AnsibleEnvVars = append(p.config.AnsibleEnvVars, PackerEnvVar) } if len(p.config.LocalPort) > 0 { @@ -514,6 +515,12 @@ func newSigner(privKeyFile string) (*signer, error) { return signer, nil } +func getWinRMPassword() string { + winRMPass, _ := commonhelper.RetrieveSharedState("winrm_password") + return winRMPass + +} + // Ui provides concurrency-safe access to packer.Ui. type Ui struct { sem chan int From 6646d42490aba125d05dc86e0d2dbe8f071bda13 Mon Sep 17 00:00:00 2001 From: Levi Date: Mon, 2 Jul 2018 20:42:21 -0400 Subject: [PATCH 105/220] updated function calls to include buildname and changed variable names --- provisioner/ansible/provisioner.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/provisioner/ansible/provisioner.go b/provisioner/ansible/provisioner.go index a01d3f4cb..a221d02da 100644 --- a/provisioner/ansible/provisioner.go +++ b/provisioner/ansible/provisioner.go @@ -58,7 +58,7 @@ type Config struct { UseSFTP bool `mapstructure:"use_sftp"` InventoryDirectory string `mapstructure:"inventory_directory"` InventoryFile string `mapstructure:"inventory_file"` - SetPackerPasswd bool `mapstructure:"set_packer_passwd"` + SetWinrmPasswd bool `mapstructure:"set_winrm_passwd"` } type Provisioner struct { @@ -120,11 +120,6 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { p.config.AnsibleEnvVars = append(p.config.AnsibleEnvVars, "ANSIBLE_SCP_IF_SSH=True") } - if p.config.SetPackerPasswd { - var PackerEnvVar string = fmt.Sprintf("PACKER_RANDOM_PASSWORD=%s", getWinRMPassword()) - p.config.AnsibleEnvVars = append(p.config.AnsibleEnvVars, PackerEnvVar) - } - if len(p.config.LocalPort) > 0 { if _, err := strconv.ParseUint(p.config.LocalPort, 10, 16); err != nil { errs = packer.MultiErrorAppend(errs, fmt.Errorf("local_port: %s must be a valid port", p.config.LocalPort)) @@ -196,6 +191,12 @@ func (p *Provisioner) getVersion() error { func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { ui.Say("Provisioning with Ansible...") + if p.config.SetWinrmPasswd { + var WinrmEnvVar string = fmt.Sprintf("GENERATED_WINRM_PASSWORD=%s", getWinRMPassword(p.config.PackerBuildName)) + p.config.AnsibleEnvVars = append(p.config.AnsibleEnvVars, WinrmEnvVar) + ui.Say("Setting Environment variable GENERATED_WINRM_PASSWORD to WinRM password.") + } + k, err := newUserKey(p.config.SSHAuthorizedKeyFile) if err != nil { return err @@ -515,10 +516,9 @@ func newSigner(privKeyFile string) (*signer, error) { return signer, nil } -func getWinRMPassword() string { - winRMPass, _ := commonhelper.RetrieveSharedState("winrm_password") +func getWinRMPassword(buildName string) string { + winRMPass, _ := commonhelper.RetrieveSharedState("winrm_password", buildName) return winRMPass - } // Ui provides concurrency-safe access to packer.Ui. From 17074cda2ce6652543afd2857e3ecc60551888dd Mon Sep 17 00:00:00 2001 From: Levi Date: Sat, 14 Jul 2018 15:09:48 -0400 Subject: [PATCH 106/220] added set_winrm_passwd usage instructions --- website/source/docs/provisioners/ansible.html.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/website/source/docs/provisioners/ansible.html.md b/website/source/docs/provisioners/ansible.html.md index 26047458d..8bc697cad 100644 --- a/website/source/docs/provisioners/ansible.html.md +++ b/website/source/docs/provisioners/ansible.html.md @@ -128,6 +128,11 @@ Optional Parameters: - `user` (string) - The `ansible_user` to use. Defaults to the user running packer. +- `set_winrm_passwd` (boolean) - Set to `true` to access the randomly-generated + EC2 Windows password through the environment variable `GENERATED_WINRM_PASSWORD`. + You will also need to set `ansible_password` in your ansible playbook, for example, + `ansible_password: "{{ lookup('env','GENERATED_WINRM_PASSWORD') }}"` + ## Default Extra Variables In addition to being able to specify extra arguments using the From e729b21212851719cfd6020ac53fe8bd6825dcdb Mon Sep 17 00:00:00 2001 From: Sergio Millan Rodriguez Date: Mon, 16 Jul 2018 11:38:14 +0200 Subject: [PATCH 107/220] passing projectid to getRootVolumeID rather than the whole config struct --- builder/cloudstack/step_create_template.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/builder/cloudstack/step_create_template.go b/builder/cloudstack/step_create_template.go index 0a51e3cc4..706d570f6 100644 --- a/builder/cloudstack/step_create_template.go +++ b/builder/cloudstack/step_create_template.go @@ -51,7 +51,7 @@ func (s *stepCreateTemplate) Run(_ context.Context, state multistep.StateBag) mu } ui.Message("Retrieving the ROOT volume ID...") - volumeID, err := getRootVolumeID(client, instanceID, config) + volumeID, err := getRootVolumeID(client, instanceID, config.Project) if err != nil { state.Put("error", err) ui.Error(err.Error()) @@ -89,15 +89,15 @@ func (s *stepCreateTemplate) Cleanup(state multistep.StateBag) { // Nothing to cleanup for this step. } -func getRootVolumeID(client *cloudstack.CloudStackClient, instanceID string, config *Config) (string, error) { +func getRootVolumeID(client *cloudstack.CloudStackClient, instanceID, projectID string) (string, error) { // Retrieve the virtual machine object. p := client.Volume.NewListVolumesParams() // Set the type and virtual machine ID p.SetType("ROOT") p.SetVirtualmachineid(instanceID) - if config.Project != "" { - p.SetProjectid(config.Project) + if projectID != "" { + p.SetProjectid(projectID) } volumes, err := client.Volume.ListVolumes(p) From 472a7820eb75df758616d90286a3f6fdbb4d24e0 Mon Sep 17 00:00:00 2001 From: Sergio Millan Rodriguez Date: Mon, 16 Jul 2018 11:39:15 +0200 Subject: [PATCH 108/220] Using UI keypair meaningful message --- builder/cloudstack/step_create_instance.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/cloudstack/step_create_instance.go b/builder/cloudstack/step_create_instance.go index 49c728f66..81f0c0699 100644 --- a/builder/cloudstack/step_create_instance.go +++ b/builder/cloudstack/step_create_instance.go @@ -48,7 +48,7 @@ func (s *stepCreateInstance) Run(_ context.Context, state multistep.StateBag) mu if keypair, ok := state.GetOk("keypair"); ok { kp := keypair.(string) - ui.Message(fmt.Sprintf("Found keypair: %s", kp)) + ui.Message(fmt.Sprintf("Using keypair: %s", kp)) p.SetKeypair(kp) } From f4020835d609f3a4408d1b2ffd209aee8a0313e5 Mon Sep 17 00:00:00 2001 From: Sergio Millan Rodriguez Date: Mon, 16 Jul 2018 13:06:51 +0200 Subject: [PATCH 109/220] flag to setup networking without firewall rules --- builder/cloudstack/config.go | 43 +++++++++---------- .../cloudstack/step_configure_networking.go | 9 +++- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/builder/cloudstack/config.go b/builder/cloudstack/config.go index b0c338272..3d15d27a2 100644 --- a/builder/cloudstack/config.go +++ b/builder/cloudstack/config.go @@ -27,28 +27,27 @@ type Config struct { HTTPGetOnly bool `mapstructure:"http_get_only"` SSLNoVerify bool `mapstructure:"ssl_no_verify"` - CIDRList []string `mapstructure:"cidr_list"` - CreateSecurityGroup bool `mapstructure:"create_security_group"` - DiskOffering string `mapstructure:"disk_offering"` - DiskSize int64 `mapstructure:"disk_size"` - Expunge bool `mapstructure:"expunge"` - Hypervisor string `mapstructure:"hypervisor"` - InstanceName string `mapstructure:"instance_name"` - Keypair string `mapstructure:"keypair"` - Network string `mapstructure:"network"` - Project string `mapstructure:"project"` - PublicIPAddress string `mapstructure:"public_ip_address"` - SecurityGroups []string `mapstructure:"security_groups"` - ServiceOffering string `mapstructure:"service_offering"` - CreateNetworkACL bool `mapstructure:"create_network_acl"` - CreateFirewallRule bool `mapstructure:"create_firewall_rule"` - SourceISO string `mapstructure:"source_iso"` - SourceTemplate string `mapstructure:"source_template"` - TemporaryKeypairName string `mapstructure:"temporary_keypair_name"` - UseLocalIPAddress bool `mapstructure:"use_local_ip_address"` - UserData string `mapstructure:"user_data"` - UserDataFile string `mapstructure:"user_data_file"` - Zone string `mapstructure:"zone"` + CIDRList []string `mapstructure:"cidr_list"` + CreateSecurityGroup bool `mapstructure:"create_security_group"` + DiskOffering string `mapstructure:"disk_offering"` + DiskSize int64 `mapstructure:"disk_size"` + Expunge bool `mapstructure:"expunge"` + Hypervisor string `mapstructure:"hypervisor"` + InstanceName string `mapstructure:"instance_name"` + Keypair string `mapstructure:"keypair"` + Network string `mapstructure:"network"` + Project string `mapstructure:"project"` + PublicIPAddress string `mapstructure:"public_ip_address"` + SecurityGroups []string `mapstructure:"security_groups"` + ServiceOffering string `mapstructure:"service_offering"` + PreventFirewallChanges bool `mapstructure:"prevent_firewall_changes"` + SourceISO string `mapstructure:"source_iso"` + SourceTemplate string `mapstructure:"source_template"` + TemporaryKeypairName string `mapstructure:"temporary_keypair_name"` + UseLocalIPAddress bool `mapstructure:"use_local_ip_address"` + UserData string `mapstructure:"user_data"` + UserDataFile string `mapstructure:"user_data_file"` + Zone string `mapstructure:"zone"` TemplateName string `mapstructure:"template_name"` TemplateDisplayText string `mapstructure:"template_display_text"` diff --git a/builder/cloudstack/step_configure_networking.go b/builder/cloudstack/step_configure_networking.go index ccda39107..577b4b1f2 100644 --- a/builder/cloudstack/step_configure_networking.go +++ b/builder/cloudstack/step_configure_networking.go @@ -117,7 +117,12 @@ func (s *stepSetupNetworking) Run(_ context.Context, state multistep.StateBag) m // Store the port forward ID. state.Put("port_forward_id", forward.Id) - if network.Vpcid != "" && config.CreateNetworkACL { + if config.PreventFirewallChanges { + ui.Message("Networking has been setup (without firewall changes)!") + return multistep.ActionContinue + } + + if network.Vpcid != "" { ui.Message("Creating network ACL rule...") if network.Aclid == "" { @@ -149,7 +154,7 @@ func (s *stepSetupNetworking) Run(_ context.Context, state multistep.StateBag) m // Store the network ACL rule ID. state.Put("network_acl_rule_id", aclRule.Id) - } else if config.CreateFirewallRule { + } else { ui.Message("Creating firewall rule...") // Create a new parameter struct. From 742bcf5afbfcc4706c5c7c26310c8134184f54f9 Mon Sep 17 00:00:00 2001 From: Sergio Millan Rodriguez Date: Mon, 16 Jul 2018 13:31:29 +0200 Subject: [PATCH 110/220] added documentation for prevent_firewall_changes flag --- website/source/docs/builders/cloudstack.html.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/website/source/docs/builders/cloudstack.html.md b/website/source/docs/builders/cloudstack.html.md index 9268d628b..22b9f91d1 100644 --- a/website/source/docs/builders/cloudstack.html.md +++ b/website/source/docs/builders/cloudstack.html.md @@ -117,6 +117,9 @@ builder. - `instance_name` (string) - The name of the instance. Defaults to "packer-UUID" where UUID is dynamically generated. +- `prevent_firewall_changes` (boolean) - Set to `true` to prevent network ACLs + or firewall rules creation. Defaults to `false`. + - `project` (string) - The name or ID of the project to deploy the instance to. - `public_ip_address` (string) - The public IP address or it's ID used for From 618f125135a9af8a617a2ba439d092722d5fe1d1 Mon Sep 17 00:00:00 2001 From: James Nugent Date: Mon, 16 Jul 2018 13:03:55 -0500 Subject: [PATCH 111/220] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a160717b4..4dc2f8b26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.2.6 (Unreleased) + +### IMPROVEMENTS: + +* builder/amazon: Spot requests may now have tags applied using the `spot_tags` option [GH-5452] + ## 1.2.5 (July 16, 2018) ### BUG FIXES: From 8d9452a140719cc7783ee8eab34cf4f62a675226 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Mon, 16 Jul 2018 13:01:42 -0700 Subject: [PATCH 112/220] final changelog update for v.1.2.5 --- CHANGELOG.md | 79 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4dc2f8b26..0d10296eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,40 +2,67 @@ ### IMPROVEMENTS: -* builder/amazon: Spot requests may now have tags applied using the `spot_tags` option [GH-5452] +### BUG FIXES: ## 1.2.5 (July 16, 2018) ### BUG FIXES: -* core: Fix bug in parsing of iso checksum files that arose when setting iso_url to a relative filepath. [GH-6488] -* communicator/winrm: Revert an attempt to determine whether remote upload destinations were files or directories, as this broke uploads on systems without Powershell installed. [GH-6481] -* builder/amazon: Replace packer's waiters with those from the AWS sdk, solving several timeout bugs. [GH-6332] -* builder/azure: update the max length of managed_image_resource_group to match new increased length of 90 characters. [GH-6477] -* builder/vmware: Fix bug where we couldn't discover IP if vm_name differed from the vmx displayName. [GH-6448] -* fix: Fix bug where fixer for ssh_private_ip that failed when boolean values are passed as strings. [GH-6458] -* builder/qemu: vnc_bind_address was not being passed to qemu. [GH-6467] -* builder/qemu: Fix error race condition in qemu builder that caused convert to fail on ubuntu 18.x [GH-6437] -* builder/vmware: Fix validation to prevent hang when remopte_password is not sent but vmware is building on esxi. [GH-6424] -* builder/virtualbox: Allow iso_url to be a symlink. [GH-6370] -* builder/vmware: Don't fail on DHCP lease files that cannot be read, fixing bug where builder failed on NAT networks that don't serve DHCP. [GH-6415] -* builder/hyper-v: Fix secure boot template feature so that it properly passes the temolate for MicrosoftUEFICertificateAuthority. [GH-6415] +* builder/alickoud: Fix issue where internet_max_bandwidth_out template option + was not being passed to builder. [GH-6416] * builder/alicloud: Fix an issue with VPC cleanup. [GH-6418] -* builder/alickoud: Fix issue where internet_max_bandwidth_out template option was not being passed to builder. [GH-6416] -* builder/hyperv: Fix bug in HyperV IP lookups that was causing breakages in FreeBSD/OpenBSD builds. [GH-6416] -* core: Fix Packer crash caused by improper error handling in the downloader. [GH-6381] -* provisioner/powershell: Make upload of powershell variables retryable, in case of system restarts. [GH-6388] -* builder/amazon-chroot: Fix communicator bug that broke chroot builds. [GH-6363] -* builder/vmware:Correctly default the vm export format to ovf; this is what the docs claimed we already did, but we didn't. [GH-4538] +* builder/amazon-chroot: Fix communicator bug that broke chroot builds. + [GH-6363] +* builder/amazon: Replace packer's waiters with those from the AWS sdk, solving + several timeout bugs. [GH-6332] +* builder/azure: update azure-sdk-for-go, fixing 32-bit build errors. [GH-6479] +* builder/azure: update the max length of managed_image_resource_group to match + new increased length of 90 characters. [GH-6477] +* builder/hyper-v: Fix secure boot template feature so that it properly passes + the temolate for MicrosoftUEFICertificateAuthority. [GH-6415] +* builder/hyperv: Fix bug in HyperV IP lookups that was causing breakages in + FreeBSD/OpenBSD builds. [GH-6416] +* builder/qemu: Fix error race condition in qemu builder that caused convert to + fail on ubuntu 18.x [GH-6437] +* builder/qemu: vnc_bind_address was not being passed to qemu. [GH-6467] +* builder/virtualbox: Allow iso_url to be a symlink. [GH-6370] +* builder/vmware: Don't fail on DHCP lease files that cannot be read, fixing + bug where builder failed on NAT networks that don't serve DHCP. [GH-6415] +* builder/vmware: Fix bug where we couldn't discover IP if vm_name differed + from the vmx displayName. [GH-6448] +* builder/vmware: Fix validation to prevent hang when remopte_password is not + sent but vmware is building on esxi. [GH-6424] +* builder/vmware:Correctly default the vm export format to ovf; this is what + the docs claimed we already did, but we didn't. [GH-4538] +* communicator/winrm: Revert an attempt to determine whether remote upload + destinations were files or directories, as this broke uploads on systems + without Powershell installed. [GH-6481] +* core: Fix bug in parsing of iso checksum files that arose when setting + iso_url to a relative filepath. [GH-6488] +* core: Fix Packer crash caused by improper error handling in the downloader. + [GH-6381] +* fix: Fix bug where fixer for ssh_private_ip that failed when boolean values + are passed as strings. [GH-6458] +* provisioner/powershell: Make upload of powershell variables retryable, in + case of system restarts. [GH-6388] ### IMPROVEMENTS: -* post-processor/googlecompute-import: Added new googlecompute-import post-processor [GH-6451] -* builder/scaleway: Add new "bootscript" parameter, allowing the user to not use the default local bootscript [GH-6439] -* builder/vmware: Add support for linked clones to vmware-vmx. [GH-6394] -* builder/oracle-oci: Add new "instance_name" template option. [GH-6408] * builder/amazon: Add the ap-northeast-3 region. [GH-6385] -* debug: The -debug flag will now cause Packer to pause between provisioner scripts in addition to Packer steps. [GH-4663] -* provisioner/ansible: Add new "playbook_files" option to execute multiple playbooks within one provisioner call. [GH-5086] -* builder/openstack: Add support for token authorization and cloud.yaml. [GH-6362] +* builder/amazon: Spot requests may now have tags applied using the `spot_tags` + option [GH-5452] +* builder/cloudstack: Add support for Projectid and new config option + prevent_firewall_changes. [GH-6487] +* builder/openstack: Add support for token authorization and cloud.yaml. + [GH-6362] +* builder/oracle-oci: Add new "instance_name" template option. [GH-6408] +* builder/scaleway: Add new "bootscript" parameter, allowing the user to not + use the default local bootscript [GH-6439] +* builder/vmware: Add support for linked clones to vmware-vmx. [GH-6394] +* debug: The -debug flag will now cause Packer to pause between provisioner + scripts in addition to Packer steps. [GH-4663] +* post-processor/googlecompute-import: Added new googlecompute-import post- + processor [GH-6451] +* provisioner/ansible: Add new "playbook_files" option to execute multiple + playbooks within one provisioner call. [GH-5086] ## 1.2.4 (May 29, 2018) From 456a42c341f1bea4e0b56cd8b750504502f50471 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Mon, 16 Jul 2018 13:03:09 -0700 Subject: [PATCH 113/220] cut v.1.2.5 --- version/version.go | 4 ++-- website/config.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/version/version.go b/version/version.go index 76bf8120b..c785d4567 100644 --- a/version/version.go +++ b/version/version.go @@ -9,12 +9,12 @@ import ( var GitCommit string // The main version number that is being run at the moment. -const Version = "1.3.0" +const Version = "1.2.5" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. -const VersionPrerelease = "dev" +const VersionPrerelease = "" func FormattedVersion() string { var versionString bytes.Buffer diff --git a/website/config.rb b/website/config.rb index 1a0f09c95..dc89c0b69 100644 --- a/website/config.rb +++ b/website/config.rb @@ -2,7 +2,7 @@ set :base_url, "https://www.packer.io/" activate :hashicorp do |h| h.name = "packer" - h.version = "1.2.4" + h.version = "1.2.5" h.github_slug = "hashicorp/packer" h.website_root = "website" end From d1cc5451e933f39986bdc1069e9d26e534cde548 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Mon, 16 Jul 2018 13:10:23 -0700 Subject: [PATCH 114/220] Cut version 1.2.5 --- vendor/vendor.json | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/vendor/vendor.json b/vendor/vendor.json index 203593780..6ec355621 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -9,7 +9,7 @@ "revisionTime": "2016-08-11T22:04:02Z" }, { - "checksumSHA1": "aspvORKGJoiAwyzot4bsHqt/17Y=", + "checksumSHA1": "TY1n3V3oj1YcvXPTUVnlRlNfGow=", "path": "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute", "revision": "ef33a0a23b66ba5e81f699d03dc48b723c1bad50", "revisionTime": "2018-06-15T22:13:27Z", @@ -17,7 +17,7 @@ "versionExact": "v17.3.1" }, { - "checksumSHA1": "jD1gZ3he4E6iYOZn7D24dKeLG8k=", + "checksumSHA1": "qzopX7CTZDrbARD7A8DBBbevmyM=", "path": "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network", "revision": "ef33a0a23b66ba5e81f699d03dc48b723c1bad50", "revisionTime": "2018-06-15T22:13:27Z", @@ -25,7 +25,7 @@ "versionExact": "v17.3.1" }, { - "checksumSHA1": "pJ2o3U5IZP9z5dKYl69maIBXUOY=", + "checksumSHA1": "DJY5zDEcGa82/Hbfud8lgHCuvU4=", "path": "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2016-06-01/subscriptions", "revision": "ef33a0a23b66ba5e81f699d03dc48b723c1bad50", "revisionTime": "2018-06-15T22:13:27Z", @@ -33,7 +33,7 @@ "versionExact": "v17.3.1" }, { - "checksumSHA1": "hnlMpNzAV5mu4PHvyTuBc/BC8aA=", + "checksumSHA1": "928vJH7PbmZ6/3pG5GIlaw+h7B4=", "path": "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources", "revision": "ef33a0a23b66ba5e81f699d03dc48b723c1bad50", "revisionTime": "2018-06-15T22:13:27Z", @@ -41,7 +41,7 @@ "versionExact": "v17.3.1" }, { - "checksumSHA1": "qHMzicMTsihjgKyS/VB8oguXmmc=", + "checksumSHA1": "ySkjHczHi2zN8B1TuWfvKVLGetw=", "path": "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2017-10-01/storage", "revision": "ef33a0a23b66ba5e81f699d03dc48b723c1bad50", "revisionTime": "2018-06-15T22:13:27Z", @@ -49,7 +49,7 @@ "versionExact": "v17.3.1" }, { - "checksumSHA1": "1fQaVn4mDau1rUfyWGitatAvXdM=", + "checksumSHA1": "m3K3q/zhkmRtlIGWqMWgqzWR6C4=", "path": "github.com/Azure/azure-sdk-for-go/storage", "revision": "ef33a0a23b66ba5e81f699d03dc48b723c1bad50", "revisionTime": "2018-06-15T22:13:27Z", @@ -57,7 +57,7 @@ "versionExact": "v17.3.1" }, { - "checksumSHA1": "BeO7/Ld5yP8m32hHNGQBSUvQjaw=", + "checksumSHA1": "Zl5uxmDmvXF6ADQsggG50XCiWmY=", "path": "github.com/Azure/azure-sdk-for-go/version", "revision": "ef33a0a23b66ba5e81f699d03dc48b723c1bad50", "revisionTime": "2018-06-15T22:13:27Z", @@ -65,7 +65,7 @@ "versionExact": "v17.3.1" }, { - "checksumSHA1": "q3bhLdUVAz5dmDFvfKJJSTd/BaE=", + "checksumSHA1": "4Ba4uKXCFYkXa54FD7NyI8EsXG4=", "comment": "v7.0.7", "path": "github.com/Azure/go-autorest/autorest", "revision": "1f7cd6cfe0adea687ad44a512dfe76140f804318", @@ -74,7 +74,7 @@ "versionExact": "v10.12.0" }, { - "checksumSHA1": "Ygkay0Aq7zeg8A9DSRWI+flRcFk=", + "checksumSHA1": "dMSqbz496pHMUGW8ID67vpafGto=", "path": "github.com/Azure/go-autorest/autorest/adal", "revision": "1f7cd6cfe0adea687ad44a512dfe76140f804318", "revisionTime": "2018-06-28T21:22:21Z", @@ -82,7 +82,7 @@ "versionExact": "v10.12.0" }, { - "checksumSHA1": "O8hvZ5SZ6o/mGOTivIagc1uPdl4=", + "checksumSHA1": "NT4tlDNlszWmb7gCXnYCkcvQxhs=", "comment": "v7.0.7", "path": "github.com/Azure/go-autorest/autorest/azure", "revision": "1f7cd6cfe0adea687ad44a512dfe76140f804318", @@ -91,7 +91,7 @@ "versionExact": "v10.12.0" }, { - "checksumSHA1": "KcxXWvXhVIkfqdGR+TQqWyCbgZk=", + "checksumSHA1": "9nXCi9qQsYjxCeajJKWttxgEt0I=", "comment": "v7.0.7", "path": "github.com/Azure/go-autorest/autorest/date", "revision": "1f7cd6cfe0adea687ad44a512dfe76140f804318", @@ -100,7 +100,7 @@ "versionExact": "v10.12.0" }, { - "checksumSHA1": "8XiRKZWE6XGsb0eJfG4P98JwaXw=", + "checksumSHA1": "SbBb2GcJNm5GjuPKGL2777QywR4=", "comment": "v7.0.7", "path": "github.com/Azure/go-autorest/autorest/to", "revision": "1f7cd6cfe0adea687ad44a512dfe76140f804318", @@ -109,7 +109,7 @@ "versionExact": "v10.12.0" }, { - "checksumSHA1": "SVU/fTZ9osBm+WPdd5y71RabAzE=", + "checksumSHA1": "HjdLfAF3oA2In8F3FKh/Y+BPyXk=", "path": "github.com/Azure/go-autorest/autorest/validation", "revision": "1f7cd6cfe0adea687ad44a512dfe76140f804318", "revisionTime": "2018-06-28T21:22:21Z", From b28098e0f79b0f6b795f0cc3db00489c0ac18ce8 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Mon, 16 Jul 2018 13:25:32 -0700 Subject: [PATCH 115/220] update to version 1.2.6-dev --- version/version.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version/version.go b/version/version.go index c785d4567..e2653351c 100644 --- a/version/version.go +++ b/version/version.go @@ -9,12 +9,12 @@ import ( var GitCommit string // The main version number that is being run at the moment. -const Version = "1.2.5" +const Version = "1.2.6" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. -const VersionPrerelease = "" +const VersionPrerelease = "dev" func FormattedVersion() string { var versionString bytes.Buffer From 1781d352a5ba2193d89fa780719eb2dc10f69a79 Mon Sep 17 00:00:00 2001 From: Patrick Double Date: Mon, 16 Jul 2018 15:35:02 -0500 Subject: [PATCH 116/220] Add Vagrantfile fragment with docker tag specified --- post-processor/vagrant/docker.go | 5 ++++- post-processor/vagrant/post-processor.go | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/post-processor/vagrant/docker.go b/post-processor/vagrant/docker.go index 50b811c8f..6f5aeb3dc 100644 --- a/post-processor/vagrant/docker.go +++ b/post-processor/vagrant/docker.go @@ -16,11 +16,14 @@ func (p *DockerProvider) Process(ui packer.Ui, artifact packer.Artifact, dir str // Create the metadata metadata = map[string]interface{}{"provider": "docker"} - vagrantfile = fmt.Sprintf(dockerVagrantfile) + vagrantfile = fmt.Sprintf(dockerVagrantfile, artifact.Id()) return } var dockerVagrantfile = ` Vagrant.configure("2") do |config| + config.vm.provider :docker do |docker, override| + docker.image = "%s" + end end ` diff --git a/post-processor/vagrant/post-processor.go b/post-processor/vagrant/post-processor.go index 3d54d49f7..1aab0ca23 100644 --- a/post-processor/vagrant/post-processor.go +++ b/post-processor/vagrant/post-processor.go @@ -32,6 +32,8 @@ var builtins = map[string]string{ "transcend.qemu": "libvirt", "ustream.lxc": "lxc", "packer.post-processor.docker-import": "docker", + "packer.post-processor.docker-tag": "docker", + "packer.post-processor.docker-push": "docker", } type Config struct { From a5493e49061a1d6340d4632fe43675f0d5eff975 Mon Sep 17 00:00:00 2001 From: Levi Blaney Date: Mon, 16 Jul 2018 17:26:38 -0400 Subject: [PATCH 117/220] added the builders that set_winrm_passwd works with --- website/source/docs/provisioners/ansible.html.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/website/source/docs/provisioners/ansible.html.md b/website/source/docs/provisioners/ansible.html.md index 8bc697cad..64630822d 100644 --- a/website/source/docs/provisioners/ansible.html.md +++ b/website/source/docs/provisioners/ansible.html.md @@ -128,9 +128,11 @@ Optional Parameters: - `user` (string) - The `ansible_user` to use. Defaults to the user running packer. -- `set_winrm_passwd` (boolean) - Set to `true` to access the randomly-generated - EC2 Windows password through the environment variable `GENERATED_WINRM_PASSWORD`. - You will also need to set `ansible_password` in your ansible playbook, for example, +- `set_winrm_passwd` (boolean) - Set to `true` if you are running on AWS, Azure or + Google Compute and would like to access the generated password that Packer uses to + connect to the instance via WinRM. The password will be avaliable on the builder + through the environment variable `GENERATED_WINRM_PASSWORD`. You will also need to + set `ansible_password` in your ansible playbook, for example, `ansible_password: "{{ lookup('env','GENERATED_WINRM_PASSWORD') }}"` ## Default Extra Variables From f5e17d1cad159e2f4122bb7a8ff7743e8c531574 Mon Sep 17 00:00:00 2001 From: Levi Blaney Date: Mon, 16 Jul 2018 19:13:05 -0400 Subject: [PATCH 118/220] changed wording from builder to provisoner --- website/source/docs/provisioners/ansible.html.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/source/docs/provisioners/ansible.html.md b/website/source/docs/provisioners/ansible.html.md index 64630822d..2fda46679 100644 --- a/website/source/docs/provisioners/ansible.html.md +++ b/website/source/docs/provisioners/ansible.html.md @@ -130,9 +130,9 @@ Optional Parameters: - `set_winrm_passwd` (boolean) - Set to `true` if you are running on AWS, Azure or Google Compute and would like to access the generated password that Packer uses to - connect to the instance via WinRM. The password will be avaliable on the builder - through the environment variable `GENERATED_WINRM_PASSWORD`. You will also need to - set `ansible_password` in your ansible playbook, for example, + connect to the instance via WinRM. The password will be avaliable to the Ansible + provisioner through the environment variable `GENERATED_WINRM_PASSWORD`. You will + also need to set `ansible_password` in your ansible playbook, for example, `ansible_password: "{{ lookup('env','GENERATED_WINRM_PASSWORD') }}"` ## Default Extra Variables From cf04fd55ea8898b1197464553ba1568b0dae5f96 Mon Sep 17 00:00:00 2001 From: Sean Malloy Date: Mon, 16 Jul 2018 20:40:19 -0500 Subject: [PATCH 119/220] Add missing link to googlecompute-import post-processor docs --- website/source/layouts/docs.erb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/website/source/layouts/docs.erb b/website/source/layouts/docs.erb index 552b154ab..89e58b8fb 100644 --- a/website/source/layouts/docs.erb +++ b/website/source/layouts/docs.erb @@ -281,6 +281,9 @@ > Google Compute Export + > + Google Compute Import + > Manifest From a301145ae15179059f60734ac73613c8c023d496 Mon Sep 17 00:00:00 2001 From: Patrick Double Date: Tue, 17 Jul 2018 09:41:18 -0500 Subject: [PATCH 120/220] Allow docker build as input to vagrant, docs --- post-processor/vagrant/post-processor.go | 1 + website/source/docs/post-processors/vagrant.html.md | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/post-processor/vagrant/post-processor.go b/post-processor/vagrant/post-processor.go index 1aab0ca23..c0151220f 100644 --- a/post-processor/vagrant/post-processor.go +++ b/post-processor/vagrant/post-processor.go @@ -31,6 +31,7 @@ var builtins = map[string]string{ "MSOpenTech.hyperv": "hyperv", "transcend.qemu": "libvirt", "ustream.lxc": "lxc", + "packer.docker": "docker", "packer.post-processor.docker-import": "docker", "packer.post-processor.docker-tag": "docker", "packer.post-processor.docker-push": "docker", diff --git a/website/source/docs/post-processors/vagrant.html.md b/website/source/docs/post-processors/vagrant.html.md index 099051a81..3032c2f8b 100644 --- a/website/source/docs/post-processors/vagrant.html.md +++ b/website/source/docs/post-processors/vagrant.html.md @@ -39,6 +39,7 @@ providers. - QEMU - VirtualBox - VMware +- Docker -> **Support for additional providers** is planned. If the Vagrant post-processor doesn't support creating boxes for a provider you care about, @@ -114,6 +115,7 @@ The available provider names are: - `scaleway` - `virtualbox` - `vmware` +- `docker` ## Input Artifacts @@ -124,3 +126,10 @@ it. Please see the [documentation on input artifacts](/docs/templates/post-processors.html#toc_2) for more information. + +### Docker + +Using the Docker builder or one of the Docker post processors as an input +artifact will cause the `Vagrantfile` to include a reference to the image. For +post processors allowing a tag to be specified, such as `docker-import` or +`docker-tag`, the tag will be used. Otherwise, the sha256 hash will be used. From 7630268e1dd6238ecec8b2a26fa7df801a8cb46d Mon Sep 17 00:00:00 2001 From: xxx Date: Tue, 17 Jul 2018 17:41:19 +0200 Subject: [PATCH 121/220] Incorporate review comments --- builder/oracle/oci/config.go | 8 ++++++-- builder/oracle/oci/config_test.go | 1 - builder/oracle/oci/driver_oci.go | 4 ++-- website/source/docs/builders/oracle-oci.html.md | 4 +++- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/builder/oracle/oci/config.go b/builder/oracle/oci/config.go index 16e80f2b0..eda312ee2 100644 --- a/builder/oracle/oci/config.go +++ b/builder/oracle/oci/config.go @@ -48,8 +48,12 @@ type Config struct { // Instance InstanceName string `mapstructure:"instance_name"` - // MetaData is optional but will be constructed to include UserData or UserDataFile under the "user_data" key - MetaData map[string]string `mapstructure:"metadata"` + // Metadata optionally contains custom metadata key/value pairs provided in the + // configuration. While this can be used to set metadata["user_data"] the explicit + // "user_data" and "user_data_file" values will have precedence. + // An instance's metadata can be obtained from at http://169.254.169.254 on the + // launched instance. + Metadata map[string]string `mapstructure:"metadata"` // UserData and UserDataFile file are both optional and mutually exclusive. UserData string `mapstructure:"user_data"` diff --git a/builder/oracle/oci/config_test.go b/builder/oracle/oci/config_test.go index b590bf392..51cbb386d 100644 --- a/builder/oracle/oci/config_test.go +++ b/builder/oracle/oci/config_test.go @@ -238,7 +238,6 @@ func TestConfig(t *testing.T) { t.Errorf("Expected ConfigProvider.KeyFingerprint: %s, got %s", expected, fingerprint) } }) - } // BaseTestConfig creates the base (DEFAULT) config including a temporary key diff --git a/builder/oracle/oci/driver_oci.go b/builder/oracle/oci/driver_oci.go index b1386b8c6..138bb6474 100644 --- a/builder/oracle/oci/driver_oci.go +++ b/builder/oracle/oci/driver_oci.go @@ -42,8 +42,8 @@ func (d *driverOCI) CreateInstance(ctx context.Context, publicKey string) (strin metadata := map[string]string{ "ssh_authorized_keys": publicKey, } - if d.cfg.MetaData != nil { - for key, value := range d.cfg.MetaData { + if d.cfg.Metadata != nil { + for key, value := range d.cfg.Metadata { metadata[key] = value } } diff --git a/website/source/docs/builders/oracle-oci.html.md b/website/source/docs/builders/oracle-oci.html.md index b651196d1..e2360a5c1 100644 --- a/website/source/docs/builders/oracle-oci.html.md +++ b/website/source/docs/builders/oracle-oci.html.md @@ -125,7 +125,9 @@ builder. - `use_private_ip` (boolean) - Use private ip addresses to connect to the instance via ssh. - - `metadata` (map of strings) - Metadata to be injected in the build instance. + - `metadata` (map of strings) - Metadata optionally contains custom metadata key/value pairs provided in the +configuration. While this can be used to set metadata["user_data"] the explicit "user_data" and "user_data_file" values will have precedence. An instance's metadata can be obtained from at http://169.254.169.254 on the +launched instance. - `user_data` (string) - user_data to be used by cloud init. See [the Oracle docs](https://docs.us-phoenix-1.oraclecloud.com/api/#/en/iaas/20160918/LaunchInstanceDetails) for more details. Generally speaking, it is easier to use the `user_data_file`, From 990d139d4598edb1eb22c1141cf4d14e4e87adf7 Mon Sep 17 00:00:00 2001 From: Robert Neumayer Date: Tue, 17 Jul 2018 17:44:27 +0200 Subject: [PATCH 122/220] Fix typo in oci documentation --- website/source/docs/builders/oracle-oci.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/builders/oracle-oci.html.md b/website/source/docs/builders/oracle-oci.html.md index 4329a56f5..46501ed78 100644 --- a/website/source/docs/builders/oracle-oci.html.md +++ b/website/source/docs/builders/oracle-oci.html.md @@ -127,7 +127,7 @@ builder. - `user_data` (string) - user_data to be used by cloud init. See [the Oracle docs](https://docs.us-phoenix-1.oraclecloud.com/api/#/en/iaas/20160918/LaunchInstanceDetails) for more details. Generally speaking, it is easier to use the `user_data_file`, - but you can use this option to put either the platintext data or the base64 + but you can use this option to put either the plaintext data or the base64 encoded data directly into your Packer config. - `user_data_file` (string) - Path to a file to be used as user_data by cloud From edcc0b3853faa0ab0f940415fd05e23b109a936a Mon Sep 17 00:00:00 2001 From: Mathieu Tarral Date: Tue, 17 Jul 2018 18:49:36 +0300 Subject: [PATCH 123/220] shell-local: expose PACKER_HTTP_ADDR env var --- common/shell-local/run.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/common/shell-local/run.go b/common/shell-local/run.go index 51bb047b0..ede99e30d 100644 --- a/common/shell-local/run.go +++ b/common/shell-local/run.go @@ -9,6 +9,7 @@ import ( "sort" "strings" + "github.com/hashicorp/packer/common" commonhelper "github.com/hashicorp/packer/helper/common" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" @@ -165,6 +166,12 @@ func createFlattenedEnvVars(config *Config) (string, error) { envVars["PACKER_BUILD_NAME"] = fmt.Sprintf("%s", config.PackerBuildName) envVars["PACKER_BUILDER_TYPE"] = fmt.Sprintf("%s", config.PackerBuilderType) + // expose PACKER_HTTP_ADDR + httpAddr := common.GetHTTPAddr() + if httpAddr != "" { + envVars["PACKER_HTTP_ADDR"] = fmt.Sprintf("%s", httpAddr) + } + // interpolate environment variables config.Ctx.Data = &EnvVarsTemplate{ WinRMPassword: getWinRMPassword(config.PackerBuildName), From 221761d97acda4e185c4a5cf730d0cfb9ca758fa Mon Sep 17 00:00:00 2001 From: Mathieu Tarral Date: Tue, 17 Jul 2018 18:50:40 +0300 Subject: [PATCH 124/220] shell-local: add docs for PACKER_HTTP_ADDR env var --- website/source/docs/provisioners/shell-local.html.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/website/source/docs/provisioners/shell-local.html.md b/website/source/docs/provisioners/shell-local.html.md index d64e19fac..16719f239 100644 --- a/website/source/docs/provisioners/shell-local.html.md +++ b/website/source/docs/provisioners/shell-local.html.md @@ -184,6 +184,13 @@ commonly useful environmental variables: machine that the script is running on. This is useful if you want to run only certain parts of the script on systems built with certain builders. +- `PACKER_HTTP_ADDR` If using a builder that provides an http server for file + transfer (such as hyperv, parallels, qemu, virtualbox, and vmware), this + will be set to the address. You can use this address in your provisioner to + download large files over http. This may be useful if you're experiencing + slower speeds using the default file provisioner. A file provisioner using + the `winrm` communicator may experience these types of difficulties. + ## Safely Writing A Script Whether you use the `inline` option, or pass it a direct `script` or `scripts`, From 3450b6fd6f2dfdc043b4d8c55f8b6605d63cf588 Mon Sep 17 00:00:00 2001 From: Mathieu Tarral Date: Tue, 17 Jul 2018 17:03:05 +0300 Subject: [PATCH 125/220] ansible: expose packer_http_addr extra var --- provisioner/ansible/provisioner.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/provisioner/ansible/provisioner.go b/provisioner/ansible/provisioner.go index d6e785c70..ae03284a6 100644 --- a/provisioner/ansible/provisioner.go +++ b/provisioner/ansible/provisioner.go @@ -336,6 +336,13 @@ func (p *Provisioner) executeAnsible(ui packer.Ui, comm packer.Communicator, pri // args = append(args, "--private-key", privKeyFile) args = append(args, "-e", fmt.Sprintf("ansible_ssh_private_key_file=%s", privKeyFile)) } + + // expose packer_http_addr extra variable + httpAddr := common.GetHTTPAddr() + if httpAddr != "" { + args = append(args, "--extra-vars", fmt.Sprintf("packer_http_addr=%s", httpAddr)) + } + args = append(args, p.config.ExtraArguments...) if len(p.config.AnsibleEnvVars) > 0 { envvars = append(envvars, p.config.AnsibleEnvVars...) From 430d9389bee1259f6cb16af4e6c4031156feccd8 Mon Sep 17 00:00:00 2001 From: Mathieu Tarral Date: Tue, 17 Jul 2018 17:15:35 +0300 Subject: [PATCH 126/220] website: add documentation for packer_http_addr extra variable --- website/source/docs/provisioners/ansible.html.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/website/source/docs/provisioners/ansible.html.md b/website/source/docs/provisioners/ansible.html.md index 26047458d..0096eaf22 100644 --- a/website/source/docs/provisioners/ansible.html.md +++ b/website/source/docs/provisioners/ansible.html.md @@ -142,6 +142,13 @@ commonly useful Ansible variables: machine that the script is running on. This is useful if you want to run only certain parts of the playbook on systems built with certain builders. +- `packer_http_addr` If using a builder that provides an http server for file + transfer (such as hyperv, parallels, qemu, virtualbox, and vmware), this + will be set to the address. You can use this address in your provisioner to + download large files over http. This may be useful if you're experiencing + slower speeds using the default file provisioner. A file provisioner using + the `winrm` communicator may experience these types of difficulties. + ## Debugging To debug underlying issues with Ansible, add `"-vvvv"` to `"extra_arguments"` to enable verbose logging. From 066b364873a9cf773238f4d5a66820c1edc0068e Mon Sep 17 00:00:00 2001 From: Patrick Double Date: Tue, 17 Jul 2018 15:07:22 -0500 Subject: [PATCH 127/220] Remove packer.docker from vagrant post processor builtins --- post-processor/vagrant/post-processor.go | 1 - 1 file changed, 1 deletion(-) diff --git a/post-processor/vagrant/post-processor.go b/post-processor/vagrant/post-processor.go index c0151220f..1aab0ca23 100644 --- a/post-processor/vagrant/post-processor.go +++ b/post-processor/vagrant/post-processor.go @@ -31,7 +31,6 @@ var builtins = map[string]string{ "MSOpenTech.hyperv": "hyperv", "transcend.qemu": "libvirt", "ustream.lxc": "lxc", - "packer.docker": "docker", "packer.post-processor.docker-import": "docker", "packer.post-processor.docker-tag": "docker", "packer.post-processor.docker-push": "docker", From c7fef8d22a13ea364deae36b9d04d00cac589ff2 Mon Sep 17 00:00:00 2001 From: Patrick Double Date: Tue, 17 Jul 2018 15:10:53 -0500 Subject: [PATCH 128/220] Update vagrant post-process docs --- website/source/docs/post-processors/vagrant.html.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/website/source/docs/post-processors/vagrant.html.md b/website/source/docs/post-processors/vagrant.html.md index 3032c2f8b..35321172a 100644 --- a/website/source/docs/post-processors/vagrant.html.md +++ b/website/source/docs/post-processors/vagrant.html.md @@ -133,3 +133,6 @@ Using the Docker builder or one of the Docker post processors as an input artifact will cause the `Vagrantfile` to include a reference to the image. For post processors allowing a tag to be specified, such as `docker-import` or `docker-tag`, the tag will be used. Otherwise, the sha256 hash will be used. + +Note: Using the `docker` builder to save the image as a tar file cannot be used +to produce a Vagrant box. \ No newline at end of file From 9384f322f6206ff9a9ee475453e5d99a10b0e190 Mon Sep 17 00:00:00 2001 From: Matthew Hooker Date: Tue, 17 Jul 2018 13:29:46 -0700 Subject: [PATCH 129/220] Prevent make fmt from failing in default case Apologies for the terrible hack. This just makes sure we always have a default file to format, so if the unformatted list is empty we don't error. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 345a27cac..e0791add6 100644 --- a/Makefile +++ b/Makefile @@ -61,7 +61,7 @@ dev: deps ## Build and install a development build @cp $(GOPATH)/bin/packer pkg/$(GOOS)_$(GOARCH) fmt: ## Format Go code - @gofmt -w -s $(UNFORMATTED_FILES) + @gofmt -w -s main.go $(UNFORMATTED_FILES) fmt-check: ## Check go code formatting @echo "==> Checking that code complies with gofmt requirements..." From e146973d081c876022f21bd7b111cd932ce71e1c Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Tue, 17 Jul 2018 12:52:32 -0700 Subject: [PATCH 130/220] change implementation to set winrm password in way that matches powershell and shell-local implementations; sanitize logs --- provisioner/ansible/provisioner.go | 44 +++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/provisioner/ansible/provisioner.go b/provisioner/ansible/provisioner.go index a221d02da..ead4d44b2 100644 --- a/provisioner/ansible/provisioner.go +++ b/provisioner/ansible/provisioner.go @@ -58,7 +58,6 @@ type Config struct { UseSFTP bool `mapstructure:"use_sftp"` InventoryDirectory string `mapstructure:"inventory_directory"` InventoryFile string `mapstructure:"inventory_file"` - SetWinrmPasswd bool `mapstructure:"set_winrm_passwd"` } type Provisioner struct { @@ -69,9 +68,19 @@ type Provisioner struct { ansibleMajVersion uint } +type PassthroughTemplate struct { + WinRMPassword string +} + func (p *Provisioner) Prepare(raws ...interface{}) error { p.done = make(chan struct{}) + // Create passthrough for winrm password so we can fill it in once we know + // it + p.config.ctx.Data = &PassthroughTemplate{ + WinRMPassword: `{{.WinRMPassword}}`, + } + err := config.Decode(&p.config, &config.DecodeOpts{ Interpolate: true, InterpolateContext: &p.config.ctx, @@ -190,11 +199,24 @@ func (p *Provisioner) getVersion() error { func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { ui.Say("Provisioning with Ansible...") - - if p.config.SetWinrmPasswd { - var WinrmEnvVar string = fmt.Sprintf("GENERATED_WINRM_PASSWORD=%s", getWinRMPassword(p.config.PackerBuildName)) - p.config.AnsibleEnvVars = append(p.config.AnsibleEnvVars, WinrmEnvVar) - ui.Say("Setting Environment variable GENERATED_WINRM_PASSWORD to WinRM password.") + // Interpolate env vars to check for .WinRMPassword + p.config.ctx.Data = &PassthroughTemplate{ + WinRMPassword: getWinRMPassword(p.config.PackerBuildName), + } + for i, envVar := range p.config.AnsibleEnvVars { + envVar, err := interpolate.Render(envVar, &p.config.ctx) + if err != nil { + return fmt.Errorf("Could not interpolate ansible env vars: %s", err) + } + p.config.AnsibleEnvVars[i] = envVar + } + // Interpolate extra vars to check for .WinRMPassword + for i, arg := range p.config.ExtraArguments { + arg, err := interpolate.Render(arg, &p.config.ctx) + if err != nil { + return fmt.Errorf("Could not interpolate ansible env vars: %s", err) + } + p.config.ExtraArguments[i] = arg } k, err := newUserKey(p.config.SSHAuthorizedKeyFile) @@ -389,7 +411,15 @@ func (p *Provisioner) executeAnsible(ui packer.Ui, comm packer.Communicator, pri go repeat(stdout) go repeat(stderr) - ui.Say(fmt.Sprintf("Executing Ansible: %s", strings.Join(cmd.Args, " "))) + // remove winrm password from command, if it's been added + flattenedCmd := strings.Join(cmd.Args, " ") + sanitized := flattenedCmd + if len(getWinRMPassword(p.config.PackerBuildName)) > 0 { + sanitized = strings.Replace(sanitized, + getWinRMPassword(p.config.PackerBuildName), "*****", -1) + } + ui.Say(fmt.Sprintf("Executing Ansible: %s", sanitized)) + if err := cmd.Start(); err != nil { return err } From 885ecb0790124ec0ff2a4cbfc66193cf302f4276 Mon Sep 17 00:00:00 2001 From: Anshul Sharma Date: Wed, 18 Jul 2018 13:01:15 +0300 Subject: [PATCH 131/220] Issue-6309 Amazon Chroot Provider - Add tags on CreateVolume --- builder/amazon/chroot/builder.go | 4 +++ builder/amazon/chroot/step_create_volume.go | 27 +++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/builder/amazon/chroot/builder.go b/builder/amazon/chroot/builder.go index a8b20276a..052429e2e 100644 --- a/builder/amazon/chroot/builder.go +++ b/builder/amazon/chroot/builder.go @@ -44,6 +44,7 @@ type Config struct { RootVolumeSize int64 `mapstructure:"root_volume_size"` SourceAmi string `mapstructure:"source_ami"` SourceAmiFilter awscommon.AmiFilterOptions `mapstructure:"source_ami_filter"` + RootVolumeTags awscommon.TagMap `mapstructure:"root_volume_tags"` ctx interpolate.Context } @@ -67,6 +68,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { "ami_description", "snapshot_tags", "tags", + "root_volume_tags", "command_wrapper", "post_mount_commands", "pre_mount_commands", @@ -230,6 +232,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &StepPrepareDevice{}, &StepCreateVolume{ RootVolumeSize: b.config.RootVolumeSize, + RootVolumeTags: b.config.RootVolumeTags, + Ctx: b.config.ctx, }, &StepAttachVolume{}, &StepEarlyUnflock{}, diff --git a/builder/amazon/chroot/step_create_volume.go b/builder/amazon/chroot/step_create_volume.go index 725c8240b..4adf3074f 100644 --- a/builder/amazon/chroot/step_create_volume.go +++ b/builder/amazon/chroot/step_create_volume.go @@ -10,6 +10,7 @@ import ( awscommon "github.com/hashicorp/packer/builder/amazon/common" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" + "github.com/hashicorp/packer/template/interpolate" ) // StepCreateVolume creates a new volume from the snapshot of the root @@ -20,6 +21,8 @@ import ( type StepCreateVolume struct { volumeId string RootVolumeSize int64 + RootVolumeTags awscommon.TagMap + Ctx interpolate.Context } func (s *StepCreateVolume) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { @@ -28,6 +31,26 @@ func (s *StepCreateVolume) Run(ctx context.Context, state multistep.StateBag) mu instance := state.Get("instance").(*ec2.Instance) ui := state.Get("ui").(packer.Ui) + volTags, err := s.RootVolumeTags.EC2Tags(s.Ctx, *ec2conn.Config.Region, state) + if err != nil { + err := fmt.Errorf("Error tagging volumes: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + // Collect tags for tagging on resource creation + var tagSpecs []*ec2.TagSpecification + + if len(volTags) > 0 { + runVolTags := &ec2.TagSpecification{ + ResourceType: aws.String("volume"), + Tags: volTags, + } + + tagSpecs = append(tagSpecs, runVolTags) + } + var createVolume *ec2.CreateVolumeInput if config.FromScratch { createVolume = &ec2.CreateVolumeInput{ @@ -69,6 +92,10 @@ func (s *StepCreateVolume) Run(ctx context.Context, state multistep.StateBag) mu } } + if len(tagSpecs) > 0 { + createVolume.SetTagSpecifications(tagSpecs) + volTags.Report(ui) + } log.Printf("Create args: %+v", createVolume) createVolumeResp, err := ec2conn.CreateVolume(createVolume) From e8a7d948dbf0a45b1022b6ca4856b9893bbbfe91 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Wed, 18 Jul 2018 09:42:15 -0700 Subject: [PATCH 132/220] update docs --- .../source/docs/provisioners/ansible.html.md | 36 +++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/website/source/docs/provisioners/ansible.html.md b/website/source/docs/provisioners/ansible.html.md index 2fda46679..bf1145f64 100644 --- a/website/source/docs/provisioners/ansible.html.md +++ b/website/source/docs/provisioners/ansible.html.md @@ -14,7 +14,7 @@ Type: `ansible` The `ansible` Packer provisioner runs Ansible playbooks. It dynamically creates an Ansible inventory file configured to use SSH, runs an SSH server, executes `ansible-playbook`, and marshals Ansible plays through the SSH server to the -machine being provisioned by Packer. +machine being provisioned by Packer. -> **Note:**: Any `remote_user` defined in tasks will be ignored. Packer will always connect with the user given in the json config for this provisioner. @@ -61,6 +61,15 @@ Optional Parameters: "ansible_env_vars": [ "ANSIBLE_HOST_KEY_CHECKING=False", "ANSIBLE_SSH_ARGS='-o ForwardAgent=yes -o ControlMaster=auto -o ControlPersist=60s'", "ANSIBLE_NOCOLOR=True" ] } ``` + If you are running a Windows build on AWS, Azure or Google Compute and would + like to access the auto-generated password that Packer uses to connect to a + Windows instance via WinRM, you can use the template variable + {{.WinRMPassword}} in this option. + For example: + + ```json + "ansible_env_vars": [ "WINRM_PASSWORD={{.WinRMPassword}}" ], + ``` - `command` (string) - The command to invoke ansible. Defaults to `ansible-playbook`. @@ -72,12 +81,24 @@ Optional Parameters: These arguments *will not* be passed through a shell and arguments should not be quoted. Usage example: - ``` json + ```json { "extra_arguments": [ "--extra-vars", "Region={{user `Region`}} Stage={{user `Stage`}}" ] } ``` + If you are running a Windows build on AWS, Azure or Google Compute and would + like to access the auto-generated password that Packer uses to connect to a + Windows instance via WinRM, you can use the template variable + {{.WinRMPassword}} in this option. + For example: + + ```json + "extra_arguments": [ + "--extra-vars", "winrm_password={{ .WinRMPassword }}" + ] + ``` + - `groups` (array of strings) - The groups into which the Ansible host should be placed. When unspecified, the host is not associated with any groups. @@ -128,13 +149,6 @@ Optional Parameters: - `user` (string) - The `ansible_user` to use. Defaults to the user running packer. -- `set_winrm_passwd` (boolean) - Set to `true` if you are running on AWS, Azure or - Google Compute and would like to access the generated password that Packer uses to - connect to the instance via WinRM. The password will be avaliable to the Ansible - provisioner through the environment variable `GENERATED_WINRM_PASSWORD`. You will - also need to set `ansible_password` in your ansible playbook, for example, - `ansible_password: "{{ lookup('env','GENERATED_WINRM_PASSWORD') }}"` - ## Default Extra Variables In addition to being able to specify extra arguments using the @@ -153,7 +167,7 @@ commonly useful Ansible variables: To debug underlying issues with Ansible, add `"-vvvv"` to `"extra_arguments"` to enable verbose logging. -``` json +```json { "extra_arguments": [ "-vvvv" ] } @@ -174,7 +188,7 @@ Redhat / CentOS builds have been known to fail with the following error due to ` Building within a chroot (e.g. `amazon-chroot`) requires changing the Ansible connection to chroot. -``` json +```json { "builders": [ { From 814c1cf2b2d734fe8fa4f1d4877ba0bc2680644a Mon Sep 17 00:00:00 2001 From: Matthew Hooker Date: Wed, 18 Jul 2018 13:00:45 -0700 Subject: [PATCH 133/220] spellfix --- builder/amazon/common/state.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/amazon/common/state.go b/builder/amazon/common/state.go index c2390d8b1..b76352a5e 100644 --- a/builder/amazon/common/state.go +++ b/builder/amazon/common/state.go @@ -324,7 +324,7 @@ func applyEnvOverrides(envOverrides overridableWaitVars) []request.WaiterOption } if len(waitOpts) == 0 { log.Printf("No AWS timeout and polling overrides have been set. " + - "Packer will defalt to waiter-specific delays and timeouts. If you would " + + "Packer will default to waiter-specific delays and timeouts. If you would " + "like to customize the length of time between retries and max " + "number of retries you may do so by setting the environment " + "variables AWS_POLL_DELAY_SECONDS and AWS_MAX_ATTEMPTS to your " + From ce08eb8b7c3621bef708d22d91056998d38cda41 Mon Sep 17 00:00:00 2001 From: Patrick Double Date: Thu, 19 Jul 2018 20:41:26 -0500 Subject: [PATCH 134/220] Cleanup docs --- .../source/docs/post-processors/vagrant.html.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/website/source/docs/post-processors/vagrant.html.md b/website/source/docs/post-processors/vagrant.html.md index 35321172a..bc6e581bd 100644 --- a/website/source/docs/post-processors/vagrant.html.md +++ b/website/source/docs/post-processors/vagrant.html.md @@ -129,10 +129,13 @@ artifacts](/docs/templates/post-processors.html#toc_2) for more information. ### Docker -Using the Docker builder or one of the Docker post processors as an input -artifact will cause the `Vagrantfile` to include a reference to the image. For -post processors allowing a tag to be specified, such as `docker-import` or -`docker-tag`, the tag will be used. Otherwise, the sha256 hash will be used. +Using a Docker input artifact will include a reference to the image in the +`Vagrantfile`. If the image tag is not specified in the post-processor, the +sha256 hash will be used. -Note: Using the `docker` builder to save the image as a tar file cannot be used -to produce a Vagrant box. \ No newline at end of file +The following Docker input artifacts are supported: + + - `docker` builder with `commit: true`, always uses the sha256 hash + - `docker-import` + - `docker-tag` + - `docker-push` \ No newline at end of file From 431cbb2ad5d648f35bd63eb14255863225b9fe13 Mon Sep 17 00:00:00 2001 From: Anshul Sharma Date: Fri, 20 Jul 2018 09:04:49 +0300 Subject: [PATCH 135/220] Added Docs --- website/source/docs/builders/amazon-chroot.html.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/website/source/docs/builders/amazon-chroot.html.md b/website/source/docs/builders/amazon-chroot.html.md index 9c16fc320..116fd9ae5 100644 --- a/website/source/docs/builders/amazon-chroot.html.md +++ b/website/source/docs/builders/amazon-chroot.html.md @@ -254,6 +254,11 @@ each category, the available configuration keys are alphabetized. of the `source_ami` unless `from_scratch` is `true`, in which case this field must be defined. +- `root_volume_tags` (object of key/value strings) - Tags to apply to the volumes + that are *launched*. This is a + [template engine](/docs/templates/engine.html), + see [Build template data](#build-template-data) for more information. + - `skip_region_validation` (boolean) - Set to true if you want to skip validation of the `ami_regions` configuration option. Default `false`. From 4f9a91012f7586b74a18cf4042b0b0045e74f217 Mon Sep 17 00:00:00 2001 From: Patrick Double Date: Fri, 20 Jul 2018 15:27:29 -0500 Subject: [PATCH 136/220] Change docker-push to return docker-import artifact --- Makefile | 1 + post-processor/docker-push/post-processor.go | 10 +++++- .../docker-push/post-processor_test.go | 33 ++++++++++++------- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index b22d61e93..5203d31a2 100644 --- a/Makefile +++ b/Makefile @@ -43,6 +43,7 @@ package: @sh -c "$(CURDIR)/scripts/dist.sh $(VERSION)" deps: + @go get golang.org/x/tools/cmd/goimports @go get golang.org/x/tools/cmd/stringer @go get -u github.com/mna/pigeon @go get github.com/kardianos/govendor diff --git a/post-processor/docker-push/post-processor.go b/post-processor/docker-push/post-processor.go index f0fee00ca..2ffc3e5a5 100644 --- a/post-processor/docker-push/post-processor.go +++ b/post-processor/docker-push/post-processor.go @@ -12,6 +12,8 @@ import ( "github.com/hashicorp/packer/template/interpolate" ) +const BuilderIdImport = "packer.post-processor.docker-import" + type Config struct { common.PackerConfig `mapstructure:",squash"` @@ -103,5 +105,11 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac return nil, false, err } - return nil, false, nil + artifact = &docker.ImportArtifact{ + BuilderIdValue: BuilderIdImport, + Driver: driver, + IdValue: name, + } + + return artifact, true, nil } diff --git a/post-processor/docker-push/post-processor_test.go b/post-processor/docker-push/post-processor_test.go index d132595e5..1eee102cb 100644 --- a/post-processor/docker-push/post-processor_test.go +++ b/post-processor/docker-push/post-processor_test.go @@ -42,11 +42,11 @@ func TestPostProcessor_PostProcess(t *testing.T) { } result, keep, err := p.PostProcess(testUi(), artifact) - if result != nil { - t.Fatal("should be nil") + if _, ok := result.(packer.Artifact); !ok { + t.Fatal("should be instance of Artifact") } - if keep { - t.Fatal("should not keep") + if !keep { + t.Fatal("should keep") } if err != nil { t.Fatalf("err: %s", err) @@ -58,6 +58,9 @@ func TestPostProcessor_PostProcess(t *testing.T) { if driver.PushName != "foo/bar" { t.Fatal("bad name") } + if result.Id() != "foo/bar" { + t.Fatal("bad image id") + } } func TestPostProcessor_PostProcess_portInName(t *testing.T) { @@ -69,11 +72,11 @@ func TestPostProcessor_PostProcess_portInName(t *testing.T) { } result, keep, err := p.PostProcess(testUi(), artifact) - if result != nil { - t.Fatal("should be nil") + if _, ok := result.(packer.Artifact); !ok { + t.Fatal("should be instance of Artifact") } - if keep { - t.Fatal("should not keep") + if !keep { + t.Fatal("should keep") } if err != nil { t.Fatalf("err: %s", err) @@ -85,6 +88,9 @@ func TestPostProcessor_PostProcess_portInName(t *testing.T) { if driver.PushName != "localhost:5000/foo/bar" { t.Fatal("bad name") } + if result.Id() != "localhost:5000/foo/bar" { + t.Fatal("bad image id") + } } func TestPostProcessor_PostProcess_tags(t *testing.T) { @@ -96,11 +102,11 @@ func TestPostProcessor_PostProcess_tags(t *testing.T) { } result, keep, err := p.PostProcess(testUi(), artifact) - if result != nil { - t.Fatal("should be nil") + if _, ok := result.(packer.Artifact); !ok { + t.Fatal("should be instance of Artifact") } - if keep { - t.Fatal("should not keep") + if !keep { + t.Fatal("should keep") } if err != nil { t.Fatalf("err: %s", err) @@ -112,4 +118,7 @@ func TestPostProcessor_PostProcess_tags(t *testing.T) { if driver.PushName != "hashicorp/ubuntu:precise" { t.Fatalf("bad name: %s", driver.PushName) } + if result.Id() != "hashicorp/ubuntu:precise" { + t.Fatal("bad image id") + } } From a2f5fbadf65148fa4f678e13b49eaa190c5f2855 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Mon, 23 Jul 2018 09:54:08 -0700 Subject: [PATCH 137/220] don't fail if you can't find abs or relative path. --- common/iso_config.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/common/iso_config.go b/common/iso_config.go index 857c13f57..8736586dc 100644 --- a/common/iso_config.go +++ b/common/iso_config.go @@ -147,12 +147,14 @@ func (c *ISOConfig) parseCheckSumFile(rd *bufio.Reader) error { absPath, err := filepath.Abs(u.Path) if err != nil { - return fmt.Errorf("Unable to generate absolute path from provided iso_url: %s", err) + log.Printf("Unable to generate absolute path from provided iso_url: %s", err) + absPath = "" } relpath, err := filepath.Rel(filepath.Dir(checksumurl.Path), absPath) if err != nil { - return err + log.Printf("Unable to determine relative pathing; continuing with abspath.") + relpath = "" } filename := filepath.Base(u.Path) From 5ef8b555592cb26391183c1b3065229b17bfa43b Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Mon, 23 Jul 2018 10:34:05 -0700 Subject: [PATCH 138/220] need log import --- common/iso_config.go | 1 + 1 file changed, 1 insertion(+) diff --git a/common/iso_config.go b/common/iso_config.go index 8736586dc..4f30580bc 100644 --- a/common/iso_config.go +++ b/common/iso_config.go @@ -4,6 +4,7 @@ import ( "bufio" "errors" "fmt" + "log" "net/http" "net/url" "os" From 4495f93478c26177bd12b99af203d99a49680363 Mon Sep 17 00:00:00 2001 From: Matthew Hooker Date: Mon, 23 Jul 2018 13:53:22 -0700 Subject: [PATCH 139/220] update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d10296eb..e87c2e5da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ### IMPROVEMENTS: +* command/validate: Warn users if config needs fixing. [GH-6423] + ### BUG FIXES: ## 1.2.5 (July 16, 2018) From 8f1eb5a61b04371ba21aa0822eb2b294d5c5b834 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Mon, 23 Jul 2018 16:12:21 -0700 Subject: [PATCH 140/220] fix crash caused by invalid datacenter url --- post-processor/vsphere-template/post-processor.go | 1 + 1 file changed, 1 insertion(+) diff --git a/post-processor/vsphere-template/post-processor.go b/post-processor/vsphere-template/post-processor.go index bba5e33ea..deed5c2d7 100644 --- a/post-processor/vsphere-template/post-processor.go +++ b/post-processor/vsphere-template/post-processor.go @@ -76,6 +76,7 @@ func (p *PostProcessor) Configure(raws ...interface{}) error { if err != nil { errs = packer.MultiErrorAppend( errs, fmt.Errorf("Error invalid vSphere sdk endpoint: %s", err)) + return errs } sdk.User = url.UserPassword(p.config.Username, p.config.Password) From c1edcd3774964c59bcee111d57c06a644769db3e Mon Sep 17 00:00:00 2001 From: Anshul Sharma Date: Thu, 26 Jul 2018 09:30:51 +0300 Subject: [PATCH 141/220] amazon-ebssurrogate clean up volumes --- .../amazon/{ebs => common}/step_cleanup_volumes.go | 11 +++++------ builder/amazon/ebs/builder.go | 2 +- builder/amazon/ebssurrogate/builder.go | 3 +++ 3 files changed, 9 insertions(+), 7 deletions(-) rename builder/amazon/{ebs => common}/step_cleanup_volumes.go (90%) diff --git a/builder/amazon/ebs/step_cleanup_volumes.go b/builder/amazon/common/step_cleanup_volumes.go similarity index 90% rename from builder/amazon/ebs/step_cleanup_volumes.go rename to builder/amazon/common/step_cleanup_volumes.go index 3fd0de64f..f805681bf 100644 --- a/builder/amazon/ebs/step_cleanup_volumes.go +++ b/builder/amazon/common/step_cleanup_volumes.go @@ -1,4 +1,4 @@ -package ebs +package common import ( "context" @@ -6,7 +6,6 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" - "github.com/hashicorp/packer/builder/amazon/common" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) @@ -14,16 +13,16 @@ import ( // stepCleanupVolumes cleans up any orphaned volumes that were not designated to // remain after termination of the instance. These volumes are typically ones // that are marked as "delete on terminate:false" in the source_ami of a build. -type stepCleanupVolumes struct { - BlockDevices common.BlockDevices +type StepCleanupVolumes struct { + BlockDevices BlockDevices } -func (s *stepCleanupVolumes) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *StepCleanupVolumes) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { // stepCleanupVolumes is for Cleanup only return multistep.ActionContinue } -func (s *stepCleanupVolumes) Cleanup(state multistep.StateBag) { +func (s *StepCleanupVolumes) Cleanup(state multistep.StateBag) { ec2conn := state.Get("ec2").(*ec2.EC2) instanceRaw := state.Get("instance") var instance *ec2.Instance diff --git a/builder/amazon/ebs/builder.go b/builder/amazon/ebs/builder.go index bd10ad36a..f2c0bcbec 100644 --- a/builder/amazon/ebs/builder.go +++ b/builder/amazon/ebs/builder.go @@ -191,7 +191,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe VpcId: b.config.VpcId, TemporarySGSourceCidr: b.config.TemporarySGSourceCidr, }, - &stepCleanupVolumes{ + &awscommon.StepCleanupVolumes{ BlockDevices: b.config.BlockDevices, }, instanceStep, diff --git a/builder/amazon/ebssurrogate/builder.go b/builder/amazon/ebssurrogate/builder.go index 9642c1a83..e9cc8ad7d 100644 --- a/builder/amazon/ebssurrogate/builder.go +++ b/builder/amazon/ebssurrogate/builder.go @@ -208,6 +208,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe VpcId: b.config.VpcId, TemporarySGSourceCidr: b.config.TemporarySGSourceCidr, }, + &awscommon.StepCleanupVolumes{ + BlockDevices: b.config.BlockDevices, + }, instanceStep, &awscommon.StepGetPassword{ Debug: b.config.PackerDebug, From 887e6945345397dfa8f7efbf7da4c8cdad0013b4 Mon Sep 17 00:00:00 2001 From: rsclarke Date: Fri, 27 Jul 2018 20:24:06 +0800 Subject: [PATCH 142/220] add ssh agent support for qemu builder --- builder/qemu/ssh.go | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/builder/qemu/ssh.go b/builder/qemu/ssh.go index 9c565eb32..1ee44ddb0 100644 --- a/builder/qemu/ssh.go +++ b/builder/qemu/ssh.go @@ -1,10 +1,15 @@ package qemu import ( + "fmt" + "net" + "os" + commonssh "github.com/hashicorp/packer/common/ssh" - "github.com/hashicorp/packer/communicator/ssh" + packerssh "github.com/hashicorp/packer/communicator/ssh" "github.com/hashicorp/packer/helper/multistep" gossh "golang.org/x/crypto/ssh" + "golang.org/x/crypto/ssh/agent" ) func commHost(state multistep.StateBag) (string, error) { @@ -19,10 +24,29 @@ func commPort(state multistep.StateBag) (int, error) { func sshConfig(state multistep.StateBag) (*gossh.ClientConfig, error) { config := state.Get("config").(*Config) - auth := []gossh.AuthMethod{ - gossh.Password(config.Comm.SSHPassword), - gossh.KeyboardInteractive( - ssh.PasswordKeyboardInteractive(config.Comm.SSHPassword)), + var auth []gossh.AuthMethod + + if config.Comm.SSHAgentAuth { + authSock := os.Getenv("SSH_AUTH_SOCK") + if authSock == "" { + return nil, fmt.Errorf("SSH_AUTH_SOCK is not set") + } + + sshAgent, err := net.Dial("unix", authSock) + if err != nil { + return nil, fmt.Errorf("Cannot connect to SSH Agent socket %q: %s", authSock, err) + } + auth = []gossh.AuthMethod{ + gossh.PublicKeysCallback(agent.NewClient(sshAgent).Signers), + } + } + + if config.Comm.SSHPassword != "" { + auth = append(auth, + gossh.Password(config.Comm.SSHPassword), + gossh.KeyboardInteractive( + packerssh.PasswordKeyboardInteractive(config.Comm.SSHPassword)), + ) } if config.Comm.SSHPrivateKey != "" { From 71e43d0b7fc5e88bedac386db65631251cd8512c Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago Date: Sat, 28 Jul 2018 18:36:57 -0500 Subject: [PATCH 143/220] Updated common/download.go to handle when a connection error happens (response is nil), and reformatted the error that's returned when an HTTP error occurs. --- common/download.go | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/common/download.go b/common/download.go index 59d882b50..09457ef0b 100644 --- a/common/download.go +++ b/common/download.go @@ -278,12 +278,24 @@ func (d *HTTPDownloader) Download(dst *os.File, src *url.URL) error { } resp, err := httpClient.Do(req) - if err != nil { - log.Printf("[DEBUG] (download) Error making HTTP HEAD request: %s", err.Error()) + if err != nil || resp == nil { + + if resp == nil { + log.Printf("[DEBUG] (download) HTTP connection error: %s", err.Error()) + + } else if resp.StatusCode >= 400 && resp.StatusCode < 600 { + log.Printf("[DEBUG] (download) Non-successful HTTP status code (%s) while making HEAD request: %s", resp.Status, err.Error()) + + } else { + log.Printf("[DEBUG] (download) Error making HTTP HEAD request (%s): %s", resp.Status, err.Error()) + } + } else { + if resp.StatusCode >= 200 && resp.StatusCode < 300 { // If the HEAD request succeeded, then attempt to set the range // query if we can. + if resp.Header.Get("Accept-Ranges") == "bytes" { if fi, err := dst.Stat(); err == nil { if _, err = dst.Seek(0, os.SEEK_END); err == nil { @@ -293,6 +305,7 @@ func (d *HTTPDownloader) Download(dst *os.File, src *url.URL) error { } } } + } else { log.Printf("[DEBUG] (download) Unexpected HTTP response during HEAD request: %s", resp.Status) } @@ -302,12 +315,17 @@ func (d *HTTPDownloader) Download(dst *os.File, src *url.URL) error { req.Method = "GET" resp, err = httpClient.Do(req) - if err != nil { - return err - } else { - if resp.StatusCode >= 400 && resp.StatusCode < 600 { - return fmt.Errorf("Error making HTTP GET request: %s", resp.Status) + if err == nil && (resp.StatusCode >= 400 && resp.StatusCode < 600) { + return fmt.Errorf("Error making HTTP GET request: %s", resp.Status) + + } else if err != nil { + if resp == nil { + return fmt.Errorf("HTTP connection error: %s", err.Error()) + + } else if resp.StatusCode >= 400 && resp.StatusCode < 600 { + return fmt.Errorf("HTTP %s error: %s", resp.Status, err.Error()) } + return fmt.Errorf("HTTP error: %s", err.Error()) } d.total = d.current + uint64(resp.ContentLength) From a3cec4f274ec1182b66e697bb8faa4f4cbfceb4c Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago Date: Sun, 29 Jul 2018 02:18:26 -0500 Subject: [PATCH 144/220] Emit both the host and the communicator to the user during StepConnect. --- helper/communicator/step_connect.go | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/helper/communicator/step_connect.go b/helper/communicator/step_connect.go index 273935710..10adc5d2b 100644 --- a/helper/communicator/step_connect.go +++ b/helper/communicator/step_connect.go @@ -45,6 +45,8 @@ type StepConnect struct { } func (s *StepConnect) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + ui := state.Get("ui").(packer.Ui) + typeMap := map[string]multistep.Step{ "none": nil, "ssh": &StepConnectSSH{ @@ -71,19 +73,26 @@ func (s *StepConnect) Run(ctx context.Context, state multistep.StateBag) multist } if step == nil { - comm, err := none.New("none") - if err != nil { + if comm, err := none.New("none"); err != nil { err := fmt.Errorf("Failed to set communicator 'none': %s", err) state.Put("error", err) - ui := state.Get("ui").(packer.Ui) ui.Error(err.Error()) return multistep.ActionHalt + + } else { + state.Put("communicator", comm) + log.Printf("[INFO] communicator disabled, will not connect") } - state.Put("communicator", comm) - log.Printf("[INFO] communicator disabled, will not connect") return multistep.ActionContinue } + if host, err := s.Host(state); err == nil { + ui.Say(fmt.Sprintf("Using %s communicator to connect: %s", s.Config.Type, host)) + + } else { + log.Printf("[DEBUG] Unable to get address during connection step: %s", err) + } + s.substep = step return s.substep.Run(ctx, state) } From e5b740e22322e0e455c2b1f9584c64cc252bedb6 Mon Sep 17 00:00:00 2001 From: Omer Katz Date: Sun, 29 Jul 2018 13:16:41 +0300 Subject: [PATCH 145/220] Determine lxc root according to the running user. --- builder/lxc/step_lxc_create.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/builder/lxc/step_lxc_create.go b/builder/lxc/step_lxc_create.go index 0c89ce190..1526ed715 100644 --- a/builder/lxc/step_lxc_create.go +++ b/builder/lxc/step_lxc_create.go @@ -3,6 +3,8 @@ package lxc import ( "context" "fmt" + "log" + "os/user" "path/filepath" "github.com/hashicorp/packer/helper/multistep" @@ -19,6 +21,13 @@ func (s *stepLxcCreate) Run(_ context.Context, state multistep.StateBag) multist // TODO: read from env lxc_dir := "/var/lib/lxc" + user, err := user.Current() + if err != nil { + log.Print("Cannot find current user. Falling back to /var/lib/lxc...") + } + if user.Uid != "0" && user.HomeDir != "" { + lxc_dir = filepath.Join(user.HomeDir, ".local", "share", "lxc") + } rootfs := filepath.Join(lxc_dir, name, "rootfs") if config.PackerForce { From 808df82eeabe488eca28c5b11a3b38c595afdb8b Mon Sep 17 00:00:00 2001 From: Omer Katz Date: Sun, 29 Jul 2018 15:57:49 +0300 Subject: [PATCH 146/220] Remove privilege escalation with sudo when copying files. Preserve file permission mapping when copying files. --- builder/lxc/communicator.go | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/builder/lxc/communicator.go b/builder/lxc/communicator.go index 3a7505d1f..c52c95d72 100644 --- a/builder/lxc/communicator.go +++ b/builder/lxc/communicator.go @@ -59,7 +59,6 @@ func (c *LxcAttachCommunicator) Start(cmd *packer.RemoteCmd) error { } func (c *LxcAttachCommunicator) Upload(dst string, r io.Reader, fi *os.FileInfo) error { - dst = filepath.Join(c.RootFs, dst) log.Printf("Uploading to rootfs: %s", dst) tf, err := ioutil.TempFile("", "packer-lxc-attach") if err != nil { @@ -68,7 +67,11 @@ func (c *LxcAttachCommunicator) Upload(dst string, r io.Reader, fi *os.FileInfo) defer os.Remove(tf.Name()) io.Copy(tf, r) - cpCmd, err := c.CmdWrapper(fmt.Sprintf("sudo cp %s %s", tf.Name(), dst)) + attachCommand := []string{"cat", "%s", " | ", "lxc-attach"} + attachCommand = append(attachCommand, c.AttachOptions...) + attachCommand = append(attachCommand, []string{"--name", "%s", "--", "/bin/sh -c \"/bin/cat > %s\""}...) + + cpCmd, err := c.CmdWrapper(fmt.Sprintf(strings.Join(attachCommand, " "), tf.Name(), c.ContainerName, dst)) if err != nil { return err } @@ -78,14 +81,14 @@ func (c *LxcAttachCommunicator) Upload(dst string, r io.Reader, fi *os.FileInfo) // rename tempfile to match original file name. This makes sure that if file is being // moved into a directory, the filename is preserved instead of a temp name. adjustedTempName := filepath.Join(tfDir, (*fi).Name()) - mvCmd, err := c.CmdWrapper(fmt.Sprintf("sudo mv %s %s", tf.Name(), adjustedTempName)) + mvCmd, err := c.CmdWrapper(fmt.Sprintf("mv %s %s", tf.Name(), adjustedTempName)) if err != nil { return err } defer os.Remove(adjustedTempName) ShellCommand(mvCmd).Run() // change cpCmd to use new file name as source - cpCmd, err = c.CmdWrapper(fmt.Sprintf("sudo cp %s %s", adjustedTempName, dst)) + cpCmd, err = c.CmdWrapper(fmt.Sprintf(strings.Join(attachCommand, " "), adjustedTempName, c.ContainerName, dst)) if err != nil { return err } @@ -100,7 +103,7 @@ func (c *LxcAttachCommunicator) UploadDir(dst string, src string, exclude []stri // TODO: remove any file copied if it appears in `exclude` dest := filepath.Join(c.RootFs, dst) log.Printf("Uploading directory '%s' to rootfs '%s'", src, dest) - cpCmd, err := c.CmdWrapper(fmt.Sprintf("sudo cp -R %s/. %s", src, dest)) + cpCmd, err := c.CmdWrapper(fmt.Sprintf("cp -R %s/. %s", src, dest)) if err != nil { return err } @@ -131,7 +134,7 @@ func (c *LxcAttachCommunicator) DownloadDir(src string, dst string, exclude []st func (c *LxcAttachCommunicator) Execute(commandString string) (*exec.Cmd, error) { log.Printf("Executing with lxc-attach in container: %s %s %s", c.ContainerName, c.RootFs, commandString) - attachCommand := []string{"sudo", "lxc-attach"} + attachCommand := []string{"lxc-attach"} attachCommand = append(attachCommand, c.AttachOptions...) attachCommand = append(attachCommand, []string{"--name", "%s", "--", "/bin/sh -c \"%s\""}...) From 26dd6441e039d694b4c15936e0c253632adf1739 Mon Sep 17 00:00:00 2001 From: Omer Katz Date: Sun, 29 Jul 2018 16:14:17 +0300 Subject: [PATCH 147/220] Locate lxc root directory when exporting as well. --- builder/lxc/step_export.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/builder/lxc/step_export.go b/builder/lxc/step_export.go index ddfa85048..b6f5aca5f 100644 --- a/builder/lxc/step_export.go +++ b/builder/lxc/step_export.go @@ -4,7 +4,9 @@ import ( "context" "fmt" "io" + "log" "os" + "os/user" "path/filepath" "github.com/hashicorp/packer/helper/multistep" @@ -19,7 +21,16 @@ func (s *stepExport) Run(_ context.Context, state multistep.StateBag) multistep. name := config.ContainerName - containerDir := fmt.Sprintf("/var/lib/lxc/%s", name) + lxc_dir := "/var/lib/lxc" + user, err := user.Current() + if err != nil { + log.Print("Cannot find current user. Falling back to /var/lib/lxc...") + } + if user.Uid != "0" && user.HomeDir != "" { + lxc_dir = filepath.Join(user.HomeDir, ".local", "share", "lxc") + } + + containerDir := filepath.Join(lxc_dir, name) outputPath := filepath.Join(config.OutputDir, "rootfs.tar.gz") configFilePath := filepath.Join(config.OutputDir, "lxc-config") From 7081fe990b8b0ae9bc49b557a4769f97846ec9fb Mon Sep 17 00:00:00 2001 From: Mike Zupan Date: Mon, 30 Jul 2018 07:52:40 -0600 Subject: [PATCH 148/220] Adding in droplet tags on creation --- builder/digitalocean/config.go | 5 +++++ builder/digitalocean/step_create_droplet.go | 1 + 2 files changed, 6 insertions(+) diff --git a/builder/digitalocean/config.go b/builder/digitalocean/config.go index 6e58bc759..f2f389b7a 100644 --- a/builder/digitalocean/config.go +++ b/builder/digitalocean/config.go @@ -35,6 +35,7 @@ type Config struct { DropletName string `mapstructure:"droplet_name"` UserData string `mapstructure:"user_data"` UserDataFile string `mapstructure:"user_data_file"` + RunTags []string `mapstructure:"run_tags"` ctx interpolate.Context } @@ -121,6 +122,10 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { } } + if c.RunTags == nil { + c.RunTags = make([]string, 0) + } + if errs != nil && len(errs.Errors) > 0 { return nil, nil, errs } diff --git a/builder/digitalocean/step_create_droplet.go b/builder/digitalocean/step_create_droplet.go index d9c8976bf..a67e28e79 100644 --- a/builder/digitalocean/step_create_droplet.go +++ b/builder/digitalocean/step_create_droplet.go @@ -49,6 +49,7 @@ func (s *stepCreateDroplet) Run(_ context.Context, state multistep.StateBag) mul Monitoring: c.Monitoring, IPv6: c.IPv6, UserData: userData, + Tags: c.RunTags, }) if err != nil { err := fmt.Errorf("Error creating droplet: %s", err) From 11271ead5925fea25e829d47298946b3aa0c7a42 Mon Sep 17 00:00:00 2001 From: Mike Zupan Date: Mon, 30 Jul 2018 07:55:06 -0600 Subject: [PATCH 149/220] Change name to tags --- builder/digitalocean/config.go | 6 +++--- builder/digitalocean/step_create_droplet.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/builder/digitalocean/config.go b/builder/digitalocean/config.go index f2f389b7a..bb4175972 100644 --- a/builder/digitalocean/config.go +++ b/builder/digitalocean/config.go @@ -35,7 +35,7 @@ type Config struct { DropletName string `mapstructure:"droplet_name"` UserData string `mapstructure:"user_data"` UserDataFile string `mapstructure:"user_data_file"` - RunTags []string `mapstructure:"run_tags"` + Tags []string `mapstructure:"tags"` ctx interpolate.Context } @@ -122,8 +122,8 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { } } - if c.RunTags == nil { - c.RunTags = make([]string, 0) + if c.Tags == nil { + c.Tags = make([]string, 0) } if errs != nil && len(errs.Errors) > 0 { diff --git a/builder/digitalocean/step_create_droplet.go b/builder/digitalocean/step_create_droplet.go index a67e28e79..9c6c5712a 100644 --- a/builder/digitalocean/step_create_droplet.go +++ b/builder/digitalocean/step_create_droplet.go @@ -49,7 +49,7 @@ func (s *stepCreateDroplet) Run(_ context.Context, state multistep.StateBag) mul Monitoring: c.Monitoring, IPv6: c.IPv6, UserData: userData, - Tags: c.RunTags, + Tags: c.Tags, }) if err != nil { err := fmt.Errorf("Error creating droplet: %s", err) From 9247a3c56479ee9f871416e1e80db39a2ac2ade5 Mon Sep 17 00:00:00 2001 From: Mike Zupan Date: Mon, 30 Jul 2018 11:27:57 -0600 Subject: [PATCH 150/220] adding in th docs --- website/source/docs/builders/digitalocean.html.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/source/docs/builders/digitalocean.html.md b/website/source/docs/builders/digitalocean.html.md index 5683491df..6d5be6fb7 100644 --- a/website/source/docs/builders/digitalocean.html.md +++ b/website/source/docs/builders/digitalocean.html.md @@ -88,6 +88,8 @@ builder. - `user_data_file` (string) - Path to a file that will be used for the user data when launching the Droplet. +- `tags` (list) - Tags to apply to the droplet when it is created + ## Basic Example Here is a basic example. It is completely valid as soon as you enter your own From 38280ca90a975381380b2b0da6c5a64cc5fb8784 Mon Sep 17 00:00:00 2001 From: Matthew Hooker Date: Mon, 30 Jul 2018 16:28:35 -0700 Subject: [PATCH 151/220] fix markdown formatting --- website/source/community-tools.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/community-tools.html.md b/website/source/community-tools.html.md index 799373a1b..ed970e442 100644 --- a/website/source/community-tools.html.md +++ b/website/source/community-tools.html.md @@ -39,7 +39,7 @@ power of Packer templates. \- Ubuntu 16.04 minimal Vagrant Box using Ansible provisioner * [jakobadam/packer-qemu-templates](https://github.com/jakobadam/packer-qemu-templates) - - QEMU templates for various operating systems + \- QEMU templates for various operating systems ## Wrappers From f69ab4ed774528872fd8864a179d8d5357ec6f6e Mon Sep 17 00:00:00 2001 From: Felix Yan Date: Tue, 31 Jul 2018 15:19:45 +0800 Subject: [PATCH 152/220] Fix a typo in config_test.go --- builder/oracle/oci/config_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/oracle/oci/config_test.go b/builder/oracle/oci/config_test.go index 51cbb386d..a5b67d384 100644 --- a/builder/oracle/oci/config_test.go +++ b/builder/oracle/oci/config_test.go @@ -36,7 +36,7 @@ func testConfig(accessConfFile *os.File) map[string]interface{} { } func TestConfig(t *testing.T) { - // Shared set-up and defered deletion + // Shared set-up and deferred deletion cfg, keyFile, err := baseTestConfigWithTmpKeyFile() if err != nil { From 5fff424ad5fabc82f6fa6502d9613086ba7d5bb0 Mon Sep 17 00:00:00 2001 From: lmayorga Date: Tue, 31 Jul 2018 15:09:41 -0400 Subject: [PATCH 153/220] #6297 add a documentation note for windows 2016 images --- website/source/docs/builders/amazon-ebs.html.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/website/source/docs/builders/amazon-ebs.html.md b/website/source/docs/builders/amazon-ebs.html.md index 6b48621b4..065fe8bf0 100644 --- a/website/source/docs/builders/amazon-ebs.html.md +++ b/website/source/docs/builders/amazon-ebs.html.md @@ -480,3 +480,19 @@ up all residual volumes that are not designated by the user to remain after termination. If you need to preserve those source volumes, you can overwrite the termination setting by specifying `delete_on_termination=false` in the `launch_block_device_mappings` block for the device. + +## Windows 2016 Sysprep Commands + +For Windows 2016 Images it is necessary to run Sysprep commands which can be easily added +to the provisioner section. + +```json +{ + "type": "powershell", + "inline": [ + "C:/ProgramData/Amazon/EC2-Windows/Launch/Scripts/InitializeInstance.ps1 -Schedule", + "C:/ProgramData/Amazon/EC2-Windows/Launch/Scripts/SysprepInstance.ps1 -NoShutdown" + ] + +} +``` From e74706c7618b610102eb4d3f7378192b7b4557e6 Mon Sep 17 00:00:00 2001 From: Adam Robinson Date: Tue, 31 Jul 2018 16:08:07 -0400 Subject: [PATCH 154/220] update googlecompute docs on images from scratch --- website/source/docs/builders/googlecompute.html.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/website/source/docs/builders/googlecompute.html.md b/website/source/docs/builders/googlecompute.html.md index 005258f12..eb5fb58e2 100644 --- a/website/source/docs/builders/googlecompute.html.md +++ b/website/source/docs/builders/googlecompute.html.md @@ -13,10 +13,14 @@ Type: `googlecompute` The `googlecompute` Packer builder is able to create [images](https://developers.google.com/compute/docs/images) for use with [Google -Compute Engine](https://cloud.google.com/products/compute-engine)(GCE) based on -existing images. Building GCE images from scratch is not possible from Packer at -this time. For building images from scratch, please see -[Building GCE Images from Scratch](https://cloud.google.com/compute/docs/tutorials/building-images). +Compute Engine](https://cloud.google.com/products/compute-engine) (GCE) based on +existing images. + +Building images from scratch is possible, but not with the `googlecompute` Packer builder. +The process is recommended only for advanced users, please see [Building GCE Images from Scratch] +(https://cloud.google.com/compute/docs/tutorials/building-images) +and the [Google Compute Import Post-Processor](/docs/post-processors/googlecompute-import.html) +for more information. ## Authentication From 9ff41d40513d4b24b4f7eaf18f23b2965ce4560e Mon Sep 17 00:00:00 2001 From: lmayorga Date: Wed, 1 Aug 2018 08:45:38 -0400 Subject: [PATCH 155/220] update note restriction for amazon windows 2016 amis only --- website/source/docs/builders/amazon-ebs.html.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/source/docs/builders/amazon-ebs.html.md b/website/source/docs/builders/amazon-ebs.html.md index 065fe8bf0..9c5f816e7 100644 --- a/website/source/docs/builders/amazon-ebs.html.md +++ b/website/source/docs/builders/amazon-ebs.html.md @@ -481,9 +481,9 @@ termination. If you need to preserve those source volumes, you can overwrite the termination setting by specifying `delete_on_termination=false` in the `launch_block_device_mappings` block for the device. -## Windows 2016 Sysprep Commands +## Windows 2016 Sysprep Commands - For Amazon Windows AMIs Only -For Windows 2016 Images it is necessary to run Sysprep commands which can be easily added +For Amazon Windows 2016 AMIs it is necessary to run Sysprep commands which can be easily added to the provisioner section. ```json From a3e61530680a721f5bfd8481303fca072e4971d9 Mon Sep 17 00:00:00 2001 From: Christopher Boumenot Date: Tue, 31 Jul 2018 23:35:29 -0700 Subject: [PATCH 156/220] azure: implement clean_image_name --- builder/azure/arm/config.go | 8 ++-- builder/azure/arm/template_funcs.go | 43 +++++++++++++++++ builder/azure/arm/template_funcs_test.go | 49 ++++++++++++++++++++ website/source/docs/templates/engine.html.md | 20 ++++++++ 4 files changed, 116 insertions(+), 4 deletions(-) create mode 100644 builder/azure/arm/template_funcs.go create mode 100644 builder/azure/arm/template_funcs_test.go diff --git a/builder/azure/arm/config.go b/builder/azure/arm/config.go index 98e24dd81..1abc8d494 100644 --- a/builder/azure/arm/config.go +++ b/builder/azure/arm/config.go @@ -150,7 +150,7 @@ type Config struct { winrmCertificate string Comm communicator.Config `mapstructure:",squash"` - ctx *interpolate.Context + ctx interpolate.Context //Cleanup AsyncResourceGroupDelete bool `mapstructure:"async_resourcegroup_delete"` @@ -258,10 +258,10 @@ func (c *Config) createCertificate() (string, error) { func newConfig(raws ...interface{}) (*Config, []string, error) { var c Config - + c.ctx.Funcs = TemplateFuncs err := config.Decode(&c, &config.DecodeOpts{ Interpolate: true, - InterpolateContext: c.ctx, + InterpolateContext: &c.ctx, }, raws...) if err != nil { @@ -299,7 +299,7 @@ func newConfig(raws ...interface{}) (*Config, []string, error) { } var errs *packer.MultiError - errs = packer.MultiErrorAppend(errs, c.Comm.Prepare(c.ctx)...) + errs = packer.MultiErrorAppend(errs, c.Comm.Prepare(&c.ctx)...) assertRequiredParametersSet(&c, errs) assertTagProperties(&c, errs) diff --git a/builder/azure/arm/template_funcs.go b/builder/azure/arm/template_funcs.go new file mode 100644 index 000000000..7e0d6601f --- /dev/null +++ b/builder/azure/arm/template_funcs.go @@ -0,0 +1,43 @@ +package arm + +import ( + "bytes" + "text/template" +) + +func isValidByteValue(b byte) bool { + if '0' <= b && b <= '9' { + return true + } + if 'a' <= b && b <= 'z' { + return true + } + if 'A' <= b && b <= 'Z' { + return true + } + return b == '.' || b == '_' || b == '-' +} + +// Clean up image name by replacing invalid characters with "-" +// Names are not allowed to end in '.', '-', or '_' and are trimmed. +func templateCleanImageName(s string) string { + if ok, _ := assertManagedImageName(s, ""); ok { + return s + } + b := []byte(s) + newb := make([]byte, len(b)) + for i := range newb { + if isValidByteValue(b[i]) { + newb[i] = b[i] + } else { + newb[i] = '-' + } + } + + newb = bytes.TrimRight(newb, "-_.") + return string(newb) +} + +var TemplateFuncs = template.FuncMap{ + "clean_image_name": templateCleanImageName, +} diff --git a/builder/azure/arm/template_funcs_test.go b/builder/azure/arm/template_funcs_test.go new file mode 100644 index 000000000..68acefba8 --- /dev/null +++ b/builder/azure/arm/template_funcs_test.go @@ -0,0 +1,49 @@ +package arm + +import "testing" + +func TestTemplateCleanImageName(t *testing.T) { + vals := []struct { + origName string + expected string + }{ + // test that valid name is unchanged + { + origName: "abcde-012345xyz", + expected: "abcde-012345xyz", + }, + // test that colons are converted to hyphens + { + origName: "abcde-012345v1.0:0", + expected: "abcde-012345v1.0-0", + }, + // Name starting with number is not valid, but not in scope of this + // function to correct + { + origName: "012345v1.0:0", + expected: "012345v1.0-0", + }, + // Name over 80 chars is not valid, but not corrected by this function. + { + origName: "l012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789", + expected: "l012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789", + }, + // Name cannot end in a -Name over 80 chars is not valid, but not corrected by this function. + { + origName: "abcde-:_", + expected: "abcde", + }, + // Lost of special characters + { + origName: "My()./-_:&^ $%[]#'@name", + expected: "My--.--_-----------name", + }, + } + + for _, v := range vals { + name := templateCleanImageName(v.origName) + if name != v.expected { + t.Fatalf("template names do not match: expected %s got %s\n", v.expected, name) + } + } +} diff --git a/website/source/docs/templates/engine.html.md b/website/source/docs/templates/engine.html.md index dd5c9e0fe..f8dbc6468 100644 --- a/website/source/docs/templates/engine.html.md +++ b/website/source/docs/templates/engine.html.md @@ -73,6 +73,26 @@ Here is a full list of the available functions for reference. fail because the image name will start with a number, which is why in the above example we prepend the isotime with "mybuild". +#### Specific to Azure builders: + +- `clean_image_name` - Azure managed image names can only contain + certain characters and the maximum length is 80. This function + will replace illegal characters with a "-" character. Example: + + `"mybuild-{{isotime | clean_image_name}}"` will become + `mybuild-2017-10-18t02-06-30z`. + + Note: Valid Azure image names must match the regex + `^[^_\\W][\\w-._)]{0,79}$` + + This engine does not guarantee that the final image name will + match the regex; it will not truncate your name if it exceeds 80 + characters, and it will not validate that the beginning and end of + the engine's output are valid. It will truncate invalid + characters from the end of the name when converting illegal + characters. For example, `"managed_image_name: "My-Name::"` will + be converted to `"managed_image_name: "My-Name"` + ## Template variables Template variables are special variables automatically set by Packer at build time. Some builders, provisioners and other components have template variables that are available only for that component. Template variables are recognizable because they're prefixed by a period, such as `{{ .Name }}`. For example, when using the [`shell`](/docs/builders/vmware-iso.html) builder template variables are available to customize the [`execute_command`](/docs/provisioners/shell.html#execute_command) parameter used to determine how Packer will run the shell command. From 8458b60b24797ad0b0abe353c20452bee8b6badf Mon Sep 17 00:00:00 2001 From: Nye Liu Date: Thu, 2 Aug 2018 12:29:17 -0700 Subject: [PATCH 157/220] Document the `config` option to the lxd builder. --- website/source/docs/builders/lxd.html.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/source/docs/builders/lxd.html.md b/website/source/docs/builders/lxd.html.md index 4f8cf9c84..19e64375f 100644 --- a/website/source/docs/builders/lxd.html.md +++ b/website/source/docs/builders/lxd.html.md @@ -71,3 +71,5 @@ Below is a fully functioning example. set the description, but can be used to set anything needed. See https://stgraber.org/2016/03/30/lxd-2-0-image-management-512/ for more properties. + + - `config` (map) - List of key/value pairs you wish to pass to `lxc launch` via `--config`. Defaults to empty. From 6d6212b75efc1ec0467fdc39bc26003613f89fec Mon Sep 17 00:00:00 2001 From: Nye Liu Date: Thu, 2 Aug 2018 19:37:53 +0000 Subject: [PATCH 158/220] Fix issue #6561 - Pass "--config" option correctly to "lxc launch" --- builder/lxd/step_lxd_launch.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/lxd/step_lxd_launch.go b/builder/lxd/step_lxd_launch.go index 55b7e4954..a2baf2b11 100644 --- a/builder/lxd/step_lxd_launch.go +++ b/builder/lxd/step_lxd_launch.go @@ -26,7 +26,7 @@ func (s *stepLxdLaunch) Run(_ context.Context, state multistep.StateBag) multist } for k, v := range config.LaunchConfig { - launch_args = append(launch_args, fmt.Sprintf("--config %s=%s", k, v)) + launch_args = append(launch_args, "--config", fmt.Sprintf("%s=%s", k, v)) } ui.Say("Creating container...") From 80bd3b99d099a298605a2f91a459dfdb54b81373 Mon Sep 17 00:00:00 2001 From: Nye Liu Date: Thu, 2 Aug 2018 20:05:42 +0000 Subject: [PATCH 159/220] Fix typo, cosmetic whitespace --- website/source/docs/builders/lxd.html.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/website/source/docs/builders/lxd.html.md b/website/source/docs/builders/lxd.html.md index 19e64375f..94423c063 100644 --- a/website/source/docs/builders/lxd.html.md +++ b/website/source/docs/builders/lxd.html.md @@ -66,10 +66,11 @@ Below is a fully functioning example. - `command_wrapper` (string) - Lets you prefix all builder commands, such as with `ssh` for a remote build host. Defaults to `""`. -- `publish_properties` (map[string]string) - Pass key values to the publish +- `publish_properties` (map[string]string) - Pass key values to the publish step to be set as properties on the output image. This is most helpful to set the description, but can be used to set anything needed. See https://stgraber.org/2016/03/30/lxd-2-0-image-management-512/ for more properties. - - `config` (map) - List of key/value pairs you wish to pass to `lxc launch` via `--config`. Defaults to empty. +- `launch_config` (map[string]string) - List of key/value pairs you wish to + pass to `lxc launch` via `--config`. Defaults to empty. From 5f9d4b729fb76b9da0d4e7250d0c98cf92ec6116 Mon Sep 17 00:00:00 2001 From: chbell43 Date: Fri, 3 Aug 2018 20:46:36 +0000 Subject: [PATCH 160/220] add support for ports to the OpenStack builder For networks that have multiple subnets, we may want to target a single subnet. OpenStack doesn't let you target a single subnet in a network and so you need to make a port. --- builder/openstack/builder.go | 1 + builder/openstack/run_config.go | 1 + builder/openstack/step_run_source_server.go | 15 ++++++++++++--- website/source/docs/builders/openstack.html.md | 3 +++ 4 files changed, 17 insertions(+), 3 deletions(-) mode change 100755 => 100644 builder/openstack/builder.go diff --git a/builder/openstack/builder.go b/builder/openstack/builder.go old mode 100755 new mode 100644 index a718c3d59..8ebd65d3c --- a/builder/openstack/builder.go +++ b/builder/openstack/builder.go @@ -92,6 +92,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe SourceImageName: b.config.SourceImageName, SecurityGroups: b.config.SecurityGroups, Networks: b.config.Networks, + Ports: b.config.Ports, AvailabilityZone: b.config.AvailabilityZone, UserData: b.config.UserData, UserDataFile: b.config.UserDataFile, diff --git a/builder/openstack/run_config.go b/builder/openstack/run_config.go index 6b4e0932e..2562e0c8d 100644 --- a/builder/openstack/run_config.go +++ b/builder/openstack/run_config.go @@ -28,6 +28,7 @@ type RunConfig struct { ReuseIps bool `mapstructure:"reuse_ips"` SecurityGroups []string `mapstructure:"security_groups"` Networks []string `mapstructure:"networks"` + Ports []string `mapstructure:"ports"` UserData string `mapstructure:"user_data"` UserDataFile string `mapstructure:"user_data_file"` InstanceName string `mapstructure:"instance_name"` diff --git a/builder/openstack/step_run_source_server.go b/builder/openstack/step_run_source_server.go index bb09f85b7..0cab455cf 100644 --- a/builder/openstack/step_run_source_server.go +++ b/builder/openstack/step_run_source_server.go @@ -18,6 +18,7 @@ type StepRunSourceServer struct { SourceImageName string SecurityGroups []string Networks []string + Ports []string AvailabilityZone string UserData string UserDataFile string @@ -39,9 +40,17 @@ func (s *StepRunSourceServer) Run(_ context.Context, state multistep.StateBag) m return multistep.ActionHalt } - networks := make([]servers.Network, len(s.Networks)) - for i, networkUuid := range s.Networks { - networks[i].UUID = networkUuid + networks := make([]servers.Network, len(s.Networks) + len(s.Ports)) + i := 0 + if len(s.Ports) > 0 { + for i = 0; i < len(s.Ports); i++ { + networks[i].Port = s.Ports[i] + } + } + if len(s.Networks) > 0 { + for i = len(s.Ports); i < len(networks); i++ { + networks[i].UUID = s.Networks[i] + } } userData := []byte(s.UserData) diff --git a/website/source/docs/builders/openstack.html.md b/website/source/docs/builders/openstack.html.md index c6059da50..00f5e46dd 100644 --- a/website/source/docs/builders/openstack.html.md +++ b/website/source/docs/builders/openstack.html.md @@ -139,6 +139,9 @@ builder. - `networks` (array of strings) - A list of networks by UUID to attach to this instance. +- `ports` (array of strings) - A list of ports by UUID to attach to + this instance. + - `rackconnect_wait` (boolean) - For rackspace, whether or not to wait for Rackconnect to assign the machine an IP address before connecting via SSH. Defaults to false. From aaa42543e6fcab795190aee632309889897a4b83 Mon Sep 17 00:00:00 2001 From: chbell43 Date: Fri, 3 Aug 2018 21:32:34 +0000 Subject: [PATCH 161/220] fix formatting --- builder/openstack/step_run_source_server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/openstack/step_run_source_server.go b/builder/openstack/step_run_source_server.go index 0cab455cf..b905c05c3 100644 --- a/builder/openstack/step_run_source_server.go +++ b/builder/openstack/step_run_source_server.go @@ -40,7 +40,7 @@ func (s *StepRunSourceServer) Run(_ context.Context, state multistep.StateBag) m return multistep.ActionHalt } - networks := make([]servers.Network, len(s.Networks) + len(s.Ports)) + networks := make([]servers.Network, len(s.Networks)+len(s.Ports)) i := 0 if len(s.Ports) > 0 { for i = 0; i < len(s.Ports); i++ { From eb685b7140a849f63cd6dcbc5a5ba59a98b75ad1 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Tue, 7 Aug 2018 10:01:06 -0700 Subject: [PATCH 162/220] remove duplicate code from chef provisioner --- provisioner/chef-client/provisioner.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/provisioner/chef-client/provisioner.go b/provisioner/chef-client/provisioner.go index 13575f731..8a3bff170 100644 --- a/provisioner/chef-client/provisioner.go +++ b/provisioner/chef-client/provisioner.go @@ -174,15 +174,6 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { } } - if p.config.EncryptedDataBagSecretPath != "" { - pFileInfo, err := os.Stat(p.config.EncryptedDataBagSecretPath) - - if err != nil || pFileInfo.IsDir() { - errs = packer.MultiErrorAppend( - errs, fmt.Errorf("Bad encrypted data bag secret '%s': %s", p.config.EncryptedDataBagSecretPath, err)) - } - } - if p.config.ServerUrl == "" { errs = packer.MultiErrorAppend( errs, fmt.Errorf("server_url must be set")) From d796edc783f346b2532c23f284af991e90e12b05 Mon Sep 17 00:00:00 2001 From: Patrick Double Date: Wed, 8 Aug 2018 10:04:28 -0500 Subject: [PATCH 163/220] Add to vagrant post-processor support for Azure --- builder/azure/arm/artifact.go | 13 ++- builder/azure/arm/artifact_test.go | 28 ++++-- builder/azure/arm/builder.go | 11 ++- packer/artifact_mock.go | 9 +- post-processor/vagrant/azure.go | 67 +++++++++++++ post-processor/vagrant/azure_test.go | 94 +++++++++++++++++++ post-processor/vagrant/post-processor.go | 3 + .../docs/post-processors/vagrant.html.md | 2 + 8 files changed, 213 insertions(+), 14 deletions(-) create mode 100644 post-processor/vagrant/azure.go create mode 100644 post-processor/vagrant/azure_test.go diff --git a/builder/azure/arm/artifact.go b/builder/azure/arm/artifact.go index 8e42fa43d..f7e63d6c4 100644 --- a/builder/azure/arm/artifact.go +++ b/builder/azure/arm/artifact.go @@ -18,6 +18,9 @@ type AdditionalDiskArtifact struct { } type Artifact struct { + // OS type: Linux, Windows + OSType string + // VHD StorageAccountLocation string OSDiskUri string @@ -29,20 +32,23 @@ type Artifact struct { ManagedImageResourceGroupName string ManagedImageName string ManagedImageLocation string + ManagedImageId string // Additional Disks AdditionalDisks *[]AdditionalDiskArtifact } -func NewManagedImageArtifact(resourceGroup, name, location string) (*Artifact, error) { +func NewManagedImageArtifact(osType, resourceGroup, name, location, id string) (*Artifact, error) { return &Artifact{ ManagedImageResourceGroupName: resourceGroup, ManagedImageName: name, ManagedImageLocation: location, + ManagedImageId: id, + OSType: osType, }, nil } -func NewArtifact(template *CaptureTemplate, getSasUrl func(name string) string) (*Artifact, error) { +func NewArtifact(template *CaptureTemplate, getSasUrl func(name string) string, osType string) (*Artifact, error) { if template == nil { return nil, fmt.Errorf("nil capture template") } @@ -76,6 +82,7 @@ func NewArtifact(template *CaptureTemplate, getSasUrl func(name string) string) } return &Artifact{ + OSType: osType, OSDiskUri: vhdUri.String(), OSDiskUriReadOnlySas: getSasUrl(getStorageUrlPath(vhdUri)), TemplateUri: templateUri.String(), @@ -142,9 +149,11 @@ func (a *Artifact) String() string { var buf bytes.Buffer buf.WriteString(fmt.Sprintf("%s:\n\n", a.BuilderId())) + buf.WriteString(fmt.Sprintf("OSType: %s\n", a.OSType)) if a.isManagedImage() { buf.WriteString(fmt.Sprintf("ManagedImageResourceGroupName: %s\n", a.ManagedImageResourceGroupName)) buf.WriteString(fmt.Sprintf("ManagedImageName: %s\n", a.ManagedImageName)) + buf.WriteString(fmt.Sprintf("ManagedImageId: %s\n", a.ManagedImageId)) buf.WriteString(fmt.Sprintf("ManagedImageLocation: %s\n", a.ManagedImageLocation)) } else { buf.WriteString(fmt.Sprintf("StorageAccountLocation: %s\n", a.StorageAccountLocation)) diff --git a/builder/azure/arm/artifact_test.go b/builder/azure/arm/artifact_test.go index a86a6353e..a65427897 100644 --- a/builder/azure/arm/artifact_test.go +++ b/builder/azure/arm/artifact_test.go @@ -28,7 +28,7 @@ func TestArtifactId(t *testing.T) { }, } - artifact, err := NewArtifact(&template, getFakeSasUrl) + artifact, err := NewArtifact(&template, getFakeSasUrl, "Linux") if err != nil { t.Fatalf("err=%s", err) } @@ -59,7 +59,7 @@ func TestArtifactString(t *testing.T) { }, } - artifact, err := NewArtifact(&template, getFakeSasUrl) + artifact, err := NewArtifact(&template, getFakeSasUrl, "Linux") if err != nil { t.Fatalf("err=%s", err) } @@ -80,6 +80,9 @@ func TestArtifactString(t *testing.T) { if !strings.Contains(testSubject, "StorageAccountLocation: southcentralus") { t.Errorf("Expected String() output to contain StorageAccountLocation") } + if !strings.Contains(testSubject, "OSType: Linux") { + t.Errorf("Expected String() output to contain OSType") + } } func TestAdditionalDiskArtifactString(t *testing.T) { @@ -107,7 +110,7 @@ func TestAdditionalDiskArtifactString(t *testing.T) { }, } - artifact, err := NewArtifact(&template, getFakeSasUrl) + artifact, err := NewArtifact(&template, getFakeSasUrl, "Linux") if err != nil { t.Fatalf("err=%s", err) } @@ -128,6 +131,9 @@ func TestAdditionalDiskArtifactString(t *testing.T) { if !strings.Contains(testSubject, "StorageAccountLocation: southcentralus") { t.Errorf("Expected String() output to contain StorageAccountLocation") } + if !strings.Contains(testSubject, "OSType: Linux") { + t.Errorf("Expected String() output to contain OSType") + } if !strings.Contains(testSubject, "AdditionalDiskUri (datadisk-1): https://storage.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-datadisk-1.4085bb15-3644-4641-b9cd-f575918640b4.vhd") { t.Errorf("Expected String() output to contain AdditionalDiskUri") } @@ -154,7 +160,7 @@ func TestArtifactProperties(t *testing.T) { }, } - testSubject, err := NewArtifact(&template, getFakeSasUrl) + testSubject, err := NewArtifact(&template, getFakeSasUrl, "Linux") if err != nil { t.Fatalf("err=%s", err) } @@ -174,6 +180,9 @@ func TestArtifactProperties(t *testing.T) { if testSubject.StorageAccountLocation != "southcentralus" { t.Errorf("Expected StorageAccountLocation to be 'southcentral', but got %s", testSubject.StorageAccountLocation) } + if testSubject.OSType != "Linux" { + t.Errorf("Expected OSType to be 'Linux', but got %s", testSubject.OSType) + } } func TestAdditionalDiskArtifactProperties(t *testing.T) { @@ -201,7 +210,7 @@ func TestAdditionalDiskArtifactProperties(t *testing.T) { }, } - testSubject, err := NewArtifact(&template, getFakeSasUrl) + testSubject, err := NewArtifact(&template, getFakeSasUrl, "Linux") if err != nil { t.Fatalf("err=%s", err) } @@ -221,6 +230,9 @@ func TestAdditionalDiskArtifactProperties(t *testing.T) { if testSubject.StorageAccountLocation != "southcentralus" { t.Errorf("Expected StorageAccountLocation to be 'southcentral', but got %s", testSubject.StorageAccountLocation) } + if testSubject.OSType != "Linux" { + t.Errorf("Expected OSType to be 'Linux', but got %s", testSubject.OSType) + } if testSubject.AdditionalDisks == nil { t.Errorf("Expected AdditionalDisks to be not nil") } @@ -253,7 +265,7 @@ func TestArtifactOverHyphenatedCaptureUri(t *testing.T) { }, } - testSubject, err := NewArtifact(&template, getFakeSasUrl) + testSubject, err := NewArtifact(&template, getFakeSasUrl, "Linux") if err != nil { t.Fatalf("err=%s", err) } @@ -266,7 +278,7 @@ func TestArtifactOverHyphenatedCaptureUri(t *testing.T) { func TestArtifactRejectMalformedTemplates(t *testing.T) { template := CaptureTemplate{} - _, err := NewArtifact(&template, getFakeSasUrl) + _, err := NewArtifact(&template, getFakeSasUrl, "Linux") if err == nil { t.Fatalf("Expected artifact creation to fail, but it succeeded.") } @@ -289,7 +301,7 @@ func TestArtifactRejectMalformedStorageUri(t *testing.T) { }, } - _, err := NewArtifact(&template, getFakeSasUrl) + _, err := NewArtifact(&template, getFakeSasUrl, "Linux") if err == nil { t.Fatalf("Expected artifact creation to fail, but it succeeded.") } diff --git a/builder/azure/arm/builder.go b/builder/azure/arm/builder.go index 23d3d2181..03c6801cf 100644 --- a/builder/azure/arm/builder.go +++ b/builder/azure/arm/builder.go @@ -254,8 +254,14 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe return nil, errors.New("Build was halted.") } + osType := "Linux" + if b.config.OSType == constants.Target_Windows { + osType = "Windows" + } + if b.config.isManagedImage() { - return NewManagedImageArtifact(b.config.ManagedImageResourceGroupName, b.config.ManagedImageName, b.config.manageImageLocation) + managedImageID := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/images/%s", b.config.SubscriptionID, b.config.ManagedImageResourceGroupName, b.config.ManagedImageName) + return NewManagedImageArtifact(osType, b.config.ManagedImageResourceGroupName, b.config.ManagedImageName, b.config.manageImageLocation, managedImageID) } else if template, ok := b.stateBag.GetOk(constants.ArmCaptureTemplate); ok { return NewArtifact( template.(*CaptureTemplate), @@ -266,7 +272,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe options.Expiry = time.Now().AddDate(0, 1, 0).UTC() // one month sasUrl, _ := blob.GetSASURI(options) return sasUrl - }) + }, + osType) } return &Artifact{}, nil diff --git a/packer/artifact_mock.go b/packer/artifact_mock.go index 18f4e562f..737032447 100644 --- a/packer/artifact_mock.go +++ b/packer/artifact_mock.go @@ -7,6 +7,7 @@ type MockArtifact struct { IdValue string StateValues map[string]interface{} DestroyCalled bool + StringValue string } func (a *MockArtifact) BuilderId() string { @@ -34,8 +35,12 @@ func (a *MockArtifact) Id() string { return id } -func (*MockArtifact) String() string { - return "string" +func (a *MockArtifact) String() string { + str := a.StringValue + if str == "" { + str = "string" + } + return str } func (a *MockArtifact) State(name string) interface{} { diff --git a/post-processor/vagrant/azure.go b/post-processor/vagrant/azure.go new file mode 100644 index 000000000..031e70259 --- /dev/null +++ b/post-processor/vagrant/azure.go @@ -0,0 +1,67 @@ +package vagrant + +import ( + "fmt" + "strings" + + "github.com/hashicorp/packer/packer" +) + +type AzureProvider struct{} + +func (p *AzureProvider) KeepInputArtifact() bool { + return true +} + +func (p *AzureProvider) Process(ui packer.Ui, artifact packer.Artifact, dir string) (vagrantfile string, metadata map[string]interface{}, err error) { + // Create the metadata + metadata = map[string]interface{}{"provider": "azure"} + + var AzureImageProps map[string]string + AzureImageProps = make(map[string]string) + + // HACK(double16): It appears we can not access the Azure Artifact directly, so parse String() + artifactString := artifact.String() + ui.Message(fmt.Sprintf("artifact string: '%s'", artifactString)) + lines := strings.Split(artifactString, "\n") + for l := 0; l < len(lines); l++ { + split := strings.Split(lines[l], ": ") + if len(split) > 1 { + AzureImageProps[strings.TrimSpace(split[0])] = strings.TrimSpace(split[1]) + } + } + ui.Message(fmt.Sprintf("artifact string parsed: %+v", AzureImageProps)) + + if AzureImageProps["ManagedImageId"] != "" { + vagrantfile = fmt.Sprintf(managedImageVagrantfile, AzureImageProps["ManagedImageLocation"], AzureImageProps["ManagedImageId"]) + } else if AzureImageProps["OSDiskUri"] != "" { + vagrantfile = fmt.Sprintf(vhdVagrantfile, AzureImageProps["StorageAccountLocation"], AzureImageProps["OSDiskUri"], AzureImageProps["OSType"]) + } else { + err = fmt.Errorf("No managed image nor VHD URI found in artifact: %s", artifactString) + return + } + return +} + +var managedImageVagrantfile = ` +Vagrant.configure("2") do |config| + config.vm.provider :azure do |azure, override| + azure.location = "%s" + azure.vm_managed_image_id = "%s" + override.winrm.transport = :ssl + override.winrm.port = 5986 + end +end +` + +var vhdVagrantfile = ` +Vagrant.configure("2") do |config| + config.vm.provider :azure do |azure, override| + azure.location = "%s" + azure.vm_vhd_uri = "%s" + azure.vm_operating_system = "%s" + override.winrm.transport = :ssl + override.winrm.port = 5986 + end +end +` diff --git a/post-processor/vagrant/azure_test.go b/post-processor/vagrant/azure_test.go new file mode 100644 index 000000000..7521f4405 --- /dev/null +++ b/post-processor/vagrant/azure_test.go @@ -0,0 +1,94 @@ +package vagrant + +import ( + "strings" + "testing" + + "github.com/hashicorp/packer/packer" +) + +func TestAzureProvider_impl(t *testing.T) { + var _ Provider = new(AzureProvider) +} + +func TestAzureProvider_KeepInputArtifact(t *testing.T) { + p := new(AzureProvider) + + if !p.KeepInputArtifact() { + t.Fatal("should keep input artifact") + } +} + +func TestAzureProvider_ManagedImage(t *testing.T) { + p := new(AzureProvider) + ui := testUi() + artifact := &packer.MockArtifact{ + StringValue: `Azure.ResourceManagement.VMImage: + +OSType: Linux +ManagedImageResourceGroupName: packerruns +ManagedImageName: packer-1533651633 +ManagedImageId: /subscriptions/e6229913-d9c3-4ddd-99a4-9e1ef3beaa1b/resourceGroups/packerruns/providers/Microsoft.Compute/images/packer-1533675589 +ManagedImageLocation: westus`, + } + + vagrantfile, _, err := p.Process(ui, artifact, "foo") + if err != nil { + t.Fatalf("should not have error: %s", err) + } + result := `azure.location = "westus"` + if !strings.Contains(vagrantfile, result) { + t.Fatalf("wrong substitution: %s", vagrantfile) + } + result = `azure.vm_managed_image_id = "/subscriptions/e6229913-d9c3-4ddd-99a4-9e1ef3beaa1b/resourceGroups/packerruns/providers/Microsoft.Compute/images/packer-1533675589"` + if !strings.Contains(vagrantfile, result) { + t.Fatalf("wrong substitution: %s", vagrantfile) + } + // DO NOT set resource group in Vagrantfile, it should be separate from the image + result = `azure.resource_group_name` + if strings.Contains(vagrantfile, result) { + t.Fatalf("wrong substitution: %s", vagrantfile) + } + result = `azure.vm_operating_system` + if strings.Contains(vagrantfile, result) { + t.Fatalf("wrong substitution: %s", vagrantfile) + } +} + +func TestAzureProvider_VHD(t *testing.T) { + p := new(AzureProvider) + ui := testUi() + artifact := &packer.MockArtifact{ + IdValue: "https://packerbuildswest.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-osDisk.96ed2120-591d-4900-95b0-ee8e985f2213.vhd", + StringValue: `Azure.ResourceManagement.VMImage: + + OSType: Linux + StorageAccountLocation: westus + OSDiskUri: https://packerbuildswest.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-osDisk.96ed2120-591d-4900-95b0-ee8e985f2213.vhd + OSDiskUriReadOnlySas: https://packerbuildswest.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-osDisk.96ed2120-591d-4900-95b0-ee8e985f2213.vhd?se=2018-09-07T18%3A36%3A34Z&sig=xUiFvwAviPYoP%2Bc91vErqvwYR1eK4x%2BAx7YLMe84zzU%3D&sp=r&sr=b&sv=2016-05-31 + TemplateUri: https://packerbuildswest.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-vmTemplate.96ed2120-591d-4900-95b0-ee8e985f2213.json + TemplateUriReadOnlySas: https://packerbuildswest.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-vmTemplate.96ed2120-591d-4900-95b0-ee8e985f2213.json?se=2018-09-07T18%3A36%3A34Z&sig=lDxePyAUCZbfkB5ddiofimXfwk5INn%2F9E2BsnqIKC9Q%3D&sp=r&sr=b&sv=2016-05-31`, + } + + vagrantfile, _, err := p.Process(ui, artifact, "foo") + if err != nil { + t.Fatalf("should not have error: %s", err) + } + result := `azure.location = "westus"` + if !strings.Contains(vagrantfile, result) { + t.Fatalf("wrong substitution: %s", vagrantfile) + } + result = `azure.vm_vhd_uri = "https://packerbuildswest.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-osDisk.96ed2120-591d-4900-95b0-ee8e985f2213.vhd"` + if !strings.Contains(vagrantfile, result) { + t.Fatalf("wrong substitution: %s", vagrantfile) + } + result = `azure.vm_operating_system = "Linux"` + if !strings.Contains(vagrantfile, result) { + t.Fatalf("wrong substitution: %s", vagrantfile) + } + // DO NOT set resource group in Vagrantfile, it should be separate from the image + result = `azure.resource_group_name` + if strings.Contains(vagrantfile, result) { + t.Fatalf("wrong substitution: %s", vagrantfile) + } +} diff --git a/post-processor/vagrant/post-processor.go b/post-processor/vagrant/post-processor.go index 1aab0ca23..5ea07f3a3 100644 --- a/post-processor/vagrant/post-processor.go +++ b/post-processor/vagrant/post-processor.go @@ -31,6 +31,7 @@ var builtins = map[string]string{ "MSOpenTech.hyperv": "hyperv", "transcend.qemu": "libvirt", "ustream.lxc": "lxc", + "Azure.ResourceManagement.VMImage": "azure", "packer.post-processor.docker-import": "docker", "packer.post-processor.docker-tag": "docker", "packer.post-processor.docker-push": "docker", @@ -244,6 +245,8 @@ func providerForName(name string) Provider { return new(GoogleProvider) case "lxc": return new(LXCProvider) + case "azure": + return new(AzureProvider) case "docker": return new(DockerProvider) default: diff --git a/website/source/docs/post-processors/vagrant.html.md b/website/source/docs/post-processors/vagrant.html.md index bc6e581bd..260339e7f 100644 --- a/website/source/docs/post-processors/vagrant.html.md +++ b/website/source/docs/post-processors/vagrant.html.md @@ -33,6 +33,7 @@ providers. - AWS - DigitalOcean - Google +- Azure - Hyper-V - LXC - Parallels @@ -108,6 +109,7 @@ The available provider names are: - `aws` - `digitalocean` - `google` +- `azure` - `hyperv` - `parallels` - `libvirt` From 2868971a9ba7dd13162a0720eea64ed4e34b6329 Mon Sep 17 00:00:00 2001 From: Patrick Double Date: Thu, 9 Aug 2018 07:14:14 -0500 Subject: [PATCH 164/220] Fixes per code review --- builder/azure/arm/builder.go | 9 ++------- website/source/docs/post-processors/vagrant.html.md | 4 ++-- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/builder/azure/arm/builder.go b/builder/azure/arm/builder.go index 03c6801cf..ed42f2ac3 100644 --- a/builder/azure/arm/builder.go +++ b/builder/azure/arm/builder.go @@ -254,14 +254,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe return nil, errors.New("Build was halted.") } - osType := "Linux" - if b.config.OSType == constants.Target_Windows { - osType = "Windows" - } - if b.config.isManagedImage() { managedImageID := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/images/%s", b.config.SubscriptionID, b.config.ManagedImageResourceGroupName, b.config.ManagedImageName) - return NewManagedImageArtifact(osType, b.config.ManagedImageResourceGroupName, b.config.ManagedImageName, b.config.manageImageLocation, managedImageID) + return NewManagedImageArtifact(b.config.OSType, b.config.ManagedImageResourceGroupName, b.config.ManagedImageName, b.config.manageImageLocation, managedImageID) } else if template, ok := b.stateBag.GetOk(constants.ArmCaptureTemplate); ok { return NewArtifact( template.(*CaptureTemplate), @@ -273,7 +268,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe sasUrl, _ := blob.GetSASURI(options) return sasUrl }, - osType) + b.config.OSType) } return &Artifact{}, nil diff --git a/website/source/docs/post-processors/vagrant.html.md b/website/source/docs/post-processors/vagrant.html.md index 260339e7f..632c080f5 100644 --- a/website/source/docs/post-processors/vagrant.html.md +++ b/website/source/docs/post-processors/vagrant.html.md @@ -31,8 +31,8 @@ Currently, the Vagrant post-processor can create boxes for the following providers. - AWS +- Azure - DigitalOcean -- Google - Azure - Hyper-V - LXC @@ -107,9 +107,9 @@ where it will be set to 0. The available provider names are: - `aws` +- `azure` - `digitalocean` - `google` -- `azure` - `hyperv` - `parallels` - `libvirt` From 51b9065497b53b583d0951e894016c5c1300b3c2 Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Mon, 13 Aug 2018 12:40:42 +0200 Subject: [PATCH 165/220] split go and packer dev setups --- .github/CONTRIBUTING.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index e0c51bc78..b68e3dfbd 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -67,26 +67,28 @@ export GOPATH=$HOME/go export PATH=$PATH:$GOPATH/bin ``` -3. Download the Packer source (and its dependencies) by running +## Setting up Packer for dev + +1. Download the Packer source (and its dependencies) by running `go get github.com/hashicorp/packer`. This will download the Packer source to `$GOPATH/src/github.com/hashicorp/packer`. -4. When working on Packer, first `cd $GOPATH/src/github.com/hashicorp/packer` +2. When working on Packer, first `cd $GOPATH/src/github.com/hashicorp/packer` so you can run `make` and easily access other files. Run `make help` to get information about make targets. -5. Make your changes to the Packer source. You can run `make` in +3. Make your changes to the Packer source. You can run `make` in `$GOPATH/src/github.com/hashicorp/packer` to run tests and build the Packer binary. Any compilation errors will be shown when the binaries are rebuilding. If you don't have `make` you can simply run `go build -o bin/packer .` from the project root. -6. After running building Packer successfully, use +4. After running building Packer successfully, use `$GOPATH/src/github.com/hashicorp/packer/bin/packer` to build a machine and verify your changes work. For instance: `$GOPATH/src/github.com/hashicorp/packer/bin/packer build template.json`. -7. If everything works well and the tests pass, run `go fmt` on your code before +5. If everything works well and the tests pass, run `go fmt` on your code before submitting a pull-request. ### Opening an Pull Request From 1d025c005f4e6cca5e29a8379397044c4996b8b4 Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Mon, 13 Aug 2018 12:50:55 +0200 Subject: [PATCH 166/220] Link to godocs install steps --- .github/CONTRIBUTING.md | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index b68e3dfbd..94a61e690 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -48,26 +48,20 @@ can quickly merge or address your contributions. 5. The issue is closed. -## Setting up Go to work on Packer +## Setting up Go -If you have never worked with Go before, you will have to complete the following -steps in order to be able to compile and test Packer. These instructions target +If you have never worked with Go before, you will have to install it's +runtime in order to build packer. + +1. [Install go](https://golang.org/doc/install#install) + +## Setting up Packer for dev + +If/when you have go installed you can already `go get` packer and `make` in +order to compile and test Packer. These instructions target POSIX-like environments (Mac OS X, Linux, Cygwin, etc.) so you may need to adjust them for Windows or other shells. -1. [Download](https://golang.org/dl) and install Go. The instructions below are - for go 1.7. Earlier versions of Go are no longer supported. - -2. Set and export the `GOPATH` environment variable and update your `PATH`. For - example, you can add the following to your `.bash_profile` (or comparable - shell startup scripts): - -``` -export GOPATH=$HOME/go -export PATH=$PATH:$GOPATH/bin -``` - -## Setting up Packer for dev 1. Download the Packer source (and its dependencies) by running `go get github.com/hashicorp/packer`. This will download the Packer source to From bef5c842af1eb31be7fccc5fb5101b4a9cc337c3 Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Mon, 13 Aug 2018 12:53:41 +0200 Subject: [PATCH 167/220] re add the go 1.7 min version warning --- .github/CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 94a61e690..0f72a816c 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -61,6 +61,7 @@ If/when you have go installed you can already `go get` packer and `make` in order to compile and test Packer. These instructions target POSIX-like environments (Mac OS X, Linux, Cygwin, etc.) so you may need to adjust them for Windows or other shells. +The instructions below are for go 1.7. Earlier versions of Go are no longer supported. 1. Download the Packer source (and its dependencies) by running From 250da0ab49d9f4a15a024dcd550537c3f187ad8e Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Mon, 13 Aug 2018 17:01:13 -0700 Subject: [PATCH 168/220] fix security hole with ami filter --- builder/amazon/common/run_config.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/builder/amazon/common/run_config.go b/builder/amazon/common/run_config.go index 9467d42bd..dbafd0f38 100644 --- a/builder/amazon/common/run_config.go +++ b/builder/amazon/common/run_config.go @@ -25,6 +25,10 @@ func (d *AmiFilterOptions) Empty() bool { return len(d.Owners) == 0 && len(d.Filters) == 0 } +func (d *AmiFilterOptions) NoOwner() bool { + return len(d.Owners) == 0 +} + // RunConfig contains configuration for running an instance from a source // AMI and details on how to access that launched image. type RunConfig struct { @@ -101,6 +105,10 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { errs = append(errs, fmt.Errorf("A source_ami or source_ami_filter must be specified")) } + if c.SourceAmi == "" && c.SourceAmiFilter.NoOwner() { + errs = append(errs, fmt.Errorf("For security reasons, your source AMI filter must declare an owner.")) + } + if c.InstanceType == "" { errs = append(errs, fmt.Errorf("An instance_type must be specified")) } From 2e151f3cd0cf29c4ade884a30acbea7d6c94b8df Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Tue, 14 Aug 2018 09:49:24 +0200 Subject: [PATCH 169/220] Spelling & checks --- .github/CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 0f72a816c..b3ec404e2 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -50,7 +50,7 @@ can quickly merge or address your contributions. ## Setting up Go -If you have never worked with Go before, you will have to install it's +If you have never worked with Go before, you will have to install its runtime in order to build packer. 1. [Install go](https://golang.org/doc/install#install) @@ -61,7 +61,7 @@ If/when you have go installed you can already `go get` packer and `make` in order to compile and test Packer. These instructions target POSIX-like environments (Mac OS X, Linux, Cygwin, etc.) so you may need to adjust them for Windows or other shells. -The instructions below are for go 1.7. Earlier versions of Go are no longer supported. +The instructions below are for go 1.7. or later. 1. Download the Packer source (and its dependencies) by running From 1a17b799f1f0304a5257ae6a7f4731c3e2310a58 Mon Sep 17 00:00:00 2001 From: He Guimin Date: Wed, 15 Aug 2018 00:14:02 +0800 Subject: [PATCH 170/220] Support describing and checking source image coming from marketplace --- .../alicloud/ecs/step_check_source_image.go | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/builder/alicloud/ecs/step_check_source_image.go b/builder/alicloud/ecs/step_check_source_image.go index 6090d8868..f0fbf46e2 100644 --- a/builder/alicloud/ecs/step_check_source_image.go +++ b/builder/alicloud/ecs/step_check_source_image.go @@ -18,8 +18,12 @@ func (s *stepCheckAlicloudSourceImage) Run(_ context.Context, state multistep.St client := state.Get("client").(*ecs.Client) config := state.Get("config").(Config) ui := state.Get("ui").(packer.Ui) - images, _, err := client.DescribeImages(&ecs.DescribeImagesArgs{RegionId: common.Region(config.AlicloudRegion), - ImageId: config.AlicloudSourceImage}) + args := &ecs.DescribeImagesArgs{ + RegionId: common.Region(config.AlicloudRegion), + ImageId: config.AlicloudSourceImage, + } + args.PageSize = 50 + images, _, err := client.DescribeImages(args) if err != nil { err := fmt.Errorf("Error querying alicloud image: %s", err) state.Put("error", err) @@ -27,6 +31,19 @@ func (s *stepCheckAlicloudSourceImage) Run(_ context.Context, state multistep.St return multistep.ActionHalt } + // Describe markerplace image + args.ImageOwnerAlias = ecs.ImageOwnerMarketplace + imageMarkets, _, err := client.DescribeImages(args) + if err != nil { + err := fmt.Errorf("Error querying alicloud marketplace image: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + if len(imageMarkets) > 0 { + images = append(images, imageMarkets...) + } + if len(images) == 0 { err := fmt.Errorf("No alicloud image was found matching filters: %v", config.AlicloudSourceImage) state.Put("error", err) From 71cad4f2a91b67dd150264cc13f674035016e7fb Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Tue, 14 Aug 2018 12:30:05 -0700 Subject: [PATCH 171/220] fix tests --- builder/amazon/common/run_config_test.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/builder/amazon/common/run_config_test.go b/builder/amazon/common/run_config_test.go index fde9ef760..f43b9f12c 100644 --- a/builder/amazon/common/run_config_test.go +++ b/builder/amazon/common/run_config_test.go @@ -55,18 +55,28 @@ func TestRunConfigPrepare_InstanceType(t *testing.T) { func TestRunConfigPrepare_SourceAmi(t *testing.T) { c := testConfig() c.SourceAmi = "" - if err := c.Prepare(nil); len(err) != 1 { + if err := c.Prepare(nil); len(err) != 2 { t.Fatalf("Should error if a source_ami (or source_ami_filter) is not specified") } } func TestRunConfigPrepare_SourceAmiFilterBlank(t *testing.T) { c := testConfigFilter() - if err := c.Prepare(nil); len(err) != 1 { + if err := c.Prepare(nil); len(err) != 2 { t.Fatalf("Should error if source_ami_filter is empty or not specified (and source_ami is not specified)") } } +func TestRunConfigPrepare_SourceAmiFilterOwnersBlank(t *testing.T) { + c := testConfigFilter() + filter_key := "name" + filter_value := "foo" + c.SourceAmiFilter = AmiFilterOptions{Filters: map[*string]*string{&filter_key: &filter_value}} + if err := c.Prepare(nil); len(err) != 1 { + t.Fatalf("Should error if Owners is not specified)") + } +} + func TestRunConfigPrepare_SourceAmiFilterGood(t *testing.T) { c := testConfigFilter() owner := "123" From d57b599f3c83721750bc78ca58f862ffb840bf0a Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Tue, 14 Aug 2018 12:33:09 -0700 Subject: [PATCH 172/220] update docs --- website/source/docs/builders/amazon-chroot.html.md | 2 +- website/source/docs/builders/amazon-ebs.html.md | 2 +- website/source/docs/builders/amazon-ebssurrogate.html.md | 2 +- website/source/docs/builders/amazon-ebsvolume.html.md | 2 +- website/source/docs/builders/amazon-instance.html.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/website/source/docs/builders/amazon-chroot.html.md b/website/source/docs/builders/amazon-chroot.html.md index 116fd9ae5..82d88a053 100644 --- a/website/source/docs/builders/amazon-chroot.html.md +++ b/website/source/docs/builders/amazon-chroot.html.md @@ -300,7 +300,7 @@ each category, the available configuration keys are alphabetized. is valid. - `owners` (array of strings) - This scopes the AMIs to certain Amazon account IDs. - This is helpful to limit the AMIs to a trusted third party, or to your own account. + This is a required option, necessary to limit the AMIs your account or a trusted third party. - `most_recent` (boolean) - Selects the newest created image when true. This is most useful for selecting a daily distro build. diff --git a/website/source/docs/builders/amazon-ebs.html.md b/website/source/docs/builders/amazon-ebs.html.md index 944691794..f238d5190 100644 --- a/website/source/docs/builders/amazon-ebs.html.md +++ b/website/source/docs/builders/amazon-ebs.html.md @@ -319,7 +319,7 @@ builder. is valid. - `owners` (array of strings) - This scopes the AMIs to certain Amazon account IDs. - This is helpful to limit the AMIs to a trusted third party, or to your own account. + This is a required option, necessary to limit the AMIs your account or a trusted third party. - `most_recent` (boolean) - Selects the newest created image when true. This is most useful for selecting a daily distro build. diff --git a/website/source/docs/builders/amazon-ebssurrogate.html.md b/website/source/docs/builders/amazon-ebssurrogate.html.md index 881cce45e..d2672be0d 100644 --- a/website/source/docs/builders/amazon-ebssurrogate.html.md +++ b/website/source/docs/builders/amazon-ebssurrogate.html.md @@ -312,7 +312,7 @@ builder. is valid. - `owners` (array of strings) - This scopes the AMIs to certain Amazon account IDs. - This is helpful to limit the AMIs to a trusted third party, or to your own account. + This is a required option, necessary to limit the AMIs your account or a trusted third party. - `most_recent` (boolean) - Selects the newest created image when true. This is most useful for selecting a daily distro build. diff --git a/website/source/docs/builders/amazon-ebsvolume.html.md b/website/source/docs/builders/amazon-ebsvolume.html.md index a3ff74785..26306a1ef 100644 --- a/website/source/docs/builders/amazon-ebsvolume.html.md +++ b/website/source/docs/builders/amazon-ebsvolume.html.md @@ -240,7 +240,7 @@ builder. is valid. - `owners` (array of strings) - This scopes the AMIs to certain Amazon account IDs. - This is helpful to limit the AMIs to a trusted third party, or to your own account. + This is a required option, necessary to limit the AMIs your account or a trusted third party. - `most_recent` (boolean) - Selects the newest created image when true. This is most useful for selecting a daily distro build. diff --git a/website/source/docs/builders/amazon-instance.html.md b/website/source/docs/builders/amazon-instance.html.md index 00700dfb5..fa0a8d3e0 100644 --- a/website/source/docs/builders/amazon-instance.html.md +++ b/website/source/docs/builders/amazon-instance.html.md @@ -312,7 +312,7 @@ builder. is valid. - `owners` (array of strings) - This scopes the AMIs to certain Amazon account IDs. - This is helpful to limit the AMIs to a trusted third party, or to your own account. + This is a required option, necessary to limit the AMIs your account or a trusted third party. - `most_recent` (boolean) - Selects the newest created image when true. This is most useful for selecting a daily distro build. From f7f6a842e330b8b24105fb4dd03c58d40e92ba5b Mon Sep 17 00:00:00 2001 From: Abhinay Kumar Date: Wed, 15 Aug 2018 08:53:50 +0530 Subject: [PATCH 173/220] bug-fix: syntax error in createApplication() setup throws an error: `az: error: unrecognized arguments: az ad app list` due to a syntax error in `createApplication()` method. This patch will fix the issue of the same. --- contrib/azure-setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/azure-setup.sh b/contrib/azure-setup.sh index 6473c5a08..200469073 100755 --- a/contrib/azure-setup.sh +++ b/contrib/azure-setup.sh @@ -156,7 +156,7 @@ createApplication() { if [ "$azure_client_id" != "" ]; then echo "==> application already exist, grab appId" - azure_client_id=$(az ad app list az ad app list --output json | jq -r '.[] | select(.displayName | contains("'$meta_name'")) .appId') + azure_client_id=$(az ad app list --output json | jq -r '.[] | select(.displayName | contains("'$meta_name'")) .appId') else echo "==> application does not exist" azure_client_id=$(az ad app create --display-name $meta_name --identifier-uris http://$meta_name --homepage http://$meta_name --password $azure_client_secret --output json | jq -r .appId) From c962e7b856c82c1b83e1ecba2efd2e9244e0d1e0 Mon Sep 17 00:00:00 2001 From: Rickard von Essen Date: Wed, 15 Aug 2018 13:12:47 +0200 Subject: [PATCH 174/220] Simplified loop code --- builder/openstack/step_run_source_server.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/builder/openstack/step_run_source_server.go b/builder/openstack/step_run_source_server.go index b905c05c3..28d50ed93 100644 --- a/builder/openstack/step_run_source_server.go +++ b/builder/openstack/step_run_source_server.go @@ -42,15 +42,11 @@ func (s *StepRunSourceServer) Run(_ context.Context, state multistep.StateBag) m networks := make([]servers.Network, len(s.Networks)+len(s.Ports)) i := 0 - if len(s.Ports) > 0 { - for i = 0; i < len(s.Ports); i++ { - networks[i].Port = s.Ports[i] - } + for ; i < len(s.Ports); i++ { + networks[i].Port = s.Ports[i] } - if len(s.Networks) > 0 { - for i = len(s.Ports); i < len(networks); i++ { - networks[i].UUID = s.Networks[i] - } + for ; i < len(networks); i++ { + networks[i].UUID = s.Networks[i] } userData := []byte(s.UserData) From dc111004df806184682c73941288b6aea97d8b56 Mon Sep 17 00:00:00 2001 From: Rickard von Essen Date: Wed, 15 Aug 2018 13:37:21 +0200 Subject: [PATCH 175/220] Updated CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e87c2e5da..3f64aca34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ### IMPROVEMENTS: +* builder/openstack: Add support for ports. [GH-6570] * command/validate: Warn users if config needs fixing. [GH-6423] ### BUG FIXES: From 82e480a2859868c33187c70571453f184dfcde46 Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Wed, 15 Aug 2018 14:37:38 +0200 Subject: [PATCH 176/220] allow to use ISO images inplace v.s. copying them --- builder/virtualbox/iso/builder.go | 1 + builder/vmware/iso/builder.go | 1 + common/download.go | 5 +---- common/iso_config.go | 1 + common/step_download.go | 7 ++++++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/builder/virtualbox/iso/builder.go b/builder/virtualbox/iso/builder.go index 2ea19e70f..4e906e1cd 100644 --- a/builder/virtualbox/iso/builder.go +++ b/builder/virtualbox/iso/builder.go @@ -204,6 +204,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ResultKey: "iso_path", TargetPath: b.config.TargetPath, Url: b.config.ISOUrls, + Inplace: b.config.InplaceISO, }, &vboxcommon.StepOutputDir{ Force: b.config.PackerForce, diff --git a/builder/vmware/iso/builder.go b/builder/vmware/iso/builder.go index 0944db927..a884822b2 100644 --- a/builder/vmware/iso/builder.go +++ b/builder/vmware/iso/builder.go @@ -291,6 +291,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ResultKey: "iso_path", TargetPath: b.config.TargetPath, Url: b.config.ISOUrls, + Inplace: b.config.InplaceISO, }, &vmwcommon.StepOutputDir{ Force: b.config.PackerForce, diff --git a/common/download.go b/common/download.go index 09457ef0b..33fa7fed9 100644 --- a/common/download.go +++ b/common/download.go @@ -154,10 +154,7 @@ func (d *DownloadClient) Get() (string, error) { return "", fmt.Errorf("Unable to treat uri scheme %s as a Downloader. : %T", u.Scheme, d.downloader) } - local, ok := d.downloader.(LocalDownloader) - if !ok && !d.config.CopyFile { - d.config.CopyFile = true - } + local, _ := d.downloader.(LocalDownloader) // If we're copying the file, then just use the actual downloader if d.config.CopyFile { diff --git a/common/iso_config.go b/common/iso_config.go index 4f30580bc..e9a784266 100644 --- a/common/iso_config.go +++ b/common/iso_config.go @@ -24,6 +24,7 @@ type ISOConfig struct { TargetPath string `mapstructure:"iso_target_path"` TargetExtension string `mapstructure:"iso_target_extension"` RawSingleISOUrl string `mapstructure:"iso_url"` + InplaceISO bool `mapstructure:"iso_inplace"` } func (c *ISOConfig) Prepare(ctx *interpolate.Context) (warnings []string, errs []error) { diff --git a/common/step_download.go b/common/step_download.go index 03340b974..c35e9abef 100644 --- a/common/step_download.go +++ b/common/step_download.go @@ -45,6 +45,11 @@ type StepDownload struct { // extension on the URL is used. Otherwise, this will be forced // on the downloaded file for every URL. Extension string + + // Inplace indicates wether to copy file + // versus using it inplace. + // Inplace is only used when referencing local ISO files. + Inplace bool } func (s *StepDownload) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { @@ -89,7 +94,7 @@ func (s *StepDownload) Run(_ context.Context, state multistep.StateBag) multiste config := &DownloadConfig{ Url: url, TargetPath: targetPath, - CopyFile: false, + CopyFile: !s.Inplace, Hash: HashForType(s.ChecksumType), Checksum: checksum, UserAgent: useragent.String(), From 863222b1e28876285c1d0584dccb2c195cbd44df Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Wed, 15 Aug 2018 15:26:31 +0200 Subject: [PATCH 177/220] Also use the terminology Inplace in DownloadConfig for clarity/consistency * swapped boolean checks * swapped in tests too --- common/download.go | 17 ++++++++++------- common/download_test.go | 11 ++--------- common/step_download.go | 4 ++-- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/common/download.go b/common/download.go index 33fa7fed9..84776bee9 100644 --- a/common/download.go +++ b/common/download.go @@ -38,10 +38,10 @@ type DownloadConfig struct { // DownloaderMap maps a schema to a Download. DownloaderMap map[string]Downloader - // If true, this will copy even a local file to the target - // location. If false, then it will "download" the file by just - // returning the local path to the file. - CopyFile bool + // Inplace indicates wether to copy file + // versus using it inplace. + // Inplace can only be true when referencing local files. + Inplace bool // The hashing implementation to use to checksum the downloaded file. Hash hash.Hash @@ -154,10 +154,13 @@ func (d *DownloadClient) Get() (string, error) { return "", fmt.Errorf("Unable to treat uri scheme %s as a Downloader. : %T", u.Scheme, d.downloader) } - local, _ := d.downloader.(LocalDownloader) + local, ok := d.downloader.(LocalDownloader) + if !ok && d.config.Inplace { + d.config.Inplace = false + } // If we're copying the file, then just use the actual downloader - if d.config.CopyFile { + if d.config.Inplace == false { var f *os.File finalPath = d.config.TargetPath @@ -189,7 +192,7 @@ func (d *DownloadClient) Get() (string, error) { verify, err = d.VerifyChecksum(finalPath) if err == nil && !verify { // Only delete the file if we made a copy or downloaded it - if d.config.CopyFile { + if d.config.Inplace == false { os.Remove(finalPath) } diff --git a/common/download_test.go b/common/download_test.go index c9175b013..835b2d54b 100644 --- a/common/download_test.go +++ b/common/download_test.go @@ -58,7 +58,6 @@ func TestDownloadClient_basic(t *testing.T) { client := NewDownloadClient(&DownloadConfig{ Url: ts.URL + "/basic.txt", TargetPath: tf.Name(), - CopyFile: true, }) path, err := client.Get() @@ -94,7 +93,6 @@ func TestDownloadClient_checksumBad(t *testing.T) { TargetPath: tf.Name(), Hash: HashForType("md5"), Checksum: checksum, - CopyFile: true, }) if _, err := client.Get(); err == nil { @@ -120,7 +118,6 @@ func TestDownloadClient_checksumGood(t *testing.T) { TargetPath: tf.Name(), Hash: HashForType("md5"), Checksum: checksum, - CopyFile: true, }) path, err := client.Get() @@ -152,7 +149,6 @@ func TestDownloadClient_checksumNoDownload(t *testing.T) { TargetPath: "./test-fixtures/root/another.txt", Hash: HashForType("md5"), Checksum: checksum, - CopyFile: true, }) path, err := client.Get() if err != nil { @@ -210,7 +206,6 @@ func TestDownloadClient_resume(t *testing.T) { client := NewDownloadClient(&DownloadConfig{ Url: ts.URL, TargetPath: tf.Name(), - CopyFile: true, }) path, err := client.Get() @@ -270,7 +265,6 @@ func TestDownloadClient_usesDefaultUserAgent(t *testing.T) { config := &DownloadConfig{ Url: server.URL, TargetPath: tf.Name(), - CopyFile: true, } client := NewDownloadClient(config) @@ -303,7 +297,6 @@ func TestDownloadClient_setsUserAgent(t *testing.T) { Url: server.URL, TargetPath: tf.Name(), UserAgent: "fancy user agent", - CopyFile: true, } client := NewDownloadClient(config) @@ -402,7 +395,7 @@ func TestDownloadFileUrl(t *testing.T) { // This should be wrong. We want to make sure we don't delete Checksum: []byte("nope"), Hash: HashForType("sha256"), - CopyFile: false, + Inplace: true, } client := NewDownloadClient(config) @@ -432,7 +425,7 @@ func SimulateFileUriDownload(t *testing.T, uri string) (string, error) { // This should be wrong. We want to make sure we don't delete Checksum: []byte("nope"), Hash: HashForType("sha256"), - CopyFile: false, + Inplace: true, } // go go go diff --git a/common/step_download.go b/common/step_download.go index c35e9abef..6d2b850a0 100644 --- a/common/step_download.go +++ b/common/step_download.go @@ -48,7 +48,7 @@ type StepDownload struct { // Inplace indicates wether to copy file // versus using it inplace. - // Inplace is only used when referencing local ISO files. + // Inplace can only be true when referencing local files. Inplace bool } @@ -94,7 +94,7 @@ func (s *StepDownload) Run(_ context.Context, state multistep.StateBag) multiste config := &DownloadConfig{ Url: url, TargetPath: targetPath, - CopyFile: !s.Inplace, + Inplace: s.Inplace, Hash: HashForType(s.ChecksumType), Checksum: checksum, UserAgent: useragent.String(), From 889c89ec79fc4ee1eaff0aba597cff40119e96b9 Mon Sep 17 00:00:00 2001 From: Rickard von Essen Date: Wed, 15 Aug 2018 15:27:00 +0200 Subject: [PATCH 178/220] Validate tags --- builder/digitalocean/config.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/builder/digitalocean/config.go b/builder/digitalocean/config.go index bb4175972..19c802c4b 100644 --- a/builder/digitalocean/config.go +++ b/builder/digitalocean/config.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "os" + "regexp" "time" "github.com/hashicorp/packer/common" @@ -125,6 +126,13 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { if c.Tags == nil { c.Tags = make([]string, 0) } + tagRe := regexp.MustCompile("^[[:alnum:]:_-]{1,255}$") + + for _, t := range c.Tags { + if !tagRe.MatchString(t) { + errs = packer.MultiErrorAppend(errs, errors.New(fmt.Sprintf("invalid tag: %s", t))) + } + } if errs != nil && len(errs.Errors) > 0 { return nil, nil, errs From 17f2949e369bbf5cb5c6039b7c86983235881500 Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Wed, 15 Aug 2018 15:51:25 +0200 Subject: [PATCH 179/220] remove stuttering; ISOConfig.InplaceISO -> Inplace --- builder/virtualbox/iso/builder.go | 2 +- builder/vmware/iso/builder.go | 2 +- common/iso_config.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/builder/virtualbox/iso/builder.go b/builder/virtualbox/iso/builder.go index 4e906e1cd..7cf3dd7e3 100644 --- a/builder/virtualbox/iso/builder.go +++ b/builder/virtualbox/iso/builder.go @@ -204,7 +204,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ResultKey: "iso_path", TargetPath: b.config.TargetPath, Url: b.config.ISOUrls, - Inplace: b.config.InplaceISO, + Inplace: b.config.Inplace, }, &vboxcommon.StepOutputDir{ Force: b.config.PackerForce, diff --git a/builder/vmware/iso/builder.go b/builder/vmware/iso/builder.go index a884822b2..d428d0184 100644 --- a/builder/vmware/iso/builder.go +++ b/builder/vmware/iso/builder.go @@ -291,7 +291,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ResultKey: "iso_path", TargetPath: b.config.TargetPath, Url: b.config.ISOUrls, - Inplace: b.config.InplaceISO, + Inplace: b.config.Inplace, }, &vmwcommon.StepOutputDir{ Force: b.config.PackerForce, diff --git a/common/iso_config.go b/common/iso_config.go index e9a784266..aca468cd2 100644 --- a/common/iso_config.go +++ b/common/iso_config.go @@ -24,7 +24,7 @@ type ISOConfig struct { TargetPath string `mapstructure:"iso_target_path"` TargetExtension string `mapstructure:"iso_target_extension"` RawSingleISOUrl string `mapstructure:"iso_url"` - InplaceISO bool `mapstructure:"iso_inplace"` + Inplace bool `mapstructure:"iso_inplace"` } func (c *ISOConfig) Prepare(ctx *interpolate.Context) (warnings []string, errs []error) { From fa7b9da808322c804ba201def0ac45f7e81037c6 Mon Sep 17 00:00:00 2001 From: Rickard von Essen Date: Wed, 15 Aug 2018 15:55:30 +0200 Subject: [PATCH 180/220] Updated CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f64aca34..8ea039ed1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ### IMPROVEMENTS: +* builder/digitalocean: Add support for tagging to instances [GH-6546] * builder/openstack: Add support for ports. [GH-6570] * command/validate: Warn users if config needs fixing. [GH-6423] From b8adf689fdea38eaf8aec2207a5dcb491eae5091 Mon Sep 17 00:00:00 2001 From: Rickard von Essen Date: Wed, 15 Aug 2018 16:08:20 +0200 Subject: [PATCH 181/220] Check that only certain files are executable --- Makefile | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index cb5247d13..85971c1c4 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,8 @@ GOPATH=$(shell go env GOPATH) # gofmt UNFORMATTED_FILES=$(shell find . -not -path "./vendor/*" -name "*.go" | xargs gofmt -s -l) +EXECUTABLE_FILES=$(shell find . -type f -perm +111 | egrep -v '^\./(vendor/|\.git|bin/|scripts/|pkg/)' | egrep -v '.*(\.sh|\.bats)' | egrep -v './provisioner/ansible/test-fixtures/exit1') + # Get the git commit GIT_DIRTY=$(shell test -n "`git status --porcelain`" && echo "+CHANGES" || true) GIT_COMMIT=$(shell git rev-parse --short HEAD) @@ -75,6 +77,15 @@ fmt-check: ## Check go code formatting echo "Check passed."; \ fi +mode-check: ## Check that only certain files are executable + @echo "==> Checking that only certain files are executable..." + @if [ ! -z "$(EXECUTABLE_FILES)" ]; then \ + echo "These files should not be executable or they must be white listed in the Makefile:"; \ + echo "$(EXECUTABLE_FILES)" | xargs -n1; \ + exit 1; \ + else \ + echo "Check passed."; \ + fi fmt-docs: @find ./website/source/docs -name "*.md" -exec pandoc --wrap auto --columns 79 --atx-headers -s -f "markdown_github+yaml_metadata_block" -t "markdown_github+yaml_metadata_block" {} -o {} \; @@ -90,7 +101,7 @@ generate: deps ## Generate dynamically generated code goimports -w common/bootcommand/boot_command.go gofmt -w command/plugin.go -test: deps fmt-check ## Run unit tests +test: deps fmt-check mode-check ## Run unit tests @go test $(TEST) $(TESTARGS) -timeout=2m @go tool vet $(VET) ; if [ $$? -eq 1 ]; then \ echo "ERROR: Vet found problems in the code."; \ From 074b170ed494bc675d8524c5ec3d2648a3a51d60 Mon Sep 17 00:00:00 2001 From: Rickard von Essen Date: Wed, 15 Aug 2018 16:13:34 +0200 Subject: [PATCH 182/220] Fixed exec bit --- builder/openstack/step_stop_server.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 builder/openstack/step_stop_server.go diff --git a/builder/openstack/step_stop_server.go b/builder/openstack/step_stop_server.go old mode 100755 new mode 100644 From fae3db4e5879e868db526fc515d8167fcfc55fa8 Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Wed, 15 Aug 2018 17:09:39 +0200 Subject: [PATCH 183/220] test inplace linking --- common/download_test.go | 44 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/common/download_test.go b/common/download_test.go index 835b2d54b..9305e7db8 100644 --- a/common/download_test.go +++ b/common/download_test.go @@ -411,6 +411,50 @@ func TestDownloadFileUrl(t *testing.T) { } } +// TestDownloadFileUrl_inplace verifies that inplace setting is respected. +func TestDownloadFileUrl_inplace(t *testing.T) { + cwd, err := os.Getwd() + if err != nil { + t.Fatalf("Unable to detect working directory: %s", err) + } + cwd = filepath.ToSlash(cwd) + + // source_path is a file path and source is a network path + sourcePath := fmt.Sprintf("%s/test-fixtures/fileurl/%s", cwd, "cake") + + filePrefix := "file://" + if runtime.GOOS == "windows" { + filePrefix += "/" + } + + source := fmt.Sprintf(filePrefix + sourcePath) + t.Logf("Trying to download %s", source) + + config := &DownloadConfig{ + Url: source, + // This is correct. We want to make sure we don't delete + Checksum: []byte{96, 111, 25, 69, 248, 26, 2, 45, 14, 208, 189, 153, 237, 253, 79, 153, 8, 28, 28, 177, 249, 127, 174, 8, 114, 145, 238, 20, 233, 69, 230, 8}, + Hash: HashForType("sha256"), + Inplace: true, + } + + client := NewDownloadClient(config) + + // Verify that we fail to match the checksum + url, err := client.Get() + if err != nil { + t.Fatalf("Unexpected error: \"%v\"", err) + } + + if sourcePath != url { + t.Errorf("Inplace file get should return same path, expected %s, got %s", sourcePath, url) + } + + if _, err = os.Stat(sourcePath); err != nil { + t.Errorf("Could not stat source file: %s", sourcePath) + } +} + // SimulateFileUriDownload is a simple utility function that converts a uri // into a testable file path whilst ignoring a correct checksum match, stripping // UNC path info, and then calling stat to ensure the correct file exists. From 7872cb67b3db48bb75fc829daa17f652d9c6cbc0 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Wed, 15 Aug 2018 11:48:08 -0700 Subject: [PATCH 184/220] update changelog --- CHANGELOG.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ea039ed1..c560e0040 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,37 @@ ### IMPROVEMENTS: +* builder/amazon-chroot: New feature `root_volume_tags` to tag the created + volumes. [GH-6504] +* builder/azure: Implement clean_image_name template engine. [GH-6558] * builder/digitalocean: Add support for tagging to instances [GH-6546] +* builder/lxc: Allow unplivileged LXC containers. [GH-6279] +* builder/oci: Add `metadata` feature to Packer config. [GH-6498] * builder/openstack: Add support for ports. [GH-6570] +* builder/qemu: add ssh agent support. [GH-6541] +* builder/qemu: New `use_backing_file` feature [GH-6249] +* builder/vmware-iso: Try to use ISO files uploaded to the datastore when + building remotely instead of uploading them freshly every time [GH-5165] * command/validate: Warn users if config needs fixing. [GH-6423] +* post-processor/vagrant: Support for Docker images. [GH-6494] +* postprocessor/vagrant: Add support for Azure. [GH-6576] +* provisioner/ansible: Enable {{.WinRMPassword}} template engine. [GH-6450] +* provisioner/shell-local: Create PACKER_HTTP_ADDR environment variable + [GH-6503] ### BUG FIXES: +* builder/amazon-ebssurrogate: Clean up volumes at end of build. [GH-6514] +* builder/azure: Generated password satisfies Azure password requirements + [GH-6480] +* builder/lxc: Correctly pass "config" option to "lxc launch". [GH-6563] +* builder/vmware-iso: Fix crash caused by invalid datacenter url. [GH-6529] +* core: Better error handling in downloader when connection error occurs. + [GH-6557] +* core: Fix broken pathing checks in checksum files. [GH-6525] + +### BACKWARDS INCOMPATIBILITIES: +* builder/amazon: "owners" field on source_ami_filter is now required for + secuirty reasons. [GH-6585] ## 1.2.5 (July 16, 2018) From b2d6edf76a99de84c6c7ab3905b67817cf3cb397 Mon Sep 17 00:00:00 2001 From: Rickard von Essen Date: Thu, 16 Aug 2018 12:00:09 +0200 Subject: [PATCH 185/220] Update gophercloud/utils to add support for clouds-public.yaml --- .../utils/openstack/clientconfig/requests.go | 146 ++++++++++++++++-- .../utils/openstack/clientconfig/results.go | 28 +++- .../utils/openstack/clientconfig/utils.go | 105 ++++++++++++- vendor/vendor.json | 6 +- 4 files changed, 264 insertions(+), 21 deletions(-) diff --git a/vendor/github.com/gophercloud/utils/openstack/clientconfig/requests.go b/vendor/github.com/gophercloud/utils/openstack/clientconfig/requests.go index 254f72776..508f1ab13 100644 --- a/vendor/github.com/gophercloud/utils/openstack/clientconfig/requests.go +++ b/vendor/github.com/gophercloud/utils/openstack/clientconfig/requests.go @@ -3,6 +3,7 @@ package clientconfig import ( "fmt" "os" + "reflect" "strings" "github.com/gophercloud/gophercloud" @@ -15,14 +16,20 @@ import ( type AuthType string const ( + // AuthPassword defines an unknown version of the password AuthPassword AuthType = "password" - AuthToken AuthType = "token" + // AuthToken defined an unknown version of the token + AuthToken AuthType = "token" + // AuthV2Password defines version 2 of the password AuthV2Password AuthType = "v2password" - AuthV2Token AuthType = "v2token" + // AuthV2Token defines version 2 of the token + AuthV2Token AuthType = "v2token" + // AuthV3Password defines version 3 of the password AuthV3Password AuthType = "v3password" - AuthV3Token AuthType = "v3token" + // AuthV3Token defines version 3 of the token + AuthV3Token AuthType = "v3token" ) // ClientOpts represents options to customize the way a client is @@ -41,11 +48,16 @@ type ClientOpts struct { // AuthInfo defines the authentication information needed to // authenticate to a cloud when clouds.yaml isn't used. AuthInfo *AuthInfo + + // RegionName is the region to create a Service Client in. + // This will override a region in clouds.yaml or can be used + // when authenticating directly with AuthInfo. + RegionName string } -// LoadYAML will load a clouds.yaml file and return the full config. -func LoadYAML() (map[string]Cloud, error) { - content, err := findAndReadYAML() +// LoadCloudsYAML will load a clouds.yaml file and return the full config. +func LoadCloudsYAML() (map[string]Cloud, error) { + content, err := findAndReadCloudsYAML() if err != nil { return nil, err } @@ -59,9 +71,52 @@ func LoadYAML() (map[string]Cloud, error) { return clouds.Clouds, nil } +// LoadSecureCloudsYAML will load a secure.yaml file and return the full config. +func LoadSecureCloudsYAML() (map[string]Cloud, error) { + var secureClouds Clouds + + content, err := findAndReadSecureCloudsYAML() + if err != nil { + if err.Error() == "no secure.yaml file found" { + // secure.yaml is optional so just ignore read error + return secureClouds.Clouds, nil + } + return nil, err + } + + err = yaml.Unmarshal(content, &secureClouds) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal yaml: %v", err) + } + + return secureClouds.Clouds, nil +} + +// LoadPublicCloudsYAML will load a public-clouds.yaml file and return the full config. +func LoadPublicCloudsYAML() (map[string]Cloud, error) { + var publicClouds PublicClouds + + content, err := findAndReadPublicCloudsYAML() + if err != nil { + if err.Error() == "no clouds-public.yaml file found" { + // clouds-public.yaml is optional so just ignore read error + return publicClouds.Clouds, nil + } + + return nil, err + } + + err = yaml.Unmarshal(content, &publicClouds) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal yaml: %v", err) + } + + return publicClouds.Clouds, nil +} + // GetCloudFromYAML will return a cloud entry from a clouds.yaml file. func GetCloudFromYAML(opts *ClientOpts) (*Cloud, error) { - clouds, err := LoadYAML() + clouds, err := LoadCloudsYAML() if err != nil { return nil, fmt.Errorf("unable to load clouds.yaml: %s", err) } @@ -101,10 +156,74 @@ func GetCloudFromYAML(opts *ClientOpts) (*Cloud, error) { } } + var cloudIsInCloudsYaml bool if cloud == nil { - return nil, fmt.Errorf("Unable to determine a valid entry in clouds.yaml") + // not an immediate error as it might still be defined in secure.yaml + cloudIsInCloudsYaml = false + } else { + cloudIsInCloudsYaml = true } + publicClouds, err := LoadPublicCloudsYAML() + if err != nil { + return nil, fmt.Errorf("unable to load clouds-public.yaml: %s", err) + } + + var profileName = defaultIfEmpty(cloud.Profile, cloud.Cloud) + if profileName != "" { + publicCloud, ok := publicClouds[profileName] + if !ok { + return nil, fmt.Errorf("cloud %s does not exist in clouds-public.yaml", profileName) + } + cloud, err = mergeClouds(cloud, publicCloud) + if err != nil { + return nil, fmt.Errorf("Could not merge information from clouds.yaml and clouds-public.yaml for cloud %s", profileName) + } + } + + secureClouds, err := LoadSecureCloudsYAML() + if err != nil { + return nil, fmt.Errorf("unable to load secure.yaml: %s", err) + } + + if secureClouds != nil { + // If no entry was found in clouds.yaml, no cloud name was specified, + // and only one secureCloud entry exists, use that as the cloud entry. + if !cloudIsInCloudsYaml && cloudName == "" && len(secureClouds) == 1 { + for _, v := range secureClouds { + cloud = &v + } + } + + secureCloud, ok := secureClouds[cloudName] + if !ok && cloud == nil { + // cloud == nil serves two purposes here: + // if no entry in clouds.yaml was found and + // if a single-entry secureCloud wasn't used. + // At this point, no entry could be determined at all. + return nil, fmt.Errorf("Could not find cloud %s", cloudName) + } + + // If secureCloud has content and it differs from the cloud entry, + // merge the two together. + if !reflect.DeepEqual((Cloud{}), secureCloud) && !reflect.DeepEqual(cloud, secureCloud) { + cloud, err = mergeClouds(secureCloud, cloud) + if err != nil { + return nil, fmt.Errorf("unable to merge information from clouds.yaml and secure.yaml") + } + } + } + + // Default is to verify SSL API requests + if cloud.Verify == nil { + iTrue := true + cloud.Verify = &iTrue + } + + // TODO: this is where reading vendor files should go be considered when not found in + // clouds-public.yml + // https://github.com/openstack/openstacksdk/tree/master/openstack/config/vendors + return cloud, nil } @@ -472,11 +591,20 @@ func NewServiceClient(service string, opts *ClientOpts) (*gophercloud.ServiceCli } // Determine the region to use. + // First, see if the cloud entry has one. var region string if v := cloud.RegionName; v != "" { - region = cloud.RegionName + region = v } + // Next, see if one was specified in the ClientOpts. + // If so, this takes precedence. + if v := opts.RegionName; v != "" { + region = v + } + + // Finally, see if there's an environment variable. + // This should always override prior settings. if v := os.Getenv(envPrefix + "REGION_NAME"); v != "" { region = v } diff --git a/vendor/github.com/gophercloud/utils/openstack/clientconfig/results.go b/vendor/github.com/gophercloud/utils/openstack/clientconfig/results.go index cb7603700..b49367c3c 100644 --- a/vendor/github.com/gophercloud/utils/openstack/clientconfig/results.go +++ b/vendor/github.com/gophercloud/utils/openstack/clientconfig/results.go @@ -1,5 +1,12 @@ package clientconfig +// PublicClouds represents a collection of PublicCloud entries in clouds-public.yaml file. +// The format of the clouds-public.yml is documented at +// https://docs.openstack.org/python-openstackclient/latest/configuration/ +type PublicClouds struct { + Clouds map[string]Cloud `yaml:"public-clouds"` +} + // Clouds represents a collection of Cloud entries in a clouds.yaml file. // The format of clouds.yaml is documented at // https://docs.openstack.org/os-client-config/latest/user/configuration.html. @@ -7,8 +14,10 @@ type Clouds struct { Clouds map[string]Cloud `yaml:"clouds"` } -// Cloud represents an entry in a clouds.yaml file. +// Cloud represents an entry in a clouds.yaml/public-clouds.yaml/secure.yaml file. type Cloud struct { + Cloud string `yaml:"cloud"` + Profile string `yaml:"profile"` AuthInfo *AuthInfo `yaml:"auth"` AuthType AuthType `yaml:"auth_type"` RegionName string `yaml:"region_name"` @@ -17,9 +26,24 @@ type Cloud struct { // API Version overrides. IdentityAPIVersion string `yaml:"identity_api_version"` VolumeAPIVersion string `yaml:"volume_api_version"` + + // Verify whether or not SSL API requests should be verified. + Verify *bool `yaml:"verify"` + + // CACertFile a path to a CA Cert bundle that can be used as part of + // verifying SSL API requests. + CACertFile string `yaml:"cacert"` + + // ClientCertFile a path to a client certificate to use as part of the SSL + // transaction. + ClientCertFile string `yaml:"cert"` + + // ClientKeyFile a path to a client key to use as part of the SSL + // transaction. + ClientKeyFile string `yaml:"key"` } -// Auth represents the auth section of a cloud entry or +// AuthInfo represents the auth section of a cloud entry or // auth options entered explicitly in ClientOpts. type AuthInfo struct { // AuthURL is the keystone/identity endpoint URL. diff --git a/vendor/github.com/gophercloud/utils/openstack/clientconfig/utils.go b/vendor/github.com/gophercloud/utils/openstack/clientconfig/utils.go index 34518c6ed..3403e5355 100644 --- a/vendor/github.com/gophercloud/utils/openstack/clientconfig/utils.go +++ b/vendor/github.com/gophercloud/utils/openstack/clientconfig/utils.go @@ -1,14 +1,93 @@ package clientconfig import ( + "encoding/json" "fmt" "io/ioutil" "os" "os/user" "path/filepath" + "reflect" ) -// findAndLoadYAML attempts to locate a clouds.yaml file in the following +// defaultIfEmpty is a helper function to make it cleaner to set default value +// for strings. +func defaultIfEmpty(value string, defaultValue string) string { + if value == "" { + return defaultValue + } + return value +} + +// mergeCLouds merges two Clouds recursively (the AuthInfo also gets merged). +// In case both Clouds define a value, the value in the 'override' cloud takes precedence +func mergeClouds(override, cloud interface{}) (*Cloud, error) { + overrideJson, err := json.Marshal(override) + if err != nil { + return nil, err + } + cloudJson, err := json.Marshal(cloud) + if err != nil { + return nil, err + } + var overrideInterface interface{} + err = json.Unmarshal(overrideJson, &overrideInterface) + if err != nil { + return nil, err + } + var cloudInterface interface{} + err = json.Unmarshal(cloudJson, &cloudInterface) + if err != nil { + return nil, err + } + var mergedCloud Cloud + mergedInterface := mergeInterfaces(overrideInterface, cloudInterface) + mergedJson, err := json.Marshal(mergedInterface) + json.Unmarshal(mergedJson, &mergedCloud) + return &mergedCloud, nil +} + +// merges two interfaces. In cases where a value is defined for both 'overridingInterface' and +// 'inferiorInterface' the value in 'overridingInterface' will take precedence. +func mergeInterfaces(overridingInterface, inferiorInterface interface{}) interface{} { + switch overriding := overridingInterface.(type) { + case map[string]interface{}: + interfaceMap, ok := inferiorInterface.(map[string]interface{}) + if !ok { + return overriding + } + for k, v := range interfaceMap { + if overridingValue, ok := overriding[k]; ok { + overriding[k] = mergeInterfaces(overridingValue, v) + } else { + overriding[k] = v + } + } + case []interface{}: + list, ok := inferiorInterface.([]interface{}) + if !ok { + return overriding + } + for i := range list { + overriding = append(overriding, list[i]) + } + return overriding + case nil: + // mergeClouds(nil, map[string]interface{...}) -> map[string]interface{...} + v, ok := inferiorInterface.(map[string]interface{}) + if ok { + return v + } + } + // We don't want to override with empty values + if reflect.DeepEqual(overridingInterface, nil) || reflect.DeepEqual(reflect.Zero(reflect.TypeOf(overridingInterface)).Interface(), overridingInterface) { + return inferiorInterface + } else { + return overridingInterface + } +} + +// findAndReadCloudsYAML attempts to locate a clouds.yaml file in the following // locations: // // 1. OS_CLIENT_CONFIG_FILE @@ -17,7 +96,7 @@ import ( // 4. unix-specific site_config_dir (/etc/openstack/clouds.yaml) // // If found, the contents of the file is returned. -func findAndReadYAML() ([]byte, error) { +func findAndReadCloudsYAML() ([]byte, error) { // OS_CLIENT_CONFIG_FILE if v := os.Getenv("OS_CLIENT_CONFIG_FILE"); v != "" { if ok := fileExists(v); ok { @@ -25,13 +104,25 @@ func findAndReadYAML() ([]byte, error) { } } + return findAndReadYAML("clouds.yaml") +} + +func findAndReadPublicCloudsYAML() ([]byte, error) { + return findAndReadYAML("clouds-public.yaml") +} + +func findAndReadSecureCloudsYAML() ([]byte, error) { + return findAndReadYAML("secure.yaml") +} + +func findAndReadYAML(yamlFile string) ([]byte, error) { // current directory cwd, err := os.Getwd() if err != nil { return nil, fmt.Errorf("unable to determine working directory: %s", err) } - filename := filepath.Join(cwd, "clouds.yaml") + filename := filepath.Join(cwd, yamlFile) if ok := fileExists(filename); ok { return ioutil.ReadFile(filename) } @@ -44,18 +135,18 @@ func findAndReadYAML() ([]byte, error) { homeDir := currentUser.HomeDir if homeDir != "" { - filename := filepath.Join(homeDir, ".config/openstack/clouds.yaml") + filename := filepath.Join(homeDir, ".config/openstack/"+yamlFile) if ok := fileExists(filename); ok { return ioutil.ReadFile(filename) } } // unix-specific site config directory: /etc/openstack. - if ok := fileExists("/etc/openstack/clouds.yaml"); ok { - return ioutil.ReadFile("/etc/openstack/clouds.yaml") + if ok := fileExists("/etc/openstack/" + yamlFile); ok { + return ioutil.ReadFile("/etc/openstack/" + yamlFile) } - return nil, fmt.Errorf("no clouds.yaml file found") + return nil, fmt.Errorf("no " + yamlFile + " file found") } // fileExists checks for the existence of a file at a given location. diff --git a/vendor/vendor.json b/vendor/vendor.json index f55a3cbdb..748a0c68a 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -816,10 +816,10 @@ "revisionTime": "2018-05-31T02:06:30Z" }, { - "checksumSHA1": "ujo1JDey6cxwnGs4HXVCJNVrhHw=", + "checksumSHA1": "BYHuEArNKnTCbp/LTCwQSlaIY4Y=", "path": "github.com/gophercloud/utils/openstack/clientconfig", - "revision": "afce78e977c56ca5407957bf67e8ecc56aab601d", - "revisionTime": "2018-05-22T20:53:45Z" + "revision": "d6e28a8b3199a79da5e74e3dde1eb878ff525f1a", + "revisionTime": "2018-08-06T21:57:00Z" }, { "checksumSHA1": "xSmii71kfQASGNG2C8ttmHx9KTE=", From 773d116032483c6308b59938854a1f56b42eddcf Mon Sep 17 00:00:00 2001 From: Rickard von Essen Date: Thu, 16 Aug 2018 12:09:44 +0200 Subject: [PATCH 186/220] Updated CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c560e0040..1f12d2b54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ * builder/lxc: Allow unplivileged LXC containers. [GH-6279] * builder/oci: Add `metadata` feature to Packer config. [GH-6498] * builder/openstack: Add support for ports. [GH-6570] +* builder/openstack: Add support for getting config from clouds-public.yaml. [GH-6595] * builder/qemu: add ssh agent support. [GH-6541] * builder/qemu: New `use_backing_file` feature [GH-6249] * builder/vmware-iso: Try to use ISO files uploaded to the datastore when From d38bd6b5f85e8f104940f955834ee65f1a931128 Mon Sep 17 00:00:00 2001 From: Andrei Ozerov Date: Thu, 24 May 2018 09:58:43 +0300 Subject: [PATCH 187/220] Vendor: add Gophercloud BlockStorage V3 volumes Add the latest blockstorage v3 volumes client library. --- .../openstack/blockstorage/v3/volumes/doc.go | 5 + .../blockstorage/v3/volumes/requests.go | 202 ++++++++++++++++++ .../blockstorage/v3/volumes/results.go | 170 +++++++++++++++ .../openstack/blockstorage/v3/volumes/urls.go | 23 ++ .../openstack/blockstorage/v3/volumes/util.go | 22 ++ vendor/vendor.json | 20 +- 6 files changed, 441 insertions(+), 1 deletion(-) create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/doc.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/requests.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/results.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/urls.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/util.go diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/doc.go new file mode 100644 index 000000000..307b8b12d --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/doc.go @@ -0,0 +1,5 @@ +// Package volumes provides information and interaction with volumes in the +// OpenStack Block Storage service. A volume is a detachable block storage +// device, akin to a USB hard drive. It can only be attached to one instance at +// a time. +package volumes diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/requests.go new file mode 100644 index 000000000..43727409d --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/requests.go @@ -0,0 +1,202 @@ +package volumes + +import ( + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/pagination" +) + +// CreateOptsBuilder allows extensions to add additional parameters to the +// Create request. +type CreateOptsBuilder interface { + ToVolumeCreateMap() (map[string]interface{}, error) +} + +// CreateOpts contains options for creating a Volume. This object is passed to +// the volumes.Create function. For more information about these parameters, +// see the Volume object. +type CreateOpts struct { + // The size of the volume, in GB + Size int `json:"size" required:"true"` + // The availability zone + AvailabilityZone string `json:"availability_zone,omitempty"` + // ConsistencyGroupID is the ID of a consistency group + ConsistencyGroupID string `json:"consistencygroup_id,omitempty"` + // The volume description + Description string `json:"description,omitempty"` + // One or more metadata key and value pairs to associate with the volume + Metadata map[string]string `json:"metadata,omitempty"` + // The volume name + Name string `json:"name,omitempty"` + // the ID of the existing volume snapshot + SnapshotID string `json:"snapshot_id,omitempty"` + // SourceReplica is a UUID of an existing volume to replicate with + SourceReplica string `json:"source_replica,omitempty"` + // the ID of the existing volume + SourceVolID string `json:"source_volid,omitempty"` + // The ID of the image from which you want to create the volume. + // Required to create a bootable volume. + ImageID string `json:"imageRef,omitempty"` + // The associated volume type + VolumeType string `json:"volume_type,omitempty"` +} + +// ToVolumeCreateMap assembles a request body based on the contents of a +// CreateOpts. +func (opts CreateOpts) ToVolumeCreateMap() (map[string]interface{}, error) { + return gophercloud.BuildRequestBody(opts, "volume") +} + +// Create will create a new Volume based on the values in CreateOpts. To extract +// the Volume object from the response, call the Extract method on the +// CreateResult. +func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { + b, err := opts.ToVolumeCreateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{202}, + }) + return +} + +// Delete will delete the existing Volume with the provided ID. +func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) { + _, r.Err = client.Delete(deleteURL(client, id), nil) + return +} + +// Get retrieves the Volume with the provided ID. To extract the Volume object +// from the response, call the Extract method on the GetResult. +func Get(client *gophercloud.ServiceClient, id string) (r GetResult) { + _, r.Err = client.Get(getURL(client, id), &r.Body, nil) + return +} + +// ListOptsBuilder allows extensions to add additional parameters to the List +// request. +type ListOptsBuilder interface { + ToVolumeListQuery() (string, error) +} + +// ListOpts holds options for listing Volumes. It is passed to the volumes.List +// function. +type ListOpts struct { + // AllTenants will retrieve volumes of all tenants/projects. + AllTenants bool `q:"all_tenants"` + + // Metadata will filter results based on specified metadata. + Metadata map[string]string `q:"metadata"` + + // Name will filter by the specified volume name. + Name string `q:"name"` + + // Status will filter by the specified status. + Status string `q:"status"` + + // TenantID will filter by a specific tenant/project ID. + // Setting AllTenants is required for this. + TenantID string `q:"project_id"` + + // Comma-separated list of sort keys and optional sort directions in the + // form of [:]. + Sort string `q:"sort"` + + // Requests a page size of items. + Limit int `q:"limit"` + + // Used in conjunction with limit to return a slice of items. + Offset int `q:"offset"` + + // The ID of the last-seen item. + Marker string `q:"marker"` +} + +// ToVolumeListQuery formats a ListOpts into a query string. +func (opts ListOpts) ToVolumeListQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + return q.String(), err +} + +// List returns Volumes optionally limited by the conditions provided in ListOpts. +func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { + url := listURL(client) + if opts != nil { + query, err := opts.ToVolumeListQuery() + if err != nil { + return pagination.Pager{Err: err} + } + url += query + } + + return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { + return VolumePage{pagination.LinkedPageBase{PageResult: r}} + }) +} + +// UpdateOptsBuilder allows extensions to add additional parameters to the +// Update request. +type UpdateOptsBuilder interface { + ToVolumeUpdateMap() (map[string]interface{}, error) +} + +// UpdateOpts contain options for updating an existing Volume. This object is passed +// to the volumes.Update function. For more information about the parameters, see +// the Volume object. +type UpdateOpts struct { + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` + Metadata map[string]string `json:"metadata,omitempty"` +} + +// ToVolumeUpdateMap assembles a request body based on the contents of an +// UpdateOpts. +func (opts UpdateOpts) ToVolumeUpdateMap() (map[string]interface{}, error) { + return gophercloud.BuildRequestBody(opts, "volume") +} + +// Update will update the Volume with provided information. To extract the updated +// Volume from the response, call the Extract method on the UpdateResult. +func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { + b, err := opts.ToVolumeUpdateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Put(updateURL(client, id), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + return +} + +// IDFromName is a convienience function that returns a server's ID given its name. +func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) { + count := 0 + id := "" + pages, err := List(client, nil).AllPages() + if err != nil { + return "", err + } + + all, err := ExtractVolumes(pages) + if err != nil { + return "", err + } + + for _, s := range all { + if s.Name == name { + count++ + id = s.ID + } + } + + switch count { + case 0: + return "", gophercloud.ErrResourceNotFound{Name: name, ResourceType: "volume"} + case 1: + return id, nil + default: + return "", gophercloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "volume"} + } +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/results.go new file mode 100644 index 000000000..87f71262c --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/results.go @@ -0,0 +1,170 @@ +package volumes + +import ( + "encoding/json" + "time" + + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/pagination" +) + +// Attachment represents a Volume Attachment record +type Attachment struct { + AttachedAt time.Time `json:"-"` + AttachmentID string `json:"attachment_id"` + Device string `json:"device"` + HostName string `json:"host_name"` + ID string `json:"id"` + ServerID string `json:"server_id"` + VolumeID string `json:"volume_id"` +} + +// UnmarshalJSON is our unmarshalling helper +func (r *Attachment) UnmarshalJSON(b []byte) error { + type tmp Attachment + var s struct { + tmp + AttachedAt gophercloud.JSONRFC3339MilliNoZ `json:"attached_at"` + } + err := json.Unmarshal(b, &s) + if err != nil { + return err + } + *r = Attachment(s.tmp) + + r.AttachedAt = time.Time(s.AttachedAt) + + return err +} + +// Volume contains all the information associated with an OpenStack Volume. +type Volume struct { + // Unique identifier for the volume. + ID string `json:"id"` + // Current status of the volume. + Status string `json:"status"` + // Size of the volume in GB. + Size int `json:"size"` + // AvailabilityZone is which availability zone the volume is in. + AvailabilityZone string `json:"availability_zone"` + // The date when this volume was created. + CreatedAt time.Time `json:"-"` + // The date when this volume was last updated + UpdatedAt time.Time `json:"-"` + // Instances onto which the volume is attached. + Attachments []Attachment `json:"attachments"` + // Human-readable display name for the volume. + Name string `json:"name"` + // Human-readable description for the volume. + Description string `json:"description"` + // The type of volume to create, either SATA or SSD. + VolumeType string `json:"volume_type"` + // The ID of the snapshot from which the volume was created + SnapshotID string `json:"snapshot_id"` + // The ID of another block storage volume from which the current volume was created + SourceVolID string `json:"source_volid"` + // Arbitrary key-value pairs defined by the user. + Metadata map[string]string `json:"metadata"` + // UserID is the id of the user who created the volume. + UserID string `json:"user_id"` + // Indicates whether this is a bootable volume. + Bootable string `json:"bootable"` + // Encrypted denotes if the volume is encrypted. + Encrypted bool `json:"encrypted"` + // ReplicationStatus is the status of replication. + ReplicationStatus string `json:"replication_status"` + // ConsistencyGroupID is the consistency group ID. + ConsistencyGroupID string `json:"consistencygroup_id"` + // Multiattach denotes if the volume is multi-attach capable. + Multiattach bool `json:"multiattach"` +} + +// UnmarshalJSON another unmarshalling function +func (r *Volume) UnmarshalJSON(b []byte) error { + type tmp Volume + var s struct { + tmp + CreatedAt gophercloud.JSONRFC3339MilliNoZ `json:"created_at"` + UpdatedAt gophercloud.JSONRFC3339MilliNoZ `json:"updated_at"` + } + err := json.Unmarshal(b, &s) + if err != nil { + return err + } + *r = Volume(s.tmp) + + r.CreatedAt = time.Time(s.CreatedAt) + r.UpdatedAt = time.Time(s.UpdatedAt) + + return err +} + +// VolumePage is a pagination.pager that is returned from a call to the List function. +type VolumePage struct { + pagination.LinkedPageBase +} + +// IsEmpty returns true if a ListResult contains no Volumes. +func (r VolumePage) IsEmpty() (bool, error) { + volumes, err := ExtractVolumes(r) + return len(volumes) == 0, err +} + +func (page VolumePage) NextPageURL() (string, error) { + var s struct { + Links []gophercloud.Link `json:"volumes_links"` + } + err := page.ExtractInto(&s) + if err != nil { + return "", err + } + return gophercloud.ExtractNextURL(s.Links) +} + +// ExtractVolumes extracts and returns Volumes. It is used while iterating over a volumes.List call. +func ExtractVolumes(r pagination.Page) ([]Volume, error) { + var s []Volume + err := ExtractVolumesInto(r, &s) + return s, err +} + +type commonResult struct { + gophercloud.Result +} + +// Extract will get the Volume object out of the commonResult object. +func (r commonResult) Extract() (*Volume, error) { + var s Volume + err := r.ExtractInto(&s) + return &s, err +} + +// ExtractInto converts our response data into a volume struct +func (r commonResult) ExtractInto(v interface{}) error { + return r.Result.ExtractIntoStructPtr(v, "volume") +} + +// ExtractVolumesInto similar to ExtractInto but operates on a `list` of volumes +func ExtractVolumesInto(r pagination.Page, v interface{}) error { + return r.(VolumePage).Result.ExtractIntoSlicePtr(v, "volumes") +} + +// CreateResult contains the response body and error from a Create request. +type CreateResult struct { + commonResult +} + +// GetResult contains the response body and error from a Get request. +type GetResult struct { + commonResult +} + +// UpdateResult contains the response body and error from an Update request. +type UpdateResult struct { + commonResult +} + +// DeleteResult contains the response body and error from a Delete request. +type DeleteResult struct { + gophercloud.ErrResult +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/urls.go new file mode 100644 index 000000000..170724905 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/urls.go @@ -0,0 +1,23 @@ +package volumes + +import "github.com/gophercloud/gophercloud" + +func createURL(c *gophercloud.ServiceClient) string { + return c.ServiceURL("volumes") +} + +func listURL(c *gophercloud.ServiceClient) string { + return c.ServiceURL("volumes", "detail") +} + +func deleteURL(c *gophercloud.ServiceClient, id string) string { + return c.ServiceURL("volumes", id) +} + +func getURL(c *gophercloud.ServiceClient, id string) string { + return deleteURL(c, id) +} + +func updateURL(c *gophercloud.ServiceClient, id string) string { + return deleteURL(c, id) +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/util.go b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/util.go new file mode 100644 index 000000000..e86c1b4b4 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes/util.go @@ -0,0 +1,22 @@ +package volumes + +import ( + "github.com/gophercloud/gophercloud" +) + +// WaitForStatus will continually poll the resource, checking for a particular +// status. It will do this for the amount of seconds defined. +func WaitForStatus(c *gophercloud.ServiceClient, id, status string, secs int) error { + return gophercloud.WaitFor(secs, func() (bool, error) { + current, err := Get(c, id).Extract() + if err != nil { + return false, err + } + + if current.Status == status { + return true, nil + } + + return false, nil + }) +} diff --git a/vendor/vendor.json b/vendor/vendor.json index f55a3cbdb..8134bfe36 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -738,7 +738,25 @@ "revisionTime": "2018-05-31T02:06:30Z" }, { - "checksumSHA1": "vFS5BwnCdQIfKm1nNWrR+ijsAZA=", + "checksumSHA1": "vqXNCd2My0y/5tPC/Bs79uf6Q4E=", + "path": "github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes", + "revision": "282f25e4025de0a42015d2e2b5faef1d920aad3c", + "revisionTime": "2018-05-15T01:47:05Z" + }, + { + "checksumSHA1": "Au6MAsI90lewLByg9n+Yjtdqdh8=", + "path": "github.com/gophercloud/gophercloud/openstack/common/extensions", + "revision": "95a28eb606def6aaaed082b6b82d3244b0552184", + "revisionTime": "2017-06-23T01:44:30Z" + }, + { + "checksumSHA1": "4XWDCGMYqipwJymi9xJo9UffD7g=", + "path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions", + "revision": "95a28eb606def6aaaed082b6b82d3244b0552184", + "revisionTime": "2017-06-23T01:44:30Z" + }, + { + "checksumSHA1": "e7AW3YDVYJPKUjpqsB4AL9RRlTw=", "path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips", "revision": "7112fcd50da4ea27e8d4d499b30f04eea143bec2", "revisionTime": "2018-05-31T02:06:30Z" From cfa922a1803b17732854a1cb6b5d2816627eb7a7 Mon Sep 17 00:00:00 2001 From: Andrei Ozerov Date: Thu, 24 May 2018 10:00:20 +0300 Subject: [PATCH 188/220] Vendor: add Gophercloud Compute bootfromvolume Add the Compute service extenstion client library to allow server to be created with a remote blockstorage root volume. --- .../v2/extensions/bootfromvolume/doc.go | 152 ++++++++++++++++++ .../v2/extensions/bootfromvolume/requests.go | 120 ++++++++++++++ .../v2/extensions/bootfromvolume/results.go | 12 ++ .../v2/extensions/bootfromvolume/urls.go | 7 + vendor/vendor.json | 6 + 5 files changed, 297 insertions(+) create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/bootfromvolume/doc.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/bootfromvolume/requests.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/bootfromvolume/results.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/bootfromvolume/urls.go diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/bootfromvolume/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/bootfromvolume/doc.go new file mode 100644 index 000000000..d291325e0 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/bootfromvolume/doc.go @@ -0,0 +1,152 @@ +/* +Package bootfromvolume extends a server create request with the ability to +specify block device options. This can be used to boot a server from a block +storage volume as well as specify multiple ephemeral disks upon creation. + +It is recommended to refer to the Block Device Mapping documentation to see +all possible ways to configure a server's block devices at creation time: + +https://docs.openstack.org/nova/latest/user/block-device-mapping.html + +Note that this package implements `block_device_mapping_v2`. + +Example of Creating a Server From an Image + +This example will boot a server from an image and use a standard ephemeral +disk as the server's root disk. This is virtually no different than creating +a server without using block device mappings. + + blockDevices := []bootfromvolume.BlockDevice{ + bootfromvolume.BlockDevice{ + BootIndex: 0, + DeleteOnTermination: true, + DestinationType: bootfromvolume.DestinationLocal, + SourceType: bootfromvolume.SourceImage, + UUID: "image-uuid", + }, + } + + serverCreateOpts := servers.CreateOpts{ + Name: "server_name", + FlavorRef: "flavor-uuid", + ImageRef: "image-uuid", + } + + createOpts := bootfromvolume.CreateOptsExt{ + CreateOptsBuilder: serverCreateOpts, + BlockDevice: blockDevices, + } + + server, err := bootfromvolume.Create(client, createOpts).Extract() + if err != nil { + panic(err) + } + +Example of Creating a Server From a New Volume + +This example will create a block storage volume based on the given Image. The +server will use this volume as its root disk. + + blockDevices := []bootfromvolume.BlockDevice{ + bootfromvolume.BlockDevice{ + DeleteOnTermination: true, + DestinationType: bootfromvolume.DestinationVolume, + SourceType: bootfromvolume.SourceImage, + UUID: "image-uuid", + VolumeSize: 2, + }, + } + + serverCreateOpts := servers.CreateOpts{ + Name: "server_name", + FlavorRef: "flavor-uuid", + } + + createOpts := bootfromvolume.CreateOptsExt{ + CreateOptsBuilder: serverCreateOpts, + BlockDevice: blockDevices, + } + + server, err := bootfromvolume.Create(client, createOpts).Extract() + if err != nil { + panic(err) + } + +Example of Creating a Server From an Existing Volume + +This example will create a server with an existing volume as its root disk. + + blockDevices := []bootfromvolume.BlockDevice{ + bootfromvolume.BlockDevice{ + DeleteOnTermination: true, + DestinationType: bootfromvolume.DestinationVolume, + SourceType: bootfromvolume.SourceVolume, + UUID: "volume-uuid", + }, + } + + serverCreateOpts := servers.CreateOpts{ + Name: "server_name", + FlavorRef: "flavor-uuid", + } + + createOpts := bootfromvolume.CreateOptsExt{ + CreateOptsBuilder: serverCreateOpts, + BlockDevice: blockDevices, + } + + server, err := bootfromvolume.Create(client, createOpts).Extract() + if err != nil { + panic(err) + } + +Example of Creating a Server with Multiple Ephemeral Disks + +This example will create a server with multiple ephemeral disks. The first +block device will be based off of an existing Image. Each additional +ephemeral disks must have an index of -1. + + blockDevices := []bootfromvolume.BlockDevice{ + bootfromvolume.BlockDevice{ + BootIndex: 0, + DestinationType: bootfromvolume.DestinationLocal, + DeleteOnTermination: true, + SourceType: bootfromvolume.SourceImage, + UUID: "image-uuid", + VolumeSize: 5, + }, + bootfromvolume.BlockDevice{ + BootIndex: -1, + DestinationType: bootfromvolume.DestinationLocal, + DeleteOnTermination: true, + GuestFormat: "ext4", + SourceType: bootfromvolume.SourceBlank, + VolumeSize: 1, + }, + bootfromvolume.BlockDevice{ + BootIndex: -1, + DestinationType: bootfromvolume.DestinationLocal, + DeleteOnTermination: true, + GuestFormat: "ext4", + SourceType: bootfromvolume.SourceBlank, + VolumeSize: 1, + }, + } + + serverCreateOpts := servers.CreateOpts{ + Name: "server_name", + FlavorRef: "flavor-uuid", + ImageRef: "image-uuid", + } + + createOpts := bootfromvolume.CreateOptsExt{ + CreateOptsBuilder: serverCreateOpts, + BlockDevice: blockDevices, + } + + server, err := bootfromvolume.Create(client, createOpts).Extract() + if err != nil { + panic(err) + } +*/ +package bootfromvolume diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/bootfromvolume/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/bootfromvolume/requests.go new file mode 100644 index 000000000..9dae14c7a --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/bootfromvolume/requests.go @@ -0,0 +1,120 @@ +package bootfromvolume + +import ( + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" +) + +type ( + // DestinationType represents the type of medium being used as the + // destination of the bootable device. + DestinationType string + + // SourceType represents the type of medium being used as the source of the + // bootable device. + SourceType string +) + +const ( + // DestinationLocal DestinationType is for using an ephemeral disk as the + // destination. + DestinationLocal DestinationType = "local" + + // DestinationVolume DestinationType is for using a volume as the destination. + DestinationVolume DestinationType = "volume" + + // SourceBlank SourceType is for a "blank" or empty source. + SourceBlank SourceType = "blank" + + // SourceImage SourceType is for using images as the source of a block device. + SourceImage SourceType = "image" + + // SourceSnapshot SourceType is for using a volume snapshot as the source of + // a block device. + SourceSnapshot SourceType = "snapshot" + + // SourceVolume SourceType is for using a volume as the source of block + // device. + SourceVolume SourceType = "volume" +) + +// BlockDevice is a structure with options for creating block devices in a +// server. The block device may be created from an image, snapshot, new volume, +// or existing volume. The destination may be a new volume, existing volume +// which will be attached to the instance, ephemeral disk, or boot device. +type BlockDevice struct { + // SourceType must be one of: "volume", "snapshot", "image", or "blank". + SourceType SourceType `json:"source_type" required:"true"` + + // UUID is the unique identifier for the existing volume, snapshot, or + // image (see above). + UUID string `json:"uuid,omitempty"` + + // BootIndex is the boot index. It defaults to 0. + BootIndex int `json:"boot_index"` + + // DeleteOnTermination specifies whether or not to delete the attached volume + // when the server is deleted. Defaults to `false`. + DeleteOnTermination bool `json:"delete_on_termination"` + + // DestinationType is the type that gets created. Possible values are "volume" + // and "local". + DestinationType DestinationType `json:"destination_type,omitempty"` + + // GuestFormat specifies the format of the block device. + GuestFormat string `json:"guest_format,omitempty"` + + // VolumeSize is the size of the volume to create (in gigabytes). This can be + // omitted for existing volumes. + VolumeSize int `json:"volume_size,omitempty"` +} + +// CreateOptsExt is a structure that extends the server `CreateOpts` structure +// by allowing for a block device mapping. +type CreateOptsExt struct { + servers.CreateOptsBuilder + BlockDevice []BlockDevice `json:"block_device_mapping_v2,omitempty"` +} + +// ToServerCreateMap adds the block device mapping option to the base server +// creation options. +func (opts CreateOptsExt) ToServerCreateMap() (map[string]interface{}, error) { + base, err := opts.CreateOptsBuilder.ToServerCreateMap() + if err != nil { + return nil, err + } + + if len(opts.BlockDevice) == 0 { + err := gophercloud.ErrMissingInput{} + err.Argument = "bootfromvolume.CreateOptsExt.BlockDevice" + return nil, err + } + + serverMap := base["server"].(map[string]interface{}) + + blockDevice := make([]map[string]interface{}, len(opts.BlockDevice)) + + for i, bd := range opts.BlockDevice { + b, err := gophercloud.BuildRequestBody(bd, "") + if err != nil { + return nil, err + } + blockDevice[i] = b + } + serverMap["block_device_mapping_v2"] = blockDevice + + return base, nil +} + +// Create requests the creation of a server from the given block device mapping. +func Create(client *gophercloud.ServiceClient, opts servers.CreateOptsBuilder) (r servers.CreateResult) { + b, err := opts.ToServerCreateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200, 202}, + }) + return +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/bootfromvolume/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/bootfromvolume/results.go new file mode 100644 index 000000000..ba1eafabc --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/bootfromvolume/results.go @@ -0,0 +1,12 @@ +package bootfromvolume + +import ( + os "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" +) + +// CreateResult temporarily contains the response from a Create call. +// It embeds the standard servers.CreateResults type and so can be used the +// same way as a standard server request result. +type CreateResult struct { + os.CreateResult +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/bootfromvolume/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/bootfromvolume/urls.go new file mode 100644 index 000000000..dc007eadf --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/bootfromvolume/urls.go @@ -0,0 +1,7 @@ +package bootfromvolume + +import "github.com/gophercloud/gophercloud" + +func createURL(c *gophercloud.ServiceClient) string { + return c.ServiceURL("os-volumes_boot") +} diff --git a/vendor/vendor.json b/vendor/vendor.json index 8134bfe36..01cf5c2e3 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -755,6 +755,12 @@ "revision": "95a28eb606def6aaaed082b6b82d3244b0552184", "revisionTime": "2017-06-23T01:44:30Z" }, + { + "checksumSHA1": "kCHEEeRVZeR1LhbvNP+WyvB8z2s=", + "path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/bootfromvolume", + "revision": "282f25e4025de0a42015d2e2b5faef1d920aad3c", + "revisionTime": "2018-05-15T01:47:05Z" + }, { "checksumSHA1": "e7AW3YDVYJPKUjpqsB4AL9RRlTw=", "path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips", From d51e683bf7250313899d7b5f1666a75a8a52ce25 Mon Sep 17 00:00:00 2001 From: Andrei Ozerov Date: Thu, 24 May 2018 13:20:22 +0300 Subject: [PATCH 189/220] OpenStack builder: add Block Storage volumes This commit allows user to use the Block Storage v3 volume as the Compute instance root volume. Also it adds new volume-related parameters to the builder. --- builder/openstack/access_config.go | 7 + builder/openstack/builder.go | 30 ++-- builder/openstack/run_config.go | 22 +++ builder/openstack/run_config_test.go | 39 +++++ builder/openstack/step_create_volume.go | 173 ++++++++++++++++++++ builder/openstack/step_run_source_server.go | 58 +++++-- 6 files changed, 301 insertions(+), 28 deletions(-) create mode 100644 builder/openstack/step_create_volume.go diff --git a/builder/openstack/access_config.go b/builder/openstack/access_config.go index a5ab91b60..1fcefa659 100644 --- a/builder/openstack/access_config.go +++ b/builder/openstack/access_config.go @@ -194,6 +194,13 @@ func (c *AccessConfig) imageV2Client() (*gophercloud.ServiceClient, error) { }) } +func (c *AccessConfig) blockStorageV3Client() (*gophercloud.ServiceClient, error) { + return openstack.NewBlockStorageV3(c.osClient, gophercloud.EndpointOpts{ + Region: c.Region, + Availability: c.getEndpointType(), + }) +} + func (c *AccessConfig) getEndpointType() gophercloud.Availability { if c.EndpointType == "internal" || c.EndpointType == "internalURL" { return gophercloud.AvailabilityInternal diff --git a/builder/openstack/builder.go b/builder/openstack/builder.go index 8ebd65d3c..26105a9fd 100644 --- a/builder/openstack/builder.go +++ b/builder/openstack/builder.go @@ -86,18 +86,26 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe PrivateKeyFile: b.config.RunConfig.Comm.SSHPrivateKey, SSHAgentAuth: b.config.RunConfig.Comm.SSHAgentAuth, }, + &StepCreateVolume{ + UseBlockStorageVolume: b.config.UseBlockStorageVolume, + SourceImage: b.config.SourceImage, + VolumeName: b.config.VolumeName, + VolumeType: b.config.VolumeType, + VolumeAvailabilityZone: b.config.VolumeAvailabilityZone, + }, &StepRunSourceServer{ - Name: b.config.InstanceName, - SourceImage: b.config.SourceImage, - SourceImageName: b.config.SourceImageName, - SecurityGroups: b.config.SecurityGroups, - Networks: b.config.Networks, - Ports: b.config.Ports, - AvailabilityZone: b.config.AvailabilityZone, - UserData: b.config.UserData, - UserDataFile: b.config.UserDataFile, - ConfigDrive: b.config.ConfigDrive, - InstanceMetadata: b.config.InstanceMetadata, + Name: b.config.InstanceName, + SourceImage: b.config.SourceImage, + SourceImageName: b.config.SourceImageName, + SecurityGroups: b.config.SecurityGroups, + Networks: b.config.Networks, + Ports: b.config.Ports, + AvailabilityZone: b.config.AvailabilityZone, + UserData: b.config.UserData, + UserDataFile: b.config.UserDataFile, + ConfigDrive: b.config.ConfigDrive, + InstanceMetadata: b.config.InstanceMetadata, + UseBlockStorageVolume: b.config.UseBlockStorageVolume, }, &StepGetPassword{ Debug: b.config.PackerDebug, diff --git a/builder/openstack/run_config.go b/builder/openstack/run_config.go index 2562e0c8d..dbe9a2624 100644 --- a/builder/openstack/run_config.go +++ b/builder/openstack/run_config.go @@ -36,6 +36,11 @@ type RunConfig struct { ConfigDrive bool `mapstructure:"config_drive"` + UseBlockStorageVolume bool `mapstructure:"use_blockstorage_volume"` + VolumeName string `mapstructure:"volume_name"` + VolumeType string `mapstructure:"volume_type"` + VolumeAvailabilityZone string `mapstructure:"volume_availability_zone"` + // Not really used, but here for BC OpenstackProvider string `mapstructure:"openstack_provider"` UseFloatingIp bool `mapstructure:"use_floating_ip"` @@ -90,5 +95,22 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { } } + if c.UseBlockStorageVolume { + if c.VolumeType == "" { + errs = append(errs, errors.New("A volume_type must be provided when use_blockstorage_volume is set to true")) + } + + // Use Compute instance availability zone for the Block Storage volume if + // it's not provided. + if c.VolumeAvailabilityZone == "" { + c.VolumeAvailabilityZone = c.AvailabilityZone + } + + // Use random name for the Block Storage volume if it's not provided. + if c.VolumeName == "" { + c.VolumeName = fmt.Sprintf("packer_%s", uuid.TimeOrderedUUID()) + } + } + return errs } diff --git a/builder/openstack/run_config_test.go b/builder/openstack/run_config_test.go index 151dcd99d..b20e832d8 100644 --- a/builder/openstack/run_config_test.go +++ b/builder/openstack/run_config_test.go @@ -70,3 +70,42 @@ func TestRunConfigPrepare_SSHPort(t *testing.T) { t.Fatalf("invalid value: %d", c.Comm.SSHPort) } } + +func TestRunConfigPrepare_BlockStorage(t *testing.T) { + c := testRunConfig() + c.UseBlockStorageVolume = true + c.VolumeType = "fast" + if err := c.Prepare(nil); len(err) != 0 { + t.Fatalf("err: %s", err) + } + if c.VolumeType != "fast" { + t.Fatalf("invalid value: %s", c.VolumeType) + } + + c.AvailabilityZone = "RegionTwo" + if err := c.Prepare(nil); len(err) != 0 { + t.Fatalf("err: %s", err) + } + + if c.VolumeAvailabilityZone != "RegionTwo" { + t.Fatalf("invalid value: %s", c.VolumeAvailabilityZone) + } + + c.VolumeAvailabilityZone = "RegionOne" + if err := c.Prepare(nil); len(err) != 0 { + t.Fatalf("err: %s", err) + } + + if c.VolumeAvailabilityZone != "RegionOne" { + t.Fatalf("invalid value: %s", c.VolumeAvailabilityZone) + } + + c.VolumeName = "PackerVolume" + if err := c.Prepare(nil); len(err) != 0 { + t.Fatalf("err: %s", err) + } + + if c.VolumeName != "PackerVolume" { + t.Fatalf("invalid value: %s", c.VolumeName) + } +} diff --git a/builder/openstack/step_create_volume.go b/builder/openstack/step_create_volume.go new file mode 100644 index 000000000..6ad569c0b --- /dev/null +++ b/builder/openstack/step_create_volume.go @@ -0,0 +1,173 @@ +package openstack + +import ( + "context" + "fmt" + "log" + "time" + + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes" + "github.com/gophercloud/gophercloud/openstack/imageservice/v2/images" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" +) + +type StepCreateVolume struct { + UseBlockStorageVolume bool + SourceImage string + VolumeName string + VolumeType string + VolumeAvailabilityZone string + volumeID string + doCleanup bool +} + +func (s *StepCreateVolume) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + // Proceed only if block storage volume is required. + if !s.UseBlockStorageVolume { + return multistep.ActionContinue + } + + config := state.Get("config").(Config) + ui := state.Get("ui").(packer.Ui) + + // We will need Block Storage and Image services clients. + blockStorageClient, err := config.blockStorageV3Client() + if err != nil { + err = fmt.Errorf("Error initializing block storage client: %s", err) + state.Put("error", err) + return multistep.ActionHalt + } + imageClient, err := config.imageV2Client() + if err != nil { + err = fmt.Errorf("Error initializing image client: %s", err) + state.Put("error", err) + return multistep.ActionHalt + } + + // Get needed volume size from the source image. + volumeSize, err := GetVolumeSize(imageClient, s.SourceImage) + if err != nil { + err := fmt.Errorf("Error creating volume: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + ui.Say("Creating volume...") + volumeOpts := volumes.CreateOpts{ + Size: volumeSize, + VolumeType: s.VolumeType, + AvailabilityZone: s.VolumeAvailabilityZone, + Name: s.VolumeName, + ImageID: s.SourceImage, + } + + volume, err := volumes.Create(blockStorageClient, volumeOpts).Extract() + if err != nil { + err := fmt.Errorf("Error creating volume: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + // Wait for the volume to become ready. + ui.Say(fmt.Sprintf("Waiting for volume %s (volume id: %s) to become ready...", config.VolumeName, volume.ID)) + if err := WaitForVolume(blockStorageClient, volume.ID); err != nil { + err := fmt.Errorf("Error waiting for volume: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + // Volume was created, so remember to clean it up. + s.doCleanup = true + + // Set the Volume ID in the state. + ui.Message(fmt.Sprintf("Volume ID: %s", volume.ID)) + state.Put("volume_id", volume.ID) + s.volumeID = volume.ID + + return multistep.ActionContinue +} + +// GetVolumeSize returns volume size in gigabytes based on the image min disk +// value if it's not empty. +// Or it calculates needed gigabytes size from the image bytes size. +func GetVolumeSize(imageClient *gophercloud.ServiceClient, imageID string) (int, error) { + sourceImage, err := images.Get(imageClient, imageID).Extract() + if err != nil { + return 0, err + } + + if sourceImage.MinDiskGigabytes != 0 { + return sourceImage.MinDiskGigabytes, nil + } + + volumeSizeMB := sourceImage.SizeBytes / 1024 / 1024 + volumeSizeGB := int(sourceImage.SizeBytes / 1024 / 1024 / 1024) + + // Increment gigabytes size if the initial size can't be divided without + // remainder. + if volumeSizeMB%1024 > 0 { + volumeSizeGB++ + } + + return volumeSizeGB, nil +} + +// WaitForVolume waits for the given volume to become ready. +func WaitForVolume(blockStorageClient *gophercloud.ServiceClient, volumeID string) error { + maxNumErrors := 10 + numErrors := 0 + + for { + volume, err := volumes.Get(blockStorageClient, volumeID).Extract() + if err != nil { + errCode, ok := err.(*gophercloud.ErrUnexpectedResponseCode) + if ok && (errCode.Actual == 500 || errCode.Actual == 404) { + numErrors++ + if numErrors >= maxNumErrors { + log.Printf("[ERROR] Maximum number of errors (%d) reached; failing with: %s", numErrors, err) + return err + } + log.Printf("[ERROR] %d error received, will ignore and retry: %s", errCode.Actual, err) + time.Sleep(2 * time.Second) + continue + } + + return err + } + + if volume.Status == "available" { + return nil + } + + log.Printf("Waiting for volume creation status: %s", volume.Status) + time.Sleep(2 * time.Second) + } +} + +func (s *StepCreateVolume) Cleanup(state multistep.StateBag) { + if !s.doCleanup { + return + } + + config := state.Get("config").(Config) + ui := state.Get("ui").(packer.Ui) + + blockStorageClient, err := config.blockStorageV3Client() + if err != nil { + ui.Error(fmt.Sprintf( + "Error cleaning up volume. Please delete the volume manually: %s", s.volumeID)) + return + } + + ui.Say(fmt.Sprintf("Deleting volume: %s ...", s.volumeID)) + err = volumes.Delete(blockStorageClient, s.volumeID).ExtractErr() + if err != nil { + ui.Error(fmt.Sprintf( + "Error cleaning up volume. Please delete the volume manually: %s", s.volumeID)) + } +} diff --git a/builder/openstack/step_run_source_server.go b/builder/openstack/step_run_source_server.go index 28d50ed93..8b9b312bc 100644 --- a/builder/openstack/step_run_source_server.go +++ b/builder/openstack/step_run_source_server.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "log" + "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/bootfromvolume" "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs" "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" "github.com/hashicorp/packer/helper/multistep" @@ -13,18 +14,19 @@ import ( ) type StepRunSourceServer struct { - Name string - SourceImage string - SourceImageName string - SecurityGroups []string - Networks []string - Ports []string - AvailabilityZone string - UserData string - UserDataFile string - ConfigDrive bool - InstanceMetadata map[string]string - server *servers.Server + Name string + SourceImage string + SourceImageName string + SecurityGroups []string + Networks []string + Ports []string + AvailabilityZone string + UserData string + UserDataFile string + ConfigDrive bool + InstanceMetadata map[string]string + UseBlockStorageVolume bool + server *servers.Server } func (s *StepRunSourceServer) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { @@ -74,18 +76,40 @@ func (s *StepRunSourceServer) Run(_ context.Context, state multistep.StateBag) m ServiceClient: computeClient, Metadata: s.InstanceMetadata, } - var serverOptsExt servers.CreateOptsBuilder - keyName, hasKey := state.GetOk("keyPair") - if hasKey { - serverOptsExt = keypairs.CreateOptsExt{ + + // Create root volume in the Block Storage service if required. + // Add block device mapping v2 to the server create options if required. + if s.UseBlockStorageVolume { + volume := state.Get("volume_id").(string) + blockDeviceMappingV2 := []bootfromvolume.BlockDevice{ + bootfromvolume.BlockDevice{ + BootIndex: 0, + DestinationType: bootfromvolume.DestinationVolume, + SourceType: bootfromvolume.SourceVolume, + UUID: volume, + }, + } + // ImageRef and block device mapping is an invalid options combination. + serverOpts.ImageRef = "" + serverOptsExt = bootfromvolume.CreateOptsExt{ CreateOptsBuilder: serverOpts, - KeyName: keyName.(string), + BlockDevice: blockDeviceMappingV2, } } else { serverOptsExt = serverOpts } + // Add keypair to the server create options. + keyName, hasKey := state.GetOk("keyPair") + if hasKey { + serverOptsExt = keypairs.CreateOptsExt{ + CreateOptsBuilder: serverOptsExt, + KeyName: keyName.(string), + } + } + + ui.Say("Launching server...") s.server, err = servers.Create(computeClient, serverOptsExt).Extract() if err != nil { err := fmt.Errorf("Error launching source server: %s", err) From df74951309e9553cb9369a26cd3685147afef194 Mon Sep 17 00:00:00 2001 From: Andrei Ozerov Date: Thu, 24 May 2018 13:47:15 +0300 Subject: [PATCH 190/220] Vendor: add Gophercloud BlockStorage volumeactions Add the Block Storage service extenstion client library to allow detaching of the Instance root volume. --- .../extensions/volumeactions/doc.go | 86 ++++++ .../extensions/volumeactions/requests.go | 269 ++++++++++++++++++ .../extensions/volumeactions/results.go | 191 +++++++++++++ .../extensions/volumeactions/urls.go | 7 + vendor/vendor.json | 6 + 5 files changed, 559 insertions(+) create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/doc.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/requests.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/results.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/urls.go diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/doc.go new file mode 100644 index 000000000..a78d3d048 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/doc.go @@ -0,0 +1,86 @@ +/* +Package volumeactions provides information and interaction with volumes in the +OpenStack Block Storage service. A volume is a detachable block storage +device, akin to a USB hard drive. + +Example of Attaching a Volume to an Instance + + attachOpts := volumeactions.AttachOpts{ + MountPoint: "/mnt", + Mode: "rw", + InstanceUUID: server.ID, + } + + err := volumeactions.Attach(client, volume.ID, attachOpts).ExtractErr() + if err != nil { + panic(err) + } + + detachOpts := volumeactions.DetachOpts{ + AttachmentID: volume.Attachments[0].AttachmentID, + } + + err = volumeactions.Detach(client, volume.ID, detachOpts).ExtractErr() + if err != nil { + panic(err) + } + + +Example of Creating an Image from a Volume + + uploadImageOpts := volumeactions.UploadImageOpts{ + ImageName: "my_vol", + Force: true, + } + + volumeImage, err := volumeactions.UploadImage(client, volume.ID, uploadImageOpts).Extract() + if err != nil { + panic(err) + } + + fmt.Printf("%+v\n", volumeImage) + +Example of Extending a Volume's Size + + extendOpts := volumeactions.ExtendSizeOpts{ + NewSize: 100, + } + + err := volumeactions.ExtendSize(client, volume.ID, extendOpts).ExtractErr() + if err != nil { + panic(err) + } + +Example of Initializing a Volume Connection + + connectOpts := &volumeactions.InitializeConnectionOpts{ + IP: "127.0.0.1", + Host: "stack", + Initiator: "iqn.1994-05.com.redhat:17cf566367d2", + Multipath: gophercloud.Disabled, + Platform: "x86_64", + OSType: "linux2", + } + + connectionInfo, err := volumeactions.InitializeConnection(client, volume.ID, connectOpts).Extract() + if err != nil { + panic(err) + } + + fmt.Printf("%+v\n", connectionInfo["data"]) + + terminateOpts := &volumeactions.InitializeConnectionOpts{ + IP: "127.0.0.1", + Host: "stack", + Initiator: "iqn.1994-05.com.redhat:17cf566367d2", + Multipath: gophercloud.Disabled, + Platform: "x86_64", + OSType: "linux2", + } + + err = volumeactions.TerminateConnection(client, volume.ID, terminateOpts).ExtractErr() + if err != nil { + panic(err) + } +*/ +package volumeactions diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/requests.go new file mode 100644 index 000000000..d18bff555 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/requests.go @@ -0,0 +1,269 @@ +package volumeactions + +import ( + "github.com/gophercloud/gophercloud" +) + +// AttachOptsBuilder allows extensions to add additional parameters to the +// Attach request. +type AttachOptsBuilder interface { + ToVolumeAttachMap() (map[string]interface{}, error) +} + +// AttachMode describes the attachment mode for volumes. +type AttachMode string + +// These constants determine how a volume is attached. +const ( + ReadOnly AttachMode = "ro" + ReadWrite AttachMode = "rw" +) + +// AttachOpts contains options for attaching a Volume. +type AttachOpts struct { + // The mountpoint of this volume. + MountPoint string `json:"mountpoint,omitempty"` + + // The nova instance ID, can't set simultaneously with HostName. + InstanceUUID string `json:"instance_uuid,omitempty"` + + // The hostname of baremetal host, can't set simultaneously with InstanceUUID. + HostName string `json:"host_name,omitempty"` + + // Mount mode of this volume. + Mode AttachMode `json:"mode,omitempty"` +} + +// ToVolumeAttachMap assembles a request body based on the contents of a +// AttachOpts. +func (opts AttachOpts) ToVolumeAttachMap() (map[string]interface{}, error) { + return gophercloud.BuildRequestBody(opts, "os-attach") +} + +// Attach will attach a volume based on the values in AttachOpts. +func Attach(client *gophercloud.ServiceClient, id string, opts AttachOptsBuilder) (r AttachResult) { + b, err := opts.ToVolumeAttachMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{ + OkCodes: []int{202}, + }) + return +} + +// BeginDetach will mark the volume as detaching. +func BeginDetaching(client *gophercloud.ServiceClient, id string) (r BeginDetachingResult) { + b := map[string]interface{}{"os-begin_detaching": make(map[string]interface{})} + _, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{ + OkCodes: []int{202}, + }) + return +} + +// DetachOptsBuilder allows extensions to add additional parameters to the +// Detach request. +type DetachOptsBuilder interface { + ToVolumeDetachMap() (map[string]interface{}, error) +} + +// DetachOpts contains options for detaching a Volume. +type DetachOpts struct { + // AttachmentID is the ID of the attachment between a volume and instance. + AttachmentID string `json:"attachment_id,omitempty"` +} + +// ToVolumeDetachMap assembles a request body based on the contents of a +// DetachOpts. +func (opts DetachOpts) ToVolumeDetachMap() (map[string]interface{}, error) { + return gophercloud.BuildRequestBody(opts, "os-detach") +} + +// Detach will detach a volume based on volume ID. +func Detach(client *gophercloud.ServiceClient, id string, opts DetachOptsBuilder) (r DetachResult) { + b, err := opts.ToVolumeDetachMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{ + OkCodes: []int{202}, + }) + return +} + +// Reserve will reserve a volume based on volume ID. +func Reserve(client *gophercloud.ServiceClient, id string) (r ReserveResult) { + b := map[string]interface{}{"os-reserve": make(map[string]interface{})} + _, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{ + OkCodes: []int{200, 201, 202}, + }) + return +} + +// Unreserve will unreserve a volume based on volume ID. +func Unreserve(client *gophercloud.ServiceClient, id string) (r UnreserveResult) { + b := map[string]interface{}{"os-unreserve": make(map[string]interface{})} + _, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{ + OkCodes: []int{200, 201, 202}, + }) + return +} + +// InitializeConnectionOptsBuilder allows extensions to add additional parameters to the +// InitializeConnection request. +type InitializeConnectionOptsBuilder interface { + ToVolumeInitializeConnectionMap() (map[string]interface{}, error) +} + +// InitializeConnectionOpts hosts options for InitializeConnection. +// The fields are specific to the storage driver in use and the destination +// attachment. +type InitializeConnectionOpts struct { + IP string `json:"ip,omitempty"` + Host string `json:"host,omitempty"` + Initiator string `json:"initiator,omitempty"` + Wwpns []string `json:"wwpns,omitempty"` + Wwnns string `json:"wwnns,omitempty"` + Multipath *bool `json:"multipath,omitempty"` + Platform string `json:"platform,omitempty"` + OSType string `json:"os_type,omitempty"` +} + +// ToVolumeInitializeConnectionMap assembles a request body based on the contents of a +// InitializeConnectionOpts. +func (opts InitializeConnectionOpts) ToVolumeInitializeConnectionMap() (map[string]interface{}, error) { + b, err := gophercloud.BuildRequestBody(opts, "connector") + return map[string]interface{}{"os-initialize_connection": b}, err +} + +// InitializeConnection initializes an iSCSI connection by volume ID. +func InitializeConnection(client *gophercloud.ServiceClient, id string, opts InitializeConnectionOptsBuilder) (r InitializeConnectionResult) { + b, err := opts.ToVolumeInitializeConnectionMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(actionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200, 201, 202}, + }) + return +} + +// TerminateConnectionOptsBuilder allows extensions to add additional parameters to the +// TerminateConnection request. +type TerminateConnectionOptsBuilder interface { + ToVolumeTerminateConnectionMap() (map[string]interface{}, error) +} + +// TerminateConnectionOpts hosts options for TerminateConnection. +type TerminateConnectionOpts struct { + IP string `json:"ip,omitempty"` + Host string `json:"host,omitempty"` + Initiator string `json:"initiator,omitempty"` + Wwpns []string `json:"wwpns,omitempty"` + Wwnns string `json:"wwnns,omitempty"` + Multipath *bool `json:"multipath,omitempty"` + Platform string `json:"platform,omitempty"` + OSType string `json:"os_type,omitempty"` +} + +// ToVolumeTerminateConnectionMap assembles a request body based on the contents of a +// TerminateConnectionOpts. +func (opts TerminateConnectionOpts) ToVolumeTerminateConnectionMap() (map[string]interface{}, error) { + b, err := gophercloud.BuildRequestBody(opts, "connector") + return map[string]interface{}{"os-terminate_connection": b}, err +} + +// TerminateConnection terminates an iSCSI connection by volume ID. +func TerminateConnection(client *gophercloud.ServiceClient, id string, opts TerminateConnectionOptsBuilder) (r TerminateConnectionResult) { + b, err := opts.ToVolumeTerminateConnectionMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{ + OkCodes: []int{202}, + }) + return +} + +// ExtendSizeOptsBuilder allows extensions to add additional parameters to the +// ExtendSize request. +type ExtendSizeOptsBuilder interface { + ToVolumeExtendSizeMap() (map[string]interface{}, error) +} + +// ExtendSizeOpts contains options for extending the size of an existing Volume. +// This object is passed to the volumes.ExtendSize function. +type ExtendSizeOpts struct { + // NewSize is the new size of the volume, in GB. + NewSize int `json:"new_size" required:"true"` +} + +// ToVolumeExtendSizeMap assembles a request body based on the contents of an +// ExtendSizeOpts. +func (opts ExtendSizeOpts) ToVolumeExtendSizeMap() (map[string]interface{}, error) { + return gophercloud.BuildRequestBody(opts, "os-extend") +} + +// ExtendSize will extend the size of the volume based on the provided information. +// This operation does not return a response body. +func ExtendSize(client *gophercloud.ServiceClient, id string, opts ExtendSizeOptsBuilder) (r ExtendSizeResult) { + b, err := opts.ToVolumeExtendSizeMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{ + OkCodes: []int{202}, + }) + return +} + +// UploadImageOptsBuilder allows extensions to add additional parameters to the +// UploadImage request. +type UploadImageOptsBuilder interface { + ToVolumeUploadImageMap() (map[string]interface{}, error) +} + +// UploadImageOpts contains options for uploading a Volume to image storage. +type UploadImageOpts struct { + // Container format, may be bare, ofv, ova, etc. + ContainerFormat string `json:"container_format,omitempty"` + + // Disk format, may be raw, qcow2, vhd, vdi, vmdk, etc. + DiskFormat string `json:"disk_format,omitempty"` + + // The name of image that will be stored in glance. + ImageName string `json:"image_name,omitempty"` + + // Force image creation, usable if volume attached to instance. + Force bool `json:"force,omitempty"` +} + +// ToVolumeUploadImageMap assembles a request body based on the contents of a +// UploadImageOpts. +func (opts UploadImageOpts) ToVolumeUploadImageMap() (map[string]interface{}, error) { + return gophercloud.BuildRequestBody(opts, "os-volume_upload_image") +} + +// UploadImage will upload an image based on the values in UploadImageOptsBuilder. +func UploadImage(client *gophercloud.ServiceClient, id string, opts UploadImageOptsBuilder) (r UploadImageResult) { + b, err := opts.ToVolumeUploadImageMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(actionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{202}, + }) + return +} + +// ForceDelete will delete the volume regardless of state. +func ForceDelete(client *gophercloud.ServiceClient, id string) (r ForceDeleteResult) { + _, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"os-force_delete": ""}, nil, nil) + return +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/results.go new file mode 100644 index 000000000..5cadd360f --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/results.go @@ -0,0 +1,191 @@ +package volumeactions + +import ( + "encoding/json" + "time" + + "github.com/gophercloud/gophercloud" +) + +// AttachResult contains the response body and error from an Attach request. +type AttachResult struct { + gophercloud.ErrResult +} + +// BeginDetachingResult contains the response body and error from a BeginDetach +// request. +type BeginDetachingResult struct { + gophercloud.ErrResult +} + +// DetachResult contains the response body and error from a Detach request. +type DetachResult struct { + gophercloud.ErrResult +} + +// UploadImageResult contains the response body and error from an UploadImage +// request. +type UploadImageResult struct { + gophercloud.Result +} + +// ReserveResult contains the response body and error from a Reserve request. +type ReserveResult struct { + gophercloud.ErrResult +} + +// UnreserveResult contains the response body and error from an Unreserve +// request. +type UnreserveResult struct { + gophercloud.ErrResult +} + +// TerminateConnectionResult contains the response body and error from a +// TerminateConnection request. +type TerminateConnectionResult struct { + gophercloud.ErrResult +} + +// InitializeConnectionResult contains the response body and error from an +// InitializeConnection request. +type InitializeConnectionResult struct { + gophercloud.Result +} + +// ExtendSizeResult contains the response body and error from an ExtendSize request. +type ExtendSizeResult struct { + gophercloud.ErrResult +} + +// Extract will get the connection information out of the +// InitializeConnectionResult object. +// +// This will be a generic map[string]interface{} and the results will be +// dependent on the type of connection made. +func (r InitializeConnectionResult) Extract() (map[string]interface{}, error) { + var s struct { + ConnectionInfo map[string]interface{} `json:"connection_info"` + } + err := r.ExtractInto(&s) + return s.ConnectionInfo, err +} + +// ImageVolumeType contains volume type information obtained from UploadImage +// action. +type ImageVolumeType struct { + // The ID of a volume type. + ID string `json:"id"` + + // Human-readable display name for the volume type. + Name string `json:"name"` + + // Human-readable description for the volume type. + Description string `json:"display_description"` + + // Flag for public access. + IsPublic bool `json:"is_public"` + + // Extra specifications for volume type. + ExtraSpecs map[string]interface{} `json:"extra_specs"` + + // ID of quality of service specs. + QosSpecsID string `json:"qos_specs_id"` + + // Flag for deletion status of volume type. + Deleted bool `json:"deleted"` + + // The date when volume type was deleted. + DeletedAt time.Time `json:"-"` + + // The date when volume type was created. + CreatedAt time.Time `json:"-"` + + // The date when this volume was last updated. + UpdatedAt time.Time `json:"-"` +} + +func (r *ImageVolumeType) UnmarshalJSON(b []byte) error { + type tmp ImageVolumeType + var s struct { + tmp + CreatedAt gophercloud.JSONRFC3339MilliNoZ `json:"created_at"` + UpdatedAt gophercloud.JSONRFC3339MilliNoZ `json:"updated_at"` + DeletedAt gophercloud.JSONRFC3339MilliNoZ `json:"deleted_at"` + } + err := json.Unmarshal(b, &s) + if err != nil { + return err + } + *r = ImageVolumeType(s.tmp) + + r.CreatedAt = time.Time(s.CreatedAt) + r.UpdatedAt = time.Time(s.UpdatedAt) + r.DeletedAt = time.Time(s.DeletedAt) + + return err +} + +// VolumeImage contains information about volume uploaded to an image service. +type VolumeImage struct { + // The ID of a volume an image is created from. + VolumeID string `json:"id"` + + // Container format, may be bare, ofv, ova, etc. + ContainerFormat string `json:"container_format"` + + // Disk format, may be raw, qcow2, vhd, vdi, vmdk, etc. + DiskFormat string `json:"disk_format"` + + // Human-readable description for the volume. + Description string `json:"display_description"` + + // The ID of the created image. + ImageID string `json:"image_id"` + + // Human-readable display name for the image. + ImageName string `json:"image_name"` + + // Size of the volume in GB. + Size int `json:"size"` + + // Current status of the volume. + Status string `json:"status"` + + // The date when this volume was last updated. + UpdatedAt time.Time `json:"-"` + + // Volume type object of used volume. + VolumeType ImageVolumeType `json:"volume_type"` +} + +func (r *VolumeImage) UnmarshalJSON(b []byte) error { + type tmp VolumeImage + var s struct { + tmp + UpdatedAt gophercloud.JSONRFC3339MilliNoZ `json:"updated_at"` + } + err := json.Unmarshal(b, &s) + if err != nil { + return err + } + *r = VolumeImage(s.tmp) + + r.UpdatedAt = time.Time(s.UpdatedAt) + + return err +} + +// Extract will get an object with info about the uploaded image out of the +// UploadImageResult object. +func (r UploadImageResult) Extract() (VolumeImage, error) { + var s struct { + VolumeImage VolumeImage `json:"os-volume_upload_image"` + } + err := r.ExtractInto(&s) + return s.VolumeImage, err +} + +// ForceDeleteResult contains the response body and error from a ForceDelete request. +type ForceDeleteResult struct { + gophercloud.ErrResult +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/urls.go new file mode 100644 index 000000000..20486ed71 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions/urls.go @@ -0,0 +1,7 @@ +package volumeactions + +import "github.com/gophercloud/gophercloud" + +func actionURL(c *gophercloud.ServiceClient, id string) string { + return c.ServiceURL("volumes", id, "action") +} diff --git a/vendor/vendor.json b/vendor/vendor.json index 01cf5c2e3..0d782d013 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -737,6 +737,12 @@ "revision": "7112fcd50da4ea27e8d4d499b30f04eea143bec2", "revisionTime": "2018-05-31T02:06:30Z" }, + { + "checksumSHA1": "8YtBD+Um7I8ee1Xf1ZAWu74eP7w=", + "path": "github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions", + "revision": "282f25e4025de0a42015d2e2b5faef1d920aad3c", + "revisionTime": "2018-05-15T01:47:05Z" + }, { "checksumSHA1": "vqXNCd2My0y/5tPC/Bs79uf6Q4E=", "path": "github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes", From 005f7e56a71fdd68356b81b6e677cc54e85650d1 Mon Sep 17 00:00:00 2001 From: Andrei Ozerov Date: Thu, 24 May 2018 13:49:33 +0300 Subject: [PATCH 191/220] OpenStack builder: cleanup blockDeviceMappingV2 There is no need to indicate type of the list elements, remove it. --- builder/openstack/step_run_source_server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/openstack/step_run_source_server.go b/builder/openstack/step_run_source_server.go index 8b9b312bc..e56218467 100644 --- a/builder/openstack/step_run_source_server.go +++ b/builder/openstack/step_run_source_server.go @@ -83,7 +83,7 @@ func (s *StepRunSourceServer) Run(_ context.Context, state multistep.StateBag) m if s.UseBlockStorageVolume { volume := state.Get("volume_id").(string) blockDeviceMappingV2 := []bootfromvolume.BlockDevice{ - bootfromvolume.BlockDevice{ + { BootIndex: 0, DestinationType: bootfromvolume.DestinationVolume, SourceType: bootfromvolume.SourceVolume, From c0ffe7eb8938571b5149b636e61f66f15dcaebfe Mon Sep 17 00:00:00 2001 From: Andrei Ozerov Date: Thu, 24 May 2018 14:15:03 +0300 Subject: [PATCH 192/220] OpenStack builder: add StepDetachVolume Add a step of detaching Compute instance volume if it's created using the Block Storage service. It is needed to create a final image. This commit also moves common volume functions to a different file and fixes some messages in the StepCreateVolume. --- builder/openstack/builder.go | 3 ++ builder/openstack/step_create_volume.go | 66 +----------------------- builder/openstack/step_detach_volume.go | 54 ++++++++++++++++++++ builder/openstack/volume.go | 67 +++++++++++++++++++++++++ 4 files changed, 126 insertions(+), 64 deletions(-) create mode 100644 builder/openstack/step_detach_volume.go create mode 100644 builder/openstack/volume.go diff --git a/builder/openstack/builder.go b/builder/openstack/builder.go index 26105a9fd..5bffead8e 100644 --- a/builder/openstack/builder.go +++ b/builder/openstack/builder.go @@ -132,6 +132,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, &common.StepProvision{}, &StepStopServer{}, + &StepDetachVolume{ + UseBlockStorageVolume: b.config.UseBlockStorageVolume, + }, &stepCreateImage{}, &stepUpdateImageVisibility{}, &stepAddImageMembers{}, diff --git a/builder/openstack/step_create_volume.go b/builder/openstack/step_create_volume.go index 6ad569c0b..a188012f9 100644 --- a/builder/openstack/step_create_volume.go +++ b/builder/openstack/step_create_volume.go @@ -3,12 +3,8 @@ package openstack import ( "context" "fmt" - "log" - "time" - "github.com/gophercloud/gophercloud" "github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes" - "github.com/gophercloud/gophercloud/openstack/imageservice/v2/images" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) @@ -63,7 +59,6 @@ func (s *StepCreateVolume) Run(_ context.Context, state multistep.StateBag) mult Name: s.VolumeName, ImageID: s.SourceImage, } - volume, err := volumes.Create(blockStorageClient, volumeOpts).Extract() if err != nil { err := fmt.Errorf("Error creating volume: %s", err) @@ -72,8 +67,8 @@ func (s *StepCreateVolume) Run(_ context.Context, state multistep.StateBag) mult return multistep.ActionHalt } - // Wait for the volume to become ready. - ui.Say(fmt.Sprintf("Waiting for volume %s (volume id: %s) to become ready...", config.VolumeName, volume.ID)) + // Wait for volume to become available. + ui.Say(fmt.Sprintf("Waiting for volume %s (volume id: %s) to become available...", config.VolumeName, volume.ID)) if err := WaitForVolume(blockStorageClient, volume.ID); err != nil { err := fmt.Errorf("Error waiting for volume: %s", err) state.Put("error", err) @@ -92,63 +87,6 @@ func (s *StepCreateVolume) Run(_ context.Context, state multistep.StateBag) mult return multistep.ActionContinue } -// GetVolumeSize returns volume size in gigabytes based on the image min disk -// value if it's not empty. -// Or it calculates needed gigabytes size from the image bytes size. -func GetVolumeSize(imageClient *gophercloud.ServiceClient, imageID string) (int, error) { - sourceImage, err := images.Get(imageClient, imageID).Extract() - if err != nil { - return 0, err - } - - if sourceImage.MinDiskGigabytes != 0 { - return sourceImage.MinDiskGigabytes, nil - } - - volumeSizeMB := sourceImage.SizeBytes / 1024 / 1024 - volumeSizeGB := int(sourceImage.SizeBytes / 1024 / 1024 / 1024) - - // Increment gigabytes size if the initial size can't be divided without - // remainder. - if volumeSizeMB%1024 > 0 { - volumeSizeGB++ - } - - return volumeSizeGB, nil -} - -// WaitForVolume waits for the given volume to become ready. -func WaitForVolume(blockStorageClient *gophercloud.ServiceClient, volumeID string) error { - maxNumErrors := 10 - numErrors := 0 - - for { - volume, err := volumes.Get(blockStorageClient, volumeID).Extract() - if err != nil { - errCode, ok := err.(*gophercloud.ErrUnexpectedResponseCode) - if ok && (errCode.Actual == 500 || errCode.Actual == 404) { - numErrors++ - if numErrors >= maxNumErrors { - log.Printf("[ERROR] Maximum number of errors (%d) reached; failing with: %s", numErrors, err) - return err - } - log.Printf("[ERROR] %d error received, will ignore and retry: %s", errCode.Actual, err) - time.Sleep(2 * time.Second) - continue - } - - return err - } - - if volume.Status == "available" { - return nil - } - - log.Printf("Waiting for volume creation status: %s", volume.Status) - time.Sleep(2 * time.Second) - } -} - func (s *StepCreateVolume) Cleanup(state multistep.StateBag) { if !s.doCleanup { return diff --git a/builder/openstack/step_detach_volume.go b/builder/openstack/step_detach_volume.go new file mode 100644 index 000000000..ff739e94d --- /dev/null +++ b/builder/openstack/step_detach_volume.go @@ -0,0 +1,54 @@ +package openstack + +import ( + "context" + "fmt" + + "github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" +) + +type StepDetachVolume struct { + UseBlockStorageVolume bool +} + +func (s *StepDetachVolume) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + // Proceed only if block storage volume is used. + if !s.UseBlockStorageVolume { + return multistep.ActionContinue + } + + config := state.Get("config").(Config) + ui := state.Get("ui").(packer.Ui) + + blockStorageClient, err := config.blockStorageV3Client() + if err != nil { + err = fmt.Errorf("Error initializing block storage client: %s", err) + state.Put("error", err) + return multistep.ActionHalt + } + + volume := state.Get("volume_id").(string) + ui.Say(fmt.Sprintf("Detaching volume %s (volume id: %s)", config.VolumeName, volume)) + if err := volumeactions.Detach(blockStorageClient, volume, volumeactions.DetachOpts{}).ExtractErr(); err != nil { + err = fmt.Errorf("Error detaching block storage volume: %s", err) + state.Put("error", err) + return multistep.ActionHalt + } + + // Wait for volume to become available. + ui.Say(fmt.Sprintf("Waiting for volume %s (volume id: %s) to become available...", config.VolumeName, volume)) + if err := WaitForVolume(blockStorageClient, volume); err != nil { + err := fmt.Errorf("Error waiting for volume: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + return multistep.ActionContinue +} + +func (s *StepDetachVolume) Cleanup(multistep.StateBag) { + // No cleanup. +} diff --git a/builder/openstack/volume.go b/builder/openstack/volume.go new file mode 100644 index 000000000..5eba12578 --- /dev/null +++ b/builder/openstack/volume.go @@ -0,0 +1,67 @@ +package openstack + +import ( + "log" + "time" + + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes" + "github.com/gophercloud/gophercloud/openstack/imageservice/v2/images" +) + +// WaitForVolume waits for the given volume to become available. +func WaitForVolume(blockStorageClient *gophercloud.ServiceClient, volumeID string) error { + maxNumErrors := 10 + numErrors := 0 + + for { + volume, err := volumes.Get(blockStorageClient, volumeID).Extract() + if err != nil { + errCode, ok := err.(*gophercloud.ErrUnexpectedResponseCode) + if ok && (errCode.Actual == 500 || errCode.Actual == 404) { + numErrors++ + if numErrors >= maxNumErrors { + log.Printf("[ERROR] Maximum number of errors (%d) reached; failing with: %s", numErrors, err) + return err + } + log.Printf("[ERROR] %d error received, will ignore and retry: %s", errCode.Actual, err) + time.Sleep(2 * time.Second) + continue + } + + return err + } + + if volume.Status == "available" { + return nil + } + + log.Printf("Waiting for volume creation status: %s", volume.Status) + time.Sleep(2 * time.Second) + } +} + +// GetVolumeSize returns volume size in gigabytes based on the image min disk +// value if it's not empty. +// Or it calculates needed gigabytes size from the image bytes size. +func GetVolumeSize(imageClient *gophercloud.ServiceClient, imageID string) (int, error) { + sourceImage, err := images.Get(imageClient, imageID).Extract() + if err != nil { + return 0, err + } + + if sourceImage.MinDiskGigabytes != 0 { + return sourceImage.MinDiskGigabytes, nil + } + + volumeSizeMB := sourceImage.SizeBytes / 1024 / 1024 + volumeSizeGB := int(sourceImage.SizeBytes / 1024 / 1024 / 1024) + + // Increment gigabytes size if the initial size can't be divided without + // remainder. + if volumeSizeMB%1024 > 0 { + volumeSizeGB++ + } + + return volumeSizeGB, nil +} From 572cdeecd119cc3c92b91c1248a9a1e109767633 Mon Sep 17 00:00:00 2001 From: Andrei Ozerov Date: Thu, 24 May 2018 14:46:30 +0300 Subject: [PATCH 193/220] OpenStack builder: create image from blockstorage Allow to create final image from the Block Storage service volume. --- builder/openstack/builder.go | 4 ++- builder/openstack/step_create_image.go | 50 ++++++++++++++++++++------ 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/builder/openstack/builder.go b/builder/openstack/builder.go index 5bffead8e..56631cf0b 100644 --- a/builder/openstack/builder.go +++ b/builder/openstack/builder.go @@ -135,7 +135,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &StepDetachVolume{ UseBlockStorageVolume: b.config.UseBlockStorageVolume, }, - &stepCreateImage{}, + &stepCreateImage{ + UseBlockStorageVolume: b.config.UseBlockStorageVolume, + }, &stepUpdateImageVisibility{}, &stepAddImageMembers{}, } diff --git a/builder/openstack/step_create_image.go b/builder/openstack/step_create_image.go index de8a6f4f6..550ddcd28 100644 --- a/builder/openstack/step_create_image.go +++ b/builder/openstack/step_create_image.go @@ -6,6 +6,8 @@ import ( "log" "time" + "github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions" + "github.com/gophercloud/gophercloud" "github.com/gophercloud/gophercloud/openstack/compute/v2/images" "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" @@ -13,7 +15,9 @@ import ( "github.com/hashicorp/packer/packer" ) -type stepCreateImage struct{} +type stepCreateImage struct { + UseBlockStorageVolume bool +} func (s *stepCreateImage) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(Config) @@ -28,17 +32,41 @@ func (s *stepCreateImage) Run(_ context.Context, state multistep.StateBag) multi return multistep.ActionHalt } - // Create the image + // Create the image. + // Image source depends on the type of the Compute instance. It can be + // Block Storage service volume or regular Compute service local volume. ui.Say(fmt.Sprintf("Creating the image: %s", config.ImageName)) - imageId, err := servers.CreateImage(client, server.ID, servers.CreateImageOpts{ - Name: config.ImageName, - Metadata: config.ImageMetadata, - }).ExtractImageID() - if err != nil { - err := fmt.Errorf("Error creating image: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt + var imageId string + if s.UseBlockStorageVolume { + // We need the v3 block storage client. + blockStorageClient, err := config.blockStorageV3Client() + if err != nil { + err = fmt.Errorf("Error initializing block storage client: %s", err) + state.Put("error", err) + return multistep.ActionHalt + } + volume := state.Get("volume_id").(string) + image, err := volumeactions.UploadImage(blockStorageClient, volume, volumeactions.UploadImageOpts{ + ImageName: config.ImageName, + }).Extract() + if err != nil { + err := fmt.Errorf("Error creating image: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + imageId = image.ImageID + } else { + imageId, err = servers.CreateImage(client, server.ID, servers.CreateImageOpts{ + Name: config.ImageName, + Metadata: config.ImageMetadata, + }).ExtractImageID() + if err != nil { + err := fmt.Errorf("Error creating image: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } } // Set the Image ID in the state From 357ff19c525199f5822c6a4311d719994ff044d7 Mon Sep 17 00:00:00 2001 From: Andrei Ozerov Date: Thu, 24 May 2018 15:32:22 +0300 Subject: [PATCH 194/220] OpenStack docs: add blockstorage volumes info Add notes, available parameters and basic example of how to use OpenStack Block Storage volume as a root volume of an instance. --- .../source/docs/builders/openstack.html.md | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/website/source/docs/builders/openstack.html.md b/website/source/docs/builders/openstack.html.md index 00f5e46dd..5ac1cac85 100644 --- a/website/source/docs/builders/openstack.html.md +++ b/website/source/docs/builders/openstack.html.md @@ -36,6 +36,9 @@ installed *if you are using temporary key pairs*, i.e. don't use OS'es have OpenSSL installed by default except Windows. This have been resolved in OpenStack Ocata(Feb 2017). +~> **Note:** OpenStack Block Storage volume support is available only for +V3 Block Storage API. It's available in OpenStack since Mitaka release +(Apr 2016). ## Configuration Reference @@ -206,6 +209,22 @@ builder. - `user_data_file` (string) - Path to a file that will be used for the user data when launching the instance. +- `use_blockstorage_volume` (boolean) - Use Block Storage service volume for + the instance root volume instead of Compute service local volume (default). + +- `volume_name` (string) - Name of the Block Storage service volume. If this + isn't specified, random string will be used. + +- `volume_type` (string) - Type of the Block Storage service volume. If this + isn't specified, the default enforced by your OpenStack cluster will be + used. + +- `volume_availability_zone` (string) - Availability zone of the Block + Storage service volume. If omitted, Compute instance availability zone will + be used. If both of Compute instance and Block Storage volume availability + zones aren't specified, the default enforced by your OpenStack cluster will + be used. + ## Basic Example: DevStack Here is a basic example. This is a example to build on DevStack running in a VM. @@ -293,6 +312,31 @@ export OS_USER_DOMAIN_NAME="mydomain" export OS_PROJECT_DOMAIN_NAME="mydomain" ``` +## Basic Example: Instance with Block Storage root volume + +A basic example of Instance with a remote root Block Storage service volume. +This is a working example to build an image on private OpenStack cloud powered +by Selectel VPC. + +``` json +{ + "type": "openstack", + "identity_endpoint": "https://api.selvpc.com/identity/v3", + "tenant_id": "2e90c5c04c7b4c509be78723e2b55b77", + "username": "foo", + "password": "foo", + "region": "ru-3", + "ssh_username": "root", + "image_name": "Test image", + "source_image": "5f58ea7e-6264-4939-9d0f-0c23072b1132", + "networks": "9aab504e-bedf-48af-9256-682a7fa3dabb", + "flavor": "1001", + "availability_zone": "ru-3a", + "use_blockstorage_volume": true, + "volume_type": "fast.ru-3a" +} +``` + ## Notes on OpenStack Authorization The simplest way to get all settings for authorization against OpenStack is to From 3316d405271e966079587f17afe9de21a0b77513 Mon Sep 17 00:00:00 2001 From: Andrei Ozerov Date: Thu, 24 May 2018 15:37:18 +0300 Subject: [PATCH 195/220] OpenStack builder: make volume type optional Volume type parameter should be optional as described in API reference: https://developer.openstack.org/api-ref/block-storage/v3/#create-a-volume It should be enforced by the OpenStack cluster if not specified. --- builder/openstack/run_config.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/builder/openstack/run_config.go b/builder/openstack/run_config.go index dbe9a2624..9e89e2477 100644 --- a/builder/openstack/run_config.go +++ b/builder/openstack/run_config.go @@ -96,10 +96,6 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { } if c.UseBlockStorageVolume { - if c.VolumeType == "" { - errs = append(errs, errors.New("A volume_type must be provided when use_blockstorage_volume is set to true")) - } - // Use Compute instance availability zone for the Block Storage volume if // it's not provided. if c.VolumeAvailabilityZone == "" { From 17b368cf8b0a808a48e30083d7d4c42943f4c1b3 Mon Sep 17 00:00:00 2001 From: Rickard von Essen Date: Thu, 16 Aug 2018 12:35:13 +0200 Subject: [PATCH 196/220] Fixed vendor.json checksum --- vendor/vendor.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/vendor.json b/vendor/vendor.json index 0d782d013..88c42fcc8 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -768,7 +768,7 @@ "revisionTime": "2018-05-15T01:47:05Z" }, { - "checksumSHA1": "e7AW3YDVYJPKUjpqsB4AL9RRlTw=", + "checksumSHA1": "vFS5BwnCdQIfKm1nNWrR+ijsAZA=", "path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips", "revision": "7112fcd50da4ea27e8d4d499b30f04eea143bec2", "revisionTime": "2018-05-31T02:06:30Z" From c574dc98b9e5e18a9f72c9bcd1d8f582b1777b97 Mon Sep 17 00:00:00 2001 From: Rickard von Essen Date: Thu, 16 Aug 2018 12:49:27 +0200 Subject: [PATCH 197/220] Updated CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f12d2b54..c4e4a0982 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ * builder/oci: Add `metadata` feature to Packer config. [GH-6498] * builder/openstack: Add support for ports. [GH-6570] * builder/openstack: Add support for getting config from clouds-public.yaml. [GH-6595] +* builder/openstack: Support Block Storage volumes as boot volume. [GH-6596] * builder/qemu: add ssh agent support. [GH-6541] * builder/qemu: New `use_backing_file` feature [GH-6249] * builder/vmware-iso: Try to use ISO files uploaded to the datastore when From 2b3ea29970dcdb45dca636c9c5c5a79a33608331 Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Thu, 16 Aug 2018 18:41:44 +0200 Subject: [PATCH 198/220] show more precise error download/copy/referencing messages --- common/step_download.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/common/step_download.go b/common/step_download.go index 6d2b850a0..13f5e75fa 100644 --- a/common/step_download.go +++ b/common/step_download.go @@ -6,6 +6,7 @@ import ( "encoding/hex" "fmt" "log" + "strings" "time" "github.com/hashicorp/packer/helper/multistep" @@ -66,7 +67,7 @@ func (s *StepDownload) Run(_ context.Context, state multistep.StateBag) multiste } } - ui.Say(fmt.Sprintf("Downloading or copying %s", s.Description)) + ui.Say(fmt.Sprintf("Downloading, copying or inplace referencing %s", s.Description)) // First try to use any already downloaded file // If it fails, proceed to regular download logic @@ -99,6 +100,7 @@ func (s *StepDownload) Run(_ context.Context, state multistep.StateBag) multiste Checksum: checksum, UserAgent: useragent.String(), } + downloadConfigs[i] = config if match, _ := NewDownloadClient(config).VerifyChecksum(config.TargetPath); match { @@ -110,7 +112,11 @@ func (s *StepDownload) Run(_ context.Context, state multistep.StateBag) multiste if finalPath == "" { for i, url := range s.Url { - ui.Message(fmt.Sprintf("Downloading or copying: %s", url)) + if strings.HasPrefix(url, "file://") { + ui.Message(fmt.Sprintf("Copying or inplace referencing: %s", url)) + } else { + ui.Message(fmt.Sprintf("Downloading: %s", url)) + } config := downloadConfigs[i] From d7d4aed51c17dcc1609af633521ad4e58c58567a Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Thu, 16 Aug 2018 18:56:28 +0200 Subject: [PATCH 199/220] be even more precise --- common/step_download.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/common/step_download.go b/common/step_download.go index 13f5e75fa..071f2d44f 100644 --- a/common/step_download.go +++ b/common/step_download.go @@ -113,7 +113,11 @@ func (s *StepDownload) Run(_ context.Context, state multistep.StateBag) multiste if finalPath == "" { for i, url := range s.Url { if strings.HasPrefix(url, "file://") { - ui.Message(fmt.Sprintf("Copying or inplace referencing: %s", url)) + if s.Inplace { + ui.Message(fmt.Sprintf("Inplace referencing: %s", url)) + } else { + ui.Message(fmt.Sprintf("Copying: %s", url)) + } } else { ui.Message(fmt.Sprintf("Downloading: %s", url)) } From a4d7b3a90966bec41d21d73a8afe47c115b61ab3 Mon Sep 17 00:00:00 2001 From: Andrei Ozerov Date: Sun, 10 Jun 2018 22:24:52 +0300 Subject: [PATCH 200/220] Vendor: add Gophercloud networking floatingips Add the OpenStack Networking service's extension package to work with the newest API for floating IPs. --- .../v2/extensions/layer3/floatingips/doc.go | 71 +++++++++ .../extensions/layer3/floatingips/requests.go | 150 ++++++++++++++++++ .../extensions/layer3/floatingips/results.go | 119 ++++++++++++++ .../v2/extensions/layer3/floatingips/urls.go | 13 ++ vendor/vendor.json | 6 + 5 files changed, 359 insertions(+) create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/doc.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/requests.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/results.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/urls.go diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/doc.go new file mode 100644 index 000000000..bf5ec6807 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/doc.go @@ -0,0 +1,71 @@ +/* +package floatingips enables management and retrieval of Floating IPs from the +OpenStack Networking service. + +Example to List Floating IPs + + listOpts := floatingips.ListOpts{ + FloatingNetworkID: "a6917946-38ab-4ffd-a55a-26c0980ce5ee", + } + + allPages, err := floatingips.List(networkClient, listOpts).AllPages() + if err != nil { + panic(err) + } + + allFIPs, err := floatingips.ExtractFloatingIPs(allPages) + if err != nil { + panic(err) + } + + for _, fip := range allFIPs { + fmt.Printf("%+v\n", fip) + } + +Example to Create a Floating IP + + createOpts := floatingips.CreateOpts{ + FloatingNetworkID: "a6917946-38ab-4ffd-a55a-26c0980ce5ee", + } + + fip, err := floatingips.Create(networkingClient, createOpts).Extract() + if err != nil { + panic(err) + } + +Example to Update a Floating IP + + fipID := "2f245a7b-796b-4f26-9cf9-9e82d248fda7" + portID := "76d0a61b-b8e5-490c-9892-4cf674f2bec8" + + updateOpts := floatingips.UpdateOpts{ + PortID: &portID, + } + + fip, err := floatingips.Update(networkingClient, fipID, updateOpts).Extract() + if err != nil { + panic(err) + } + +Example to Disassociate a Floating IP with a Port + + fipID := "2f245a7b-796b-4f26-9cf9-9e82d248fda7" + + updateOpts := floatingips.UpdateOpts{ + PortID: nil, + } + + fip, err := floatingips.Update(networkingClient, fipID, updateOpts).Extract() + if err != nil { + panic(err) + } + +Example to Delete a Floating IP + + fipID := "2f245a7b-796b-4f26-9cf9-9e82d248fda7" + err := floatingips.Delete(networkClient, fipID).ExtractErr() + if err != nil { + panic(err) + } +*/ +package floatingips diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/requests.go new file mode 100644 index 000000000..d82a1bc8e --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/requests.go @@ -0,0 +1,150 @@ +package floatingips + +import ( + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/pagination" +) + +// ListOpts allows the filtering and sorting of paginated collections through +// the API. Filtering is achieved by passing in struct field values that map to +// the floating IP attributes you want to see returned. SortKey allows you to +// sort by a particular network attribute. SortDir sets the direction, and is +// either `asc' or `desc'. Marker and Limit are used for pagination. +type ListOpts struct { + ID string `q:"id"` + FloatingNetworkID string `q:"floating_network_id"` + PortID string `q:"port_id"` + FixedIP string `q:"fixed_ip_address"` + FloatingIP string `q:"floating_ip_address"` + TenantID string `q:"tenant_id"` + ProjectID string `q:"project_id"` + Limit int `q:"limit"` + Marker string `q:"marker"` + SortKey string `q:"sort_key"` + SortDir string `q:"sort_dir"` + RouterID string `q:"router_id"` + Status string `q:"status"` +} + +// List returns a Pager which allows you to iterate over a collection of +// floating IP resources. It accepts a ListOpts struct, which allows you to +// filter and sort the returned collection for greater efficiency. +func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager { + q, err := gophercloud.BuildQueryString(&opts) + if err != nil { + return pagination.Pager{Err: err} + } + u := rootURL(c) + q.String() + return pagination.NewPager(c, u, func(r pagination.PageResult) pagination.Page { + return FloatingIPPage{pagination.LinkedPageBase{PageResult: r}} + }) +} + +// CreateOptsBuilder allows extensions to add additional parameters to the +// Create request. +type CreateOptsBuilder interface { + ToFloatingIPCreateMap() (map[string]interface{}, error) +} + +// CreateOpts contains all the values needed to create a new floating IP +// resource. The only required fields are FloatingNetworkID and PortID which +// refer to the external network and internal port respectively. +type CreateOpts struct { + FloatingNetworkID string `json:"floating_network_id" required:"true"` + FloatingIP string `json:"floating_ip_address,omitempty"` + PortID string `json:"port_id,omitempty"` + FixedIP string `json:"fixed_ip_address,omitempty"` + SubnetID string `json:"subnet_id,omitempty"` + TenantID string `json:"tenant_id,omitempty"` + ProjectID string `json:"project_id,omitempty"` +} + +// ToFloatingIPCreateMap allows CreateOpts to satisfy the CreateOptsBuilder +// interface +func (opts CreateOpts) ToFloatingIPCreateMap() (map[string]interface{}, error) { + return gophercloud.BuildRequestBody(opts, "floatingip") +} + +// Create accepts a CreateOpts struct and uses the values provided to create a +// new floating IP resource. You can create floating IPs on external networks +// only. If you provide a FloatingNetworkID which refers to a network that is +// not external (i.e. its `router:external' attribute is False), the operation +// will fail and return a 400 error. +// +// If you do not specify a FloatingIP address value, the operation will +// automatically allocate an available address for the new resource. If you do +// choose to specify one, it must fall within the subnet range for the external +// network - otherwise the operation returns a 400 error. If the FloatingIP +// address is already in use, the operation returns a 409 error code. +// +// You can associate the new resource with an internal port by using the PortID +// field. If you specify a PortID that is not valid, the operation will fail and +// return 404 error code. +// +// You must also configure an IP address for the port associated with the PortID +// you have provided - this is what the FixedIP refers to: an IP fixed to a +// port. Because a port might be associated with multiple IP addresses, you can +// use the FixedIP field to associate a particular IP address rather than have +// the API assume for you. If you specify an IP address that is not valid, the +// operation will fail and return a 400 error code. If the PortID and FixedIP +// are already associated with another resource, the operation will fail and +// returns a 409 error code. +func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { + b, err := opts.ToFloatingIPCreateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = c.Post(rootURL(c), b, &r.Body, nil) + return +} + +// Get retrieves a particular floating IP resource based on its unique ID. +func Get(c *gophercloud.ServiceClient, id string) (r GetResult) { + _, r.Err = c.Get(resourceURL(c, id), &r.Body, nil) + return +} + +// UpdateOptsBuilder allows extensions to add additional parameters to the +// Update request. +type UpdateOptsBuilder interface { + ToFloatingIPUpdateMap() (map[string]interface{}, error) +} + +// UpdateOpts contains the values used when updating a floating IP resource. The +// only value that can be updated is which internal port the floating IP is +// linked to. To associate the floating IP with a new internal port, provide its +// ID. To disassociate the floating IP from all ports, provide an empty string. +type UpdateOpts struct { + PortID *string `json:"port_id"` +} + +// ToFloatingIPUpdateMap allows UpdateOpts to satisfy the UpdateOptsBuilder +// interface +func (opts UpdateOpts) ToFloatingIPUpdateMap() (map[string]interface{}, error) { + return gophercloud.BuildRequestBody(opts, "floatingip") +} + +// Update allows floating IP resources to be updated. Currently, the only way to +// "update" a floating IP is to associate it with a new internal port, or +// disassociated it from all ports. See UpdateOpts for instructions of how to +// do this. +func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { + b, err := opts.ToFloatingIPUpdateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = c.Put(resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + return +} + +// Delete will permanently delete a particular floating IP resource. Please +// ensure this is what you want - you can also disassociate the IP from existing +// internal ports. +func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) { + _, r.Err = c.Delete(resourceURL(c, id), nil) + return +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/results.go new file mode 100644 index 000000000..8b1a51764 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/results.go @@ -0,0 +1,119 @@ +package floatingips + +import ( + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/pagination" +) + +// FloatingIP represents a floating IP resource. A floating IP is an external +// IP address that is mapped to an internal port and, optionally, a specific +// IP address on a private network. In other words, it enables access to an +// instance on a private network from an external network. For this reason, +// floating IPs can only be defined on networks where the `router:external' +// attribute (provided by the external network extension) is set to True. +type FloatingIP struct { + // ID is the unique identifier for the floating IP instance. + ID string `json:"id"` + + // FloatingNetworkID is the UUID of the external network where the floating + // IP is to be created. + FloatingNetworkID string `json:"floating_network_id"` + + // FloatingIP is the address of the floating IP on the external network. + FloatingIP string `json:"floating_ip_address"` + + // PortID is the UUID of the port on an internal network that is associated + // with the floating IP. + PortID string `json:"port_id"` + + // FixedIP is the specific IP address of the internal port which should be + // associated with the floating IP. + FixedIP string `json:"fixed_ip_address"` + + // TenantID is the project owner of the floating IP. Only admin users can + // specify a project identifier other than its own. + TenantID string `json:"tenant_id"` + + // ProjectID is the project owner of the floating IP. + ProjectID string `json:"project_id"` + + // Status is the condition of the API resource. + Status string `json:"status"` + + // RouterID is the ID of the router used for this floating IP. + RouterID string `json:"router_id"` +} + +type commonResult struct { + gophercloud.Result +} + +// Extract will extract a FloatingIP resource from a result. +func (r commonResult) Extract() (*FloatingIP, error) { + var s struct { + FloatingIP *FloatingIP `json:"floatingip"` + } + err := r.ExtractInto(&s) + return s.FloatingIP, err +} + +// CreateResult represents the result of a create operation. Call its Extract +// method to interpret it as a FloatingIP. +type CreateResult struct { + commonResult +} + +// GetResult represents the result of a get operation. Call its Extract +// method to interpret it as a FloatingIP. +type GetResult struct { + commonResult +} + +// UpdateResult represents the result of an update operation. Call its Extract +// method to interpret it as a FloatingIP. +type UpdateResult struct { + commonResult +} + +// DeleteResult represents the result of an update operation. Call its +// ExtractErr method to determine if the request succeeded or failed. +type DeleteResult struct { + gophercloud.ErrResult +} + +// FloatingIPPage is the page returned by a pager when traversing over a +// collection of floating IPs. +type FloatingIPPage struct { + pagination.LinkedPageBase +} + +// NextPageURL is invoked when a paginated collection of floating IPs has +// reached the end of a page and the pager seeks to traverse over a new one. +// In order to do this, it needs to construct the next page's URL. +func (r FloatingIPPage) NextPageURL() (string, error) { + var s struct { + Links []gophercloud.Link `json:"floatingips_links"` + } + err := r.ExtractInto(&s) + if err != nil { + return "", err + } + return gophercloud.ExtractNextURL(s.Links) +} + +// IsEmpty checks whether a FloatingIPPage struct is empty. +func (r FloatingIPPage) IsEmpty() (bool, error) { + is, err := ExtractFloatingIPs(r) + return len(is) == 0, err +} + +// ExtractFloatingIPs accepts a Page struct, specifically a FloatingIPPage +// struct, and extracts the elements into a slice of FloatingIP structs. In +// other words, a generic collection is mapped into a relevant slice. +func ExtractFloatingIPs(r pagination.Page) ([]FloatingIP, error) { + var s struct { + FloatingIPs []FloatingIP `json:"floatingips"` + } + err := (r.(FloatingIPPage)).ExtractInto(&s) + return s.FloatingIPs, err +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/urls.go new file mode 100644 index 000000000..1318a184c --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips/urls.go @@ -0,0 +1,13 @@ +package floatingips + +import "github.com/gophercloud/gophercloud" + +const resourcePath = "floatingips" + +func rootURL(c *gophercloud.ServiceClient) string { + return c.ServiceURL(resourcePath) +} + +func resourceURL(c *gophercloud.ServiceClient, id string) string { + return c.ServiceURL(resourcePath, id) +} diff --git a/vendor/vendor.json b/vendor/vendor.json index 3a41f1207..b1a20d76c 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -833,6 +833,12 @@ "revision": "7112fcd50da4ea27e8d4d499b30f04eea143bec2", "revisionTime": "2018-05-31T02:06:30Z" }, + { + "checksumSHA1": "K4VAatvB/jywsU+g/mU7bnSaVaI=", + "path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips", + "revision": "00dcc07f1071d5f96520fac7a2b9a30eabccf879", + "revisionTime": "2018-06-10T02:06:14Z" + }, { "checksumSHA1": "8KE4bJzhbFZKsYMxcRg6xLqqfTg=", "path": "github.com/gophercloud/gophercloud/openstack/utils", From 4d17dbd56bd0a0eded7608750517f9f1f0dd42a4 Mon Sep 17 00:00:00 2001 From: Andrei Ozerov Date: Sun, 10 Jun 2018 22:28:00 +0300 Subject: [PATCH 201/220] Vendor: remove Gophercloud compute floatingips Remove package to work with floating IPs via the OpenStack Compute API. Floating IPs support were deprecated in the OpenStack Compute API and users need to use OpenStack Networking API for that task. --- .../compute/v2/extensions/floatingips/doc.go | 68 ----------- .../v2/extensions/floatingips/requests.go | 114 ----------------- .../v2/extensions/floatingips/results.go | 115 ------------------ .../compute/v2/extensions/floatingips/urls.go | 37 ------ 4 files changed, 334 deletions(-) delete mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/doc.go delete mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/requests.go delete mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/results.go delete mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/urls.go diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/doc.go deleted file mode 100644 index f5dbdbf8b..000000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/doc.go +++ /dev/null @@ -1,68 +0,0 @@ -/* -Package floatingips provides the ability to manage floating ips through the -Nova API. - -This API has been deprecated and will be removed from a future release of the -Nova API service. - -For environements that support this extension, this package can be used -regardless of if either Neutron or nova-network is used as the cloud's network -service. - -Example to List Floating IPs - - allPages, err := floatingips.List(computeClient).AllPages() - if err != nil { - panic(err) - } - - allFloatingIPs, err := floatingips.ExtractFloatingIPs(allPages) - if err != nil { - panic(err) - } - - for _, fip := range allFloatingIPs { - fmt.Printf("%+v\n", fip) - } - -Example to Create a Floating IP - - createOpts := floatingips.CreateOpts{ - Pool: "nova", - } - - fip, err := floatingips.Create(computeClient, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Delete a Floating IP - - err := floatingips.Delete(computeClient, "floatingip-id").ExtractErr() - if err != nil { - panic(err) - } - -Example to Associate a Floating IP With a Server - - associateOpts := floatingips.AssociateOpts{ - FloatingIP: "10.10.10.2", - } - - err := floatingips.AssociateInstance(computeClient, "server-id", associateOpts).ExtractErr() - if err != nil { - panic(err) - } - -Example to Disassociate a Floating IP From a Server - - disassociateOpts := floatingips.DisassociateOpts{ - FloatingIP: "10.10.10.2", - } - - err := floatingips.DisassociateInstance(computeClient, "server-id", disassociateOpts).ExtractErr() - if err != nil { - panic(err) - } -*/ -package floatingips diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/requests.go deleted file mode 100644 index a922639de..000000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/requests.go +++ /dev/null @@ -1,114 +0,0 @@ -package floatingips - -import ( - "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/pagination" -) - -// List returns a Pager that allows you to iterate over a collection of FloatingIPs. -func List(client *gophercloud.ServiceClient) pagination.Pager { - return pagination.NewPager(client, listURL(client), func(r pagination.PageResult) pagination.Page { - return FloatingIPPage{pagination.SinglePageBase(r)} - }) -} - -// CreateOptsBuilder allows extensions to add additional parameters to the -// Create request. -type CreateOptsBuilder interface { - ToFloatingIPCreateMap() (map[string]interface{}, error) -} - -// CreateOpts specifies a Floating IP allocation request. -type CreateOpts struct { - // Pool is the pool of Floating IPs to allocate one from. - Pool string `json:"pool" required:"true"` -} - -// ToFloatingIPCreateMap constructs a request body from CreateOpts. -func (opts CreateOpts) ToFloatingIPCreateMap() (map[string]interface{}, error) { - return gophercloud.BuildRequestBody(opts, "") -} - -// Create requests the creation of a new Floating IP. -func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToFloatingIPCreateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{ - OkCodes: []int{200}, - }) - return -} - -// Get returns data about a previously created Floating IP. -func Get(client *gophercloud.ServiceClient, id string) (r GetResult) { - _, r.Err = client.Get(getURL(client, id), &r.Body, nil) - return -} - -// Delete requests the deletion of a previous allocated Floating IP. -func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) { - _, r.Err = client.Delete(deleteURL(client, id), nil) - return -} - -// AssociateOptsBuilder allows extensions to add additional parameters to the -// Associate request. -type AssociateOptsBuilder interface { - ToFloatingIPAssociateMap() (map[string]interface{}, error) -} - -// AssociateOpts specifies the required information to associate a Floating IP with an instance -type AssociateOpts struct { - // FloatingIP is the Floating IP to associate with an instance. - FloatingIP string `json:"address" required:"true"` - - // FixedIP is an optional fixed IP address of the server. - FixedIP string `json:"fixed_address,omitempty"` -} - -// ToFloatingIPAssociateMap constructs a request body from AssociateOpts. -func (opts AssociateOpts) ToFloatingIPAssociateMap() (map[string]interface{}, error) { - return gophercloud.BuildRequestBody(opts, "addFloatingIp") -} - -// AssociateInstance pairs an allocated Floating IP with a server. -func AssociateInstance(client *gophercloud.ServiceClient, serverID string, opts AssociateOptsBuilder) (r AssociateResult) { - b, err := opts.ToFloatingIPAssociateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(associateURL(client, serverID), b, nil, nil) - return -} - -// DisassociateOptsBuilder allows extensions to add additional parameters to -// the Disassociate request. -type DisassociateOptsBuilder interface { - ToFloatingIPDisassociateMap() (map[string]interface{}, error) -} - -// DisassociateOpts specifies the required information to disassociate a -// Floating IP with a server. -type DisassociateOpts struct { - FloatingIP string `json:"address" required:"true"` -} - -// ToFloatingIPDisassociateMap constructs a request body from DisassociateOpts. -func (opts DisassociateOpts) ToFloatingIPDisassociateMap() (map[string]interface{}, error) { - return gophercloud.BuildRequestBody(opts, "removeFloatingIp") -} - -// DisassociateInstance decouples an allocated Floating IP from an instance -func DisassociateInstance(client *gophercloud.ServiceClient, serverID string, opts DisassociateOptsBuilder) (r DisassociateResult) { - b, err := opts.ToFloatingIPDisassociateMap() - if err != nil { - r.Err = err - return - } - _, r.Err = client.Post(disassociateURL(client, serverID), b, nil, nil) - return -} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/results.go deleted file mode 100644 index da4e9da0e..000000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/results.go +++ /dev/null @@ -1,115 +0,0 @@ -package floatingips - -import ( - "encoding/json" - "strconv" - - "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/pagination" -) - -// A FloatingIP is an IP that can be associated with a server. -type FloatingIP struct { - // ID is a unique ID of the Floating IP - ID string `json:"-"` - - // FixedIP is a specific IP on the server to pair the Floating IP with. - FixedIP string `json:"fixed_ip,omitempty"` - - // InstanceID is the ID of the server that is using the Floating IP. - InstanceID string `json:"instance_id"` - - // IP is the actual Floating IP. - IP string `json:"ip"` - - // Pool is the pool of Floating IPs that this Floating IP belongs to. - Pool string `json:"pool"` -} - -func (r *FloatingIP) UnmarshalJSON(b []byte) error { - type tmp FloatingIP - var s struct { - tmp - ID interface{} `json:"id"` - } - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - - *r = FloatingIP(s.tmp) - - switch t := s.ID.(type) { - case float64: - r.ID = strconv.FormatFloat(t, 'f', -1, 64) - case string: - r.ID = t - } - - return err -} - -// FloatingIPPage stores a single page of FloatingIPs from a List call. -type FloatingIPPage struct { - pagination.SinglePageBase -} - -// IsEmpty determines whether or not a FloatingIPsPage is empty. -func (page FloatingIPPage) IsEmpty() (bool, error) { - va, err := ExtractFloatingIPs(page) - return len(va) == 0, err -} - -// ExtractFloatingIPs interprets a page of results as a slice of FloatingIPs. -func ExtractFloatingIPs(r pagination.Page) ([]FloatingIP, error) { - var s struct { - FloatingIPs []FloatingIP `json:"floating_ips"` - } - err := (r.(FloatingIPPage)).ExtractInto(&s) - return s.FloatingIPs, err -} - -// FloatingIPResult is the raw result from a FloatingIP request. -type FloatingIPResult struct { - gophercloud.Result -} - -// Extract is a method that attempts to interpret any FloatingIP resource -// response as a FloatingIP struct. -func (r FloatingIPResult) Extract() (*FloatingIP, error) { - var s struct { - FloatingIP *FloatingIP `json:"floating_ip"` - } - err := r.ExtractInto(&s) - return s.FloatingIP, err -} - -// CreateResult is the response from a Create operation. Call its Extract method -// to interpret it as a FloatingIP. -type CreateResult struct { - FloatingIPResult -} - -// GetResult is the response from a Get operation. Call its Extract method to -// interpret it as a FloatingIP. -type GetResult struct { - FloatingIPResult -} - -// DeleteResult is the response from a Delete operation. Call its ExtractErr -// method to determine if the call succeeded or failed. -type DeleteResult struct { - gophercloud.ErrResult -} - -// AssociateResult is the response from a Delete operation. Call its ExtractErr -// method to determine if the call succeeded or failed. -type AssociateResult struct { - gophercloud.ErrResult -} - -// DisassociateResult is the response from a Delete operation. Call its -// ExtractErr method to determine if the call succeeded or failed. -type DisassociateResult struct { - gophercloud.ErrResult -} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/urls.go deleted file mode 100644 index 4768e5a89..000000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/urls.go +++ /dev/null @@ -1,37 +0,0 @@ -package floatingips - -import "github.com/gophercloud/gophercloud" - -const resourcePath = "os-floating-ips" - -func resourceURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL(resourcePath) -} - -func listURL(c *gophercloud.ServiceClient) string { - return resourceURL(c) -} - -func createURL(c *gophercloud.ServiceClient) string { - return resourceURL(c) -} - -func getURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL(resourcePath, id) -} - -func deleteURL(c *gophercloud.ServiceClient, id string) string { - return getURL(c, id) -} - -func serverURL(c *gophercloud.ServiceClient, serverID string) string { - return c.ServiceURL("servers/" + serverID + "/action") -} - -func associateURL(c *gophercloud.ServiceClient, serverID string) string { - return serverURL(c, serverID) -} - -func disassociateURL(c *gophercloud.ServiceClient, serverID string) string { - return serverURL(c, serverID) -} From 71bf67620ff6d71cb279d2660b6eb8ea059f91f6 Mon Sep 17 00:00:00 2001 From: Andrei Ozerov Date: Sun, 10 Jun 2018 23:45:31 +0300 Subject: [PATCH 202/220] Vendor: add Gophercloud compute attachinterfaces Add package that allows to retrieve and manage network interfaces of the OpenStack intstance. --- .../v2/extensions/attachinterfaces/doc.go | 52 +++++++++++++ .../extensions/attachinterfaces/requests.go | 72 +++++++++++++++++ .../v2/extensions/attachinterfaces/results.go | 78 +++++++++++++++++++ .../v2/extensions/attachinterfaces/urls.go | 18 +++++ vendor/vendor.json | 6 ++ 5 files changed, 226 insertions(+) create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/doc.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/requests.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/results.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/urls.go diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/doc.go new file mode 100644 index 000000000..3653122bf --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/doc.go @@ -0,0 +1,52 @@ +/* +Package attachinterfaces provides the ability to retrieve and manage network +interfaces through Nova. + +Example of Listing a Server's Interfaces + + serverID := "b07e7a3b-d951-4efc-a4f9-ac9f001afb7f" + allPages, err := attachinterfaces.List(computeClient, serverID).AllPages() + if err != nil { + panic(err) + } + + allInterfaces, err := attachinterfaces.ExtractInterfaces(allPages) + if err != nil { + panic(err) + } + + for _, interface := range allInterfaces { + fmt.Printf("%+v\n", interface) + } + +Example to Get a Server's Interface + + portID = "0dde1598-b374-474e-986f-5b8dd1df1d4e" + serverID := "b07e7a3b-d951-4efc-a4f9-ac9f001afb7f" + interface, err := attachinterfaces.Get(computeClient, serverID, portID).Extract() + if err != nil { + panic(err) + } + +Example to Create a new Interface attachment on the Server + + networkID := "8a5fe506-7e9f-4091-899b-96336909d93c" + serverID := "b07e7a3b-d951-4efc-a4f9-ac9f001afb7f" + attachOpts := attachinterfaces.CreateOpts{ + NetworkID: networkID, + } + interface, err := attachinterfaces.Create(computeClient, serverID, attachOpts).Extract() + if err != nil { + panic(err) + } + +Example to Delete an Interface attachment from the Server + + portID = "0dde1598-b374-474e-986f-5b8dd1df1d4e" + serverID := "b07e7a3b-d951-4efc-a4f9-ac9f001afb7f" + err := attachinterfaces.Delete(computeClient, serverID, portID).ExtractErr() + if err != nil { + panic(err) + } +*/ +package attachinterfaces diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/requests.go new file mode 100644 index 000000000..18dade837 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/requests.go @@ -0,0 +1,72 @@ +package attachinterfaces + +import ( + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/pagination" +) + +// List makes a request against the nova API to list the server's interfaces. +func List(client *gophercloud.ServiceClient, serverID string) pagination.Pager { + return pagination.NewPager(client, listInterfaceURL(client, serverID), func(r pagination.PageResult) pagination.Page { + return InterfacePage{pagination.SinglePageBase(r)} + }) +} + +// Get requests details on a single interface attachment by the server and port IDs. +func Get(client *gophercloud.ServiceClient, serverID, portID string) (r GetResult) { + _, r.Err = client.Get(getInterfaceURL(client, serverID, portID), &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + return +} + +// CreateOptsBuilder allows extensions to add additional parameters to the +// Create request. +type CreateOptsBuilder interface { + ToAttachInterfacesCreateMap() (map[string]interface{}, error) +} + +// CreateOpts specifies parameters of a new interface attachment. +type CreateOpts struct { + + // PortID is the ID of the port for which you want to create an interface. + // The NetworkID and PortID parameters are mutually exclusive. + // If you do not specify the PortID parameter, the OpenStack Networking API + // v2.0 allocates a port and creates an interface for it on the network. + PortID string `json:"port_id,omitempty"` + + // NetworkID is the ID of the network for which you want to create an interface. + // The NetworkID and PortID parameters are mutually exclusive. + // If you do not specify the NetworkID parameter, the OpenStack Networking + // API v2.0 uses the network information cache that is associated with the instance. + NetworkID string `json:"net_id,omitempty"` + + // Slice of FixedIPs. If you request a specific FixedIP address without a + // NetworkID, the request returns a Bad Request (400) response code. + FixedIPs []FixedIP `json:"fixed_ips,omitempty"` +} + +// ToAttachInterfacesCreateMap constructs a request body from CreateOpts. +func (opts CreateOpts) ToAttachInterfacesCreateMap() (map[string]interface{}, error) { + return gophercloud.BuildRequestBody(opts, "interfaceAttachment") +} + +// Create requests the creation of a new interface attachment on the server. +func Create(client *gophercloud.ServiceClient, serverID string, opts CreateOptsBuilder) (r CreateResult) { + b, err := opts.ToAttachInterfacesCreateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(createInterfaceURL(client, serverID), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + return +} + +// Delete makes a request against the nova API to detach a single interface from the server. +// It needs server and port IDs to make a such request. +func Delete(client *gophercloud.ServiceClient, serverID, portID string) (r DeleteResult) { + _, r.Err = client.Delete(deleteInterfaceURL(client, serverID, portID), nil) + return +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/results.go new file mode 100644 index 000000000..a16fa14f7 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/results.go @@ -0,0 +1,78 @@ +package attachinterfaces + +import ( + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/pagination" +) + +type attachInterfaceResult struct { + gophercloud.Result +} + +// Extract interprets any attachInterfaceResult as an Interface, if possible. +func (r attachInterfaceResult) Extract() (*Interface, error) { + var s struct { + Interface *Interface `json:"interfaceAttachment"` + } + err := r.ExtractInto(&s) + return s.Interface, err +} + +// GetResult is the response from a Get operation. Call its Extract +// method to interpret it as an Interface. +type GetResult struct { + attachInterfaceResult +} + +// CreateResult is the response from a Create operation. Call its Extract +// method to interpret it as an Interface. +type CreateResult struct { + attachInterfaceResult +} + +// DeleteResult is the response from a Delete operation. Call its ExtractErr +// method to determine if the call succeeded or failed. +type DeleteResult struct { + gophercloud.ErrResult +} + +// FixedIP represents a Fixed IP Address. +type FixedIP struct { + SubnetID string `json:"subnet_id"` + IPAddress string `json:"ip_address"` +} + +// Interface represents a network interface on a server. +type Interface struct { + PortState string `json:"port_state"` + FixedIPs []FixedIP `json:"fixed_ips"` + PortID string `json:"port_id"` + NetID string `json:"net_id"` + MACAddr string `json:"mac_addr"` +} + +// InterfacePage abstracts the raw results of making a List() request against +// the API. +// +// As OpenStack extensions may freely alter the response bodies of structures +// returned to the client, you may only safely access the data provided through +// the ExtractInterfaces call. +type InterfacePage struct { + pagination.SinglePageBase +} + +// IsEmpty returns true if an InterfacePage contains no interfaces. +func (r InterfacePage) IsEmpty() (bool, error) { + interfaces, err := ExtractInterfaces(r) + return len(interfaces) == 0, err +} + +// ExtractInterfaces interprets the results of a single page from a List() call, +// producing a slice of Interface structs. +func ExtractInterfaces(r pagination.Page) ([]Interface, error) { + var s struct { + Interfaces []Interface `json:"interfaceAttachments"` + } + err := (r.(InterfacePage)).ExtractInto(&s) + return s.Interfaces, err +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/urls.go new file mode 100644 index 000000000..50292e8b5 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces/urls.go @@ -0,0 +1,18 @@ +package attachinterfaces + +import "github.com/gophercloud/gophercloud" + +func listInterfaceURL(client *gophercloud.ServiceClient, serverID string) string { + return client.ServiceURL("servers", serverID, "os-interface") +} + +func getInterfaceURL(client *gophercloud.ServiceClient, serverID, portID string) string { + return client.ServiceURL("servers", serverID, "os-interface", portID) +} + +func createInterfaceURL(client *gophercloud.ServiceClient, serverID string) string { + return client.ServiceURL("servers", serverID, "os-interface") +} +func deleteInterfaceURL(client *gophercloud.ServiceClient, serverID, portID string) string { + return client.ServiceURL("servers", serverID, "os-interface", portID) +} diff --git a/vendor/vendor.json b/vendor/vendor.json index b1a20d76c..b9c26792e 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -773,6 +773,12 @@ "revision": "7112fcd50da4ea27e8d4d499b30f04eea143bec2", "revisionTime": "2018-05-31T02:06:30Z" }, + { + "checksumSHA1": "lW+ldKF07Zz/C7WYPTchfr1USrQ=", + "path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces", + "revision": "00dcc07f1071d5f96520fac7a2b9a30eabccf879", + "revisionTime": "2018-06-10T02:06:14Z" + }, { "checksumSHA1": "lAQuKIqTuQ9JuMgN0pPkNtRH2RM=", "path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs", From f0f1967c9fcebaad59e8bb450bc83f99837c3b00 Mon Sep 17 00:00:00 2001 From: Andrei Ozerov Date: Tue, 12 Jun 2018 09:47:16 +0300 Subject: [PATCH 203/220] Vendor: add Gophercloud networking v2 networks Add package that allow to work with OpenStack networks via the Networking V2 service API. --- .../openstack/networking/v2/networks/doc.go | 65 +++++++ .../networking/v2/networks/requests.go | 168 ++++++++++++++++++ .../networking/v2/networks/results.go | 118 ++++++++++++ .../openstack/networking/v2/networks/urls.go | 31 ++++ vendor/vendor.json | 6 + 5 files changed, 388 insertions(+) create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/doc.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/requests.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/results.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/urls.go diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/doc.go new file mode 100644 index 000000000..e768b71f8 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/doc.go @@ -0,0 +1,65 @@ +/* +Package networks contains functionality for working with Neutron network +resources. A network is an isolated virtual layer-2 broadcast domain that is +typically reserved for the tenant who created it (unless you configure the +network to be shared). Tenants can create multiple networks until the +thresholds per-tenant quota is reached. + +In the v2.0 Networking API, the network is the main entity. Ports and subnets +are always associated with a network. + +Example to List Networks + + listOpts := networks.ListOpts{ + TenantID: "a99e9b4e620e4db09a2dfb6e42a01e66", + } + + allPages, err := networks.List(networkClient, listOpts).AllPages() + if err != nil { + panic(err) + } + + allNetworks, err := networks.ExtractNetworks(allPages) + if err != nil { + panic(err) + } + + for _, network := range allNetworks { + fmt.Printf("%+v", network) + } + +Example to Create a Network + + iTrue := true + createOpts := networks.CreateOpts{ + Name: "network_1", + AdminStateUp: &iTrue, + } + + network, err := networks.Create(networkClient, createOpts).Extract() + if err != nil { + panic(err) + } + +Example to Update a Network + + networkID := "484cda0e-106f-4f4b-bb3f-d413710bbe78" + + updateOpts := networks.UpdateOpts{ + Name: "new_name", + } + + network, err := networks.Update(networkClient, networkID, updateOpts).Extract() + if err != nil { + panic(err) + } + +Example to Delete a Network + + networkID := "484cda0e-106f-4f4b-bb3f-d413710bbe78" + err := networks.Delete(networkClient, networkID).ExtractErr() + if err != nil { + panic(err) + } +*/ +package networks diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/requests.go new file mode 100644 index 000000000..bc4460a06 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/requests.go @@ -0,0 +1,168 @@ +package networks + +import ( + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/pagination" +) + +// ListOptsBuilder allows extensions to add additional parameters to the +// List request. +type ListOptsBuilder interface { + ToNetworkListQuery() (string, error) +} + +// ListOpts allows the filtering and sorting of paginated collections through +// the API. Filtering is achieved by passing in struct field values that map to +// the network attributes you want to see returned. SortKey allows you to sort +// by a particular network attribute. SortDir sets the direction, and is either +// `asc' or `desc'. Marker and Limit are used for pagination. +type ListOpts struct { + Status string `q:"status"` + Name string `q:"name"` + AdminStateUp *bool `q:"admin_state_up"` + TenantID string `q:"tenant_id"` + ProjectID string `q:"project_id"` + Shared *bool `q:"shared"` + ID string `q:"id"` + Marker string `q:"marker"` + Limit int `q:"limit"` + SortKey string `q:"sort_key"` + SortDir string `q:"sort_dir"` +} + +// ToNetworkListQuery formats a ListOpts into a query string. +func (opts ListOpts) ToNetworkListQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + return q.String(), err +} + +// List returns a Pager which allows you to iterate over a collection of +// networks. It accepts a ListOpts struct, which allows you to filter and sort +// the returned collection for greater efficiency. +func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { + url := listURL(c) + if opts != nil { + query, err := opts.ToNetworkListQuery() + if err != nil { + return pagination.Pager{Err: err} + } + url += query + } + return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { + return NetworkPage{pagination.LinkedPageBase{PageResult: r}} + }) +} + +// Get retrieves a specific network based on its unique ID. +func Get(c *gophercloud.ServiceClient, id string) (r GetResult) { + _, r.Err = c.Get(getURL(c, id), &r.Body, nil) + return +} + +// CreateOptsBuilder allows extensions to add additional parameters to the +// Create request. +type CreateOptsBuilder interface { + ToNetworkCreateMap() (map[string]interface{}, error) +} + +// CreateOpts represents options used to create a network. +type CreateOpts struct { + AdminStateUp *bool `json:"admin_state_up,omitempty"` + Name string `json:"name,omitempty"` + Shared *bool `json:"shared,omitempty"` + TenantID string `json:"tenant_id,omitempty"` + ProjectID string `json:"project_id,omitempty"` + AvailabilityZoneHints []string `json:"availability_zone_hints,omitempty"` +} + +// ToNetworkCreateMap builds a request body from CreateOpts. +func (opts CreateOpts) ToNetworkCreateMap() (map[string]interface{}, error) { + return gophercloud.BuildRequestBody(opts, "network") +} + +// Create accepts a CreateOpts struct and creates a new network using the values +// provided. This operation does not actually require a request body, i.e. the +// CreateOpts struct argument can be empty. +// +// The tenant ID that is contained in the URI is the tenant that creates the +// network. An admin user, however, has the option of specifying another tenant +// ID in the CreateOpts struct. +func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { + b, err := opts.ToNetworkCreateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = c.Post(createURL(c), b, &r.Body, nil) + return +} + +// UpdateOptsBuilder allows extensions to add additional parameters to the +// Update request. +type UpdateOptsBuilder interface { + ToNetworkUpdateMap() (map[string]interface{}, error) +} + +// UpdateOpts represents options used to update a network. +type UpdateOpts struct { + AdminStateUp *bool `json:"admin_state_up,omitempty"` + Name string `json:"name,omitempty"` + Shared *bool `json:"shared,omitempty"` +} + +// ToNetworkUpdateMap builds a request body from UpdateOpts. +func (opts UpdateOpts) ToNetworkUpdateMap() (map[string]interface{}, error) { + return gophercloud.BuildRequestBody(opts, "network") +} + +// Update accepts a UpdateOpts struct and updates an existing network using the +// values provided. For more information, see the Create function. +func Update(c *gophercloud.ServiceClient, networkID string, opts UpdateOptsBuilder) (r UpdateResult) { + b, err := opts.ToNetworkUpdateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = c.Put(updateURL(c, networkID), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200, 201}, + }) + return +} + +// Delete accepts a unique ID and deletes the network associated with it. +func Delete(c *gophercloud.ServiceClient, networkID string) (r DeleteResult) { + _, r.Err = c.Delete(deleteURL(c, networkID), nil) + return +} + +// IDFromName is a convenience function that returns a network's ID, given +// its name. +func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) { + count := 0 + id := "" + pages, err := List(client, nil).AllPages() + if err != nil { + return "", err + } + + all, err := ExtractNetworks(pages) + if err != nil { + return "", err + } + + for _, s := range all { + if s.Name == name { + count++ + id = s.ID + } + } + + switch count { + case 0: + return "", gophercloud.ErrResourceNotFound{Name: name, ResourceType: "network"} + case 1: + return id, nil + default: + return "", gophercloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "network"} + } +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/results.go new file mode 100644 index 000000000..62f4b3c3a --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/results.go @@ -0,0 +1,118 @@ +package networks + +import ( + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/pagination" +) + +type commonResult struct { + gophercloud.Result +} + +// Extract is a function that accepts a result and extracts a network resource. +func (r commonResult) Extract() (*Network, error) { + var s Network + err := r.ExtractInto(&s) + return &s, err +} + +func (r commonResult) ExtractInto(v interface{}) error { + return r.Result.ExtractIntoStructPtr(v, "network") +} + +// CreateResult represents the result of a create operation. Call its Extract +// method to interpret it as a Network. +type CreateResult struct { + commonResult +} + +// GetResult represents the result of a get operation. Call its Extract +// method to interpret it as a Network. +type GetResult struct { + commonResult +} + +// UpdateResult represents the result of an update operation. Call its Extract +// method to interpret it as a Network. +type UpdateResult struct { + commonResult +} + +// DeleteResult represents the result of a delete operation. Call its +// ExtractErr method to determine if the request succeeded or failed. +type DeleteResult struct { + gophercloud.ErrResult +} + +// Network represents, well, a network. +type Network struct { + // UUID for the network + ID string `json:"id"` + + // Human-readable name for the network. Might not be unique. + Name string `json:"name"` + + // The administrative state of network. If false (down), the network does not + // forward packets. + AdminStateUp bool `json:"admin_state_up"` + + // Indicates whether network is currently operational. Possible values include + // `ACTIVE', `DOWN', `BUILD', or `ERROR'. Plug-ins might define additional + // values. + Status string `json:"status"` + + // Subnets associated with this network. + Subnets []string `json:"subnets"` + + // TenantID is the project owner of the network. + TenantID string `json:"tenant_id"` + + // ProjectID is the project owner of the network. + ProjectID string `json:"project_id"` + + // Specifies whether the network resource can be accessed by any tenant. + Shared bool `json:"shared"` + + // Availability zone hints groups network nodes that run services like DHCP, L3, FW, and others. + // Used to make network resources highly available. + AvailabilityZoneHints []string `json:"availability_zone_hints"` +} + +// NetworkPage is the page returned by a pager when traversing over a +// collection of networks. +type NetworkPage struct { + pagination.LinkedPageBase +} + +// NextPageURL is invoked when a paginated collection of networks has reached +// the end of a page and the pager seeks to traverse over a new one. In order +// to do this, it needs to construct the next page's URL. +func (r NetworkPage) NextPageURL() (string, error) { + var s struct { + Links []gophercloud.Link `json:"networks_links"` + } + err := r.ExtractInto(&s) + if err != nil { + return "", err + } + return gophercloud.ExtractNextURL(s.Links) +} + +// IsEmpty checks whether a NetworkPage struct is empty. +func (r NetworkPage) IsEmpty() (bool, error) { + is, err := ExtractNetworks(r) + return len(is) == 0, err +} + +// ExtractNetworks accepts a Page struct, specifically a NetworkPage struct, +// and extracts the elements into a slice of Network structs. In other words, +// a generic collection is mapped into a relevant slice. +func ExtractNetworks(r pagination.Page) ([]Network, error) { + var s []Network + err := ExtractNetworksInto(r, &s) + return s, err +} + +func ExtractNetworksInto(r pagination.Page, v interface{}) error { + return r.(NetworkPage).Result.ExtractIntoSlicePtr(v, "networks") +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/urls.go new file mode 100644 index 000000000..4a8fb1dc7 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/urls.go @@ -0,0 +1,31 @@ +package networks + +import "github.com/gophercloud/gophercloud" + +func resourceURL(c *gophercloud.ServiceClient, id string) string { + return c.ServiceURL("networks", id) +} + +func rootURL(c *gophercloud.ServiceClient) string { + return c.ServiceURL("networks") +} + +func getURL(c *gophercloud.ServiceClient, id string) string { + return resourceURL(c, id) +} + +func listURL(c *gophercloud.ServiceClient) string { + return rootURL(c) +} + +func createURL(c *gophercloud.ServiceClient) string { + return rootURL(c) +} + +func updateURL(c *gophercloud.ServiceClient, id string) string { + return resourceURL(c, id) +} + +func deleteURL(c *gophercloud.ServiceClient, id string) string { + return resourceURL(c, id) +} diff --git a/vendor/vendor.json b/vendor/vendor.json index b9c26792e..a1909dd59 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -845,6 +845,12 @@ "revision": "00dcc07f1071d5f96520fac7a2b9a30eabccf879", "revisionTime": "2018-06-10T02:06:14Z" }, + { + "checksumSHA1": "XEVvG2f/dqATN4aCluZlPylW+9A=", + "path": "github.com/gophercloud/gophercloud/openstack/networking/v2/networks", + "revision": "00dcc07f1071d5f96520fac7a2b9a30eabccf879", + "revisionTime": "2018-06-10T02:06:14Z" + }, { "checksumSHA1": "8KE4bJzhbFZKsYMxcRg6xLqqfTg=", "path": "github.com/gophercloud/gophercloud/openstack/utils", From 68afd3d8da8f8f61035bf4bd766a5cce55eba8cf Mon Sep 17 00:00:00 2001 From: Andrei Ozerov Date: Tue, 12 Jun 2018 09:54:30 +0300 Subject: [PATCH 204/220] Vendor: add Gophercloud networking v2 external Add package that allow to work with OpenStack networks with external attribute via the Networking V2 service API. --- .../networking/v2/extensions/external/doc.go | 53 ++++++++++++ .../v2/extensions/external/requests.go | 84 +++++++++++++++++++ .../v2/extensions/external/results.go | 8 ++ vendor/vendor.json | 6 ++ 4 files changed, 151 insertions(+) create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external/doc.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external/requests.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external/results.go diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external/doc.go new file mode 100644 index 000000000..eda010cb0 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external/doc.go @@ -0,0 +1,53 @@ +/* +Package external provides information and interaction with the external +extension for the OpenStack Networking service. + +Example to List Networks with External Information + + iTrue := true + networkListOpts := networks.ListOpts{} + listOpts := external.ListOptsExt{ + ListOptsBuilder: networkListOpts, + External: &iTrue, + } + + type NetworkWithExternalExt struct { + networks.Network + external.NetworkExternalExt + } + + var allNetworks []NetworkWithExternalExt + + allPages, err := networks.List(networkClient, listOpts).AllPages() + if err != nil { + panic(err) + } + + err = networks.ExtractNetworksInto(allPages, &allNetworks) + if err != nil { + panic(err) + } + + for _, network := range allNetworks { + fmt.Println("%+v\n", network) + } + +Example to Create a Network with External Information + + iTrue := true + networkCreateOpts := networks.CreateOpts{ + Name: "private", + AdminStateUp: &iTrue, + } + + createOpts := external.CreateOptsExt{ + networkCreateOpts, + &iTrue, + } + + network, err := networks.Create(networkClient, createOpts).Extract() + if err != nil { + panic(err) + } +*/ +package external diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external/requests.go new file mode 100644 index 000000000..ced5efed8 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external/requests.go @@ -0,0 +1,84 @@ +package external + +import ( + "net/url" + "strconv" + + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/openstack/networking/v2/networks" +) + +// ListOptsExt adds the external network options to the base ListOpts. +type ListOptsExt struct { + networks.ListOptsBuilder + External *bool `q:"router:external"` +} + +// ToNetworkListQuery adds the router:external option to the base network +// list options. +func (opts ListOptsExt) ToNetworkListQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts.ListOptsBuilder) + if err != nil { + return "", err + } + + params := q.Query() + if opts.External != nil { + v := strconv.FormatBool(*opts.External) + params.Add("router:external", v) + } + + q = &url.URL{RawQuery: params.Encode()} + return q.String(), err +} + +// CreateOptsExt is the structure used when creating new external network +// resources. It embeds networks.CreateOpts and so inherits all of its required +// and optional fields, with the addition of the External field. +type CreateOptsExt struct { + networks.CreateOptsBuilder + External *bool `json:"router:external,omitempty"` +} + +// ToNetworkCreateMap adds the router:external options to the base network +// creation options. +func (opts CreateOptsExt) ToNetworkCreateMap() (map[string]interface{}, error) { + base, err := opts.CreateOptsBuilder.ToNetworkCreateMap() + if err != nil { + return nil, err + } + + if opts.External == nil { + return base, nil + } + + networkMap := base["network"].(map[string]interface{}) + networkMap["router:external"] = opts.External + + return base, nil +} + +// UpdateOptsExt is the structure used when updating existing external network +// resources. It embeds networks.UpdateOpts and so inherits all of its required +// and optional fields, with the addition of the External field. +type UpdateOptsExt struct { + networks.UpdateOptsBuilder + External *bool `json:"router:external,omitempty"` +} + +// ToNetworkUpdateMap casts an UpdateOpts struct to a map. +func (opts UpdateOptsExt) ToNetworkUpdateMap() (map[string]interface{}, error) { + base, err := opts.UpdateOptsBuilder.ToNetworkUpdateMap() + if err != nil { + return nil, err + } + + if opts.External == nil { + return base, nil + } + + networkMap := base["network"].(map[string]interface{}) + networkMap["router:external"] = opts.External + + return base, nil +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external/results.go new file mode 100644 index 000000000..7cbbffdcf --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external/results.go @@ -0,0 +1,8 @@ +package external + +// NetworkExternalExt represents a decorated form of a Network with based on the +// "external-net" extension. +type NetworkExternalExt struct { + // Specifies whether the network is an external network or not. + External bool `json:"router:external"` +} diff --git a/vendor/vendor.json b/vendor/vendor.json index a1909dd59..db4e04b40 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -839,6 +839,12 @@ "revision": "7112fcd50da4ea27e8d4d499b30f04eea143bec2", "revisionTime": "2018-05-31T02:06:30Z" }, + { + "checksumSHA1": "x6lD4wQOZc1rtm6kMaUBMwLxAlA=", + "path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external", + "revision": "00dcc07f1071d5f96520fac7a2b9a30eabccf879", + "revisionTime": "2018-06-10T02:06:14Z" + }, { "checksumSHA1": "K4VAatvB/jywsU+g/mU7bnSaVaI=", "path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips", From 0eef9b42920a8d0ef4ff1d14161320b464540971 Mon Sep 17 00:00:00 2001 From: Andrei Ozerov Date: Tue, 12 Jun 2018 11:38:54 +0300 Subject: [PATCH 205/220] OpenStack builder: floating IP refactoring Remove usage of the deprecated OpenStack Compute service floating IP management and add methods to work with the OpenStack Networking service floating IPs API. Remove usage of the deprecated OpenStack Compute service floating IP pools and add methods to work with the OpenStack Networking service external networks API. Move reusable logic of working with the OpenStack Networking service API to a separate methods in the networking.go file. Pass error messages from the API services to the ui messages in the allocate IP step. --- builder/openstack/access_config.go | 7 + builder/openstack/builder.go | 6 +- builder/openstack/networks.go | 114 ++++++++++++++++ builder/openstack/run_config.go | 10 +- builder/openstack/ssh.go | 8 +- builder/openstack/step_allocate_ip.go | 179 +++++++++++++++----------- 6 files changed, 233 insertions(+), 91 deletions(-) create mode 100644 builder/openstack/networks.go diff --git a/builder/openstack/access_config.go b/builder/openstack/access_config.go index 1fcefa659..377a0c3a7 100644 --- a/builder/openstack/access_config.go +++ b/builder/openstack/access_config.go @@ -201,6 +201,13 @@ func (c *AccessConfig) blockStorageV3Client() (*gophercloud.ServiceClient, error }) } +func (c *AccessConfig) networkV2Client() (*gophercloud.ServiceClient, error) { + return openstack.NewNetworkV2(c.osClient, gophercloud.EndpointOpts{ + Region: c.Region, + Availability: c.getEndpointType(), + }) +} + func (c *AccessConfig) getEndpointType() gophercloud.Availability { if c.EndpointType == "internal" || c.EndpointType == "internalURL" { return gophercloud.AvailabilityInternal diff --git a/builder/openstack/builder.go b/builder/openstack/builder.go index 56631cf0b..c505233bb 100644 --- a/builder/openstack/builder.go +++ b/builder/openstack/builder.go @@ -115,9 +115,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Wait: b.config.RackconnectWait, }, &StepAllocateIp{ - FloatingIpPool: b.config.FloatingIpPool, - FloatingIp: b.config.FloatingIp, - ReuseIps: b.config.ReuseIps, + FloatingNetwork: b.config.FloatingNetwork, + FloatingIP: b.config.FloatingIP, + ReuseIPs: b.config.ReuseIPs, }, &communicator.StepConnect{ Config: &b.config.RunConfig.Comm, diff --git a/builder/openstack/networks.go b/builder/openstack/networks.go new file mode 100644 index 000000000..ac56fa531 --- /dev/null +++ b/builder/openstack/networks.go @@ -0,0 +1,114 @@ +package openstack + +import ( + "fmt" + + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces" + "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external" + "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips" + "github.com/gophercloud/gophercloud/openstack/networking/v2/networks" + "github.com/gophercloud/gophercloud/pagination" +) + +// ExternalNetwork is a network with external router. +type ExternalNetwork struct { + networks.Network + external.NetworkExternalExt +} + +// FindExternalNetwork returns existing network with external router. +// It will return first network if there are many. +func FindExternalNetwork(client *gophercloud.ServiceClient) (*ExternalNetwork, error) { + var externalNetworks []ExternalNetwork + + allPages, err := networks.List(client, networks.ListOpts{ + Status: "ACTIVE", + }).AllPages() + if err != nil { + return nil, err + } + + // Extract external networks from found networks. + err = networks.ExtractNetworksInto(allPages, &externalNetworks) + if err != nil { + return nil, err + } + + if len(externalNetworks) == 0 { + return nil, fmt.Errorf("no external networks found") + } + + // Return the first external network. + return &externalNetworks[0], nil +} + +// CheckFloatingIP gets a floating IP by its ID and checks if it is already +// associated with any internal interface. +// It returns floating IP if it can be used. +func CheckFloatingIP(client *gophercloud.ServiceClient, id string) (*floatingips.FloatingIP, error) { + floatingIP, err := floatingips.Get(client, id).Extract() + if err != nil { + return nil, err + } + if floatingIP.PortID != "" { + return nil, fmt.Errorf("provided floating IP '%s' is already associated with port '%s'", + id, floatingIP.PortID) + } + + return floatingIP, nil +} + +// FindFreeFloatingIP returns free unassociated floating IP. +// It will return first floating IP if there are many. +func FindFreeFloatingIP(client *gophercloud.ServiceClient) (*floatingips.FloatingIP, error) { + var freeFloatingIP *floatingips.FloatingIP + + pager := floatingips.List(client, floatingips.ListOpts{ + Status: "DOWN", + }) + err := pager.EachPage(func(page pagination.Page) (bool, error) { + candidates, err := floatingips.ExtractFloatingIPs(page) + if err != nil { + return false, err // stop and throw error out + } + + for _, candidate := range candidates { + if candidate.PortID != "" { + continue // this floating IP is associated with port, move to next in list + } + + // Floating IP is able to be allocated. + freeFloatingIP = &candidate + return false, nil // stop iterating over pages + } + return true, nil // try the next page + }) + if err != nil { + return nil, err + } + if freeFloatingIP == nil { + return nil, fmt.Errorf("no free floating IPs found") + } + + return freeFloatingIP, nil +} + +// GetInstancePortID returns internal port of the instance that can be used for +// the association of a floating IP. +// It will return an ID of a first port if there are many. +func GetInstancePortID(client *gophercloud.ServiceClient, id string) (string, error) { + interfacesPage, err := attachinterfaces.List(client, id).AllPages() + if err != nil { + return "", err + } + interfaces, err := attachinterfaces.ExtractInterfaces(interfacesPage) + if err != nil { + return "", err + } + if len(interfaces) == 0 { + return "", fmt.Errorf("instance '%s' has no interfaces", id) + } + + return interfaces[0].PortID, nil +} diff --git a/builder/openstack/run_config.go b/builder/openstack/run_config.go index 9e89e2477..1b2f209c8 100644 --- a/builder/openstack/run_config.go +++ b/builder/openstack/run_config.go @@ -23,9 +23,9 @@ type RunConfig struct { Flavor string `mapstructure:"flavor"` AvailabilityZone string `mapstructure:"availability_zone"` RackconnectWait bool `mapstructure:"rackconnect_wait"` - FloatingIpPool string `mapstructure:"floating_ip_pool"` - FloatingIp string `mapstructure:"floating_ip"` - ReuseIps bool `mapstructure:"reuse_ips"` + FloatingNetwork string `mapstructure:"floating_network"` + FloatingIP string `mapstructure:"floating_ip"` + ReuseIPs bool `mapstructure:"reuse_ips"` SecurityGroups []string `mapstructure:"security_groups"` Networks []string `mapstructure:"networks"` Ports []string `mapstructure:"ports"` @@ -57,10 +57,6 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { c.TemporaryKeyPairName = fmt.Sprintf("packer_%s", uuid.TimeOrderedUUID()) } - if c.UseFloatingIp && c.FloatingIpPool == "" { - c.FloatingIpPool = "public" - } - // Validation errs := c.Comm.Prepare(ctx) diff --git a/builder/openstack/ssh.go b/builder/openstack/ssh.go index 1dd6672c4..15c9bc36f 100644 --- a/builder/openstack/ssh.go +++ b/builder/openstack/ssh.go @@ -9,8 +9,8 @@ import ( "time" "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips" "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" + "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips" packerssh "github.com/hashicorp/packer/communicator/ssh" "github.com/hashicorp/packer/helper/multistep" "golang.org/x/crypto/ssh" @@ -35,9 +35,9 @@ func CommHost( // If we have a floating IP, use that ip := state.Get("access_ip").(*floatingips.FloatingIP) - if ip != nil && ip.IP != "" { - log.Printf("[DEBUG] Using floating IP %s to connect", ip.IP) - return ip.IP, nil + if ip != nil && ip.FloatingIP != "" { + log.Printf("[DEBUG] Using floating IP %s to connect", ip.FloatingIP) + return ip.FloatingIP, nil } if s.AccessIPv4 != "" { diff --git a/builder/openstack/step_allocate_ip.go b/builder/openstack/step_allocate_ip.go index fb53ce434..b5a517680 100644 --- a/builder/openstack/step_allocate_ip.go +++ b/builder/openstack/step_allocate_ip.go @@ -4,17 +4,16 @@ import ( "context" "fmt" - "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips" "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" - "github.com/gophercloud/gophercloud/pagination" + "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) type StepAllocateIp struct { - FloatingIpPool string - FloatingIp string - ReuseIps bool + FloatingNetwork string + FloatingIP string + ReuseIPs bool } func (s *StepAllocateIp) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { @@ -23,123 +22,149 @@ func (s *StepAllocateIp) Run(_ context.Context, state multistep.StateBag) multis server := state.Get("server").(*servers.Server) // We need the v2 compute client - client, err := config.computeV2Client() + computeClient, err := config.computeV2Client() if err != nil { err = fmt.Errorf("Error initializing compute client: %s", err) state.Put("error", err) return multistep.ActionHalt } - var instanceIp floatingips.FloatingIP + // We need the v2 network client + networkClient, err := config.networkV2Client() + if err != nil { + err = fmt.Errorf("Error initializing network client: %s", err) + state.Put("error", err) + return multistep.ActionHalt + } + + var instanceIP floatingips.FloatingIP // This is here in case we error out before putting instanceIp into the // statebag below, because it is requested by Cleanup() - state.Put("access_ip", &instanceIp) + state.Put("access_ip", &instanceIP) - if s.FloatingIp != "" { - instanceIp.IP = s.FloatingIp - } else if s.FloatingIpPool != "" { - // If ReuseIps is set to true and we have a free floating IP in - // the pool, use it first rather than creating one - if s.ReuseIps { - ui.Say(fmt.Sprintf("Searching for unassociated floating IP in pool %s", s.FloatingIpPool)) - pager := floatingips.List(client) - err := pager.EachPage(func(page pagination.Page) (bool, error) { - candidates, err := floatingips.ExtractFloatingIPs(page) - - if err != nil { - return false, err // stop and throw error out - } - - for _, candidate := range candidates { - if candidate.Pool != s.FloatingIpPool || candidate.InstanceID != "" { - continue // move to next in list - } - - // In correct pool and able to be allocated - instanceIp.IP = candidate.IP - ui.Message(fmt.Sprintf("Selected floating IP: %s", instanceIp.IP)) - state.Put("floatingip_istemp", false) - return false, nil // stop iterating over pages - } - return true, nil // try the next page - }) - - if err != nil { - err := fmt.Errorf("Error searching for floating ip from pool '%s'", s.FloatingIpPool) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } + // Try to use floating IP provided by the user or find a free floating IP. + if s.FloatingIP != "" { + freeFloatingIP, err := CheckFloatingIP(networkClient, s.FloatingIP) + if err != nil { + err := fmt.Errorf("Error using provided floating IP '%s': %s", s.FloatingIP, err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt } - if instanceIp.IP == "" { - ui.Say(fmt.Sprintf("Creating floating IP...")) - ui.Message(fmt.Sprintf("Pool: %s", s.FloatingIpPool)) - newIp, err := floatingips.Create(client, floatingips.CreateOpts{ - Pool: s.FloatingIpPool, - }).Extract() - if err != nil { - err := fmt.Errorf("Error creating floating ip from pool '%s'", s.FloatingIpPool) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - - instanceIp = *newIp - ui.Message(fmt.Sprintf("Created floating IP: %s", instanceIp.IP)) - state.Put("floatingip_istemp", true) + instanceIP = *freeFloatingIP + ui.Message(fmt.Sprintf("Selected floating IP: '%s' (%s)", instanceIP.ID, instanceIP.FloatingIP)) + state.Put("floatingip_istemp", false) + } else if s.ReuseIPs { + // If ReuseIPs is set to true and we have a free floating IP, use it rather + // than creating one. + ui.Say(fmt.Sprint("Searching for unassociated floating IP")) + freeFloatingIP, err := FindFreeFloatingIP(networkClient) + if err != nil { + err := fmt.Errorf("Error searching for floating IP: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt } + + instanceIP = *freeFloatingIP + ui.Message(fmt.Sprintf("Selected floating IP: '%s' (%s)", instanceIP.ID, instanceIP.FloatingIP)) + state.Put("floatingip_istemp", false) } - if instanceIp.IP != "" { - ui.Say(fmt.Sprintf("Associating floating IP with server...")) - ui.Message(fmt.Sprintf("IP: %s", instanceIp.IP)) - err := floatingips.AssociateInstance(client, server.ID, floatingips.AssociateOpts{ - FloatingIP: instanceIp.IP, - }).ExtractErr() + // Create a new floating IP if it wasn't obtained in the previous step. + if instanceIP.ID == "" { + // Search for the external network that can be used for the floating IPs if + // user hasn't provided any. + floatingNetwork := s.FloatingNetwork + if floatingNetwork == "" { + ui.Say(fmt.Sprintf("Searching for the external network...")) + externalNetwork, err := FindExternalNetwork(networkClient) + if err != nil { + err := fmt.Errorf("Error searching the external network: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + floatingNetwork = externalNetwork.ID + } + + ui.Say(fmt.Sprintf("Creating floating IP...")) + newIP, err := floatingips.Create(networkClient, floatingips.CreateOpts{ + FloatingNetworkID: floatingNetwork, + }).Extract() + if err != nil { + err := fmt.Errorf("Error creating floating IP from floating network '%s': %s", floatingNetwork, err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + instanceIP = *newIP + ui.Message(fmt.Sprintf("Created floating IP: '%s' (%s)", instanceIP.ID, instanceIP.FloatingIP)) + state.Put("floatingip_istemp", true) + } + + // Assoctate a floating IP that was obtained in the previous steps. + if instanceIP.ID != "" { + ui.Say(fmt.Sprintf("Associating floating IP '%s' (%s) with instance port...", + instanceIP.ID, instanceIP.FloatingIP)) + + portID, err := GetInstancePortID(computeClient, server.ID) + if err != nil { + err := fmt.Errorf("Error getting interfaces of the instance '%s': %s", server.ID, err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + _, err = floatingips.Update(networkClient, instanceIP.ID, floatingips.UpdateOpts{ + PortID: &portID, + }).Extract() if err != nil { err := fmt.Errorf( - "Error associating floating IP %s with instance: %s", - instanceIp.IP, err) + "Error associating floating IP '%s' (%s) with instance port '%s': %s", + instanceIP.ID, instanceIP.FloatingIP, portID, err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } ui.Message(fmt.Sprintf( - "Added floating IP %s to instance!", instanceIp.IP)) + "Added floating IP '%s' (%s) to instance!", instanceIP.ID, instanceIP.FloatingIP)) } - state.Put("access_ip", &instanceIp) + state.Put("access_ip", &instanceIP) return multistep.ActionContinue } func (s *StepAllocateIp) Cleanup(state multistep.StateBag) { config := state.Get("config").(Config) ui := state.Get("ui").(packer.Ui) - instanceIp := state.Get("access_ip").(*floatingips.FloatingIP) + instanceIP := state.Get("access_ip").(*floatingips.FloatingIP) // Don't delete pool addresses we didn't allocate if state.Get("floatingip_istemp") == false { return } - // We need the v2 compute client - client, err := config.computeV2Client() + // We need the v2 network client + client, err := config.networkV2Client() if err != nil { ui.Error(fmt.Sprintf( - "Error deleting temporary floating IP %s", instanceIp.IP)) + "Error deleting temporary floating IP '%s' (%s)", instanceIP.ID, instanceIP.FloatingIP)) return } - if s.FloatingIpPool != "" && instanceIp.ID != "" { - if err := floatingips.Delete(client, instanceIp.ID).ExtractErr(); err != nil { + if instanceIP.ID != "" { + if err := floatingips.Delete(client, instanceIP.ID).ExtractErr(); err != nil { ui.Error(fmt.Sprintf( - "Error deleting temporary floating IP %s", instanceIp.IP)) + "Error deleting temporary floating IP '%s' (%s)", instanceIP.ID, instanceIP.FloatingIP)) return } - ui.Say(fmt.Sprintf("Deleted temporary floating IP %s", instanceIp.IP)) + ui.Say(fmt.Sprintf("Deleted temporary floating IP '%s' (%s)", instanceIP.ID, instanceIP.FloatingIP)) } } From c9047cbfbe71986d31de0c852785f2e741292bce Mon Sep 17 00:00:00 2001 From: Andrei Ozerov Date: Tue, 12 Jun 2018 14:08:17 +0300 Subject: [PATCH 206/220] OpenStack builder: update floating IP params Rename "floating_network" to the "floating_ip_network". Return old "floating_ip_pool" parameter for backward compatibility with old configuration files. It's value will be passed to the "floating_ip_network" parameter. --- builder/openstack/builder.go | 6 ++--- builder/openstack/run_config.go | 37 ++++++++++++++++----------- builder/openstack/run_config_test.go | 16 +++++++++--- builder/openstack/step_allocate_ip.go | 8 +++--- 4 files changed, 41 insertions(+), 26 deletions(-) diff --git a/builder/openstack/builder.go b/builder/openstack/builder.go index c505233bb..2938d67c0 100644 --- a/builder/openstack/builder.go +++ b/builder/openstack/builder.go @@ -115,9 +115,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Wait: b.config.RackconnectWait, }, &StepAllocateIp{ - FloatingNetwork: b.config.FloatingNetwork, - FloatingIP: b.config.FloatingIP, - ReuseIPs: b.config.ReuseIPs, + FloatingIPNetwork: b.config.FloatingIPNetwork, + FloatingIP: b.config.FloatingIP, + ReuseIPs: b.config.ReuseIPs, }, &communicator.StepConnect{ Config: &b.config.RunConfig.Comm, diff --git a/builder/openstack/run_config.go b/builder/openstack/run_config.go index 1b2f209c8..ad9fa41aa 100644 --- a/builder/openstack/run_config.go +++ b/builder/openstack/run_config.go @@ -18,24 +18,27 @@ type RunConfig struct { SSHInterface string `mapstructure:"ssh_interface"` SSHIPVersion string `mapstructure:"ssh_ip_version"` - SourceImage string `mapstructure:"source_image"` - SourceImageName string `mapstructure:"source_image_name"` - Flavor string `mapstructure:"flavor"` - AvailabilityZone string `mapstructure:"availability_zone"` - RackconnectWait bool `mapstructure:"rackconnect_wait"` - FloatingNetwork string `mapstructure:"floating_network"` - FloatingIP string `mapstructure:"floating_ip"` - ReuseIPs bool `mapstructure:"reuse_ips"` - SecurityGroups []string `mapstructure:"security_groups"` - Networks []string `mapstructure:"networks"` - Ports []string `mapstructure:"ports"` - UserData string `mapstructure:"user_data"` - UserDataFile string `mapstructure:"user_data_file"` - InstanceName string `mapstructure:"instance_name"` - InstanceMetadata map[string]string `mapstructure:"instance_metadata"` + SourceImage string `mapstructure:"source_image"` + SourceImageName string `mapstructure:"source_image_name"` + Flavor string `mapstructure:"flavor"` + AvailabilityZone string `mapstructure:"availability_zone"` + RackconnectWait bool `mapstructure:"rackconnect_wait"` + FloatingIPNetwork string `mapstructure:"floating_ip_network"` + FloatingIP string `mapstructure:"floating_ip"` + ReuseIPs bool `mapstructure:"reuse_ips"` + SecurityGroups []string `mapstructure:"security_groups"` + Networks []string `mapstructure:"networks"` + Ports []string `mapstructure:"ports"` + UserData string `mapstructure:"user_data"` + UserDataFile string `mapstructure:"user_data_file"` + InstanceName string `mapstructure:"instance_name"` + InstanceMetadata map[string]string `mapstructure:"instance_metadata"` ConfigDrive bool `mapstructure:"config_drive"` + // Used for BC, value will be passed to the "floating_ip_network" + FloatingIPPool string `mapstructure:"floating_ip_pool"` + UseBlockStorageVolume bool `mapstructure:"use_blockstorage_volume"` VolumeName string `mapstructure:"volume_name"` VolumeType string `mapstructure:"volume_type"` @@ -57,6 +60,10 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { c.TemporaryKeyPairName = fmt.Sprintf("packer_%s", uuid.TimeOrderedUUID()) } + if c.FloatingIPPool != "" { + c.FloatingIPNetwork = c.FloatingIPPool + } + // Validation errs := c.Comm.Prepare(ctx) diff --git a/builder/openstack/run_config_test.go b/builder/openstack/run_config_test.go index b20e832d8..1f9960e27 100644 --- a/builder/openstack/run_config_test.go +++ b/builder/openstack/run_config_test.go @@ -101,11 +101,19 @@ func TestRunConfigPrepare_BlockStorage(t *testing.T) { } c.VolumeName = "PackerVolume" - if err := c.Prepare(nil); len(err) != 0 { - t.Fatalf("err: %s", err) - } - if c.VolumeName != "PackerVolume" { t.Fatalf("invalid value: %s", c.VolumeName) } } + +func TestRunConfigPrepare_FloatingIPPoolCompat(t *testing.T) { + c := testRunConfig() + c.FloatingIPPool = "uuid" + if err := c.Prepare(nil); len(err) != 0 { + t.Fatalf("err: %s", err) + } + + if c.FloatingIPNetwork != "uuid" { + t.Fatalf("invalid value: %s", c.FloatingIPNetwork) + } +} diff --git a/builder/openstack/step_allocate_ip.go b/builder/openstack/step_allocate_ip.go index b5a517680..7c864ca7a 100644 --- a/builder/openstack/step_allocate_ip.go +++ b/builder/openstack/step_allocate_ip.go @@ -11,9 +11,9 @@ import ( ) type StepAllocateIp struct { - FloatingNetwork string - FloatingIP string - ReuseIPs bool + FloatingIPNetwork string + FloatingIP string + ReuseIPs bool } func (s *StepAllocateIp) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { @@ -77,7 +77,7 @@ func (s *StepAllocateIp) Run(_ context.Context, state multistep.StateBag) multis if instanceIP.ID == "" { // Search for the external network that can be used for the floating IPs if // user hasn't provided any. - floatingNetwork := s.FloatingNetwork + floatingNetwork := s.FloatingIPNetwork if floatingNetwork == "" { ui.Say(fmt.Sprintf("Searching for the external network...")) externalNetwork, err := FindExternalNetwork(networkClient) From 29c20eae78b0b43cbfd45ebd70b2770a3eb5f252 Mon Sep 17 00:00:00 2001 From: Andrei Ozerov Date: Tue, 12 Jun 2018 14:22:14 +0300 Subject: [PATCH 207/220] Docs: update OpenStack floating IPs notes Introduce the new "floating_ip_network" parameter and add deprecation warning for the "floating_ip_pool" parameter. --- website/source/docs/builders/openstack.html.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/website/source/docs/builders/openstack.html.md b/website/source/docs/builders/openstack.html.md index 5ac1cac85..e81eb5ce9 100644 --- a/website/source/docs/builders/openstack.html.md +++ b/website/source/docs/builders/openstack.html.md @@ -112,8 +112,11 @@ builder. - `floating_ip` (string) - A specific floating IP to assign to this instance. -- `floating_ip_pool` (string) - The name of the floating IP pool to use to - allocate a floating IP. +- `floating_ip_network` (string) - The ID of an external network that can be + used for creation of a new floating IP. + +- `floating_ip_pool` (string) - *Deprecated* use `floating_ip_network` + instead. - `image_members` (array of strings) - List of members to add to the image after creation. An image member is usually a project (also called the From 511c4fbabe059b3d5ea59f22c95a87f1169fa7e9 Mon Sep 17 00:00:00 2001 From: Andrei Ozerov Date: Thu, 16 Aug 2018 22:21:05 +0300 Subject: [PATCH 208/220] Vendor: update OpenStack floatingips Fetch latest version of the Gophercloud Neutron floatingips package and sort vendor.json. --- vendor/vendor.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/vendor/vendor.json b/vendor/vendor.json index db4e04b40..24f1021b8 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -761,6 +761,12 @@ "revision": "95a28eb606def6aaaed082b6b82d3244b0552184", "revisionTime": "2017-06-23T01:44:30Z" }, + { + "checksumSHA1": "lW+ldKF07Zz/C7WYPTchfr1USrQ=", + "path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces", + "revision": "00dcc07f1071d5f96520fac7a2b9a30eabccf879", + "revisionTime": "2018-06-10T02:06:14Z" + }, { "checksumSHA1": "kCHEEeRVZeR1LhbvNP+WyvB8z2s=", "path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/bootfromvolume", @@ -773,12 +779,6 @@ "revision": "7112fcd50da4ea27e8d4d499b30f04eea143bec2", "revisionTime": "2018-05-31T02:06:30Z" }, - { - "checksumSHA1": "lW+ldKF07Zz/C7WYPTchfr1USrQ=", - "path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces", - "revision": "00dcc07f1071d5f96520fac7a2b9a30eabccf879", - "revisionTime": "2018-06-10T02:06:14Z" - }, { "checksumSHA1": "lAQuKIqTuQ9JuMgN0pPkNtRH2RM=", "path": "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs", @@ -848,8 +848,8 @@ { "checksumSHA1": "K4VAatvB/jywsU+g/mU7bnSaVaI=", "path": "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips", - "revision": "00dcc07f1071d5f96520fac7a2b9a30eabccf879", - "revisionTime": "2018-06-10T02:06:14Z" + "revision": "83835c772d1adf71e8df7440d5da9ad039dc049e", + "revisionTime": "2018-08-15T02:05:10Z" }, { "checksumSHA1": "XEVvG2f/dqATN4aCluZlPylW+9A=", From 1af899248bd285ceb04d98982e34c6410e216f75 Mon Sep 17 00:00:00 2001 From: Andrei Ozerov Date: Thu, 16 Aug 2018 23:38:41 +0300 Subject: [PATCH 209/220] OpenStack builder: allow floating IP network name Add support for the external network reference by it's name apart from ID. Include external network id in a log message of the openstack/step_allocate_ip. --- builder/openstack/networks.go | 37 +++++++++++++++++++++++++++ builder/openstack/step_allocate_ip.go | 20 ++++++++++----- 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/builder/openstack/networks.go b/builder/openstack/networks.go index ac56fa531..8afc31013 100644 --- a/builder/openstack/networks.go +++ b/builder/openstack/networks.go @@ -3,6 +3,7 @@ package openstack import ( "fmt" + "github.com/google/uuid" "github.com/gophercloud/gophercloud" "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces" "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external" @@ -112,3 +113,39 @@ func GetInstancePortID(client *gophercloud.ServiceClient, id string) (string, er return interfaces[0].PortID, nil } + +// CheckExternalNetworkRef checks provided network reference and returns a valid +// Networking service ID. +func CheckExternalNetworkRef(client *gophercloud.ServiceClient, networkRef string) (string, error) { + if _, err := uuid.Parse(networkRef); err != nil { + return GetExternalNetworkIDByName(client, networkRef) + } + + return networkRef, nil +} + +// GetExternalNetworkIDByName searches for the external network ID by the provided name. +func GetExternalNetworkIDByName(client *gophercloud.ServiceClient, networkName string) (string, error) { + var externalNetworks []ExternalNetwork + + allPages, err := networks.List(client, networks.ListOpts{ + Name: networkName, + }).AllPages() + if err != nil { + return "", err + } + + if err := networks.ExtractNetworksInto(allPages, &externalNetworks); err != nil { + return "", err + } + + if len(externalNetworks) == 0 { + return "", fmt.Errorf("can't find external network %s", networkName) + } + // Check and return the first external network. + if !externalNetworks[0].External { + return "", fmt.Errorf("network %s is not external", networkName) + } + + return externalNetworks[0].ID, nil +} diff --git a/builder/openstack/step_allocate_ip.go b/builder/openstack/step_allocate_ip.go index 7c864ca7a..ad58ad352 100644 --- a/builder/openstack/step_allocate_ip.go +++ b/builder/openstack/step_allocate_ip.go @@ -75,10 +75,19 @@ func (s *StepAllocateIp) Run(_ context.Context, state multistep.StateBag) multis // Create a new floating IP if it wasn't obtained in the previous step. if instanceIP.ID == "" { - // Search for the external network that can be used for the floating IPs if - // user hasn't provided any. - floatingNetwork := s.FloatingIPNetwork - if floatingNetwork == "" { + var floatingNetwork string + + if s.FloatingIPNetwork != "" { + // Validate provided external network reference and get an ID. + floatingNetwork, err = CheckExternalNetworkRef(networkClient, s.FloatingIPNetwork) + if err != nil { + err := fmt.Errorf("Error using the provided floating_ip_network: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } else { + // Search for the external network that can be used for the floating IPs. ui.Say(fmt.Sprintf("Searching for the external network...")) externalNetwork, err := FindExternalNetwork(networkClient) if err != nil { @@ -87,11 +96,10 @@ func (s *StepAllocateIp) Run(_ context.Context, state multistep.StateBag) multis ui.Error(err.Error()) return multistep.ActionHalt } - floatingNetwork = externalNetwork.ID } - ui.Say(fmt.Sprintf("Creating floating IP...")) + ui.Say(fmt.Sprintf("Creating floating IP using network %s ...", floatingNetwork)) newIP, err := floatingips.Create(networkClient, floatingips.CreateOpts{ FloatingNetworkID: floatingNetwork, }).Extract() From 72de95a7e193a514f09646bc37b2cdd0577e9888 Mon Sep 17 00:00:00 2001 From: Andrei Ozerov Date: Thu, 16 Aug 2018 23:42:35 +0300 Subject: [PATCH 210/220] Vendor: add github.com/google/uuid package Add a package to work with UUIDs. This package is used by the OpenStack builder to check the provided network reference. --- vendor/github.com/google/uuid/CONTRIBUTING.md | 10 + vendor/github.com/google/uuid/CONTRIBUTORS | 9 + vendor/github.com/google/uuid/LICENSE | 27 +++ vendor/github.com/google/uuid/README.md | 23 ++ vendor/github.com/google/uuid/dce.go | 80 +++++++ vendor/github.com/google/uuid/doc.go | 12 ++ vendor/github.com/google/uuid/hash.go | 53 +++++ vendor/github.com/google/uuid/marshal.go | 39 ++++ vendor/github.com/google/uuid/node.go | 90 ++++++++ vendor/github.com/google/uuid/node_js.go | 12 ++ vendor/github.com/google/uuid/node_net.go | 33 +++ vendor/github.com/google/uuid/sql.go | 59 ++++++ vendor/github.com/google/uuid/time.go | 123 +++++++++++ vendor/github.com/google/uuid/util.go | 43 ++++ vendor/github.com/google/uuid/uuid.go | 198 ++++++++++++++++++ vendor/github.com/google/uuid/version1.go | 44 ++++ vendor/github.com/google/uuid/version4.go | 38 ++++ vendor/vendor.json | 6 + 18 files changed, 899 insertions(+) create mode 100644 vendor/github.com/google/uuid/CONTRIBUTING.md create mode 100644 vendor/github.com/google/uuid/CONTRIBUTORS create mode 100644 vendor/github.com/google/uuid/LICENSE create mode 100644 vendor/github.com/google/uuid/README.md create mode 100644 vendor/github.com/google/uuid/dce.go create mode 100644 vendor/github.com/google/uuid/doc.go create mode 100644 vendor/github.com/google/uuid/hash.go create mode 100644 vendor/github.com/google/uuid/marshal.go create mode 100644 vendor/github.com/google/uuid/node.go create mode 100644 vendor/github.com/google/uuid/node_js.go create mode 100644 vendor/github.com/google/uuid/node_net.go create mode 100644 vendor/github.com/google/uuid/sql.go create mode 100644 vendor/github.com/google/uuid/time.go create mode 100644 vendor/github.com/google/uuid/util.go create mode 100644 vendor/github.com/google/uuid/uuid.go create mode 100644 vendor/github.com/google/uuid/version1.go create mode 100644 vendor/github.com/google/uuid/version4.go diff --git a/vendor/github.com/google/uuid/CONTRIBUTING.md b/vendor/github.com/google/uuid/CONTRIBUTING.md new file mode 100644 index 000000000..04fdf09f1 --- /dev/null +++ b/vendor/github.com/google/uuid/CONTRIBUTING.md @@ -0,0 +1,10 @@ +# How to contribute + +We definitely welcome patches and contribution to this project! + +### Legal requirements + +In order to protect both you and ourselves, you will need to sign the +[Contributor License Agreement](https://cla.developers.google.com/clas). + +You may have already signed it for other Google projects. diff --git a/vendor/github.com/google/uuid/CONTRIBUTORS b/vendor/github.com/google/uuid/CONTRIBUTORS new file mode 100644 index 000000000..b4bb97f6b --- /dev/null +++ b/vendor/github.com/google/uuid/CONTRIBUTORS @@ -0,0 +1,9 @@ +Paul Borman +bmatsuo +shawnps +theory +jboverfelt +dsymonds +cd1 +wallclockbuilder +dansouza diff --git a/vendor/github.com/google/uuid/LICENSE b/vendor/github.com/google/uuid/LICENSE new file mode 100644 index 000000000..5dc68268d --- /dev/null +++ b/vendor/github.com/google/uuid/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009,2014 Google Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/google/uuid/README.md b/vendor/github.com/google/uuid/README.md new file mode 100644 index 000000000..21205eaeb --- /dev/null +++ b/vendor/github.com/google/uuid/README.md @@ -0,0 +1,23 @@ +**This package is currently in development and the API may not be stable.** + +The API will become stable with v1. + +# uuid ![build status](https://travis-ci.org/google/uuid.svg?branch=master) +The uuid package generates and inspects UUIDs based on +[RFC 4122](http://tools.ietf.org/html/rfc4122) +and DCE 1.1: Authentication and Security Services. + +This package is based on the github.com/pborman/uuid package (previously named +code.google.com/p/go-uuid). It differs from these earlier packages in that +a UUID is a 16 byte array rather than a byte slice. One loss due to this +change is the ability to represent an invalid UUID (vs a NIL UUID). + +###### Install +`go get github.com/google/uuid` + +###### Documentation +[![GoDoc](https://godoc.org/github.com/google/uuid?status.svg)](http://godoc.org/github.com/google/uuid) + +Full `go doc` style documentation for the package can be viewed online without +installing this package by using the GoDoc site here: +http://godoc.org/github.com/google/uuid diff --git a/vendor/github.com/google/uuid/dce.go b/vendor/github.com/google/uuid/dce.go new file mode 100644 index 000000000..fa820b9d3 --- /dev/null +++ b/vendor/github.com/google/uuid/dce.go @@ -0,0 +1,80 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "encoding/binary" + "fmt" + "os" +) + +// A Domain represents a Version 2 domain +type Domain byte + +// Domain constants for DCE Security (Version 2) UUIDs. +const ( + Person = Domain(0) + Group = Domain(1) + Org = Domain(2) +) + +// NewDCESecurity returns a DCE Security (Version 2) UUID. +// +// The domain should be one of Person, Group or Org. +// On a POSIX system the id should be the users UID for the Person +// domain and the users GID for the Group. The meaning of id for +// the domain Org or on non-POSIX systems is site defined. +// +// For a given domain/id pair the same token may be returned for up to +// 7 minutes and 10 seconds. +func NewDCESecurity(domain Domain, id uint32) (UUID, error) { + uuid, err := NewUUID() + if err == nil { + uuid[6] = (uuid[6] & 0x0f) | 0x20 // Version 2 + uuid[9] = byte(domain) + binary.BigEndian.PutUint32(uuid[0:], id) + } + return uuid, err +} + +// NewDCEPerson returns a DCE Security (Version 2) UUID in the person +// domain with the id returned by os.Getuid. +// +// NewDCESecurity(Person, uint32(os.Getuid())) +func NewDCEPerson() (UUID, error) { + return NewDCESecurity(Person, uint32(os.Getuid())) +} + +// NewDCEGroup returns a DCE Security (Version 2) UUID in the group +// domain with the id returned by os.Getgid. +// +// NewDCESecurity(Group, uint32(os.Getgid())) +func NewDCEGroup() (UUID, error) { + return NewDCESecurity(Group, uint32(os.Getgid())) +} + +// Domain returns the domain for a Version 2 UUID. Domains are only defined +// for Version 2 UUIDs. +func (uuid UUID) Domain() Domain { + return Domain(uuid[9]) +} + +// ID returns the id for a Version 2 UUID. IDs are only defined for Version 2 +// UUIDs. +func (uuid UUID) ID() uint32 { + return binary.BigEndian.Uint32(uuid[0:4]) +} + +func (d Domain) String() string { + switch d { + case Person: + return "Person" + case Group: + return "Group" + case Org: + return "Org" + } + return fmt.Sprintf("Domain%d", int(d)) +} diff --git a/vendor/github.com/google/uuid/doc.go b/vendor/github.com/google/uuid/doc.go new file mode 100644 index 000000000..5b8a4b9af --- /dev/null +++ b/vendor/github.com/google/uuid/doc.go @@ -0,0 +1,12 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package uuid generates and inspects UUIDs. +// +// UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security +// Services. +// +// A UUID is a 16 byte (128 bit) array. UUIDs may be used as keys to +// maps or compared directly. +package uuid diff --git a/vendor/github.com/google/uuid/hash.go b/vendor/github.com/google/uuid/hash.go new file mode 100644 index 000000000..b17461631 --- /dev/null +++ b/vendor/github.com/google/uuid/hash.go @@ -0,0 +1,53 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "crypto/md5" + "crypto/sha1" + "hash" +) + +// Well known namespace IDs and UUIDs +var ( + NameSpaceDNS = Must(Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8")) + NameSpaceURL = Must(Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8")) + NameSpaceOID = Must(Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8")) + NameSpaceX500 = Must(Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8")) + Nil UUID // empty UUID, all zeros +) + +// NewHash returns a new UUID derived from the hash of space concatenated with +// data generated by h. The hash should be at least 16 byte in length. The +// first 16 bytes of the hash are used to form the UUID. The version of the +// UUID will be the lower 4 bits of version. NewHash is used to implement +// NewMD5 and NewSHA1. +func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID { + h.Reset() + h.Write(space[:]) + h.Write(data) + s := h.Sum(nil) + var uuid UUID + copy(uuid[:], s) + uuid[6] = (uuid[6] & 0x0f) | uint8((version&0xf)<<4) + uuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant + return uuid +} + +// NewMD5 returns a new MD5 (Version 3) UUID based on the +// supplied name space and data. It is the same as calling: +// +// NewHash(md5.New(), space, data, 3) +func NewMD5(space UUID, data []byte) UUID { + return NewHash(md5.New(), space, data, 3) +} + +// NewSHA1 returns a new SHA1 (Version 5) UUID based on the +// supplied name space and data. It is the same as calling: +// +// NewHash(sha1.New(), space, data, 5) +func NewSHA1(space UUID, data []byte) UUID { + return NewHash(sha1.New(), space, data, 5) +} diff --git a/vendor/github.com/google/uuid/marshal.go b/vendor/github.com/google/uuid/marshal.go new file mode 100644 index 000000000..84bbc5880 --- /dev/null +++ b/vendor/github.com/google/uuid/marshal.go @@ -0,0 +1,39 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import "fmt" + +// MarshalText implements encoding.TextMarshaler. +func (uuid UUID) MarshalText() ([]byte, error) { + var js [36]byte + encodeHex(js[:], uuid) + return js[:], nil +} + +// UnmarshalText implements encoding.TextUnmarshaler. +func (uuid *UUID) UnmarshalText(data []byte) error { + // See comment in ParseBytes why we do this. + // id, err := ParseBytes(data) + id, err := ParseBytes(data) + if err == nil { + *uuid = id + } + return err +} + +// MarshalBinary implements encoding.BinaryMarshaler. +func (uuid UUID) MarshalBinary() ([]byte, error) { + return uuid[:], nil +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler. +func (uuid *UUID) UnmarshalBinary(data []byte) error { + if len(data) != 16 { + return fmt.Errorf("invalid UUID (got %d bytes)", len(data)) + } + copy(uuid[:], data) + return nil +} diff --git a/vendor/github.com/google/uuid/node.go b/vendor/github.com/google/uuid/node.go new file mode 100644 index 000000000..384f07d02 --- /dev/null +++ b/vendor/github.com/google/uuid/node.go @@ -0,0 +1,90 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "sync" +) + +var ( + nodeMu sync.Mutex + ifname string // name of interface being used + nodeID [6]byte // hardware for version 1 UUIDs + zeroID [6]byte // nodeID with only 0's +) + +// NodeInterface returns the name of the interface from which the NodeID was +// derived. The interface "user" is returned if the NodeID was set by +// SetNodeID. +func NodeInterface() string { + defer nodeMu.Unlock() + nodeMu.Lock() + return ifname +} + +// SetNodeInterface selects the hardware address to be used for Version 1 UUIDs. +// If name is "" then the first usable interface found will be used or a random +// Node ID will be generated. If a named interface cannot be found then false +// is returned. +// +// SetNodeInterface never fails when name is "". +func SetNodeInterface(name string) bool { + defer nodeMu.Unlock() + nodeMu.Lock() + return setNodeInterface(name) +} + +func setNodeInterface(name string) bool { + + iname, addr := getHardwareInterface(name) // null implementation for js + if iname != "" && addr != nil { + ifname = iname + copy(nodeID[:], addr) + return true + } + + // We found no interfaces with a valid hardware address. If name + // does not specify a specific interface generate a random Node ID + // (section 4.1.6) + if name == "" { + randomBits(nodeID[:]) + return true + } + return false +} + +// NodeID returns a slice of a copy of the current Node ID, setting the Node ID +// if not already set. +func NodeID() []byte { + defer nodeMu.Unlock() + nodeMu.Lock() + if nodeID == zeroID { + setNodeInterface("") + } + nid := nodeID + return nid[:] +} + +// SetNodeID sets the Node ID to be used for Version 1 UUIDs. The first 6 bytes +// of id are used. If id is less than 6 bytes then false is returned and the +// Node ID is not set. +func SetNodeID(id []byte) bool { + if len(id) < 6 { + return false + } + defer nodeMu.Unlock() + nodeMu.Lock() + copy(nodeID[:], id) + ifname = "user" + return true +} + +// NodeID returns the 6 byte node id encoded in uuid. It returns nil if uuid is +// not valid. The NodeID is only well defined for version 1 and 2 UUIDs. +func (uuid UUID) NodeID() []byte { + var node [6]byte + copy(node[:], uuid[10:]) + return node[:] +} diff --git a/vendor/github.com/google/uuid/node_js.go b/vendor/github.com/google/uuid/node_js.go new file mode 100644 index 000000000..24b78edc9 --- /dev/null +++ b/vendor/github.com/google/uuid/node_js.go @@ -0,0 +1,12 @@ +// Copyright 2017 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build js + +package uuid + +// getHardwareInterface returns nil values for the JS version of the code. +// This remvoves the "net" dependency, because it is not used in the browser. +// Using the "net" library inflates the size of the transpiled JS code by 673k bytes. +func getHardwareInterface(name string) (string, []byte) { return "", nil } diff --git a/vendor/github.com/google/uuid/node_net.go b/vendor/github.com/google/uuid/node_net.go new file mode 100644 index 000000000..0cbbcddbd --- /dev/null +++ b/vendor/github.com/google/uuid/node_net.go @@ -0,0 +1,33 @@ +// Copyright 2017 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !js + +package uuid + +import "net" + +var interfaces []net.Interface // cached list of interfaces + +// getHardwareInterface returns the name and hardware address of interface name. +// If name is "" then the name and hardware address of one of the system's +// interfaces is returned. If no interfaces are found (name does not exist or +// there are no interfaces) then "", nil is returned. +// +// Only addresses of at least 6 bytes are returned. +func getHardwareInterface(name string) (string, []byte) { + if interfaces == nil { + var err error + interfaces, err = net.Interfaces() + if err != nil { + return "", nil + } + } + for _, ifs := range interfaces { + if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) { + return ifs.Name, ifs.HardwareAddr + } + } + return "", nil +} diff --git a/vendor/github.com/google/uuid/sql.go b/vendor/github.com/google/uuid/sql.go new file mode 100644 index 000000000..f326b54db --- /dev/null +++ b/vendor/github.com/google/uuid/sql.go @@ -0,0 +1,59 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "database/sql/driver" + "fmt" +) + +// Scan implements sql.Scanner so UUIDs can be read from databases transparently +// Currently, database types that map to string and []byte are supported. Please +// consult database-specific driver documentation for matching types. +func (uuid *UUID) Scan(src interface{}) error { + switch src := src.(type) { + case nil: + return nil + + case string: + // if an empty UUID comes from a table, we return a null UUID + if src == "" { + return nil + } + + // see Parse for required string format + u, err := Parse(src) + if err != nil { + return fmt.Errorf("Scan: %v", err) + } + + *uuid = u + + case []byte: + // if an empty UUID comes from a table, we return a null UUID + if len(src) == 0 { + return nil + } + + // assumes a simple slice of bytes if 16 bytes + // otherwise attempts to parse + if len(src) != 16 { + return uuid.Scan(string(src)) + } + copy((*uuid)[:], src) + + default: + return fmt.Errorf("Scan: unable to scan type %T into UUID", src) + } + + return nil +} + +// Value implements sql.Valuer so that UUIDs can be written to databases +// transparently. Currently, UUIDs map to strings. Please consult +// database-specific driver documentation for matching types. +func (uuid UUID) Value() (driver.Value, error) { + return uuid.String(), nil +} diff --git a/vendor/github.com/google/uuid/time.go b/vendor/github.com/google/uuid/time.go new file mode 100644 index 000000000..e6ef06cdc --- /dev/null +++ b/vendor/github.com/google/uuid/time.go @@ -0,0 +1,123 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "encoding/binary" + "sync" + "time" +) + +// A Time represents a time as the number of 100's of nanoseconds since 15 Oct +// 1582. +type Time int64 + +const ( + lillian = 2299160 // Julian day of 15 Oct 1582 + unix = 2440587 // Julian day of 1 Jan 1970 + epoch = unix - lillian // Days between epochs + g1582 = epoch * 86400 // seconds between epochs + g1582ns100 = g1582 * 10000000 // 100s of a nanoseconds between epochs +) + +var ( + timeMu sync.Mutex + lasttime uint64 // last time we returned + clockSeq uint16 // clock sequence for this run + + timeNow = time.Now // for testing +) + +// UnixTime converts t the number of seconds and nanoseconds using the Unix +// epoch of 1 Jan 1970. +func (t Time) UnixTime() (sec, nsec int64) { + sec = int64(t - g1582ns100) + nsec = (sec % 10000000) * 100 + sec /= 10000000 + return sec, nsec +} + +// GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and +// clock sequence as well as adjusting the clock sequence as needed. An error +// is returned if the current time cannot be determined. +func GetTime() (Time, uint16, error) { + defer timeMu.Unlock() + timeMu.Lock() + return getTime() +} + +func getTime() (Time, uint16, error) { + t := timeNow() + + // If we don't have a clock sequence already, set one. + if clockSeq == 0 { + setClockSequence(-1) + } + now := uint64(t.UnixNano()/100) + g1582ns100 + + // If time has gone backwards with this clock sequence then we + // increment the clock sequence + if now <= lasttime { + clockSeq = ((clockSeq + 1) & 0x3fff) | 0x8000 + } + lasttime = now + return Time(now), clockSeq, nil +} + +// ClockSequence returns the current clock sequence, generating one if not +// already set. The clock sequence is only used for Version 1 UUIDs. +// +// The uuid package does not use global static storage for the clock sequence or +// the last time a UUID was generated. Unless SetClockSequence is used, a new +// random clock sequence is generated the first time a clock sequence is +// requested by ClockSequence, GetTime, or NewUUID. (section 4.2.1.1) +func ClockSequence() int { + defer timeMu.Unlock() + timeMu.Lock() + return clockSequence() +} + +func clockSequence() int { + if clockSeq == 0 { + setClockSequence(-1) + } + return int(clockSeq & 0x3fff) +} + +// SetClockSequence sets the clock sequence to the lower 14 bits of seq. Setting to +// -1 causes a new sequence to be generated. +func SetClockSequence(seq int) { + defer timeMu.Unlock() + timeMu.Lock() + setClockSequence(seq) +} + +func setClockSequence(seq int) { + if seq == -1 { + var b [2]byte + randomBits(b[:]) // clock sequence + seq = int(b[0])<<8 | int(b[1]) + } + oldSeq := clockSeq + clockSeq = uint16(seq&0x3fff) | 0x8000 // Set our variant + if oldSeq != clockSeq { + lasttime = 0 + } +} + +// Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in +// uuid. The time is only defined for version 1 and 2 UUIDs. +func (uuid UUID) Time() Time { + time := int64(binary.BigEndian.Uint32(uuid[0:4])) + time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32 + time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48 + return Time(time) +} + +// ClockSequence returns the clock sequence encoded in uuid. +// The clock sequence is only well defined for version 1 and 2 UUIDs. +func (uuid UUID) ClockSequence() int { + return int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff +} diff --git a/vendor/github.com/google/uuid/util.go b/vendor/github.com/google/uuid/util.go new file mode 100644 index 000000000..5ea6c7378 --- /dev/null +++ b/vendor/github.com/google/uuid/util.go @@ -0,0 +1,43 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "io" +) + +// randomBits completely fills slice b with random data. +func randomBits(b []byte) { + if _, err := io.ReadFull(rander, b); err != nil { + panic(err.Error()) // rand should never fail + } +} + +// xvalues returns the value of a byte as a hexadecimal digit or 255. +var xvalues = [256]byte{ + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255, + 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +} + +// xtob converts hex characters x1 and x2 into a byte. +func xtob(x1, x2 byte) (byte, bool) { + b1 := xvalues[x1] + b2 := xvalues[x2] + return (b1 << 4) | b2, b1 != 255 && b2 != 255 +} diff --git a/vendor/github.com/google/uuid/uuid.go b/vendor/github.com/google/uuid/uuid.go new file mode 100644 index 000000000..7f3643fe9 --- /dev/null +++ b/vendor/github.com/google/uuid/uuid.go @@ -0,0 +1,198 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "bytes" + "crypto/rand" + "encoding/hex" + "errors" + "fmt" + "io" + "strings" +) + +// A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC +// 4122. +type UUID [16]byte + +// A Version represents a UUID's version. +type Version byte + +// A Variant represents a UUID's variant. +type Variant byte + +// Constants returned by Variant. +const ( + Invalid = Variant(iota) // Invalid UUID + RFC4122 // The variant specified in RFC4122 + Reserved // Reserved, NCS backward compatibility. + Microsoft // Reserved, Microsoft Corporation backward compatibility. + Future // Reserved for future definition. +) + +var rander = rand.Reader // random function + +// Parse decodes s into a UUID or returns an error. Both the UUID form of +// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and +// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded. +func Parse(s string) (UUID, error) { + var uuid UUID + if len(s) != 36 { + if len(s) != 36+9 { + return uuid, fmt.Errorf("invalid UUID length: %d", len(s)) + } + if strings.ToLower(s[:9]) != "urn:uuid:" { + return uuid, fmt.Errorf("invalid urn prefix: %q", s[:9]) + } + s = s[9:] + } + if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' { + return uuid, errors.New("invalid UUID format") + } + for i, x := range [16]int{ + 0, 2, 4, 6, + 9, 11, + 14, 16, + 19, 21, + 24, 26, 28, 30, 32, 34} { + v, ok := xtob(s[x], s[x+1]) + if !ok { + return uuid, errors.New("invalid UUID format") + } + uuid[i] = v + } + return uuid, nil +} + +// ParseBytes is like Parse, except it parses a byte slice instead of a string. +func ParseBytes(b []byte) (UUID, error) { + var uuid UUID + if len(b) != 36 { + if len(b) != 36+9 { + return uuid, fmt.Errorf("invalid UUID length: %d", len(b)) + } + if !bytes.Equal(bytes.ToLower(b[:9]), []byte("urn:uuid:")) { + return uuid, fmt.Errorf("invalid urn prefix: %q", b[:9]) + } + b = b[9:] + } + if b[8] != '-' || b[13] != '-' || b[18] != '-' || b[23] != '-' { + return uuid, errors.New("invalid UUID format") + } + for i, x := range [16]int{ + 0, 2, 4, 6, + 9, 11, + 14, 16, + 19, 21, + 24, 26, 28, 30, 32, 34} { + v, ok := xtob(b[x], b[x+1]) + if !ok { + return uuid, errors.New("invalid UUID format") + } + uuid[i] = v + } + return uuid, nil +} + +// FromBytes creates a new UUID from a byte slice. Returns an error if the slice +// does not have a length of 16. The bytes are copied from the slice. +func FromBytes(b []byte) (uuid UUID, err error) { + err = uuid.UnmarshalBinary(b) + return uuid, err +} + +// Must returns uuid if err is nil and panics otherwise. +func Must(uuid UUID, err error) UUID { + if err != nil { + panic(err) + } + return uuid +} + +// String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +// , or "" if uuid is invalid. +func (uuid UUID) String() string { + var buf [36]byte + encodeHex(buf[:], uuid) + return string(buf[:]) +} + +// URN returns the RFC 2141 URN form of uuid, +// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, or "" if uuid is invalid. +func (uuid UUID) URN() string { + var buf [36 + 9]byte + copy(buf[:], "urn:uuid:") + encodeHex(buf[9:], uuid) + return string(buf[:]) +} + +func encodeHex(dst []byte, uuid UUID) { + hex.Encode(dst[:], uuid[:4]) + dst[8] = '-' + hex.Encode(dst[9:13], uuid[4:6]) + dst[13] = '-' + hex.Encode(dst[14:18], uuid[6:8]) + dst[18] = '-' + hex.Encode(dst[19:23], uuid[8:10]) + dst[23] = '-' + hex.Encode(dst[24:], uuid[10:]) +} + +// Variant returns the variant encoded in uuid. +func (uuid UUID) Variant() Variant { + switch { + case (uuid[8] & 0xc0) == 0x80: + return RFC4122 + case (uuid[8] & 0xe0) == 0xc0: + return Microsoft + case (uuid[8] & 0xe0) == 0xe0: + return Future + default: + return Reserved + } +} + +// Version returns the version of uuid. +func (uuid UUID) Version() Version { + return Version(uuid[6] >> 4) +} + +func (v Version) String() string { + if v > 15 { + return fmt.Sprintf("BAD_VERSION_%d", v) + } + return fmt.Sprintf("VERSION_%d", v) +} + +func (v Variant) String() string { + switch v { + case RFC4122: + return "RFC4122" + case Reserved: + return "Reserved" + case Microsoft: + return "Microsoft" + case Future: + return "Future" + case Invalid: + return "Invalid" + } + return fmt.Sprintf("BadVariant%d", int(v)) +} + +// SetRand sets the random number generator to r, which implements io.Reader. +// If r.Read returns an error when the package requests random data then +// a panic will be issued. +// +// Calling SetRand with nil sets the random number generator to the default +// generator. +func SetRand(r io.Reader) { + if r == nil { + rander = rand.Reader + return + } + rander = r +} diff --git a/vendor/github.com/google/uuid/version1.go b/vendor/github.com/google/uuid/version1.go new file mode 100644 index 000000000..199a1ac65 --- /dev/null +++ b/vendor/github.com/google/uuid/version1.go @@ -0,0 +1,44 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "encoding/binary" +) + +// NewUUID returns a Version 1 UUID based on the current NodeID and clock +// sequence, and the current time. If the NodeID has not been set by SetNodeID +// or SetNodeInterface then it will be set automatically. If the NodeID cannot +// be set NewUUID returns nil. If clock sequence has not been set by +// SetClockSequence then it will be set automatically. If GetTime fails to +// return the current NewUUID returns nil and an error. +// +// In most cases, New should be used. +func NewUUID() (UUID, error) { + nodeMu.Lock() + if nodeID == zeroID { + setNodeInterface("") + } + nodeMu.Unlock() + + var uuid UUID + now, seq, err := GetTime() + if err != nil { + return uuid, err + } + + timeLow := uint32(now & 0xffffffff) + timeMid := uint16((now >> 32) & 0xffff) + timeHi := uint16((now >> 48) & 0x0fff) + timeHi |= 0x1000 // Version 1 + + binary.BigEndian.PutUint32(uuid[0:], timeLow) + binary.BigEndian.PutUint16(uuid[4:], timeMid) + binary.BigEndian.PutUint16(uuid[6:], timeHi) + binary.BigEndian.PutUint16(uuid[8:], seq) + copy(uuid[10:], nodeID[:]) + + return uuid, nil +} diff --git a/vendor/github.com/google/uuid/version4.go b/vendor/github.com/google/uuid/version4.go new file mode 100644 index 000000000..84af91c9f --- /dev/null +++ b/vendor/github.com/google/uuid/version4.go @@ -0,0 +1,38 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import "io" + +// New creates a new random UUID or panics. New is equivalent to +// the expression +// +// uuid.Must(uuid.NewRandom()) +func New() UUID { + return Must(NewRandom()) +} + +// NewRandom returns a Random (Version 4) UUID. +// +// The strength of the UUIDs is based on the strength of the crypto/rand +// package. +// +// A note about uniqueness derived from the UUID Wikipedia entry: +// +// Randomly generated UUIDs have 122 random bits. One's annual risk of being +// hit by a meteorite is estimated to be one chance in 17 billion, that +// means the probability is about 0.00000000006 (6 × 10−11), +// equivalent to the odds of creating a few tens of trillions of UUIDs in a +// year and having one duplicate. +func NewRandom() (UUID, error) { + var uuid UUID + _, err := io.ReadFull(rander, uuid[:]) + if err != nil { + return Nil, err + } + uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4 + uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10 + return uuid, nil +} diff --git a/vendor/vendor.json b/vendor/vendor.json index 24f1021b8..8e50f2acf 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -719,6 +719,12 @@ "revision": "6f45313302b9c56850fc17f99e40caebce98c716", "revisionTime": "2015-01-27T13:39:51Z" }, + { + "checksumSHA1": "uFNLkTxk8BkHTk0Jcub2lj2BX4M=", + "path": "github.com/google/uuid", + "revision": "dec09d789f3dba190787f8b4454c7d3c936fed9e", + "revisionTime": "2017-11-29T19:10:14Z" + }, { "checksumSHA1": "qduT9GZUhXc00XoHEwLx16Xn9gM=", "path": "github.com/gophercloud/gophercloud", From 5d6ba4301dd34f1b2f420cf3db11c3521496ffc1 Mon Sep 17 00:00:00 2001 From: Andrei Ozerov Date: Fri, 17 Aug 2018 00:15:18 +0300 Subject: [PATCH 211/220] OpenStack builder: fix floating_ip_pool validation Only use "floating_ip_pool" if "floating_ip_network" wasn't set. Update unit test for the OpenStack builder parameters. --- builder/openstack/run_config.go | 2 +- builder/openstack/run_config_test.go | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/builder/openstack/run_config.go b/builder/openstack/run_config.go index ad9fa41aa..b98b65ea8 100644 --- a/builder/openstack/run_config.go +++ b/builder/openstack/run_config.go @@ -60,7 +60,7 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { c.TemporaryKeyPairName = fmt.Sprintf("packer_%s", uuid.TimeOrderedUUID()) } - if c.FloatingIPPool != "" { + if c.FloatingIPPool != "" && c.FloatingIPNetwork == "" { c.FloatingIPNetwork = c.FloatingIPPool } diff --git a/builder/openstack/run_config_test.go b/builder/openstack/run_config_test.go index 1f9960e27..6ce0cf602 100644 --- a/builder/openstack/run_config_test.go +++ b/builder/openstack/run_config_test.go @@ -108,12 +108,22 @@ func TestRunConfigPrepare_BlockStorage(t *testing.T) { func TestRunConfigPrepare_FloatingIPPoolCompat(t *testing.T) { c := testRunConfig() - c.FloatingIPPool = "uuid" + c.FloatingIPPool = "uuid1" if err := c.Prepare(nil); len(err) != 0 { t.Fatalf("err: %s", err) } - if c.FloatingIPNetwork != "uuid" { + if c.FloatingIPNetwork != "uuid1" { + t.Fatalf("invalid value: %s", c.FloatingIPNetwork) + } + + c.FloatingIPNetwork = "uuid2" + c.FloatingIPPool = "uuid3" + if err := c.Prepare(nil); len(err) != 0 { + t.Fatalf("err: %s", err) + } + + if c.FloatingIPNetwork != "uuid2" { t.Fatalf("invalid value: %s", c.FloatingIPNetwork) } } From 2cde0d6132dbe09948d56bf1b55f8a4edcfc8704 Mon Sep 17 00:00:00 2001 From: Marcel Prince Date: Thu, 16 Aug 2018 14:23:29 -0700 Subject: [PATCH 212/220] Add env template function to doc --- website/source/docs/templates/engine.html.md | 1 + 1 file changed, 1 insertion(+) diff --git a/website/source/docs/templates/engine.html.md b/website/source/docs/templates/engine.html.md index f8dbc6468..e0bbda586 100644 --- a/website/source/docs/templates/engine.html.md +++ b/website/source/docs/templates/engine.html.md @@ -33,6 +33,7 @@ Here is a full list of the available functions for reference. - `build_name` - The name of the build being run. - `build_type` - The type of the builder being used currently. +- `env` - Returns environment variables. See example in [using home variable](/docs/templates/user-variables.html#using-home-variable) - `isotime [FORMAT]` - UTC time, which can be [formatted](https://golang.org/pkg/time/#example_Time_Format). See more examples below in [the `isotime` format reference](/docs/templates/engine.html#isotime-function-format-reference). From 103403db4800312823294a227d3c5647a3c33789 Mon Sep 17 00:00:00 2001 From: Andrei Ozerov Date: Fri, 17 Aug 2018 00:49:06 +0300 Subject: [PATCH 213/220] OpenStack builder: do not always use floating IPs Only associate floating IPs if user provided "floating_ip_network" or "floating_ip". Remove FindExternalNetwork helper method because it won't be used. --- builder/openstack/networks.go | 48 ++++++--------------------- builder/openstack/step_allocate_ip.go | 40 +++++++--------------- 2 files changed, 23 insertions(+), 65 deletions(-) diff --git a/builder/openstack/networks.go b/builder/openstack/networks.go index 8afc31013..30c435ee8 100644 --- a/builder/openstack/networks.go +++ b/builder/openstack/networks.go @@ -12,38 +12,6 @@ import ( "github.com/gophercloud/gophercloud/pagination" ) -// ExternalNetwork is a network with external router. -type ExternalNetwork struct { - networks.Network - external.NetworkExternalExt -} - -// FindExternalNetwork returns existing network with external router. -// It will return first network if there are many. -func FindExternalNetwork(client *gophercloud.ServiceClient) (*ExternalNetwork, error) { - var externalNetworks []ExternalNetwork - - allPages, err := networks.List(client, networks.ListOpts{ - Status: "ACTIVE", - }).AllPages() - if err != nil { - return nil, err - } - - // Extract external networks from found networks. - err = networks.ExtractNetworksInto(allPages, &externalNetworks) - if err != nil { - return nil, err - } - - if len(externalNetworks) == 0 { - return nil, fmt.Errorf("no external networks found") - } - - // Return the first external network. - return &externalNetworks[0], nil -} - // CheckFloatingIP gets a floating IP by its ID and checks if it is already // associated with any internal interface. // It returns floating IP if it can be used. @@ -114,18 +82,24 @@ func GetInstancePortID(client *gophercloud.ServiceClient, id string) (string, er return interfaces[0].PortID, nil } -// CheckExternalNetworkRef checks provided network reference and returns a valid +// CheckFloatingIPNetwork checks provided network reference and returns a valid // Networking service ID. -func CheckExternalNetworkRef(client *gophercloud.ServiceClient, networkRef string) (string, error) { +func CheckFloatingIPNetwork(client *gophercloud.ServiceClient, networkRef string) (string, error) { if _, err := uuid.Parse(networkRef); err != nil { - return GetExternalNetworkIDByName(client, networkRef) + return GetFloatingIPNetworkIDByName(client, networkRef) } return networkRef, nil } -// GetExternalNetworkIDByName searches for the external network ID by the provided name. -func GetExternalNetworkIDByName(client *gophercloud.ServiceClient, networkName string) (string, error) { +// ExternalNetwork is a network with external router. +type ExternalNetwork struct { + networks.Network + external.NetworkExternalExt +} + +// GetFloatingIPNetworkIDByName searches for the external network ID by the provided name. +func GetFloatingIPNetworkIDByName(client *gophercloud.ServiceClient, networkName string) (string, error) { var externalNetworks []ExternalNetwork allPages, err := networks.List(client, networks.ListOpts{ diff --git a/builder/openstack/step_allocate_ip.go b/builder/openstack/step_allocate_ip.go index ad58ad352..f4bc0c42a 100644 --- a/builder/openstack/step_allocate_ip.go +++ b/builder/openstack/step_allocate_ip.go @@ -43,8 +43,9 @@ func (s *StepAllocateIp) Run(_ context.Context, state multistep.StateBag) multis // statebag below, because it is requested by Cleanup() state.Put("access_ip", &instanceIP) - // Try to use floating IP provided by the user or find a free floating IP. + // WRITE NEW COMMENT> if s.FloatingIP != "" { + // Try to use FloatingIP if it was provided by the user. freeFloatingIP, err := CheckFloatingIP(networkClient, s.FloatingIP) if err != nil { err := fmt.Errorf("Error using provided floating IP '%s': %s", s.FloatingIP, err) @@ -71,32 +72,15 @@ func (s *StepAllocateIp) Run(_ context.Context, state multistep.StateBag) multis instanceIP = *freeFloatingIP ui.Message(fmt.Sprintf("Selected floating IP: '%s' (%s)", instanceIP.ID, instanceIP.FloatingIP)) state.Put("floatingip_istemp", false) - } - - // Create a new floating IP if it wasn't obtained in the previous step. - if instanceIP.ID == "" { - var floatingNetwork string - - if s.FloatingIPNetwork != "" { - // Validate provided external network reference and get an ID. - floatingNetwork, err = CheckExternalNetworkRef(networkClient, s.FloatingIPNetwork) - if err != nil { - err := fmt.Errorf("Error using the provided floating_ip_network: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - } else { - // Search for the external network that can be used for the floating IPs. - ui.Say(fmt.Sprintf("Searching for the external network...")) - externalNetwork, err := FindExternalNetwork(networkClient) - if err != nil { - err := fmt.Errorf("Error searching the external network: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - floatingNetwork = externalNetwork.ID + } else if s.FloatingIPNetwork != "" { + // Lastly, if FloatingIPNetwork was provided by the user, we need to use it + // to allocate a new floating IP and associate it to the instance. + floatingNetwork, err := CheckFloatingIPNetwork(networkClient, s.FloatingIPNetwork) + if err != nil { + err := fmt.Errorf("Error using the provided floating_ip_network: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt } ui.Say(fmt.Sprintf("Creating floating IP using network %s ...", floatingNetwork)) @@ -115,7 +99,7 @@ func (s *StepAllocateIp) Run(_ context.Context, state multistep.StateBag) multis state.Put("floatingip_istemp", true) } - // Assoctate a floating IP that was obtained in the previous steps. + // Assoctate a floating IP if it was obtained in the previous steps. if instanceIP.ID != "" { ui.Say(fmt.Sprintf("Associating floating IP '%s' (%s) with instance port...", instanceIP.ID, instanceIP.FloatingIP)) From 6bf442f039d51f45babe2d055f56eaaa9f78a491 Mon Sep 17 00:00:00 2001 From: Andrei Ozerov Date: Fri, 17 Aug 2018 07:55:31 +0300 Subject: [PATCH 214/220] OpenStack builder: fix floating IP docs Update website documentation about "floating_ip_network" parameter. Add new inline comment about alghoritm that is used for checking floatingIP-related configuration parameters. --- builder/openstack/step_allocate_ip.go | 7 ++++++- website/source/docs/builders/openstack.html.md | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/builder/openstack/step_allocate_ip.go b/builder/openstack/step_allocate_ip.go index f4bc0c42a..9570473fc 100644 --- a/builder/openstack/step_allocate_ip.go +++ b/builder/openstack/step_allocate_ip.go @@ -43,7 +43,12 @@ func (s *StepAllocateIp) Run(_ context.Context, state multistep.StateBag) multis // statebag below, because it is requested by Cleanup() state.Put("access_ip", &instanceIP) - // WRITE NEW COMMENT> + // Try to Use the OpenStack floating IP by checking provided parameters in + // the following order: + // - try to use "FloatingIP" ID directly if it's provided + // - try to find free floating IP in the project if "ReuseIPs" is set + // - create a new floating IP if "FloatingIPNetwork" is provided (it can be + // ID or name of the network). if s.FloatingIP != "" { // Try to use FloatingIP if it was provided by the user. freeFloatingIP, err := CheckFloatingIP(networkClient, s.FloatingIP) diff --git a/website/source/docs/builders/openstack.html.md b/website/source/docs/builders/openstack.html.md index e81eb5ce9..a05ce3d67 100644 --- a/website/source/docs/builders/openstack.html.md +++ b/website/source/docs/builders/openstack.html.md @@ -112,8 +112,8 @@ builder. - `floating_ip` (string) - A specific floating IP to assign to this instance. -- `floating_ip_network` (string) - The ID of an external network that can be - used for creation of a new floating IP. +- `floating_ip_network` (string) - The ID or name of an external network that + can be used for creation of a new floating IP. - `floating_ip_pool` (string) - *Deprecated* use `floating_ip_network` instead. From c744e8b2bbaf2d752bfb1536f41b17f774f5d064 Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Fri, 17 Aug 2018 09:29:39 +0200 Subject: [PATCH 215/220] make download messages less redudant and more simple --- common/step_download.go | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/common/step_download.go b/common/step_download.go index 071f2d44f..9110653b2 100644 --- a/common/step_download.go +++ b/common/step_download.go @@ -6,7 +6,6 @@ import ( "encoding/hex" "fmt" "log" - "strings" "time" "github.com/hashicorp/packer/helper/multistep" @@ -67,7 +66,7 @@ func (s *StepDownload) Run(_ context.Context, state multistep.StateBag) multiste } } - ui.Say(fmt.Sprintf("Downloading, copying or inplace referencing %s", s.Description)) + ui.Say(fmt.Sprintf("Retrieving %s", s.Description)) // First try to use any already downloaded file // If it fails, proceed to regular download logic @@ -112,14 +111,10 @@ func (s *StepDownload) Run(_ context.Context, state multistep.StateBag) multiste if finalPath == "" { for i, url := range s.Url { - if strings.HasPrefix(url, "file://") { - if s.Inplace { - ui.Message(fmt.Sprintf("Inplace referencing: %s", url)) - } else { - ui.Message(fmt.Sprintf("Copying: %s", url)) - } + if s.Inplace { + ui.Message(fmt.Sprintf("Using file in-place: %s", url)) } else { - ui.Message(fmt.Sprintf("Downloading: %s", url)) + ui.Message(fmt.Sprintf("Transferring file from path: %s", url)) } config := downloadConfigs[i] From 3ea8f9f50db3228a60739d31754cc97c901d6ff0 Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Fri, 17 Aug 2018 12:41:37 +0200 Subject: [PATCH 216/220] Small updates on the googlecompute website docs --- website/source/docs/builders/googlecompute.html.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/website/source/docs/builders/googlecompute.html.md b/website/source/docs/builders/googlecompute.html.md index eb5fb58e2..c4fa94850 100644 --- a/website/source/docs/builders/googlecompute.html.md +++ b/website/source/docs/builders/googlecompute.html.md @@ -124,9 +124,13 @@ is assumed to be the path to the file containing the JSON. ### Windows Example -Before you can provision using the winrm communicator, you need to navigate to -https://console.cloud.google.com/networking/firewalls/list to allow traffic +Before you can provision using the winrm communicator, you need to allow traffic through google's firewall on the winrm port (tcp:5986). +You can do so using the gcloud command. +``` +gcloud compute firewall-rules create allow-winrm --allow tcp:5986 +``` +Or alternatively by navigating to https://console.cloud.google.com/networking/firewalls/list. Once this is set up, the following is a complete working packer config after setting a valid `account_file` and `project_id`: @@ -153,6 +157,7 @@ setting a valid `account_file` and `project_id`: ] } ``` +This build can take up to 15 min. ### Nested Hypervisor Example From b85756c01e3a4ac86169ade70c7dfaa4e1ea4977 Mon Sep 17 00:00:00 2001 From: Rickard von Essen Date: Fri, 17 Aug 2018 15:40:31 +0200 Subject: [PATCH 217/220] Updated CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4e4a0982..179c1cb7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ * builder/openstack: Add support for ports. [GH-6570] * builder/openstack: Add support for getting config from clouds-public.yaml. [GH-6595] * builder/openstack: Support Block Storage volumes as boot volume. [GH-6596] +* builder/openstack: Migrate floating IP usage to Network v2 API from Compute API. [GH-6373] * builder/qemu: add ssh agent support. [GH-6541] * builder/qemu: New `use_backing_file` feature [GH-6249] * builder/vmware-iso: Try to use ISO files uploaded to the datastore when From 3b7e23e7f97278bf7f91cb60a74ab5fe1fd6007d Mon Sep 17 00:00:00 2001 From: Rickard von Essen Date: Fri, 17 Aug 2018 20:33:14 +0200 Subject: [PATCH 218/220] Added missing gophercloud files --- .../openstack/common/extensions/doc.go | 15 +++ .../openstack/common/extensions/errors.go | 1 + .../openstack/common/extensions/requests.go | 20 +++ .../openstack/common/extensions/results.go | 53 ++++++++ .../openstack/common/extensions/urls.go | 13 ++ .../compute/v2/extensions/delegate.go | 23 ++++ .../openstack/compute/v2/extensions/doc.go | 3 + .../compute/v2/extensions/floatingips/doc.go | 68 +++++++++++ .../v2/extensions/floatingips/requests.go | 114 +++++++++++++++++ .../v2/extensions/floatingips/results.go | 115 ++++++++++++++++++ .../compute/v2/extensions/floatingips/urls.go | 37 ++++++ 11 files changed, 462 insertions(+) create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/doc.go create mode 100755 vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/errors.go create mode 100755 vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/requests.go create mode 100755 vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/results.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/urls.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/delegate.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/doc.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/doc.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/requests.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/results.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/urls.go diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/doc.go new file mode 100644 index 000000000..4a168f4b2 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/doc.go @@ -0,0 +1,15 @@ +// Package extensions provides information and interaction with the different extensions available +// for an OpenStack service. +// +// The purpose of OpenStack API extensions is to: +// +// - Introduce new features in the API without requiring a version change. +// - Introduce vendor-specific niche functionality. +// - Act as a proving ground for experimental functionalities that might be included in a future +// version of the API. +// +// Extensions usually have tags that prevent conflicts with other extensions that define attributes +// or resources with the same names, and with core resources and attributes. +// Because an extension might not be supported by all plug-ins, its availability varies with deployments +// and the specific plug-in. +package extensions diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/errors.go b/vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/errors.go new file mode 100755 index 000000000..aeec0fa75 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/errors.go @@ -0,0 +1 @@ +package extensions diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/requests.go new file mode 100755 index 000000000..46b7d60cd --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/requests.go @@ -0,0 +1,20 @@ +package extensions + +import ( + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/pagination" +) + +// Get retrieves information for a specific extension using its alias. +func Get(c *gophercloud.ServiceClient, alias string) (r GetResult) { + _, r.Err = c.Get(ExtensionURL(c, alias), &r.Body, nil) + return +} + +// List returns a Pager which allows you to iterate over the full collection of extensions. +// It does not accept query parameters. +func List(c *gophercloud.ServiceClient) pagination.Pager { + return pagination.NewPager(c, ListExtensionURL(c), func(r pagination.PageResult) pagination.Page { + return ExtensionPage{pagination.SinglePageBase(r)} + }) +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/results.go new file mode 100755 index 000000000..d5f865091 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/results.go @@ -0,0 +1,53 @@ +package extensions + +import ( + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/pagination" +) + +// GetResult temporarily stores the result of a Get call. +// Use its Extract() method to interpret it as an Extension. +type GetResult struct { + gophercloud.Result +} + +// Extract interprets a GetResult as an Extension. +func (r GetResult) Extract() (*Extension, error) { + var s struct { + Extension *Extension `json:"extension"` + } + err := r.ExtractInto(&s) + return s.Extension, err +} + +// Extension is a struct that represents an OpenStack extension. +type Extension struct { + Updated string `json:"updated"` + Name string `json:"name"` + Links []interface{} `json:"links"` + Namespace string `json:"namespace"` + Alias string `json:"alias"` + Description string `json:"description"` +} + +// ExtensionPage is the page returned by a pager when traversing over a collection of extensions. +type ExtensionPage struct { + pagination.SinglePageBase +} + +// IsEmpty checks whether an ExtensionPage struct is empty. +func (r ExtensionPage) IsEmpty() (bool, error) { + is, err := ExtractExtensions(r) + return len(is) == 0, err +} + +// ExtractExtensions accepts a Page struct, specifically an ExtensionPage struct, and extracts the +// elements into a slice of Extension structs. +// In other words, a generic collection is mapped into a relevant slice. +func ExtractExtensions(r pagination.Page) ([]Extension, error) { + var s struct { + Extensions []Extension `json:"extensions"` + } + err := (r.(ExtensionPage)).ExtractInto(&s) + return s.Extensions, err +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/urls.go new file mode 100644 index 000000000..eaf38b2d1 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/common/extensions/urls.go @@ -0,0 +1,13 @@ +package extensions + +import "github.com/gophercloud/gophercloud" + +// ExtensionURL generates the URL for an extension resource by name. +func ExtensionURL(c *gophercloud.ServiceClient, name string) string { + return c.ServiceURL("extensions", name) +} + +// ListExtensionURL generates the URL for the extensions resource collection. +func ListExtensionURL(c *gophercloud.ServiceClient) string { + return c.ServiceURL("extensions") +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/delegate.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/delegate.go new file mode 100644 index 000000000..00e7c3bec --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/delegate.go @@ -0,0 +1,23 @@ +package extensions + +import ( + "github.com/gophercloud/gophercloud" + common "github.com/gophercloud/gophercloud/openstack/common/extensions" + "github.com/gophercloud/gophercloud/pagination" +) + +// ExtractExtensions interprets a Page as a slice of Extensions. +func ExtractExtensions(page pagination.Page) ([]common.Extension, error) { + return common.ExtractExtensions(page) +} + +// Get retrieves information for a specific extension using its alias. +func Get(c *gophercloud.ServiceClient, alias string) common.GetResult { + return common.Get(c, alias) +} + +// List returns a Pager which allows you to iterate over the full collection of extensions. +// It does not accept query parameters. +func List(c *gophercloud.ServiceClient) pagination.Pager { + return common.List(c) +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/doc.go new file mode 100644 index 000000000..2b447da1d --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/doc.go @@ -0,0 +1,3 @@ +// Package extensions provides information and interaction with the +// different extensions available for the OpenStack Compute service. +package extensions diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/doc.go new file mode 100644 index 000000000..f5dbdbf8b --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/doc.go @@ -0,0 +1,68 @@ +/* +Package floatingips provides the ability to manage floating ips through the +Nova API. + +This API has been deprecated and will be removed from a future release of the +Nova API service. + +For environements that support this extension, this package can be used +regardless of if either Neutron or nova-network is used as the cloud's network +service. + +Example to List Floating IPs + + allPages, err := floatingips.List(computeClient).AllPages() + if err != nil { + panic(err) + } + + allFloatingIPs, err := floatingips.ExtractFloatingIPs(allPages) + if err != nil { + panic(err) + } + + for _, fip := range allFloatingIPs { + fmt.Printf("%+v\n", fip) + } + +Example to Create a Floating IP + + createOpts := floatingips.CreateOpts{ + Pool: "nova", + } + + fip, err := floatingips.Create(computeClient, createOpts).Extract() + if err != nil { + panic(err) + } + +Example to Delete a Floating IP + + err := floatingips.Delete(computeClient, "floatingip-id").ExtractErr() + if err != nil { + panic(err) + } + +Example to Associate a Floating IP With a Server + + associateOpts := floatingips.AssociateOpts{ + FloatingIP: "10.10.10.2", + } + + err := floatingips.AssociateInstance(computeClient, "server-id", associateOpts).ExtractErr() + if err != nil { + panic(err) + } + +Example to Disassociate a Floating IP From a Server + + disassociateOpts := floatingips.DisassociateOpts{ + FloatingIP: "10.10.10.2", + } + + err := floatingips.DisassociateInstance(computeClient, "server-id", disassociateOpts).ExtractErr() + if err != nil { + panic(err) + } +*/ +package floatingips diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/requests.go new file mode 100644 index 000000000..a922639de --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/requests.go @@ -0,0 +1,114 @@ +package floatingips + +import ( + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/pagination" +) + +// List returns a Pager that allows you to iterate over a collection of FloatingIPs. +func List(client *gophercloud.ServiceClient) pagination.Pager { + return pagination.NewPager(client, listURL(client), func(r pagination.PageResult) pagination.Page { + return FloatingIPPage{pagination.SinglePageBase(r)} + }) +} + +// CreateOptsBuilder allows extensions to add additional parameters to the +// Create request. +type CreateOptsBuilder interface { + ToFloatingIPCreateMap() (map[string]interface{}, error) +} + +// CreateOpts specifies a Floating IP allocation request. +type CreateOpts struct { + // Pool is the pool of Floating IPs to allocate one from. + Pool string `json:"pool" required:"true"` +} + +// ToFloatingIPCreateMap constructs a request body from CreateOpts. +func (opts CreateOpts) ToFloatingIPCreateMap() (map[string]interface{}, error) { + return gophercloud.BuildRequestBody(opts, "") +} + +// Create requests the creation of a new Floating IP. +func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { + b, err := opts.ToFloatingIPCreateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + return +} + +// Get returns data about a previously created Floating IP. +func Get(client *gophercloud.ServiceClient, id string) (r GetResult) { + _, r.Err = client.Get(getURL(client, id), &r.Body, nil) + return +} + +// Delete requests the deletion of a previous allocated Floating IP. +func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) { + _, r.Err = client.Delete(deleteURL(client, id), nil) + return +} + +// AssociateOptsBuilder allows extensions to add additional parameters to the +// Associate request. +type AssociateOptsBuilder interface { + ToFloatingIPAssociateMap() (map[string]interface{}, error) +} + +// AssociateOpts specifies the required information to associate a Floating IP with an instance +type AssociateOpts struct { + // FloatingIP is the Floating IP to associate with an instance. + FloatingIP string `json:"address" required:"true"` + + // FixedIP is an optional fixed IP address of the server. + FixedIP string `json:"fixed_address,omitempty"` +} + +// ToFloatingIPAssociateMap constructs a request body from AssociateOpts. +func (opts AssociateOpts) ToFloatingIPAssociateMap() (map[string]interface{}, error) { + return gophercloud.BuildRequestBody(opts, "addFloatingIp") +} + +// AssociateInstance pairs an allocated Floating IP with a server. +func AssociateInstance(client *gophercloud.ServiceClient, serverID string, opts AssociateOptsBuilder) (r AssociateResult) { + b, err := opts.ToFloatingIPAssociateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(associateURL(client, serverID), b, nil, nil) + return +} + +// DisassociateOptsBuilder allows extensions to add additional parameters to +// the Disassociate request. +type DisassociateOptsBuilder interface { + ToFloatingIPDisassociateMap() (map[string]interface{}, error) +} + +// DisassociateOpts specifies the required information to disassociate a +// Floating IP with a server. +type DisassociateOpts struct { + FloatingIP string `json:"address" required:"true"` +} + +// ToFloatingIPDisassociateMap constructs a request body from DisassociateOpts. +func (opts DisassociateOpts) ToFloatingIPDisassociateMap() (map[string]interface{}, error) { + return gophercloud.BuildRequestBody(opts, "removeFloatingIp") +} + +// DisassociateInstance decouples an allocated Floating IP from an instance +func DisassociateInstance(client *gophercloud.ServiceClient, serverID string, opts DisassociateOptsBuilder) (r DisassociateResult) { + b, err := opts.ToFloatingIPDisassociateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(disassociateURL(client, serverID), b, nil, nil) + return +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/results.go new file mode 100644 index 000000000..da4e9da0e --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/results.go @@ -0,0 +1,115 @@ +package floatingips + +import ( + "encoding/json" + "strconv" + + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/pagination" +) + +// A FloatingIP is an IP that can be associated with a server. +type FloatingIP struct { + // ID is a unique ID of the Floating IP + ID string `json:"-"` + + // FixedIP is a specific IP on the server to pair the Floating IP with. + FixedIP string `json:"fixed_ip,omitempty"` + + // InstanceID is the ID of the server that is using the Floating IP. + InstanceID string `json:"instance_id"` + + // IP is the actual Floating IP. + IP string `json:"ip"` + + // Pool is the pool of Floating IPs that this Floating IP belongs to. + Pool string `json:"pool"` +} + +func (r *FloatingIP) UnmarshalJSON(b []byte) error { + type tmp FloatingIP + var s struct { + tmp + ID interface{} `json:"id"` + } + err := json.Unmarshal(b, &s) + if err != nil { + return err + } + + *r = FloatingIP(s.tmp) + + switch t := s.ID.(type) { + case float64: + r.ID = strconv.FormatFloat(t, 'f', -1, 64) + case string: + r.ID = t + } + + return err +} + +// FloatingIPPage stores a single page of FloatingIPs from a List call. +type FloatingIPPage struct { + pagination.SinglePageBase +} + +// IsEmpty determines whether or not a FloatingIPsPage is empty. +func (page FloatingIPPage) IsEmpty() (bool, error) { + va, err := ExtractFloatingIPs(page) + return len(va) == 0, err +} + +// ExtractFloatingIPs interprets a page of results as a slice of FloatingIPs. +func ExtractFloatingIPs(r pagination.Page) ([]FloatingIP, error) { + var s struct { + FloatingIPs []FloatingIP `json:"floating_ips"` + } + err := (r.(FloatingIPPage)).ExtractInto(&s) + return s.FloatingIPs, err +} + +// FloatingIPResult is the raw result from a FloatingIP request. +type FloatingIPResult struct { + gophercloud.Result +} + +// Extract is a method that attempts to interpret any FloatingIP resource +// response as a FloatingIP struct. +func (r FloatingIPResult) Extract() (*FloatingIP, error) { + var s struct { + FloatingIP *FloatingIP `json:"floating_ip"` + } + err := r.ExtractInto(&s) + return s.FloatingIP, err +} + +// CreateResult is the response from a Create operation. Call its Extract method +// to interpret it as a FloatingIP. +type CreateResult struct { + FloatingIPResult +} + +// GetResult is the response from a Get operation. Call its Extract method to +// interpret it as a FloatingIP. +type GetResult struct { + FloatingIPResult +} + +// DeleteResult is the response from a Delete operation. Call its ExtractErr +// method to determine if the call succeeded or failed. +type DeleteResult struct { + gophercloud.ErrResult +} + +// AssociateResult is the response from a Delete operation. Call its ExtractErr +// method to determine if the call succeeded or failed. +type AssociateResult struct { + gophercloud.ErrResult +} + +// DisassociateResult is the response from a Delete operation. Call its +// ExtractErr method to determine if the call succeeded or failed. +type DisassociateResult struct { + gophercloud.ErrResult +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/urls.go new file mode 100644 index 000000000..4768e5a89 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips/urls.go @@ -0,0 +1,37 @@ +package floatingips + +import "github.com/gophercloud/gophercloud" + +const resourcePath = "os-floating-ips" + +func resourceURL(c *gophercloud.ServiceClient) string { + return c.ServiceURL(resourcePath) +} + +func listURL(c *gophercloud.ServiceClient) string { + return resourceURL(c) +} + +func createURL(c *gophercloud.ServiceClient) string { + return resourceURL(c) +} + +func getURL(c *gophercloud.ServiceClient, id string) string { + return c.ServiceURL(resourcePath, id) +} + +func deleteURL(c *gophercloud.ServiceClient, id string) string { + return getURL(c, id) +} + +func serverURL(c *gophercloud.ServiceClient, serverID string) string { + return c.ServiceURL("servers/" + serverID + "/action") +} + +func associateURL(c *gophercloud.ServiceClient, serverID string) string { + return serverURL(c, serverID) +} + +func disassociateURL(c *gophercloud.ServiceClient, serverID string) string { + return serverURL(c, serverID) +} From 6b3844a64f5e5a198467ddae9081717a8e0a5927 Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Mon, 20 Aug 2018 10:48:06 +0200 Subject: [PATCH 219/220] Revert "allow to use ISO images in-place v.s. copying them" --- builder/virtualbox/iso/builder.go | 1 - builder/vmware/iso/builder.go | 1 - common/download.go | 16 ++++----- common/download_test.go | 55 +++++-------------------------- common/iso_config.go | 1 - common/step_download.go | 16 ++------- 6 files changed, 20 insertions(+), 70 deletions(-) diff --git a/builder/virtualbox/iso/builder.go b/builder/virtualbox/iso/builder.go index 7cf3dd7e3..2ea19e70f 100644 --- a/builder/virtualbox/iso/builder.go +++ b/builder/virtualbox/iso/builder.go @@ -204,7 +204,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ResultKey: "iso_path", TargetPath: b.config.TargetPath, Url: b.config.ISOUrls, - Inplace: b.config.Inplace, }, &vboxcommon.StepOutputDir{ Force: b.config.PackerForce, diff --git a/builder/vmware/iso/builder.go b/builder/vmware/iso/builder.go index d428d0184..0944db927 100644 --- a/builder/vmware/iso/builder.go +++ b/builder/vmware/iso/builder.go @@ -291,7 +291,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ResultKey: "iso_path", TargetPath: b.config.TargetPath, Url: b.config.ISOUrls, - Inplace: b.config.Inplace, }, &vmwcommon.StepOutputDir{ Force: b.config.PackerForce, diff --git a/common/download.go b/common/download.go index 84776bee9..09457ef0b 100644 --- a/common/download.go +++ b/common/download.go @@ -38,10 +38,10 @@ type DownloadConfig struct { // DownloaderMap maps a schema to a Download. DownloaderMap map[string]Downloader - // Inplace indicates wether to copy file - // versus using it inplace. - // Inplace can only be true when referencing local files. - Inplace bool + // If true, this will copy even a local file to the target + // location. If false, then it will "download" the file by just + // returning the local path to the file. + CopyFile bool // The hashing implementation to use to checksum the downloaded file. Hash hash.Hash @@ -155,12 +155,12 @@ func (d *DownloadClient) Get() (string, error) { } local, ok := d.downloader.(LocalDownloader) - if !ok && d.config.Inplace { - d.config.Inplace = false + if !ok && !d.config.CopyFile { + d.config.CopyFile = true } // If we're copying the file, then just use the actual downloader - if d.config.Inplace == false { + if d.config.CopyFile { var f *os.File finalPath = d.config.TargetPath @@ -192,7 +192,7 @@ func (d *DownloadClient) Get() (string, error) { verify, err = d.VerifyChecksum(finalPath) if err == nil && !verify { // Only delete the file if we made a copy or downloaded it - if d.config.Inplace == false { + if d.config.CopyFile { os.Remove(finalPath) } diff --git a/common/download_test.go b/common/download_test.go index 9305e7db8..c9175b013 100644 --- a/common/download_test.go +++ b/common/download_test.go @@ -58,6 +58,7 @@ func TestDownloadClient_basic(t *testing.T) { client := NewDownloadClient(&DownloadConfig{ Url: ts.URL + "/basic.txt", TargetPath: tf.Name(), + CopyFile: true, }) path, err := client.Get() @@ -93,6 +94,7 @@ func TestDownloadClient_checksumBad(t *testing.T) { TargetPath: tf.Name(), Hash: HashForType("md5"), Checksum: checksum, + CopyFile: true, }) if _, err := client.Get(); err == nil { @@ -118,6 +120,7 @@ func TestDownloadClient_checksumGood(t *testing.T) { TargetPath: tf.Name(), Hash: HashForType("md5"), Checksum: checksum, + CopyFile: true, }) path, err := client.Get() @@ -149,6 +152,7 @@ func TestDownloadClient_checksumNoDownload(t *testing.T) { TargetPath: "./test-fixtures/root/another.txt", Hash: HashForType("md5"), Checksum: checksum, + CopyFile: true, }) path, err := client.Get() if err != nil { @@ -206,6 +210,7 @@ func TestDownloadClient_resume(t *testing.T) { client := NewDownloadClient(&DownloadConfig{ Url: ts.URL, TargetPath: tf.Name(), + CopyFile: true, }) path, err := client.Get() @@ -265,6 +270,7 @@ func TestDownloadClient_usesDefaultUserAgent(t *testing.T) { config := &DownloadConfig{ Url: server.URL, TargetPath: tf.Name(), + CopyFile: true, } client := NewDownloadClient(config) @@ -297,6 +303,7 @@ func TestDownloadClient_setsUserAgent(t *testing.T) { Url: server.URL, TargetPath: tf.Name(), UserAgent: "fancy user agent", + CopyFile: true, } client := NewDownloadClient(config) @@ -395,7 +402,7 @@ func TestDownloadFileUrl(t *testing.T) { // This should be wrong. We want to make sure we don't delete Checksum: []byte("nope"), Hash: HashForType("sha256"), - Inplace: true, + CopyFile: false, } client := NewDownloadClient(config) @@ -411,50 +418,6 @@ func TestDownloadFileUrl(t *testing.T) { } } -// TestDownloadFileUrl_inplace verifies that inplace setting is respected. -func TestDownloadFileUrl_inplace(t *testing.T) { - cwd, err := os.Getwd() - if err != nil { - t.Fatalf("Unable to detect working directory: %s", err) - } - cwd = filepath.ToSlash(cwd) - - // source_path is a file path and source is a network path - sourcePath := fmt.Sprintf("%s/test-fixtures/fileurl/%s", cwd, "cake") - - filePrefix := "file://" - if runtime.GOOS == "windows" { - filePrefix += "/" - } - - source := fmt.Sprintf(filePrefix + sourcePath) - t.Logf("Trying to download %s", source) - - config := &DownloadConfig{ - Url: source, - // This is correct. We want to make sure we don't delete - Checksum: []byte{96, 111, 25, 69, 248, 26, 2, 45, 14, 208, 189, 153, 237, 253, 79, 153, 8, 28, 28, 177, 249, 127, 174, 8, 114, 145, 238, 20, 233, 69, 230, 8}, - Hash: HashForType("sha256"), - Inplace: true, - } - - client := NewDownloadClient(config) - - // Verify that we fail to match the checksum - url, err := client.Get() - if err != nil { - t.Fatalf("Unexpected error: \"%v\"", err) - } - - if sourcePath != url { - t.Errorf("Inplace file get should return same path, expected %s, got %s", sourcePath, url) - } - - if _, err = os.Stat(sourcePath); err != nil { - t.Errorf("Could not stat source file: %s", sourcePath) - } -} - // SimulateFileUriDownload is a simple utility function that converts a uri // into a testable file path whilst ignoring a correct checksum match, stripping // UNC path info, and then calling stat to ensure the correct file exists. @@ -469,7 +432,7 @@ func SimulateFileUriDownload(t *testing.T, uri string) (string, error) { // This should be wrong. We want to make sure we don't delete Checksum: []byte("nope"), Hash: HashForType("sha256"), - Inplace: true, + CopyFile: false, } // go go go diff --git a/common/iso_config.go b/common/iso_config.go index aca468cd2..4f30580bc 100644 --- a/common/iso_config.go +++ b/common/iso_config.go @@ -24,7 +24,6 @@ type ISOConfig struct { TargetPath string `mapstructure:"iso_target_path"` TargetExtension string `mapstructure:"iso_target_extension"` RawSingleISOUrl string `mapstructure:"iso_url"` - Inplace bool `mapstructure:"iso_inplace"` } func (c *ISOConfig) Prepare(ctx *interpolate.Context) (warnings []string, errs []error) { diff --git a/common/step_download.go b/common/step_download.go index 9110653b2..03340b974 100644 --- a/common/step_download.go +++ b/common/step_download.go @@ -45,11 +45,6 @@ type StepDownload struct { // extension on the URL is used. Otherwise, this will be forced // on the downloaded file for every URL. Extension string - - // Inplace indicates wether to copy file - // versus using it inplace. - // Inplace can only be true when referencing local files. - Inplace bool } func (s *StepDownload) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { @@ -66,7 +61,7 @@ func (s *StepDownload) Run(_ context.Context, state multistep.StateBag) multiste } } - ui.Say(fmt.Sprintf("Retrieving %s", s.Description)) + ui.Say(fmt.Sprintf("Downloading or copying %s", s.Description)) // First try to use any already downloaded file // If it fails, proceed to regular download logic @@ -94,12 +89,11 @@ func (s *StepDownload) Run(_ context.Context, state multistep.StateBag) multiste config := &DownloadConfig{ Url: url, TargetPath: targetPath, - Inplace: s.Inplace, + CopyFile: false, Hash: HashForType(s.ChecksumType), Checksum: checksum, UserAgent: useragent.String(), } - downloadConfigs[i] = config if match, _ := NewDownloadClient(config).VerifyChecksum(config.TargetPath); match { @@ -111,11 +105,7 @@ func (s *StepDownload) Run(_ context.Context, state multistep.StateBag) multiste if finalPath == "" { for i, url := range s.Url { - if s.Inplace { - ui.Message(fmt.Sprintf("Using file in-place: %s", url)) - } else { - ui.Message(fmt.Sprintf("Transferring file from path: %s", url)) - } + ui.Message(fmt.Sprintf("Downloading or copying: %s", url)) config := downloadConfigs[i] From a5587e30ec55e81b0ac373b50900ce73dd7ca5bc Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Mon, 20 Aug 2018 11:38:41 +0200 Subject: [PATCH 220/220] log wether the file was transfered or is just being inplace referenced --- common/step_download.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/common/step_download.go b/common/step_download.go index 03340b974..1719c5987 100644 --- a/common/step_download.go +++ b/common/step_download.go @@ -61,7 +61,7 @@ func (s *StepDownload) Run(_ context.Context, state multistep.StateBag) multiste } } - ui.Say(fmt.Sprintf("Downloading or copying %s", s.Description)) + ui.Say(fmt.Sprintf("Retrieving %s", s.Description)) // First try to use any already downloaded file // If it fails, proceed to regular download logic @@ -104,9 +104,7 @@ func (s *StepDownload) Run(_ context.Context, state multistep.StateBag) multiste } if finalPath == "" { - for i, url := range s.Url { - ui.Message(fmt.Sprintf("Downloading or copying: %s", url)) - + for i := range s.Url { config := downloadConfigs[i] path, err, retry := s.download(config, state) @@ -159,6 +157,11 @@ func (s *StepDownload) download(config *DownloadConfig, state multistep.StateBag if err != nil { return "", err, true } + if download.config.CopyFile { + ui.Message(fmt.Sprintf("Transferred: %s", config.Url)) + } else { + ui.Message(fmt.Sprintf("Using file in-place: %s", config.Url)) + } return path, nil, true case <-progressTicker.C: