From ea78cb62fd8d4e9e94bd8861b85c979246a50062 Mon Sep 17 00:00:00 2001 From: chbell43 Date: Fri, 26 Oct 2018 19:28:42 +0000 Subject: [PATCH 01/87] Make the config.networkV2Client conditional In cases where the OpenStack environment does not contain a v2 network, the builder will error out. We only need the networkV2Client when using floating IPs. This will allow packer to work in environments where a v2 network is not available. --- builder/openstack/step_allocate_ip.go | 32 +++++++++++++++------------ 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/builder/openstack/step_allocate_ip.go b/builder/openstack/step_allocate_ip.go index 74bf63b75..cd15afa35 100644 --- a/builder/openstack/step_allocate_ip.go +++ b/builder/openstack/step_allocate_ip.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/gophercloud/gophercloud" "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips" "github.com/hashicorp/packer/helper/multistep" @@ -29,12 +30,15 @@ func (s *StepAllocateIp) Run(_ context.Context, state multistep.StateBag) multis return multistep.ActionHalt } - // 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 + // We might need the v2 network client + var networkClient *gophercloud.ServiceClient + if s.FloatingIP != "" || s.ReuseIPs || s.FloatingIPNetwork != "" { + 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 @@ -147,15 +151,15 @@ func (s *StepAllocateIp) Cleanup(state multistep.StateBag) { return } - // We need the v2 network client - client, err := config.networkV2Client() - if err != nil { - ui.Error(fmt.Sprintf( - "Error deleting temporary floating IP '%s' (%s)", instanceIP.ID, instanceIP.FloatingIP)) - return - } + if instanceIP.FloatingIP != "" && instanceIP.ID != "" { + // We need the v2 network client + client, err := config.networkV2Client() + if err != nil { + ui.Error(fmt.Sprintf( + "Error deleting temporary floating IP '%s' (%s)", instanceIP.ID, instanceIP.FloatingIP)) + return + } - if instanceIP.ID != "" { if err := floatingips.Delete(client, instanceIP.ID).ExtractErr(); err != nil { ui.Error(fmt.Sprintf( "Error deleting temporary floating IP '%s' (%s)", instanceIP.ID, instanceIP.FloatingIP)) From 653fa2298fd7c27389f72d2519929263bf24ebe1 Mon Sep 17 00:00:00 2001 From: chbell43 Date: Mon, 29 Oct 2018 18:36:08 +0000 Subject: [PATCH 02/87] use guard clauses * just return early if no FloatingIP is required * move the instanceIP declaration up and store in the state bag to avoid errors in ssh.go --- builder/openstack/step_allocate_ip.go | 54 +++++++++++++++------------ 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/builder/openstack/step_allocate_ip.go b/builder/openstack/step_allocate_ip.go index cd15afa35..50a5e16ed 100644 --- a/builder/openstack/step_allocate_ip.go +++ b/builder/openstack/step_allocate_ip.go @@ -4,7 +4,6 @@ import ( "context" "fmt" - "github.com/gophercloud/gophercloud" "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips" "github.com/hashicorp/packer/helper/multistep" @@ -22,6 +21,17 @@ func (s *StepAllocateIp) Run(_ context.Context, state multistep.StateBag) multis config := state.Get("config").(*Config) server := state.Get("server").(*servers.Server) + 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) + + if s.FloatingIP == "" && !s.ReuseIPs && s.FloatingIPNetwork == "" { + ui.Message("Floating IP not required") + return multistep.ActionContinue + } + // We need the v2 compute client computeClient, err := config.computeV2Client() if err != nil { @@ -30,23 +40,14 @@ func (s *StepAllocateIp) Run(_ context.Context, state multistep.StateBag) multis return multistep.ActionHalt } - // We might need the v2 network client - var networkClient *gophercloud.ServiceClient - if s.FloatingIP != "" || s.ReuseIPs || s.FloatingIPNetwork != "" { - networkClient, err = config.networkV2Client() - if err != nil { - err = fmt.Errorf("Error initializing network client: %s", err) - state.Put("error", err) - return multistep.ActionHalt - } + // 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) - // 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 @@ -146,20 +147,25 @@ func (s *StepAllocateIp) Cleanup(state multistep.StateBag) { ui := state.Get("ui").(packer.Ui) instanceIP := state.Get("access_ip").(*floatingips.FloatingIP) + // Don't clean up if unless required + if instanceIP.ID == "" && instanceIP.FloatingIP == "" { + return + } + // Don't delete pool addresses we didn't allocate if state.Get("floatingip_istemp") == false { return } - if instanceIP.FloatingIP != "" && instanceIP.ID != "" { - // We need the v2 network client - client, err := config.networkV2Client() - if err != nil { - ui.Error(fmt.Sprintf( - "Error deleting temporary floating IP '%s' (%s)", instanceIP.ID, instanceIP.FloatingIP)) - return - } + // We need the v2 network client + client, err := config.networkV2Client() + if err != nil { + ui.Error(fmt.Sprintf( + "Error deleting temporary floating IP '%s' (%s)", instanceIP.ID, instanceIP.FloatingIP)) + return + } + if instanceIP.ID != "" { if err := floatingips.Delete(client, instanceIP.ID).ExtractErr(); err != nil { ui.Error(fmt.Sprintf( "Error deleting temporary floating IP '%s' (%s)", instanceIP.ID, instanceIP.FloatingIP)) From 802e7d467d0e5f570cd24d9c039365bcced82f2b Mon Sep 17 00:00:00 2001 From: Kevin Bulebush Date: Fri, 23 Nov 2018 19:27:28 -0500 Subject: [PATCH 03/87] openstack: Add support for tagging new images. --- builder/openstack/builder.go | 1 + builder/openstack/image_config.go | 1 + builder/openstack/step_update_image_tags.go | 52 +++++++++++++++++++ .../source/docs/builders/openstack.html.md | 3 ++ 4 files changed, 57 insertions(+) create mode 100644 builder/openstack/step_update_image_tags.go diff --git a/builder/openstack/builder.go b/builder/openstack/builder.go index 7ab5fa6c3..bc87c3375 100644 --- a/builder/openstack/builder.go +++ b/builder/openstack/builder.go @@ -142,6 +142,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &stepCreateImage{ UseBlockStorageVolume: b.config.UseBlockStorageVolume, }, + &stepUpdateImageTags{}, &stepUpdateImageVisibility{}, &stepAddImageMembers{}, } diff --git a/builder/openstack/image_config.go b/builder/openstack/image_config.go index f17ad753d..ffc9c6896 100644 --- a/builder/openstack/image_config.go +++ b/builder/openstack/image_config.go @@ -15,6 +15,7 @@ type ImageConfig struct { ImageVisibility imageservice.ImageVisibility `mapstructure:"image_visibility"` ImageMembers []string `mapstructure:"image_members"` ImageDiskFormat string `mapstructure:"image_disk_format"` + ImageTags []string `mapstructure:"image_tags"` } func (c *ImageConfig) Prepare(ctx *interpolate.Context) []error { diff --git a/builder/openstack/step_update_image_tags.go b/builder/openstack/step_update_image_tags.go new file mode 100644 index 000000000..b3c93d5de --- /dev/null +++ b/builder/openstack/step_update_image_tags.go @@ -0,0 +1,52 @@ +package openstack + +import ( + "context" + "fmt" + "strings" + + imageservice "github.com/gophercloud/gophercloud/openstack/imageservice/v2/images" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" +) + +type stepUpdateImageTags struct{} + +func (s *stepUpdateImageTags) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + imageId := state.Get("image").(string) + ui := state.Get("ui").(packer.Ui) + config := state.Get("config").(*Config) + + if len(config.ImageTags) == 0 { + return multistep.ActionContinue + } + imageClient, err := config.imageV2Client() + if err != nil { + err = fmt.Errorf("Error initializing image service client: %s", err) + state.Put("error", err) + return multistep.ActionHalt + } + + ui.Say(fmt.Sprintf("Updating image tags to %s", strings.Join(config.ImageTags, ", "))) + r := imageservice.Update( + imageClient, + imageId, + imageservice.UpdateOpts{ + imageservice.ReplaceImageTags{ + NewTags: config.ImageTags, + }, + }, + ) + + if _, err = r.Extract(); err != nil { + err = fmt.Errorf("Error updating image tags: %s", err) + state.Put("error", err) + return multistep.ActionHalt + } + + return multistep.ActionContinue +} + +func (s *stepUpdateImageTags) Cleanup(multistep.StateBag) { + // No cleanup... +} diff --git a/website/source/docs/builders/openstack.html.md b/website/source/docs/builders/openstack.html.md index 263610c0f..064f1e313 100644 --- a/website/source/docs/builders/openstack.html.md +++ b/website/source/docs/builders/openstack.html.md @@ -127,6 +127,9 @@ builder. after creation. An image member is usually a project (also called the "tenant") with whom the image is shared. +- `image_tags` (array of strings) - List of tags to add to the image after + creation. + - `image_visibility` (string) - One of "public", "private", "shared", or "community". From a7b407eab6afa1e4fd6574199e7bc4c33b9465f2 Mon Sep 17 00:00:00 2001 From: Matt Dainty Date: Thu, 6 Dec 2018 15:09:57 +0000 Subject: [PATCH 04/87] Naive support for elevated support for puppet-server provisioner This commit just lifts the various bits out of the powershell provisioner. --- provisioner/puppet-server/elevated.go | 100 +++++++++++++++++ provisioner/puppet-server/provisioner.go | 137 ++++++++++++++++++++++- 2 files changed, 233 insertions(+), 4 deletions(-) create mode 100644 provisioner/puppet-server/elevated.go diff --git a/provisioner/puppet-server/elevated.go b/provisioner/puppet-server/elevated.go new file mode 100644 index 000000000..5890a2aa0 --- /dev/null +++ b/provisioner/puppet-server/elevated.go @@ -0,0 +1,100 @@ +package puppetserver + +import ( + "text/template" +) + +type elevatedOptions struct { + User string + Password string + TaskName string + TaskDescription string + LogFile string + XMLEscapedCommand string +} + +var elevatedTemplate = template.Must(template.New("ElevatedCommand").Parse(` +$name = "{{.TaskName}}" +$log = [System.Environment]::ExpandEnvironmentVariables("{{.LogFile}}") +$s = New-Object -ComObject "Schedule.Service" +$s.Connect() +$t = $s.NewTask($null) +$xml = [xml]@' + + + + {{.TaskDescription}} + + + + {{.User}} + Password + HighestAvailable + + + + IgnoreNew + false + false + true + false + false + + false + false + + true + true + false + false + false + PT24H + 4 + + + + cmd + /c {{.XMLEscapedCommand}} + + + +'@ +$logon_type = 1 +$password = "{{.Password}}" +if ($password.Length -eq 0) { + $logon_type = 5 + $password = $null + $ns = New-Object System.Xml.XmlNamespaceManager($xml.NameTable) + $ns.AddNamespace("ns", $xml.DocumentElement.NamespaceURI) + $node = $xml.SelectSingleNode("/ns:Task/ns:Principals/ns:Principal/ns:LogonType", $ns) + $node.ParentNode.RemoveChild($node) | Out-Null +} +$t.XmlText = $xml.OuterXml +if (Test-Path variable:global:ProgressPreference){$ProgressPreference="SilentlyContinue"} +$f = $s.GetFolder("\") +$f.RegisterTaskDefinition($name, $t, 6, "{{.User}}", $password, $logon_type, $null) | Out-Null +$t = $f.GetTask("\$name") +$t.Run($null) | Out-Null +$timeout = 10 +$sec = 0 +while ((!($t.state -eq 4)) -and ($sec -lt $timeout)) { + Start-Sleep -s 1 + $sec++ +} + +$line = 0 +do { + Start-Sleep -m 100 + if (Test-Path $log) { + Get-Content $log | select -skip $line | ForEach { + $line += 1 + Write-Output "$_" + } + } +} while (!($t.state -eq 3)) +$result = $t.LastTaskResult +if (Test-Path $log) { + Remove-Item $log -Force -ErrorAction SilentlyContinue | Out-Null +} +[System.Runtime.Interopservices.Marshal]::ReleaseComObject($s) | Out-Null +exit $result`)) diff --git a/provisioner/puppet-server/provisioner.go b/provisioner/puppet-server/provisioner.go index b7ec34ea7..4612606fe 100644 --- a/provisioner/puppet-server/provisioner.go +++ b/provisioner/puppet-server/provisioner.go @@ -3,18 +3,30 @@ package puppetserver import ( + "bytes" + "encoding/xml" "fmt" + "log" "os" "path/filepath" "strings" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/common/uuid" + commonhelper "github.com/hashicorp/packer/helper/common" "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/provisioner" "github.com/hashicorp/packer/template/interpolate" ) +var psEscape = strings.NewReplacer( + "$", "`$", + "\"", "`\"", + "`", "``", + "'", "`'", +) + type Config struct { common.PackerConfig `mapstructure:",squash"` ctx interpolate.Context @@ -63,6 +75,12 @@ type Config struct { // The directory from which the command will be executed. // Packer requires the directory to exist when running puppet. WorkingDir string `mapstructure:"working_directory"` + + // Instructs the communicator to run the remote script as a Windows + // scheduled task, effectively elevating the remote user by impersonating + // a logged-in user + ElevatedUser string `mapstructure:"elevated_user"` + ElevatedPassword string `mapstructure:"elevated_password"` } type guestOSTypeConfig struct { @@ -112,6 +130,7 @@ var guestOSTypeConfigs = map[string]guestOSTypeConfig{ type Provisioner struct { config Config + communicator packer.Communicator guestOSTypeConfig guestOSTypeConfig guestCommands *provisioner.GuestCommands } @@ -129,7 +148,17 @@ type ExecuteTemplate struct { WorkingDir string } +type EnvVarsTemplate struct { + WinRMPassword string +} + func (p *Provisioner) Prepare(raws ...interface{}) error { + // Create passthrough for winrm password so we can fill it in once we know + // it + p.config.ctx.Data = &EnvVarsTemplate{ + WinRMPassword: `{{.WinRMPassword}}`, + } + err := config.Decode(&p.config, &config.DecodeOpts{ Interpolate: true, InterpolateContext: &p.config.ctx, @@ -210,6 +239,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { ui.Say("Provisioning with Puppet...") + p.communicator = comm ui.Message("Creating Puppet staging directory...") if err := p.createDir(ui, comm, p.config.StagingDir); err != nil { return fmt.Errorf("Error creating staging directory: %s", err) @@ -269,6 +299,13 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { return err } + if p.config.ElevatedUser != "" { + command, err = p.createCommandTextPrivileged(command) + if err != nil { + return err + } + } + cmd := &packer.RemoteCmd{ Command: command, } @@ -321,10 +358,7 @@ func (p *Provisioner) createDir(ui packer.Ui, comm packer.Communicator, dir stri } func (p *Provisioner) removeDir(ui packer.Ui, comm packer.Communicator, dir string) error { - cmd := &packer.RemoteCmd{ - Command: fmt.Sprintf("rm -fr '%s'", dir), - } - + cmd := &packer.RemoteCmd{Command: p.guestCommands.RemoveDir(dir)} if err := cmd.StartWithUi(comm, ui); err != nil { return err } @@ -349,3 +383,98 @@ func (p *Provisioner) uploadDirectory(ui packer.Ui, comm packer.Communicator, ds return comm.UploadDir(dst, src, nil) } + +func getWinRMPassword(buildName string) string { + winRMPass, _ := commonhelper.RetrieveSharedState("winrm_password", buildName) + packer.LogSecretFilter.Set(winRMPass) + return winRMPass +} + +func (p *Provisioner) createCommandTextPrivileged(input string) (output string, err error) { + // OK so we need an elevated shell runner to wrap our command, this is + // going to have its own path generate the script and update the command + // runner in the process + path, err := p.generateElevatedRunner(input) + if err != nil { + return "", fmt.Errorf("Error generating elevated runner: %s", err) + } + + // Return the path to the elevated shell wrapper + output = fmt.Sprintf("powershell -executionpolicy bypass -file \"%s\"", path) + + return output, err +} + +func (p *Provisioner) generateElevatedRunner(command string) (uploadedPath string, err error) { + log.Printf("Building elevated command wrapper for: %s", command) + + var buffer bytes.Buffer + + // Output from the elevated command cannot be returned directly to the + // Packer console. In order to be able to view output from elevated + // commands and scripts an indirect approach is used by which the commands + // output is first redirected to file. The output file is then 'watched' + // by Packer while the elevated command is running and any content + // appearing in the file is written out to the console. Below the portion + // of command required to redirect output from the command to file is + // built and appended to the existing command string + taskName := fmt.Sprintf("packer-%s", uuid.TimeOrderedUUID()) + // Only use %ENVVAR% format for environment variables when setting the log + // file path; Do NOT use $env:ENVVAR format as it won't be expanded + // correctly in the elevatedTemplate + logFile := `%SYSTEMROOT%/Temp/` + taskName + ".out" + command += fmt.Sprintf(" > %s 2>&1", logFile) + + // elevatedTemplate wraps the command in a single quoted XML text string + // so we need to escape characters considered 'special' in XML. + err = xml.EscapeText(&buffer, []byte(command)) + if err != nil { + return "", fmt.Errorf("Error escaping characters special to XML in command %s: %s", command, err) + } + escapedCommand := buffer.String() + log.Printf("Command [%s] converted to [%s] for use in XML string", command, escapedCommand) + buffer.Reset() + + // Escape chars special to PowerShell in the ElevatedUser string + escapedElevatedUser := psEscape.Replace(p.config.ElevatedUser) + if escapedElevatedUser != p.config.ElevatedUser { + log.Printf("Elevated user %s converted to %s after escaping chars special to PowerShell", + p.config.ElevatedUser, escapedElevatedUser) + } + // Replace ElevatedPassword for winrm users who used this feature + p.config.ctx.Data = &EnvVarsTemplate{ + WinRMPassword: getWinRMPassword(p.config.PackerBuildName), + } + + p.config.ElevatedPassword, _ = interpolate.Render(p.config.ElevatedPassword, &p.config.ctx) + + // Escape chars special to PowerShell in the ElevatedPassword string + escapedElevatedPassword := psEscape.Replace(p.config.ElevatedPassword) + if escapedElevatedPassword != p.config.ElevatedPassword { + log.Printf("Elevated password %s converted to %s after escaping chars special to PowerShell", + p.config.ElevatedPassword, escapedElevatedPassword) + } + + // Generate command + err = elevatedTemplate.Execute(&buffer, elevatedOptions{ + User: escapedElevatedUser, + Password: escapedElevatedPassword, + TaskName: taskName, + TaskDescription: "Packer elevated task", + LogFile: logFile, + XMLEscapedCommand: escapedCommand, + }) + + if err != nil { + fmt.Printf("Error creating elevated template: %s", err) + return "", err + } + uuid := uuid.TimeOrderedUUID() + path := fmt.Sprintf(`C:/Windows/Temp/packer-elevated-shell-%s.ps1`, uuid) + log.Printf("Uploading elevated shell wrapper for command [%s] to [%s]", command, path) + err = p.communicator.Upload(path, &buffer, nil) + if err != nil { + return "", fmt.Errorf("Error preparing elevated powershell script: %s", err) + } + return path, err +} From 11be4ffc4b3bb3a8055c9cb623dfbf1f00d784df Mon Sep 17 00:00:00 2001 From: Matt Dainty Date: Thu, 6 Dec 2018 18:00:22 +0000 Subject: [PATCH 05/87] Attempt at generalising elevated support Refactor puppet-server provisioner to use it. --- provisioner/elevated.go | 192 +++++++++++++++++++++++ provisioner/puppet-server/elevated.go | 100 ------------ provisioner/puppet-server/provisioner.go | 99 ++---------- 3 files changed, 201 insertions(+), 190 deletions(-) create mode 100644 provisioner/elevated.go delete mode 100644 provisioner/puppet-server/elevated.go diff --git a/provisioner/elevated.go b/provisioner/elevated.go new file mode 100644 index 000000000..d34e97e0a --- /dev/null +++ b/provisioner/elevated.go @@ -0,0 +1,192 @@ +package provisioner + +import ( + "bytes" + "encoding/xml" + "fmt" + "log" + "strings" + "text/template" + + "github.com/hashicorp/packer/common/uuid" + "github.com/hashicorp/packer/packer" +) + +type ElevatedProvisioner interface { + Communicator() packer.Communicator + ElevatedUser() string + ElevatedPassword() string +} + +type elevatedOptions struct { + User string + Password string + TaskName string + TaskDescription string + LogFile string + XMLEscapedCommand string +} + +var psEscape = strings.NewReplacer( + "$", "`$", + "\"", "`\"", + "`", "``", + "'", "`'", +) + +var elevatedTemplate = template.Must(template.New("ElevatedCommand").Parse(` +$name = "{{.TaskName}}" +$log = [System.Environment]::ExpandEnvironmentVariables("{{.LogFile}}") +$s = New-Object -ComObject "Schedule.Service" +$s.Connect() +$t = $s.NewTask($null) +$xml = [xml]@' + + + + {{.TaskDescription}} + + + + {{.User}} + Password + HighestAvailable + + + + IgnoreNew + false + false + true + false + false + + false + false + + true + true + false + false + false + PT24H + 4 + + + + cmd + /c {{.XMLEscapedCommand}} + + + +'@ +$logon_type = 1 +$password = "{{.Password}}" +if ($password.Length -eq 0) { + $logon_type = 5 + $password = $null + $ns = New-Object System.Xml.XmlNamespaceManager($xml.NameTable) + $ns.AddNamespace("ns", $xml.DocumentElement.NamespaceURI) + $node = $xml.SelectSingleNode("/ns:Task/ns:Principals/ns:Principal/ns:LogonType", $ns) + $node.ParentNode.RemoveChild($node) | Out-Null +} +$t.XmlText = $xml.OuterXml +if (Test-Path variable:global:ProgressPreference){$ProgressPreference="SilentlyContinue"} +$f = $s.GetFolder("\") +$f.RegisterTaskDefinition($name, $t, 6, "{{.User}}", $password, $logon_type, $null) | Out-Null +$t = $f.GetTask("\$name") +$t.Run($null) | Out-Null +$timeout = 10 +$sec = 0 +while ((!($t.state -eq 4)) -and ($sec -lt $timeout)) { + Start-Sleep -s 1 + $sec++ +} + +$line = 0 +do { + Start-Sleep -m 100 + if (Test-Path $log) { + Get-Content $log | select -skip $line | ForEach { + $line += 1 + Write-Output "$_" + } + } +} while (!($t.state -eq 3)) +$result = $t.LastTaskResult +if (Test-Path $log) { + Remove-Item $log -Force -ErrorAction SilentlyContinue | Out-Null +} +[System.Runtime.Interopservices.Marshal]::ReleaseComObject($s) | Out-Null +exit $result`)) + +func GenerateElevatedRunner(command string, p ElevatedProvisioner) (uploadedPath string, err error) { + log.Printf("Building elevated command wrapper for: %s", command) + + var buffer bytes.Buffer + + // Output from the elevated command cannot be returned directly to the + // Packer console. In order to be able to view output from elevated + // commands and scripts an indirect approach is used by which the commands + // output is first redirected to file. The output file is then 'watched' + // by Packer while the elevated command is running and any content + // appearing in the file is written out to the console. Below the portion + // of command required to redirect output from the command to file is + // built and appended to the existing command string + taskName := fmt.Sprintf("packer-%s", uuid.TimeOrderedUUID()) + // Only use %ENVVAR% format for environment variables when setting the log + // file path; Do NOT use $env:ENVVAR format as it won't be expanded + // correctly in the elevatedTemplate + logFile := `%SYSTEMROOT%/Temp/` + taskName + ".out" + command += fmt.Sprintf(" > %s 2>&1", logFile) + + // elevatedTemplate wraps the command in a single quoted XML text string + // so we need to escape characters considered 'special' in XML. + err = xml.EscapeText(&buffer, []byte(command)) + if err != nil { + return "", fmt.Errorf("Error escaping characters special to XML in command %s: %s", command, err) + } + escapedCommand := buffer.String() + log.Printf("Command [%s] converted to [%s] for use in XML string", command, escapedCommand) + buffer.Reset() + + // Escape chars special to PowerShell in the ElevatedUser string + elevatedUser := p.ElevatedUser() + escapedElevatedUser := psEscape.Replace(elevatedUser) + if escapedElevatedUser != elevatedUser { + log.Printf("Elevated user %s converted to %s after escaping chars special to PowerShell", + elevatedUser, escapedElevatedUser) + } + + // Escape chars special to PowerShell in the ElevatedPassword string + elevatedPassword := p.ElevatedPassword() + escapedElevatedPassword := psEscape.Replace(elevatedPassword) + if escapedElevatedPassword != elevatedPassword { + log.Printf("Elevated password %s converted to %s after escaping chars special to PowerShell", + elevatedPassword, escapedElevatedPassword) + } + + // Generate command + err = elevatedTemplate.Execute(&buffer, elevatedOptions{ + User: escapedElevatedUser, + Password: escapedElevatedPassword, + TaskName: taskName, + TaskDescription: "Packer elevated task", + LogFile: logFile, + XMLEscapedCommand: escapedCommand, + }) + + if err != nil { + fmt.Printf("Error creating elevated template: %s", err) + return "", err + } + uuid := uuid.TimeOrderedUUID() + path := fmt.Sprintf(`C:/Windows/Temp/packer-elevated-shell-%s.ps1`, uuid) + log.Printf("Uploading elevated shell wrapper for command [%s] to [%s]", command, path) + err = p.Communicator().Upload(path, &buffer, nil) + if err != nil { + return "", fmt.Errorf("Error preparing elevated powershell script: %s", err) + } + + return fmt.Sprintf("powershell -executionpolicy bypass -file \"%s\"", path), err +} diff --git a/provisioner/puppet-server/elevated.go b/provisioner/puppet-server/elevated.go deleted file mode 100644 index 5890a2aa0..000000000 --- a/provisioner/puppet-server/elevated.go +++ /dev/null @@ -1,100 +0,0 @@ -package puppetserver - -import ( - "text/template" -) - -type elevatedOptions struct { - User string - Password string - TaskName string - TaskDescription string - LogFile string - XMLEscapedCommand string -} - -var elevatedTemplate = template.Must(template.New("ElevatedCommand").Parse(` -$name = "{{.TaskName}}" -$log = [System.Environment]::ExpandEnvironmentVariables("{{.LogFile}}") -$s = New-Object -ComObject "Schedule.Service" -$s.Connect() -$t = $s.NewTask($null) -$xml = [xml]@' - - - - {{.TaskDescription}} - - - - {{.User}} - Password - HighestAvailable - - - - IgnoreNew - false - false - true - false - false - - false - false - - true - true - false - false - false - PT24H - 4 - - - - cmd - /c {{.XMLEscapedCommand}} - - - -'@ -$logon_type = 1 -$password = "{{.Password}}" -if ($password.Length -eq 0) { - $logon_type = 5 - $password = $null - $ns = New-Object System.Xml.XmlNamespaceManager($xml.NameTable) - $ns.AddNamespace("ns", $xml.DocumentElement.NamespaceURI) - $node = $xml.SelectSingleNode("/ns:Task/ns:Principals/ns:Principal/ns:LogonType", $ns) - $node.ParentNode.RemoveChild($node) | Out-Null -} -$t.XmlText = $xml.OuterXml -if (Test-Path variable:global:ProgressPreference){$ProgressPreference="SilentlyContinue"} -$f = $s.GetFolder("\") -$f.RegisterTaskDefinition($name, $t, 6, "{{.User}}", $password, $logon_type, $null) | Out-Null -$t = $f.GetTask("\$name") -$t.Run($null) | Out-Null -$timeout = 10 -$sec = 0 -while ((!($t.state -eq 4)) -and ($sec -lt $timeout)) { - Start-Sleep -s 1 - $sec++ -} - -$line = 0 -do { - Start-Sleep -m 100 - if (Test-Path $log) { - Get-Content $log | select -skip $line | ForEach { - $line += 1 - Write-Output "$_" - } - } -} while (!($t.state -eq 3)) -$result = $t.LastTaskResult -if (Test-Path $log) { - Remove-Item $log -Force -ErrorAction SilentlyContinue | Out-Null -} -[System.Runtime.Interopservices.Marshal]::ReleaseComObject($s) | Out-Null -exit $result`)) diff --git a/provisioner/puppet-server/provisioner.go b/provisioner/puppet-server/provisioner.go index 4612606fe..686bdf847 100644 --- a/provisioner/puppet-server/provisioner.go +++ b/provisioner/puppet-server/provisioner.go @@ -3,16 +3,12 @@ package puppetserver import ( - "bytes" - "encoding/xml" "fmt" - "log" "os" "path/filepath" "strings" "github.com/hashicorp/packer/common" - "github.com/hashicorp/packer/common/uuid" commonhelper "github.com/hashicorp/packer/helper/common" "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/packer" @@ -20,13 +16,6 @@ import ( "github.com/hashicorp/packer/template/interpolate" ) -var psEscape = strings.NewReplacer( - "$", "`$", - "\"", "`\"", - "`", "``", - "'", "`'", -) - type Config struct { common.PackerConfig `mapstructure:",squash"` ctx interpolate.Context @@ -300,7 +289,7 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { } if p.config.ElevatedUser != "" { - command, err = p.createCommandTextPrivileged(command) + command, err = provisioner.GenerateElevatedRunner(command, p) if err != nil { return err } @@ -390,91 +379,21 @@ func getWinRMPassword(buildName string) string { return winRMPass } -func (p *Provisioner) createCommandTextPrivileged(input string) (output string, err error) { - // OK so we need an elevated shell runner to wrap our command, this is - // going to have its own path generate the script and update the command - // runner in the process - path, err := p.generateElevatedRunner(input) - if err != nil { - return "", fmt.Errorf("Error generating elevated runner: %s", err) - } - - // Return the path to the elevated shell wrapper - output = fmt.Sprintf("powershell -executionpolicy bypass -file \"%s\"", path) - - return output, err +func (p *Provisioner) Communicator() packer.Communicator { + return p.communicator } -func (p *Provisioner) generateElevatedRunner(command string) (uploadedPath string, err error) { - log.Printf("Building elevated command wrapper for: %s", command) +func (p *Provisioner) ElevatedUser() string { + return p.config.ElevatedUser +} - var buffer bytes.Buffer - - // Output from the elevated command cannot be returned directly to the - // Packer console. In order to be able to view output from elevated - // commands and scripts an indirect approach is used by which the commands - // output is first redirected to file. The output file is then 'watched' - // by Packer while the elevated command is running and any content - // appearing in the file is written out to the console. Below the portion - // of command required to redirect output from the command to file is - // built and appended to the existing command string - taskName := fmt.Sprintf("packer-%s", uuid.TimeOrderedUUID()) - // Only use %ENVVAR% format for environment variables when setting the log - // file path; Do NOT use $env:ENVVAR format as it won't be expanded - // correctly in the elevatedTemplate - logFile := `%SYSTEMROOT%/Temp/` + taskName + ".out" - command += fmt.Sprintf(" > %s 2>&1", logFile) - - // elevatedTemplate wraps the command in a single quoted XML text string - // so we need to escape characters considered 'special' in XML. - err = xml.EscapeText(&buffer, []byte(command)) - if err != nil { - return "", fmt.Errorf("Error escaping characters special to XML in command %s: %s", command, err) - } - escapedCommand := buffer.String() - log.Printf("Command [%s] converted to [%s] for use in XML string", command, escapedCommand) - buffer.Reset() - - // Escape chars special to PowerShell in the ElevatedUser string - escapedElevatedUser := psEscape.Replace(p.config.ElevatedUser) - if escapedElevatedUser != p.config.ElevatedUser { - log.Printf("Elevated user %s converted to %s after escaping chars special to PowerShell", - p.config.ElevatedUser, escapedElevatedUser) - } +func (p *Provisioner) ElevatedPassword() string { // Replace ElevatedPassword for winrm users who used this feature p.config.ctx.Data = &EnvVarsTemplate{ WinRMPassword: getWinRMPassword(p.config.PackerBuildName), } - p.config.ElevatedPassword, _ = interpolate.Render(p.config.ElevatedPassword, &p.config.ctx) + elevatedPassword, _ := interpolate.Render(p.config.ElevatedPassword, &p.config.ctx) - // Escape chars special to PowerShell in the ElevatedPassword string - escapedElevatedPassword := psEscape.Replace(p.config.ElevatedPassword) - if escapedElevatedPassword != p.config.ElevatedPassword { - log.Printf("Elevated password %s converted to %s after escaping chars special to PowerShell", - p.config.ElevatedPassword, escapedElevatedPassword) - } - - // Generate command - err = elevatedTemplate.Execute(&buffer, elevatedOptions{ - User: escapedElevatedUser, - Password: escapedElevatedPassword, - TaskName: taskName, - TaskDescription: "Packer elevated task", - LogFile: logFile, - XMLEscapedCommand: escapedCommand, - }) - - if err != nil { - fmt.Printf("Error creating elevated template: %s", err) - return "", err - } - uuid := uuid.TimeOrderedUUID() - path := fmt.Sprintf(`C:/Windows/Temp/packer-elevated-shell-%s.ps1`, uuid) - log.Printf("Uploading elevated shell wrapper for command [%s] to [%s]", command, path) - err = p.communicator.Upload(path, &buffer, nil) - if err != nil { - return "", fmt.Errorf("Error preparing elevated powershell script: %s", err) - } - return path, err + return elevatedPassword } From 042e9ad14b7620469d92e4c19257d4b19d11ec34 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 6 Dec 2018 13:30:20 -0800 Subject: [PATCH 06/87] Move logging about aws waiters to the access config prepare() so that it's only spit out once per builder. --- builder/amazon/common/access_config.go | 1 + builder/amazon/common/state.go | 50 ++++++++++++------- .../amazon-import/post-processor.go | 1 + 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/builder/amazon/common/access_config.go b/builder/amazon/common/access_config.go index b7856b29f..d7a8ec9dc 100644 --- a/builder/amazon/common/access_config.go +++ b/builder/amazon/common/access_config.go @@ -110,6 +110,7 @@ func (c *AccessConfig) Session() (*session.Session, error) { if c.DecodeAuthZMessages { DecodeAuthZMessages(c.session) } + LogEnvOverrideWarnings() return c.session, nil } diff --git a/builder/amazon/common/state.go b/builder/amazon/common/state.go index 84adea957..ca07b81d0 100644 --- a/builder/amazon/common/state.go +++ b/builder/amazon/common/state.go @@ -1,6 +1,7 @@ package common import ( + "fmt" "log" "os" "strconv" @@ -307,6 +308,36 @@ func getEnvOverrides() overridableWaitVars { return envValues } +func LogEnvOverrideWarnings() { + pollDelay := os.Getenv("AWS_POLL_DELAY_SECONDS") + timeoutSeconds := os.Getenv("AWS_TIMEOUT_SECONDS") + maxAttempts := os.Getenv("AWS_MAX_ATTEMPTS") + + if maxAttempts != "" && timeoutSeconds != "" { + warning := fmt.Sprintf("[WARNING] (aws): AWS_MAX_ATTEMPTS and " + + "AWS_TIMEOUT_SECONDS are both set. Packer will use " + + "AWS_MAX_ATTEMPTS and discard AWS_TIMEOUT_SECONDS.") + if pollDelay == "" { + warning = fmt.Sprintf("%s Since you have not set the poll delay, "+ + "Packer will default to a 2-second delay.", warning) + } + log.Printf(warning) + } else if timeoutSeconds != "" { + log.Printf("[WARNING] (aws): 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.") + } + if maxAttempts == "" && timeoutSeconds == "" && pollDelay == "" { + log.Printf("[INFO] (aws): No AWS timeout and polling overrides have been set. " + + "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 " + + "desired values.") + } +} + func applyEnvOverrides(envOverrides overridableWaitVars) []request.WaiterOption { waitOpts := make([]request.WaiterOption, 0) // If user has set poll delay seconds, overwrite it. If user has NOT, @@ -320,18 +351,7 @@ func applyEnvOverrides(envOverrides overridableWaitVars) []request.WaiterOption // attempts, default to whatever the waiter has set as a default. if envOverrides.awsMaxAttempts.overridden { waitOpts = append(waitOpts, request.WithWaiterMaxAttempts(envOverrides.awsMaxAttempts.Val)) - } - - 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 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 := envOverrides.awsTimeoutSeconds.Val / envOverrides.awsPollDelaySeconds.Val // override the delay so we can get the timeout right if !envOverrides.awsPollDelaySeconds.overridden { @@ -340,14 +360,6 @@ func applyEnvOverrides(envOverrides overridableWaitVars) []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 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 " + - "desired values.") - } return waitOpts } diff --git a/post-processor/amazon-import/post-processor.go b/post-processor/amazon-import/post-processor.go index e4df4ea01..1bc8508d5 100644 --- a/post-processor/amazon-import/post-processor.go +++ b/post-processor/amazon-import/post-processor.go @@ -103,6 +103,7 @@ func (p *PostProcessor) Configure(raws ...interface{}) error { if len(errs.Errors) > 0 { return errs } + awscommon.LogEnvOverrideWarnings() packer.LogSecretFilter.Set(p.config.AccessKey, p.config.SecretKey, p.config.Token) log.Println(p.config) From a42f8fac4db5ca9a34297a71ac25c6fc8e32896a Mon Sep 17 00:00:00 2001 From: Matt Dainty Date: Fri, 7 Dec 2018 11:08:11 +0000 Subject: [PATCH 07/87] Elevated support for puppet-masterless provisioner This should fix #5478. --- provisioner/puppet-masterless/provisioner.go | 56 ++++++++++++++++++-- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/provisioner/puppet-masterless/provisioner.go b/provisioner/puppet-masterless/provisioner.go index 3254a6134..8368e37d3 100644 --- a/provisioner/puppet-masterless/provisioner.go +++ b/provisioner/puppet-masterless/provisioner.go @@ -10,6 +10,7 @@ import ( "strings" "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/provisioner" @@ -65,6 +66,12 @@ type Config struct { // The directory from which the command will be executed. // Packer requires the directory to exist when running puppet. WorkingDir string `mapstructure:"working_directory"` + + // Instructs the communicator to run the remote script as a Windows + // scheduled task, effectively elevating the remote user by impersonating + // a logged-in user + ElevatedUser string `mapstructure:"elevated_user"` + ElevatedPassword string `mapstructure:"elevated_password"` } type guestOSTypeConfig struct { @@ -117,6 +124,7 @@ var guestOSTypeConfigs = map[string]guestOSTypeConfig{ type Provisioner struct { config Config + communicator packer.Communicator guestOSTypeConfig guestOSTypeConfig guestCommands *provisioner.GuestCommands } @@ -135,7 +143,17 @@ type ExecuteTemplate struct { WorkingDir string } +type EnvVarsTemplate struct { + WinRMPassword string +} + func (p *Provisioner) Prepare(raws ...interface{}) error { + // Create passthrough for winrm password so we can fill it in once we know + // it + p.config.ctx.Data = &EnvVarsTemplate{ + WinRMPassword: `{{.WinRMPassword}}`, + } + err := config.Decode(&p.config, &config.DecodeOpts{ Interpolate: true, InterpolateContext: &p.config.ctx, @@ -240,6 +258,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { ui.Say("Provisioning with Puppet...") + p.communicator = comm ui.Message("Creating Puppet staging directory...") if err := p.createDir(ui, comm, p.config.StagingDir); err != nil { return fmt.Errorf("Error creating staging directory: %s", err) @@ -316,6 +335,13 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { return err } + if p.config.ElevatedUser != "" { + command, err = provisioner.GenerateElevatedRunner(command, p) + if err != nil { + return err + } + } + cmd := &packer.RemoteCmd{ Command: command, } @@ -432,10 +458,7 @@ func (p *Provisioner) createDir(ui packer.Ui, comm packer.Communicator, dir stri } func (p *Provisioner) removeDir(ui packer.Ui, comm packer.Communicator, dir string) error { - cmd := &packer.RemoteCmd{ - Command: fmt.Sprintf("rm -fr '%s'", dir), - } - + cmd := &packer.RemoteCmd{Command: p.guestCommands.RemoveDir(dir)} if err := cmd.StartWithUi(comm, ui); err != nil { return err } @@ -460,3 +483,28 @@ func (p *Provisioner) uploadDirectory(ui packer.Ui, comm packer.Communicator, ds return comm.UploadDir(dst, src, nil) } + +func getWinRMPassword(buildName string) string { + winRMPass, _ := commonhelper.RetrieveSharedState("winrm_password", buildName) + packer.LogSecretFilter.Set(winRMPass) + return winRMPass +} + +func (p *Provisioner) Communicator() packer.Communicator { + return p.communicator +} + +func (p *Provisioner) ElevatedUser() string { + return p.config.ElevatedUser +} + +func (p *Provisioner) ElevatedPassword() string { + // Replace ElevatedPassword for winrm users who used this feature + p.config.ctx.Data = &EnvVarsTemplate{ + WinRMPassword: getWinRMPassword(p.config.PackerBuildName), + } + + elevatedPassword, _ := interpolate.Render(p.config.ElevatedPassword, &p.config.ctx) + + return elevatedPassword +} From 2e4b00f59dd24b3a8e3943dc253d622cc639922b Mon Sep 17 00:00:00 2001 From: Matt Dainty Date: Fri, 7 Dec 2018 15:30:50 +0000 Subject: [PATCH 08/87] Refactor powershell provisioner Use the common elevated code instead. --- provisioner/powershell/elevated.go | 100 -------------------------- provisioner/powershell/provisioner.go | 84 +++------------------- 2 files changed, 11 insertions(+), 173 deletions(-) delete mode 100644 provisioner/powershell/elevated.go diff --git a/provisioner/powershell/elevated.go b/provisioner/powershell/elevated.go deleted file mode 100644 index be8dcdf62..000000000 --- a/provisioner/powershell/elevated.go +++ /dev/null @@ -1,100 +0,0 @@ -package powershell - -import ( - "text/template" -) - -type elevatedOptions struct { - User string - Password string - TaskName string - TaskDescription string - LogFile string - XMLEscapedCommand string -} - -var elevatedTemplate = template.Must(template.New("ElevatedCommand").Parse(` -$name = "{{.TaskName}}" -$log = [System.Environment]::ExpandEnvironmentVariables("{{.LogFile}}") -$s = New-Object -ComObject "Schedule.Service" -$s.Connect() -$t = $s.NewTask($null) -$xml = [xml]@' - - - - {{.TaskDescription}} - - - - {{.User}} - Password - HighestAvailable - - - - IgnoreNew - false - false - true - false - false - - false - false - - true - true - false - false - false - PT24H - 4 - - - - cmd - /c {{.XMLEscapedCommand}} - - - -'@ -$logon_type = 1 -$password = "{{.Password}}" -if ($password.Length -eq 0) { - $logon_type = 5 - $password = $null - $ns = New-Object System.Xml.XmlNamespaceManager($xml.NameTable) - $ns.AddNamespace("ns", $xml.DocumentElement.NamespaceURI) - $node = $xml.SelectSingleNode("/ns:Task/ns:Principals/ns:Principal/ns:LogonType", $ns) - $node.ParentNode.RemoveChild($node) | Out-Null -} -$t.XmlText = $xml.OuterXml -if (Test-Path variable:global:ProgressPreference){$ProgressPreference="SilentlyContinue"} -$f = $s.GetFolder("\") -$f.RegisterTaskDefinition($name, $t, 6, "{{.User}}", $password, $logon_type, $null) | Out-Null -$t = $f.GetTask("\$name") -$t.Run($null) | Out-Null -$timeout = 10 -$sec = 0 -while ((!($t.state -eq 4)) -and ($sec -lt $timeout)) { - Start-Sleep -s 1 - $sec++ -} - -$line = 0 -do { - Start-Sleep -m 100 - if (Test-Path $log) { - Get-Content $log | select -skip $line | ForEach { - $line += 1 - Write-Output "$_" - } - } -} while (!($t.state -eq 3)) -$result = $t.LastTaskResult -if (Test-Path $log) { - Remove-Item $log -Force -ErrorAction SilentlyContinue | Out-Null -} -[System.Runtime.Interopservices.Marshal]::ReleaseComObject($s) | Out-Null -exit $result`)) diff --git a/provisioner/powershell/provisioner.go b/provisioner/powershell/provisioner.go index ed35bdd01..fa4586fb3 100644 --- a/provisioner/powershell/provisioner.go +++ b/provisioner/powershell/provisioner.go @@ -4,8 +4,6 @@ package powershell import ( "bufio" - "bytes" - "encoding/xml" "errors" "fmt" "io/ioutil" @@ -20,6 +18,7 @@ import ( commonhelper "github.com/hashicorp/packer/helper/common" "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/packer" + "github.com/hashicorp/packer/provisioner" "github.com/hashicorp/packer/template/interpolate" ) @@ -498,90 +497,29 @@ func (p *Provisioner) createCommandTextPrivileged() (command string, err error) return "", fmt.Errorf("Error processing command: %s", err) } - // OK so we need an elevated shell runner to wrap our command, this is - // going to have its own path generate the script and update the command - // runner in the process - path, err := p.generateElevatedRunner(command) + command, err = provisioner.GenerateElevatedRunner(command, p) if err != nil { return "", fmt.Errorf("Error generating elevated runner: %s", err) } - // Return the path to the elevated shell wrapper - command = fmt.Sprintf("powershell -executionpolicy bypass -file \"%s\"", path) - return command, err } -func (p *Provisioner) generateElevatedRunner(command string) (uploadedPath string, err error) { - log.Printf("Building elevated command wrapper for: %s", command) +func (p *Provisioner) Communicator() packer.Communicator { + return p.communicator +} - var buffer bytes.Buffer +func (p *Provisioner) ElevatedUser() string { + return p.config.ElevatedUser +} - // Output from the elevated command cannot be returned directly to the - // Packer console. In order to be able to view output from elevated - // commands and scripts an indirect approach is used by which the commands - // output is first redirected to file. The output file is then 'watched' - // by Packer while the elevated command is running and any content - // appearing in the file is written out to the console. Below the portion - // of command required to redirect output from the command to file is - // built and appended to the existing command string - taskName := fmt.Sprintf("packer-%s", uuid.TimeOrderedUUID()) - // Only use %ENVVAR% format for environment variables when setting the log - // file path; Do NOT use $env:ENVVAR format as it won't be expanded - // correctly in the elevatedTemplate - logFile := `%SYSTEMROOT%/Temp/` + taskName + ".out" - command += fmt.Sprintf(" > %s 2>&1", logFile) - - // elevatedTemplate wraps the command in a single quoted XML text string - // so we need to escape characters considered 'special' in XML. - err = xml.EscapeText(&buffer, []byte(command)) - if err != nil { - return "", fmt.Errorf("Error escaping characters special to XML in command %s: %s", command, err) - } - escapedCommand := buffer.String() - log.Printf("Command [%s] converted to [%s] for use in XML string", command, escapedCommand) - buffer.Reset() - - // Escape chars special to PowerShell in the ElevatedUser string - escapedElevatedUser := psEscape.Replace(p.config.ElevatedUser) - if escapedElevatedUser != p.config.ElevatedUser { - log.Printf("Elevated user %s converted to %s after escaping chars special to PowerShell", - p.config.ElevatedUser, escapedElevatedUser) - } +func (p *Provisioner) ElevatedPassword() string { // Replace ElevatedPassword for winrm users who used this feature p.config.ctx.Data = &EnvVarsTemplate{ WinRMPassword: getWinRMPassword(p.config.PackerBuildName), } - p.config.ElevatedPassword, _ = interpolate.Render(p.config.ElevatedPassword, &p.config.ctx) + elevatedPassword, _ := interpolate.Render(p.config.ElevatedPassword, &p.config.ctx) - // Escape chars special to PowerShell in the ElevatedPassword string - escapedElevatedPassword := psEscape.Replace(p.config.ElevatedPassword) - if escapedElevatedPassword != p.config.ElevatedPassword { - log.Printf("Elevated password %s converted to %s after escaping chars special to PowerShell", - p.config.ElevatedPassword, escapedElevatedPassword) - } - - // Generate command - err = elevatedTemplate.Execute(&buffer, elevatedOptions{ - User: escapedElevatedUser, - Password: escapedElevatedPassword, - TaskName: taskName, - TaskDescription: "Packer elevated task", - LogFile: logFile, - XMLEscapedCommand: escapedCommand, - }) - - if err != nil { - fmt.Printf("Error creating elevated template: %s", err) - return "", err - } - uuid := uuid.TimeOrderedUUID() - path := fmt.Sprintf(`C:/Windows/Temp/packer-elevated-shell-%s.ps1`, uuid) - log.Printf("Uploading elevated shell wrapper for command [%s] to [%s]", command, path) - err = p.communicator.Upload(path, &buffer, nil) - if err != nil { - return "", fmt.Errorf("Error preparing elevated powershell script: %s", err) - } - return path, err + return elevatedPassword } From 3585b8023f92a7336f723c56c547858e835e6bf9 Mon Sep 17 00:00:00 2001 From: Matt Dainty Date: Fri, 7 Dec 2018 15:36:30 +0000 Subject: [PATCH 09/87] Update docs for Puppet provisioners --- website/source/docs/provisioners/puppet-masterless.html.md | 5 +++++ website/source/docs/provisioners/puppet-server.html.md | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/website/source/docs/provisioners/puppet-masterless.html.md b/website/source/docs/provisioners/puppet-masterless.html.md index 8882907bb..fdd93138c 100644 --- a/website/source/docs/provisioners/puppet-masterless.html.md +++ b/website/source/docs/provisioners/puppet-masterless.html.md @@ -114,6 +114,11 @@ manifests you should use `manifest_file` instead. be run. If using Hiera files with relative paths, this option can be helpful. (default: `staging_directory`) +- `elevated_user` and `elevated_password` (string) - If specified, Puppet + will be run with elevated privileges using the given Windows user. See the + [powershell](/docs/provisioners/powershell.html) provider for the full + details. + ## Execute Command By default, Packer uses the following command (broken across multiple lines for diff --git a/website/source/docs/provisioners/puppet-server.html.md b/website/source/docs/provisioners/puppet-server.html.md index 29e559966..cef82ff68 100644 --- a/website/source/docs/provisioners/puppet-server.html.md +++ b/website/source/docs/provisioners/puppet-server.html.md @@ -100,6 +100,11 @@ listed below: be run. If using Hiera files with relative paths, this option can be helpful. (default: `staging_directory`) +- `elevated_user` and `elevated_password` (string) - If specified, Puppet + will be run with elevated privileges using the given Windows user. See the + [powershell](/docs/provisioners/powershell.html) provider for the full + details. + ## Execute Command By default, Packer uses the following command (broken across multiple lines for From 19bd28cd72a7ade96ab21986f568db4515bc9fa1 Mon Sep 17 00:00:00 2001 From: Matt Dainty Date: Fri, 7 Dec 2018 16:23:03 +0000 Subject: [PATCH 10/87] Fix/add tests --- packer/provisioner_mock.go | 12 +++++++ provisioner/elevated_test.go | 38 ++++++++++++++++++++++ provisioner/powershell/provisioner_test.go | 24 -------------- 3 files changed, 50 insertions(+), 24 deletions(-) create mode 100644 provisioner/elevated_test.go diff --git a/packer/provisioner_mock.go b/packer/provisioner_mock.go index 62b304ccb..0c7a25791 100644 --- a/packer/provisioner_mock.go +++ b/packer/provisioner_mock.go @@ -34,3 +34,15 @@ func (t *MockProvisioner) Provision(ui Ui, comm Communicator) error { func (t *MockProvisioner) Cancel() { t.CancelCalled = true } + +func (t *MockProvisioner) Communicator() Communicator { + return t.ProvCommunicator +} + +func (t *MockProvisioner) ElevatedUser() string { + return "user" +} + +func (t *MockProvisioner) ElevatedPassword() string { + return "password" +} diff --git a/provisioner/elevated_test.go b/provisioner/elevated_test.go new file mode 100644 index 000000000..ac8759ef2 --- /dev/null +++ b/provisioner/elevated_test.go @@ -0,0 +1,38 @@ +package provisioner + +import ( + "regexp" + "testing" + + "github.com/hashicorp/packer/packer" +) + +func testConfig() map[string]interface{} { + return map[string]interface{}{ + "inline": []interface{}{"foo", "bar"}, + } +} + +func TestProvisioner_GenerateElevatedRunner(t *testing.T) { + + // Non-elevated + config := testConfig() + p := new(packer.MockProvisioner) + p.Prepare(config) + comm := new(packer.MockCommunicator) + p.ProvCommunicator = comm + path, err := GenerateElevatedRunner("whoami", p) + + if err != nil { + t.Fatalf("Did not expect error: %s", err.Error()) + } + + if comm.UploadCalled != true { + t.Fatalf("Should have uploaded file") + } + + matched, _ := regexp.MatchString("C:/Windows/Temp/packer-elevated-shell.*", path) + if !matched { + t.Fatalf("Got unexpected file: %s", path) + } +} diff --git a/provisioner/powershell/provisioner_test.go b/provisioner/powershell/provisioner_test.go index b0a0a27ab..eef61bf8d 100644 --- a/provisioner/powershell/provisioner_test.go +++ b/provisioner/powershell/provisioner_test.go @@ -654,30 +654,6 @@ func TestProvision_uploadEnvVars(t *testing.T) { } } -func TestProvision_generateElevatedShellRunner(t *testing.T) { - - // Non-elevated - config := testConfig() - p := new(Provisioner) - p.Prepare(config) - comm := new(packer.MockCommunicator) - p.communicator = comm - path, err := p.generateElevatedRunner("whoami") - - if err != nil { - t.Fatalf("Did not expect error: %s", err.Error()) - } - - if comm.UploadCalled != true { - t.Fatalf("Should have uploaded file") - } - - matched, _ := regexp.MatchString("C:/Windows/Temp/packer-elevated-shell.*", path) - if !matched { - t.Fatalf("Got unexpected file: %s", path) - } -} - func TestRetryable(t *testing.T) { config := testConfig() From 12bf7fc4d653457d52704ebbb3fbd554bd31587e Mon Sep 17 00:00:00 2001 From: Tom Elliff Date: Mon, 10 Dec 2018 19:13:28 +0000 Subject: [PATCH 11/87] Check that the KMS key ID is valid KMS key IDs can be given as either a raw key ID, an alias (always prefixed with 'alias/'), the full ARN to the KMS key ID or the full ARN to the KMS key alias. Should help with https://github.com/hashicorp/packer/issues/6599 but probably isn't enough to fully close it. --- builder/amazon/common/ami_config.go | 38 ++++++++++++++++++++++++ builder/amazon/common/ami_config_test.go | 35 ++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/builder/amazon/common/ami_config.go b/builder/amazon/common/ami_config.go index a03c3a789..9d75aa5fc 100644 --- a/builder/amazon/common/ami_config.go +++ b/builder/amazon/common/ami_config.go @@ -3,6 +3,7 @@ package common import ( "fmt" "log" + "regexp" "github.com/hashicorp/packer/template/interpolate" ) @@ -62,6 +63,23 @@ func (c *AMIConfig) Prepare(accessConfig *AccessConfig, ctx *interpolate.Context errs = append(errs, fmt.Errorf("Cannot share AMI with encrypted boot volume")) } + var kmsKeys []string + if len(c.AMIKmsKeyId) > 0 { + kmsKeys = append(kmsKeys, c.AMIKmsKeyId) + } + if len(c.AMIRegionKMSKeyIDs) > 0 { + for _, kmsKey := range c.AMIRegionKMSKeyIDs { + if len(kmsKey) == 0 { + kmsKeys = append(kmsKeys, c.AMIKmsKeyId) + } + } + } + for _, kmsKey := range kmsKeys { + if !validateKmsKey(kmsKey) { + errs = append(errs, fmt.Errorf("%s is not a valid KMS Key Id.", kmsKey)) + } + } + if len(c.SnapshotUsers) > 0 { if len(c.AMIKmsKeyId) == 0 && c.AMIEncryptBootVolume { errs = append(errs, fmt.Errorf("Cannot share snapshot encrypted with default KMS key")) @@ -128,3 +146,23 @@ func (c *AMIConfig) prepareRegions(accessConfig *AccessConfig) (errs []error) { } return errs } + +// See https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CopyImage.html +func validateKmsKey(kmsKey string) (valid bool) { + kmsKeyIdPattern := `[a-f0-9-]+$` + aliasPattern := `alias/[a-zA-Z0-9:/_-]+$` + kmsArnStartPattern := `^arn:aws:kms:([a-z]{2}-(gov-)?[a-z]+-\d{1})?:(\d{12}):` + if regexp.MustCompile(fmt.Sprintf("^%s", kmsKeyIdPattern)).MatchString(kmsKey) { + return true + } + if regexp.MustCompile(fmt.Sprintf("^%s", aliasPattern)).MatchString(kmsKey) { + return true + } + if regexp.MustCompile(fmt.Sprintf("%skey/%s", kmsArnStartPattern, kmsKeyIdPattern)).MatchString(kmsKey) { + return true + } + if regexp.MustCompile(fmt.Sprintf("%s%s", kmsArnStartPattern, aliasPattern)).MatchString(kmsKey) { + return true + } + return false +} diff --git a/builder/amazon/common/ami_config_test.go b/builder/amazon/common/ami_config_test.go index f7fce7411..ec1fda91a 100644 --- a/builder/amazon/common/ami_config_test.go +++ b/builder/amazon/common/ami_config_test.go @@ -176,6 +176,41 @@ func TestAMIConfigPrepare_Share_EncryptedBoot(t *testing.T) { } } +func TestAMIConfigPrepare_ValidateKmsKey(t *testing.T) { + c := testAMIConfig() + c.AMIEncryptBootVolume = true + + accessConf := testAccessConfig() + + validCases := []string{ + "abcd1234-e567-890f-a12b-a123b4cd56ef", + "alias/foo/bar", + "arn:aws:kms:us-east-1:012345678910:key/abcd1234-a123-456a-a12b-a123b4cd56ef", + "arn:aws:kms:us-east-1:012345678910:alias/foo/bar", + } + for _, validCase := range validCases { + c.AMIKmsKeyId = validCase + if err := c.Prepare(accessConf, nil); err != nil { + t.Fatalf("%s should not have failed KMS key validation", validCase) + } + } + + invalidCases := []string{ + "ABCD1234-e567-890f-a12b-a123b4cd56ef", + "ghij1234-e567-890f-a12b-a123b4cd56ef", + "ghij1234+e567_890f-a12b-a123b4cd56ef", + "foo/bar", + "arn:aws:kms:us-east-1:012345678910:foo/bar", + } + for _, invalidCase := range invalidCases { + c.AMIKmsKeyId = invalidCase + if err := c.Prepare(accessConf, nil); err == nil { + t.Fatalf("%s should have failed KMS key validation", invalidCase) + } + } + +} + func TestAMINameValidation(t *testing.T) { c := testAMIConfig() From d5854a95740a100272e07bbd17b4215ccb1e0b6b Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 11 Oct 2018 15:07:36 -0700 Subject: [PATCH 12/87] add option to test registry for certain keys to make sure windows is done with a reboot cycle --- provisioner/windows-restart/provisioner.go | 48 ++++++++++++++++++- .../docs/provisioners/windows-restart.html.md | 22 +++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/provisioner/windows-restart/provisioner.go b/provisioner/windows-restart/provisioner.go index 126a0dd52..0593024c4 100644 --- a/provisioner/windows-restart/provisioner.go +++ b/provisioner/windows-restart/provisioner.go @@ -23,6 +23,12 @@ var retryableSleep = 5 * time.Second var TryCheckReboot = `shutdown /r /f /t 60 /c "packer restart test"` var AbortReboot = `shutdown /a` +var DefaultRegistryKeys = []string{ + "HKLM:SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Component Based Servicing\\RebootPending", + "HKLM:SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Component Based Servicing\\PackagesPending", + "HKLM:Software\\Microsoft\\Windows\\CurrentVersion\\Component Based Servicing\\RebootInProgress", +} + type Config struct { common.PackerConfig `mapstructure:",squash"` @@ -36,6 +42,12 @@ type Config struct { // The timeout for waiting for the machine to restart RestartTimeout time.Duration `mapstructure:"restart_timeout"` + // Whether to check the registry (see RegistryKeys) for pending reboots + CheckKey bool `mapstructure:"check_registry"` + + // custom keys to check for + RegistryKeys []string `mapstructure:"registry_keys"` + ctx interpolate.Context } @@ -73,6 +85,10 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { p.config.RestartTimeout = 5 * time.Minute } + if len(p.config.RegistryKeys) == 0 { + p.config.RegistryKeys = DefaultRegistryKeys + } + return nil } @@ -212,7 +228,6 @@ var waitForCommunicator = func(p *Provisioner) error { log.Printf("Connected to machine") runCustomRestartCheck = false } - // This is the non-user-configurable check that powershell // modules have loaded. @@ -234,6 +249,37 @@ var waitForCommunicator = func(p *Provisioner) error { log.Printf("echo didn't succeed; retrying...") continue } + + if p.config.CheckKey { + log.Printf("Connected to machine") + shouldContinue := false + for _, RegKey := range p.config.RegistryKeys { + KeyTestCommand := winrm.Powershell(fmt.Sprintf(`Test-Path "%s"`, RegKey)) + cmdKeyCheck := &packer.RemoteCmd{Command: KeyTestCommand} + log.Printf("Checking registry for pending reboots") + var buf, buf2 bytes.Buffer + cmdKeyCheck.Stdout = &buf + cmdKeyCheck.Stdout = io.MultiWriter(cmdKeyCheck.Stdout, &buf2) + + err := p.comm.Start(cmdKeyCheck) + if err != nil { + log.Printf("Communication connection err: %s", err) + shouldContinue = true + } + cmdKeyCheck.Wait() + + stdoutToRead := buf2.String() + if strings.Contains(stdoutToRead, "True") { + log.Printf("RegistryKey %s exists; waiting...", KeyTestCommand) + shouldContinue = true + } else { + log.Printf("No Registry keys found; exiting wait loop") + } + } + if shouldContinue { + continue + } + } break } diff --git a/website/source/docs/provisioners/windows-restart.html.md b/website/source/docs/provisioners/windows-restart.html.md index ba0c8fd4e..b9ee04567 100644 --- a/website/source/docs/provisioners/windows-restart.html.md +++ b/website/source/docs/provisioners/windows-restart.html.md @@ -38,6 +38,28 @@ The reference of available configuration options is listed below. Optional parameters: +- `check_registry` (bool) - if `true`, checks for several registry keys that + indicate that the system is going to reboot. This is useful if an + installation kicks off a reboot and you want the provisioner to wait for + that reboot to complete before reconnecting. Please note that this option is + a beta feature, and we generally recommend that you finish installs that + auto-reboot (like windows updates) during your autounattend phase before our + winrm provisioner connects. + +- `registry_keys` (array of strings) - if `check-registry` is `true`, + windows-restart will not reconnect until after all of the listed keys are + no longer present in the registry. + + default: + + ``` + var DefaultRegistryKeys = []string{ + "HKLM:SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Component Based Servicing\\RebootPending", + "HKLM:SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Component Based Servicing\\PackagesPending", + "HKLM:Software\\Microsoft\\Windows\\CurrentVersion\\Component Based Servicing\\RebootInProgress", + } + ``` + - `restart_command` (string) - The command to execute to initiate the restart. By default this is `shutdown /r /f /t 0 /c "packer restart"`. From 15986a9d4fd7d10c5dd609dc1f995465ce427ab6 Mon Sep 17 00:00:00 2001 From: Matt Millican Date: Wed, 12 Dec 2018 15:10:57 -0600 Subject: [PATCH 13/87] Add note about using ssh_interface for WinRM --- website/source/docs/templates/communicator.html.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/source/docs/templates/communicator.html.md b/website/source/docs/templates/communicator.html.md index 8f88e280d..b2133f825 100644 --- a/website/source/docs/templates/communicator.html.md +++ b/website/source/docs/templates/communicator.html.md @@ -170,6 +170,8 @@ And the following MACs: The WinRM communicator has the following options. - `winrm_host` (string) - The address for WinRM to connect to. + + NOTE: If using an Amazon EBS builder, you can specify the interface WinRM connects to via [`ssh_interface`](https://www.packer.io/docs/builders/amazon-ebs.html#ssh_interface) - `winrm_insecure` (boolean) - If `true`, do not check server certificate chain and host name. From 2a79d64ae08e9d3400488c0c01813450d134feec Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Wed, 12 Dec 2018 15:29:33 -0800 Subject: [PATCH 14/87] revert changes to docker entrypoint; since this is a backwards-breaking change it needs to wait for a minor release --- builder/docker/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/docker/config.go b/builder/docker/config.go index ef2d52a63..6116a995b 100644 --- a/builder/docker/config.go +++ b/builder/docker/config.go @@ -73,7 +73,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { // Defaults if len(c.RunCommand) == 0 { - c.RunCommand = []string{"-d", "-i", "-t", "--entrypoint=/bin/sh", "--", "{{.Image}}"} + c.RunCommand = []string{"-d", "-i", "-t", "{{.Image}}", "/bin/bash"} } // Default Pull if it wasn't set From 451709b9568f76027e6beae109263f4ee579868c Mon Sep 17 00:00:00 2001 From: Matt Dainty Date: Thu, 13 Dec 2018 10:25:12 +0000 Subject: [PATCH 15/87] Elevated support for chef-client provisioner Fixes #4661 --- provisioner/chef-client/provisioner.go | 48 +++++++++++++++++++ .../docs/provisioners/chef-client.html.md | 5 ++ 2 files changed, 53 insertions(+) diff --git a/provisioner/chef-client/provisioner.go b/provisioner/chef-client/provisioner.go index 8a3bff170..6d451ace4 100644 --- a/provisioner/chef-client/provisioner.go +++ b/provisioner/chef-client/provisioner.go @@ -14,6 +14,7 @@ import ( "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/common/uuid" + commonhelper "github.com/hashicorp/packer/helper/common" "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/provisioner" @@ -50,6 +51,8 @@ type Config struct { ChefEnvironment string `mapstructure:"chef_environment"` ClientKey string `mapstructure:"client_key"` ConfigTemplate string `mapstructure:"config_template"` + ElevatedUser string `mapstructure:"elevated_user"` + ElevatedPassword string `mapstructure:"elevated_password"` EncryptedDataBagSecretPath string `mapstructure:"encrypted_data_bag_secret_path"` ExecuteCommand string `mapstructure:"execute_command"` GuestOSType string `mapstructure:"guest_os_type"` @@ -76,6 +79,7 @@ type Config struct { type Provisioner struct { config Config + communicator packer.Communicator guestOSTypeConfig guestOSTypeConfig guestCommands *provisioner.GuestCommands } @@ -94,6 +98,10 @@ type ConfigTemplate struct { ValidationKeyPath string } +type EnvVarsTemplate struct { + WinRMPassword string +} + type ExecuteTemplate struct { ConfigPath string JsonPath string @@ -111,6 +119,12 @@ type KnifeTemplate struct { } func (p *Provisioner) Prepare(raws ...interface{}) error { + // Create passthrough for winrm password so we can fill it in once we know + // it + p.config.ctx.Data = &EnvVarsTemplate{ + WinRMPassword: `{{.WinRMPassword}}`, + } + err := config.Decode(&p.config, &config.DecodeOpts{ Interpolate: true, InterpolateContext: &p.config.ctx, @@ -221,6 +235,8 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { + p.communicator = comm + nodeName := p.config.NodeName if nodeName == "" { nodeName = fmt.Sprintf("packer-%s", uuid.TimeOrderedUUID()) @@ -551,6 +567,13 @@ func (p *Provisioner) executeChef(ui packer.Ui, comm packer.Communicator, config return err } + if p.config.ElevatedUser != "" { + command, err = provisioner.GenerateElevatedRunner(command, p) + if err != nil { + return err + } + } + ui.Message(fmt.Sprintf("Executing Chef: %s", command)) cmd := &packer.RemoteCmd{ @@ -676,6 +699,31 @@ func (p *Provisioner) processJsonUserVars() (map[string]interface{}, error) { return result, nil } +func getWinRMPassword(buildName string) string { + winRMPass, _ := commonhelper.RetrieveSharedState("winrm_password", buildName) + packer.LogSecretFilter.Set(winRMPass) + return winRMPass +} + +func (p *Provisioner) Communicator() packer.Communicator { + return p.communicator +} + +func (p *Provisioner) ElevatedUser() string { + return p.config.ElevatedUser +} + +func (p *Provisioner) ElevatedPassword() string { + // Replace ElevatedPassword for winrm users who used this feature + p.config.ctx.Data = &EnvVarsTemplate{ + WinRMPassword: getWinRMPassword(p.config.PackerBuildName), + } + + elevatedPassword, _ := interpolate.Render(p.config.ElevatedPassword, &p.config.ctx) + + return elevatedPassword +} + var DefaultConfigTemplate = ` log_level :info log_location STDOUT diff --git a/website/source/docs/provisioners/chef-client.html.md b/website/source/docs/provisioners/chef-client.html.md index 5c8eb086d..c0ae990b9 100644 --- a/website/source/docs/provisioners/chef-client.html.md +++ b/website/source/docs/provisioners/chef-client.html.md @@ -51,6 +51,11 @@ configuration is actually required. should use a custom configuration template. See the dedicated "Chef Configuration" section below for more details. +- `elevated_user` and `elevated_password` (string) - If specified, Chef will + be run with elevated privileges using the given Windows user. See the + [powershell](/docs/provisionders/powershell.html) provisioner for the full + details. + - `encrypted_data_bag_secret_path` (string) - The path to the file containing the secret for encrypted data bags. By default, this is empty, so no secret will be available. From 845d29b458718c93fd892c52737499a451bf9fdd Mon Sep 17 00:00:00 2001 From: Matt Dainty Date: Thu, 13 Dec 2018 10:32:36 +0000 Subject: [PATCH 16/87] s/provider/provisioner/ --- website/source/docs/provisioners/puppet-masterless.html.md | 2 +- website/source/docs/provisioners/puppet-server.html.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/website/source/docs/provisioners/puppet-masterless.html.md b/website/source/docs/provisioners/puppet-masterless.html.md index fdd93138c..61196eb86 100644 --- a/website/source/docs/provisioners/puppet-masterless.html.md +++ b/website/source/docs/provisioners/puppet-masterless.html.md @@ -116,7 +116,7 @@ manifests you should use `manifest_file` instead. - `elevated_user` and `elevated_password` (string) - If specified, Puppet will be run with elevated privileges using the given Windows user. See the - [powershell](/docs/provisioners/powershell.html) provider for the full + [powershell](/docs/provisioners/powershell.html) provisioner for the full details. ## Execute Command diff --git a/website/source/docs/provisioners/puppet-server.html.md b/website/source/docs/provisioners/puppet-server.html.md index cef82ff68..840d085ad 100644 --- a/website/source/docs/provisioners/puppet-server.html.md +++ b/website/source/docs/provisioners/puppet-server.html.md @@ -102,7 +102,7 @@ listed below: - `elevated_user` and `elevated_password` (string) - If specified, Puppet will be run with elevated privileges using the given Windows user. See the - [powershell](/docs/provisioners/powershell.html) provider for the full + [powershell](/docs/provisioners/powershell.html) provisioner for the full details. ## Execute Command From b95123f45765915512342e1fa5f0cefd259e1490 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Mon, 10 Dec 2018 14:46:16 -0800 Subject: [PATCH 17/87] add new copy_in_compare flag so users can set the copy var to whatever they need in order to get the compatibility report to work. --- builder/hyperv/common/driver.go | 2 +- builder/hyperv/common/driver_mock.go | 5 ++++- builder/hyperv/common/driver_ps_4.go | 4 ++-- builder/hyperv/common/step_clone_vm.go | 6 ++++-- builder/hyperv/vmcx/builder.go | 2 ++ common/powershell/hyperv/hyperv.go | 19 ++++++++++++------- .../docs/builders/hyperv-vmcx.html.md.erb | 9 +++++++++ 7 files changed, 34 insertions(+), 13 deletions(-) diff --git a/builder/hyperv/common/driver.go b/builder/hyperv/common/driver.go index 0001bd989..5f96398ae 100644 --- a/builder/hyperv/common/driver.go +++ b/builder/hyperv/common/driver.go @@ -74,7 +74,7 @@ type Driver interface { AddVirtualMachineHardDrive(string, string, string, int64, int64, string) error - CloneVirtualMachine(string, string, string, bool, string, string, string, int64, string) error + CloneVirtualMachine(string, string, string, bool, string, string, string, int64, string, bool) error DeleteVirtualMachine(string) error diff --git a/builder/hyperv/common/driver_mock.go b/builder/hyperv/common/driver_mock.go index 5bef1b3e4..71b7a0750 100644 --- a/builder/hyperv/common/driver_mock.go +++ b/builder/hyperv/common/driver_mock.go @@ -143,6 +143,7 @@ type DriverMock struct { CloneVirtualMachine_HarddrivePath string CloneVirtualMachine_Ram int64 CloneVirtualMachine_SwitchName string + CloneVirtualMachine_Copy bool CloneVirtualMachine_Err error DeleteVirtualMachine_Called bool @@ -425,7 +426,7 @@ func (d *DriverMock) CreateVirtualMachine(vmName string, path string, harddriveP func (d *DriverMock) CloneVirtualMachine(cloneFromVmcxPath string, cloneFromVmName string, cloneFromSnapshotName string, cloneAllSnapshots bool, vmName string, path string, - harddrivePath string, ram int64, switchName string) error { + harddrivePath string, ram int64, switchName string, copyTF bool) error { d.CloneVirtualMachine_Called = true d.CloneVirtualMachine_CloneFromVmcxPath = cloneFromVmcxPath d.CloneVirtualMachine_CloneFromVmName = cloneFromVmName @@ -436,6 +437,8 @@ func (d *DriverMock) CloneVirtualMachine(cloneFromVmcxPath string, cloneFromVmNa d.CloneVirtualMachine_HarddrivePath = harddrivePath d.CloneVirtualMachine_Ram = ram d.CloneVirtualMachine_SwitchName = switchName + d.CloneVirtualMachine_Copy = copyTF + return d.CloneVirtualMachine_Err } diff --git a/builder/hyperv/common/driver_ps_4.go b/builder/hyperv/common/driver_ps_4.go index b1803971f..0ef7accf4 100644 --- a/builder/hyperv/common/driver_ps_4.go +++ b/builder/hyperv/common/driver_ps_4.go @@ -190,9 +190,9 @@ func (d *HypervPS4Driver) CreateVirtualMachine(vmName string, path string, hardd func (d *HypervPS4Driver) CloneVirtualMachine(cloneFromVmcxPath string, cloneFromVmName string, cloneFromSnapshotName string, cloneAllSnapshots bool, vmName string, path string, harddrivePath string, - ram int64, switchName string) error { + ram int64, switchName string, copyTF bool) error { return hyperv.CloneVirtualMachine(cloneFromVmcxPath, cloneFromVmName, cloneFromSnapshotName, - cloneAllSnapshots, vmName, path, harddrivePath, ram, switchName) + cloneAllSnapshots, vmName, path, harddrivePath, ram, switchName, copyTF) } func (d *HypervPS4Driver) DeleteVirtualMachine(vmName string) error { diff --git a/builder/hyperv/common/step_clone_vm.go b/builder/hyperv/common/step_clone_vm.go index f245cb4aa..09e063db3 100644 --- a/builder/hyperv/common/step_clone_vm.go +++ b/builder/hyperv/common/step_clone_vm.go @@ -22,6 +22,7 @@ type StepCloneVM struct { CloneAllSnapshots bool VMName string SwitchName string + CompareCopy bool RamSize uint Cpu uint EnableMacSpoofing bool @@ -55,8 +56,9 @@ func (s *StepCloneVM) Run(_ context.Context, state multistep.StateBag) multistep // convert the MB to bytes ramSize := int64(s.RamSize * 1024 * 1024) - err := driver.CloneVirtualMachine(s.CloneFromVMCXPath, s.CloneFromVMName, s.CloneFromSnapshotName, - s.CloneAllSnapshots, s.VMName, path, harddrivePath, ramSize, s.SwitchName) + err := driver.CloneVirtualMachine(s.CloneFromVMCXPath, s.CloneFromVMName, + s.CloneFromSnapshotName, s.CloneAllSnapshots, s.VMName, path, + harddrivePath, ramSize, s.SwitchName, s.CompareCopy) if err != nil { err := fmt.Errorf("Error cloning virtual machine: %s", err) state.Put("error", err) diff --git a/builder/hyperv/vmcx/builder.go b/builder/hyperv/vmcx/builder.go index 1178061d3..e207c548f 100644 --- a/builder/hyperv/vmcx/builder.go +++ b/builder/hyperv/vmcx/builder.go @@ -81,6 +81,7 @@ type Config struct { DifferencingDisk bool `mapstructure:"differencing_disk"` SwitchName string `mapstructure:"switch_name"` + CompareCopy bool `mapstructure:"copy_in_compare"` SwitchVlanId string `mapstructure:"switch_vlan_id"` MacAddress string `mapstructure:"mac_address"` VlanId string `mapstructure:"vlan_id"` @@ -430,6 +431,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe CloneAllSnapshots: b.config.CloneAllSnapshots, VMName: b.config.VMName, SwitchName: b.config.SwitchName, + CompareCopy: b.config.CompareCopy, RamSize: b.config.RamSize, Cpu: b.config.Cpu, EnableMacSpoofing: b.config.EnableMacSpoofing, diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index 816dad9ca..89489f8d9 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -366,10 +366,10 @@ Hyper-V\Set-VMNetworkAdapter $vmName -staticmacaddress $mac } func ImportVmcxVirtualMachine(importPath string, vmName string, harddrivePath string, - ram int64, switchName string) error { + ram int64, switchName string, copyTF bool) error { var script = ` -param([string]$importPath, [string]$vmName, [string]$harddrivePath, [long]$memoryStartupBytes, [string]$switchName) +param([string]$importPath, [string]$vmName, [string]$harddrivePath, [long]$memoryStartupBytes, [string]$switchName, [string]$copy) $VirtualHarddisksPath = Join-Path -Path $importPath -ChildPath 'Virtual Hard Disks' if (!(Test-Path $VirtualHarddisksPath)) { @@ -395,7 +395,13 @@ if (!$VirtualMachinePath){ $VirtualMachinePath = Get-ChildItem -Path $importPath -Filter *.xml -Recurse -ErrorAction SilentlyContinue | select -First 1 | %{$_.FullName} } -$compatibilityReport = Hyper-V\Compare-VM -Path $VirtualMachinePath -VirtualMachinePath $importPath -SmartPagingFilePath $importPath -SnapshotFilePath $importPath -VhdDestinationPath $VirtualHarddisksPath -GenerateNewId +$copyBool = $false +switch($copy) { + "true" { $copyBool = $true } + default { $copyBool = $false } +} + +$compatibilityReport = Hyper-V\Compare-VM -Path $VirtualMachinePath -VirtualMachinePath $importPath -SmartPagingFilePath $importPath -SnapshotFilePath $importPath -VhdDestinationPath $VirtualHarddisksPath -GenerateNewId -Copy:$false if ($vhdPath){ Copy-Item -Path $harddrivePath -Destination $vhdPath $existingFirstHarddrive = $compatibilityReport.VM.HardDrives | Select -First 1 @@ -415,16 +421,15 @@ if ($vm) { $result = Hyper-V\Rename-VM -VM $vm -NewName $VMName } ` - var ps powershell.PowerShellCmd - err := ps.Run(script, importPath, vmName, harddrivePath, strconv.FormatInt(ram, 10), switchName) + err := ps.Run(script, importPath, vmName, harddrivePath, strconv.FormatInt(ram, 10), switchName, strconv.FormatBool(copyTF)) return err } func CloneVirtualMachine(cloneFromVmcxPath string, cloneFromVmName string, cloneFromSnapshotName string, cloneAllSnapshots bool, vmName string, - path string, harddrivePath string, ram int64, switchName string) error { + path string, harddrivePath string, ram int64, switchName string, copyTF bool) error { if cloneFromVmName != "" { if err := ExportVmcxVirtualMachine(path, cloneFromVmName, @@ -439,7 +444,7 @@ func CloneVirtualMachine(cloneFromVmcxPath string, cloneFromVmName string, } } - if err := ImportVmcxVirtualMachine(path, vmName, harddrivePath, ram, switchName); err != nil { + if err := ImportVmcxVirtualMachine(path, vmName, harddrivePath, ram, switchName, copyTF); err != nil { return err } diff --git a/website/source/docs/builders/hyperv-vmcx.html.md.erb b/website/source/docs/builders/hyperv-vmcx.html.md.erb index 040f86217..fc1568657 100644 --- a/website/source/docs/builders/hyperv-vmcx.html.md.erb +++ b/website/source/docs/builders/hyperv-vmcx.html.md.erb @@ -116,6 +116,15 @@ builder. This setting only has an effect if using `clone_from_vm_name` and is ignored otherwise. +- `copy_in_compare` - (bool) When cloning a vm to build from, we run a powershell + Compare-VM command, which, depending on your version of Windows, may need + the "Copy" flag to be set to true or false. Defaults to "false". Command: + + `$compatibilityReport = Hyper-V\Compare-VM -Path $VirtualMachinePath -VirtualMachinePath $importPath -SmartPagingFilePath $importPath -SnapshotFilePath $importPath -VhdDestinationPath $VirtualHarddisksPath -GenerateNewId -Copy:$copy` + + Where $copy is replaced with either true or false depending on the value of + "copy_in_compare". + - `cpu` (number) - The number of CPUs the virtual machine should use. If this isn't specified, the default is 1 CPU. From 954c6d2bdf4a8aaf062c797451a6b5d86ca4eae0 Mon Sep 17 00:00:00 2001 From: pgrmega Date: Thu, 13 Dec 2018 18:45:14 +0100 Subject: [PATCH 18/87] Fix previous change in patch #7030 The fix is to use -Copy option, not to delete this option which is equivalent to the original -Copy:$false --- common/powershell/hyperv/hyperv.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index 816dad9ca..b6522813f 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -395,7 +395,7 @@ if (!$VirtualMachinePath){ $VirtualMachinePath = Get-ChildItem -Path $importPath -Filter *.xml -Recurse -ErrorAction SilentlyContinue | select -First 1 | %{$_.FullName} } -$compatibilityReport = Hyper-V\Compare-VM -Path $VirtualMachinePath -VirtualMachinePath $importPath -SmartPagingFilePath $importPath -SnapshotFilePath $importPath -VhdDestinationPath $VirtualHarddisksPath -GenerateNewId +$compatibilityReport = Hyper-V\Compare-VM -Path $VirtualMachinePath -VirtualMachinePath $importPath -SmartPagingFilePath $importPath -SnapshotFilePath $importPath -VhdDestinationPath $VirtualHarddisksPath -GenerateNewId -Copy if ($vhdPath){ Copy-Item -Path $harddrivePath -Destination $vhdPath $existingFirstHarddrive = $compatibilityReport.VM.HardDrives | Select -First 1 From 7d5ea43f411911a002549a013d5626fc477b92b1 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 13 Dec 2018 09:58:24 -0800 Subject: [PATCH 19/87] revert the hddorder being added to the vmx template, since it's breaking things for some of our users. --- builder/vmware/iso/step_create_vmx.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/builder/vmware/iso/step_create_vmx.go b/builder/vmware/iso/step_create_vmx.go index 5a46c14ef..2a7f64c45 100644 --- a/builder/vmware/iso/step_create_vmx.go +++ b/builder/vmware/iso/step_create_vmx.go @@ -24,8 +24,6 @@ type vmxTemplateData struct { CpuCount string MemorySize string - HDD_BootOrder string - SCSI_Present string SCSI_diskAdapterType string SATA_Present string @@ -166,7 +164,6 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist NVME_Present: "FALSE", DiskType: "scsi", - HDD_BootOrder: "scsi0:0", CDROMType: "ide", CDROMType_PrimarySecondary: "0", @@ -189,20 +186,17 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist templateData.DiskType = "ide" templateData.CDROMType = "ide" templateData.CDROMType_PrimarySecondary = "1" - templateData.HDD_BootOrder = "ide0:0" case "sata": templateData.SATA_Present = "TRUE" templateData.DiskType = "sata" templateData.CDROMType = "sata" templateData.CDROMType_PrimarySecondary = "1" - templateData.HDD_BootOrder = "sata0:0" case "nvme": templateData.NVME_Present = "TRUE" templateData.DiskType = "nvme" templateData.SATA_Present = "TRUE" templateData.CDROMType = "sata" templateData.CDROMType_PrimarySecondary = "0" - templateData.HDD_BootOrder = "nvme0:0" case "scsi": diskAdapterType = "lsilogic" fallthrough @@ -212,7 +206,6 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist templateData.DiskType = "scsi" templateData.CDROMType = "ide" templateData.CDROMType_PrimarySecondary = "0" - templateData.HDD_BootOrder = "scsi0:0" } /// Handle the cdrom adapter type. If the disk adapter type and the @@ -476,7 +469,6 @@ nvram = "{{ .Name }}.nvram" floppy0.present = "FALSE" bios.bootOrder = "hdd,cdrom" -bios.hddOrder = "{{ .HDD_BootOrder }}" // Configuration extendedConfigFile = "{{ .Name }}.vmxf" From 6e09f1623f36ba15f3842692ef86ed8502b4a231 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 13 Dec 2018 11:34:37 -0800 Subject: [PATCH 20/87] Revert "Fix previous change introduced in patch #7030" --- common/powershell/hyperv/hyperv.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index b6522813f..816dad9ca 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -395,7 +395,7 @@ if (!$VirtualMachinePath){ $VirtualMachinePath = Get-ChildItem -Path $importPath -Filter *.xml -Recurse -ErrorAction SilentlyContinue | select -First 1 | %{$_.FullName} } -$compatibilityReport = Hyper-V\Compare-VM -Path $VirtualMachinePath -VirtualMachinePath $importPath -SmartPagingFilePath $importPath -SnapshotFilePath $importPath -VhdDestinationPath $VirtualHarddisksPath -GenerateNewId -Copy +$compatibilityReport = Hyper-V\Compare-VM -Path $VirtualMachinePath -VirtualMachinePath $importPath -SmartPagingFilePath $importPath -SnapshotFilePath $importPath -VhdDestinationPath $VirtualHarddisksPath -GenerateNewId if ($vhdPath){ Copy-Item -Path $harddrivePath -Destination $vhdPath $existingFirstHarddrive = $compatibilityReport.VM.HardDrives | Select -First 1 From f9230aeb959c846fb16a2966ce9202b1767b5063 Mon Sep 17 00:00:00 2001 From: Christopher Boumenot Date: Thu, 13 Dec 2018 13:54:19 -0800 Subject: [PATCH 21/87] azure: fix snapshot regression --- builder/azure/arm/builder.go | 8 +-- builder/azure/arm/config.go | 4 +- builder/azure/arm/config_test.go | 2 - builder/azure/arm/step_snapshot_data_disks.go | 60 ++++++++++--------- .../arm/step_snapshot_data_disks_test.go | 28 +++++++-- builder/azure/arm/step_snapshot_os_disk.go | 51 ++++++++-------- .../azure/arm/step_snapshot_os_disk_test.go | 28 +++++++-- 7 files changed, 109 insertions(+), 72 deletions(-) diff --git a/builder/azure/arm/builder.go b/builder/azure/arm/builder.go index e278052f6..1dfd66fa5 100644 --- a/builder/azure/arm/builder.go +++ b/builder/azure/arm/builder.go @@ -183,8 +183,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe NewStepGetOSDisk(azureClient, ui), NewStepGetAdditionalDisks(azureClient, ui), NewStepPowerOffCompute(azureClient, ui), - NewStepSnapshotOSDisk(azureClient, ui, b.config.isManagedImage()), - NewStepSnapshotDataDisks(azureClient, ui, b.config.isManagedImage()), + NewStepSnapshotOSDisk(azureClient, ui, b.config), + NewStepSnapshotDataDisks(azureClient, ui, b.config), NewStepCaptureImage(azureClient, ui), NewStepDeleteResourceGroup(azureClient, ui), NewStepDeleteOSDisk(azureClient, ui), @@ -220,8 +220,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &packerCommon.StepProvision{}, NewStepGetOSDisk(azureClient, ui), NewStepGetAdditionalDisks(azureClient, ui), - NewStepSnapshotOSDisk(azureClient, ui, b.config.isManagedImage()), - NewStepSnapshotDataDisks(azureClient, ui, b.config.isManagedImage()), + NewStepSnapshotOSDisk(azureClient, ui, b.config), + NewStepSnapshotDataDisks(azureClient, ui, b.config), NewStepPowerOffCompute(azureClient, ui), NewStepCaptureImage(azureClient, ui), NewStepDeleteResourceGroup(azureClient, ui), diff --git a/builder/azure/arm/config.go b/builder/azure/arm/config.go index 70246b319..35f79e6f8 100644 --- a/builder/azure/arm/config.go +++ b/builder/azure/arm/config.go @@ -56,8 +56,8 @@ var ( reCaptureNamePrefix = regexp.MustCompile("^[A-Za-z0-9][A-Za-z0-9_\\-\\.]{0,23}$") reManagedDiskName = regexp.MustCompile(validManagedDiskName) reResourceGroupName = regexp.MustCompile(validResourceGroupNameRe) - reSnapshotName = regexp.MustCompile("^[A-Za-z0-9_]{10,79}$") - reSnapshotPrefix = regexp.MustCompile("^[A-Za-z0-9_]{10,59}$") + reSnapshotName = regexp.MustCompile("^[A-Za-z0-9_]{1,79}$") + reSnapshotPrefix = regexp.MustCompile("^[A-Za-z0-9_]{1,59}$") ) type PlanInformation struct { diff --git a/builder/azure/arm/config_test.go b/builder/azure/arm/config_test.go index 4b3a7796c..e5b7e6ece 100644 --- a/builder/azure/arm/config_test.go +++ b/builder/azure/arm/config_test.go @@ -669,7 +669,6 @@ func TestConfigShouldRejectMalformedManagedImageOSDiskSnapshotName(t *testing.T) } malformedManagedImageOSDiskSnapshotName := []string{ - "min_ten", "-leading-hyphen", "trailing-hyphen-", "trailing-period.", @@ -720,7 +719,6 @@ func TestConfigShouldRejectMalformedManagedImageDataDiskSnapshotPrefix(t *testin } malformedManagedImageDataDiskSnapshotPrefix := []string{ - "more_ten", "-leading-hyphen", "trailing-hyphen-", "trailing-period.", diff --git a/builder/azure/arm/step_snapshot_data_disks.go b/builder/azure/arm/step_snapshot_data_disks.go index baf56b443..f0f476d5e 100644 --- a/builder/azure/arm/step_snapshot_data_disks.go +++ b/builder/azure/arm/step_snapshot_data_disks.go @@ -13,19 +13,19 @@ import ( ) type StepSnapshotDataDisks struct { - client *AzureClient - create func(ctx context.Context, resourceGroupName string, srcUriVhd string, location string, tags map[string]*string, dstSnapshotName string) error - say func(message string) - error func(e error) - isManagedImage bool + client *AzureClient + create func(ctx context.Context, resourceGroupName string, srcUriVhd string, location string, tags map[string]*string, dstSnapshotName string) error + say func(message string) + error func(e error) + enable func() bool } -func NewStepSnapshotDataDisks(client *AzureClient, ui packer.Ui, isManagedImage bool) *StepSnapshotDataDisks { +func NewStepSnapshotDataDisks(client *AzureClient, ui packer.Ui, config *Config) *StepSnapshotDataDisks { var step = &StepSnapshotDataDisks{ - client: client, - say: func(message string) { ui.Say(message) }, - error: func(e error) { ui.Error(e.Error()) }, - isManagedImage: isManagedImage, + client: client, + say: func(message string) { ui.Say(message) }, + error: func(e error) { ui.Error(e.Error()) }, + enable: func() bool { return config.isManagedImage() && config.ManagedImageDataDiskSnapshotPrefix != "" }, } step.create = step.createDataDiskSnapshot @@ -66,32 +66,38 @@ func (s *StepSnapshotDataDisks) createDataDiskSnapshot(ctx context.Context, reso return err } - s.say(fmt.Sprintf(" -> Managed Image Data Disk Snapshot : '%s'", *(createdSnapshot.ID))) - + s.say(fmt.Sprintf(" -> Snapshot ID : '%s'", *(createdSnapshot.ID))) return nil } func (s *StepSnapshotDataDisks) Run(ctx context.Context, stateBag multistep.StateBag) multistep.StepAction { - if s.isManagedImage { + if !s.enable() { + return multistep.ActionContinue + } - s.say("Taking snapshot of data disk ...") + var resourceGroupName = stateBag.Get(constants.ArmManagedImageResourceGroupName).(string) + var location = stateBag.Get(constants.ArmLocation).(string) + var tags = stateBag.Get(constants.ArmTags).(map[string]*string) + var additionalDisks = stateBag.Get(constants.ArmAdditionalDiskVhds).([]string) + var dstSnapshotPrefix = stateBag.Get(constants.ArmManagedImageDataDiskSnapshotPrefix).(string) - var resourceGroupName = stateBag.Get(constants.ArmManagedImageResourceGroupName).(string) - var location = stateBag.Get(constants.ArmLocation).(string) - var tags = stateBag.Get(constants.ArmTags).(map[string]*string) - var additionalDisks = stateBag.Get(constants.ArmAdditionalDiskVhds).([]string) - var dstSnapshotPrefix = stateBag.Get(constants.ArmManagedImageDataDiskSnapshotPrefix).(string) + if len(additionalDisks) == 1 { + s.say(fmt.Sprintf("Snapshotting data disk ...")) + } else { + s.say(fmt.Sprintf("Snapshotting data disks ...")) + } - for i, disk := range additionalDisks { - dstSnapshotName := dstSnapshotPrefix + strconv.Itoa(i) - err := s.create(ctx, resourceGroupName, disk, location, tags, dstSnapshotName) + for i, disk := range additionalDisks { + s.say(fmt.Sprintf(" -> Data Disk : '%s'", disk)) - if err != nil { - stateBag.Put(constants.Error, err) - s.error(err) + dstSnapshotName := dstSnapshotPrefix + strconv.Itoa(i) + err := s.create(ctx, resourceGroupName, disk, location, tags, dstSnapshotName) - return multistep.ActionHalt - } + if err != nil { + stateBag.Put(constants.Error, err) + s.error(err) + + return multistep.ActionHalt } } diff --git a/builder/azure/arm/step_snapshot_data_disks_test.go b/builder/azure/arm/step_snapshot_data_disks_test.go index e7203aade..66eb2115e 100644 --- a/builder/azure/arm/step_snapshot_data_disks_test.go +++ b/builder/azure/arm/step_snapshot_data_disks_test.go @@ -13,9 +13,9 @@ func TestStepSnapshotDataDisksShouldFailIfSnapshotFails(t *testing.T) { create: func(context.Context, string, string, string, map[string]*string, string) error { return fmt.Errorf("!! Unit Test FAIL !!") }, - say: func(message string) {}, - error: func(e error) {}, - isManagedImage: true, + say: func(message string) {}, + error: func(e error) {}, + enable: func() bool { return true }, } stateBag := createTestStateBagStepSnapshotDataDisks() @@ -30,14 +30,30 @@ func TestStepSnapshotDataDisksShouldFailIfSnapshotFails(t *testing.T) { } } +func TestStepSnapshotDataDisksShouldNotExecute(t *testing.T) { + var testSubject = &StepSnapshotDataDisks{ + create: func(context.Context, string, string, string, map[string]*string, string) error { + return fmt.Errorf("!! Unit Test FAIL !!") + }, + say: func(message string) {}, + error: func(e error) {}, + enable: func() bool { return false }, + } + + var result = testSubject.Run(context.Background(), nil) + if result != multistep.ActionContinue { + t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) + } +} + func TestStepSnapshotDataDisksShouldPassIfSnapshotPasses(t *testing.T) { var testSubject = &StepSnapshotDataDisks{ create: func(context.Context, string, string, string, map[string]*string, string) error { return nil }, - say: func(message string) {}, - error: func(e error) {}, - isManagedImage: true, + say: func(message string) {}, + error: func(e error) {}, + enable: func() bool { return true }, } stateBag := createTestStateBagStepSnapshotDataDisks() diff --git a/builder/azure/arm/step_snapshot_os_disk.go b/builder/azure/arm/step_snapshot_os_disk.go index 7f349c07e..001bb5a45 100644 --- a/builder/azure/arm/step_snapshot_os_disk.go +++ b/builder/azure/arm/step_snapshot_os_disk.go @@ -11,19 +11,19 @@ import ( ) type StepSnapshotOSDisk struct { - client *AzureClient - create func(ctx context.Context, resourceGroupName string, srcUriVhd string, location string, tags map[string]*string, dstSnapshotName string) error - say func(message string) - error func(e error) - isManagedImage bool + client *AzureClient + create func(ctx context.Context, resourceGroupName string, srcUriVhd string, location string, tags map[string]*string, dstSnapshotName string) error + say func(message string) + error func(e error) + enable func() bool } -func NewStepSnapshotOSDisk(client *AzureClient, ui packer.Ui, isManagedImage bool) *StepSnapshotOSDisk { +func NewStepSnapshotOSDisk(client *AzureClient, ui packer.Ui, config *Config) *StepSnapshotOSDisk { var step = &StepSnapshotOSDisk{ - client: client, - say: func(message string) { ui.Say(message) }, - error: func(e error) { ui.Error(e.Error()) }, - isManagedImage: isManagedImage, + client: client, + say: func(message string) { ui.Say(message) }, + error: func(e error) { ui.Error(e.Error()) }, + enable: func() bool { return config.isManagedImage() && config.ManagedImageOSDiskSnapshotName != "" }, } step.create = step.createSnapshot @@ -64,30 +64,31 @@ func (s *StepSnapshotOSDisk) createSnapshot(ctx context.Context, resourceGroupNa return err } - s.say(fmt.Sprintf(" -> Managed Image OS Disk Snapshot : '%s'", *(createdSnapshot.ID))) - + s.say(fmt.Sprintf(" -> Snapshot ID : '%s'", *(createdSnapshot.ID))) return nil } func (s *StepSnapshotOSDisk) Run(ctx context.Context, stateBag multistep.StateBag) multistep.StepAction { - if s.isManagedImage { + if !s.enable() { + return multistep.ActionContinue + } - s.say("Taking snapshot of OS disk ...") + s.say("Snapshotting OS disk ...") - var resourceGroupName = stateBag.Get(constants.ArmManagedImageResourceGroupName).(string) - var location = stateBag.Get(constants.ArmLocation).(string) - var tags = stateBag.Get(constants.ArmTags).(map[string]*string) - var srcUriVhd = stateBag.Get(constants.ArmOSDiskVhd).(string) - var dstSnapshotName = stateBag.Get(constants.ArmManagedImageOSDiskSnapshotName).(string) + var resourceGroupName = stateBag.Get(constants.ArmManagedImageResourceGroupName).(string) + var location = stateBag.Get(constants.ArmLocation).(string) + var tags = stateBag.Get(constants.ArmTags).(map[string]*string) + var srcUriVhd = stateBag.Get(constants.ArmOSDiskVhd).(string) + var dstSnapshotName = stateBag.Get(constants.ArmManagedImageOSDiskSnapshotName).(string) - err := s.create(ctx, resourceGroupName, srcUriVhd, location, tags, dstSnapshotName) + s.say(fmt.Sprintf(" -> OS Disk : '%s'", srcUriVhd)) + err := s.create(ctx, resourceGroupName, srcUriVhd, location, tags, dstSnapshotName) - if err != nil { - stateBag.Put(constants.Error, err) - s.error(err) + if err != nil { + stateBag.Put(constants.Error, err) + s.error(err) - return multistep.ActionHalt - } + return multistep.ActionHalt } return multistep.ActionContinue diff --git a/builder/azure/arm/step_snapshot_os_disk_test.go b/builder/azure/arm/step_snapshot_os_disk_test.go index b7342319b..48d2211d1 100644 --- a/builder/azure/arm/step_snapshot_os_disk_test.go +++ b/builder/azure/arm/step_snapshot_os_disk_test.go @@ -13,9 +13,9 @@ func TestStepSnapshotOSDiskShouldFailIfSnapshotFails(t *testing.T) { create: func(context.Context, string, string, string, map[string]*string, string) error { return fmt.Errorf("!! Unit Test FAIL !!") }, - say: func(message string) {}, - error: func(e error) {}, - isManagedImage: true, + say: func(message string) {}, + error: func(e error) {}, + enable: func() bool { return true }, } stateBag := createTestStateBagStepSnapshotOSDisk() @@ -30,14 +30,30 @@ func TestStepSnapshotOSDiskShouldFailIfSnapshotFails(t *testing.T) { } } +func TestStepSnapshotOSDiskShouldNotExecute(t *testing.T) { + var testSubject = &StepSnapshotOSDisk{ + create: func(context.Context, string, string, string, map[string]*string, string) error { + return fmt.Errorf("!! Unit Test FAIL !!") + }, + say: func(message string) {}, + error: func(e error) {}, + enable: func() bool { return false }, + } + + var result = testSubject.Run(context.Background(), nil) + if result != multistep.ActionContinue { + t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) + } +} + func TestStepSnapshotOSDiskShouldPassIfSnapshotPasses(t *testing.T) { var testSubject = &StepSnapshotOSDisk{ create: func(context.Context, string, string, string, map[string]*string, string) error { return nil }, - say: func(message string) {}, - error: func(e error) {}, - isManagedImage: true, + say: func(message string) {}, + error: func(e error) {}, + enable: func() bool { return true }, } stateBag := createTestStateBagStepSnapshotOSDisk() From 0821653256697896ce642033f356286aae5ca544 Mon Sep 17 00:00:00 2001 From: DanHam Date: Fri, 14 Dec 2018 12:46:38 +0000 Subject: [PATCH 22/87] Fix 'nil' dir in VMware artifact when building locally --- builder/vmware/common/artifact.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/vmware/common/artifact.go b/builder/vmware/common/artifact.go index c9fa075d2..e9b02237e 100644 --- a/builder/vmware/common/artifact.go +++ b/builder/vmware/common/artifact.go @@ -62,10 +62,10 @@ func NewArtifact(remoteType string, format string, exportOutputPath string, vmNa if remoteType != "" && !skipExport { dir = new(LocalOutputDir) dir.SetOutputDir(exportOutputPath) - files, err = dir.ListFiles() } else { - files, err = state.Get("dir").(OutputDir).ListFiles() + dir = state.Get("dir").(OutputDir) } + files, err = dir.ListFiles() if err != nil { return nil, err } From 01cdd18fd3ff3e19d81ca807e56a40ad806a27d1 Mon Sep 17 00:00:00 2001 From: mr-karan Date: Fri, 14 Dec 2018 19:07:54 +0530 Subject: [PATCH 23/87] feat(provisioner/ansible): Provide extra SSH args Adds `-o IdentitiesOnly=yes` as a default flag to extra vargs in Ansible provisoner. Closes https://github.com/hashicorp/packer/issues/5329 --- provisioner/ansible-local/provisioner.go | 2 +- provisioner/ansible/provisioner.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/provisioner/ansible-local/provisioner.go b/provisioner/ansible-local/provisioner.go index bd4559388..48c4680ef 100644 --- a/provisioner/ansible-local/provisioner.go +++ b/provisioner/ansible-local/provisioner.go @@ -376,7 +376,7 @@ func (p *Provisioner) executeGalaxy(ui packer.Ui, comm packer.Communicator) erro func (p *Provisioner) executeAnsible(ui packer.Ui, comm packer.Communicator) error { inventory := filepath.ToSlash(filepath.Join(p.config.StagingDir, filepath.Base(p.config.InventoryFile))) - extraArgs := fmt.Sprintf(" --extra-vars \"packer_build_name=%s packer_builder_type=%s packer_http_addr=%s\" ", + extraArgs := fmt.Sprintf(" --extra-vars \"packer_build_name=%s packer_builder_type=%s packer_http_addr=%s -o IdentitiesOnly=yes\" ", p.config.PackerBuildName, p.config.PackerBuilderType, common.GetHTTPAddr()) if len(p.config.ExtraArguments) > 0 { extraArgs = extraArgs + strings.Join(p.config.ExtraArguments, " ") diff --git a/provisioner/ansible/provisioner.go b/provisioner/ansible/provisioner.go index ee92b1161..5b6ea9510 100644 --- a/provisioner/ansible/provisioner.go +++ b/provisioner/ansible/provisioner.go @@ -354,7 +354,7 @@ func (p *Provisioner) executeAnsible(ui packer.Ui, comm packer.Communicator, pri var envvars []string - args := []string{"--extra-vars", fmt.Sprintf("packer_build_name=%s packer_builder_type=%s", + args := []string{"--extra-vars", fmt.Sprintf("packer_build_name=%s packer_builder_type=%s -o IdentitiesOnly=yes", p.config.PackerBuildName, p.config.PackerBuilderType), "-i", inventory, playbook} if len(privKeyFile) > 0 { From 8184fcb99a76716d3dc7be2d22e622217857a40b Mon Sep 17 00:00:00 2001 From: wizurijyq <44195247+wizurijyq@users.noreply.github.com> Date: Fri, 14 Dec 2018 22:30:26 +0100 Subject: [PATCH 24/87] Make sure sshkey is not nil --- builder/hcloud/step_create_server.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/builder/hcloud/step_create_server.go b/builder/hcloud/step_create_server.go index 89c80d88f..ffaa6a60e 100644 --- a/builder/hcloud/step_create_server.go +++ b/builder/hcloud/step_create_server.go @@ -43,6 +43,10 @@ func (s *stepCreateServer) Run(ctx context.Context, state multistep.StateBag) mu state.Put("error", fmt.Errorf("Error fetching SSH key: %s", err)) return multistep.ActionHalt } + if sshKey == nil { + state.Put("error", fmt.Errorf("Could not find key: %s", k)) + return multistep.ActionHalt + } sshKeys = append(sshKeys, sshKey) } From 52176ecf2da3f52162d928357b65bff8091f1261 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Fri, 14 Dec 2018 13:53:39 -0800 Subject: [PATCH 25/87] try to remove race condition in mux test --- packer/rpc/mux_broker_test.go | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/packer/rpc/mux_broker_test.go b/packer/rpc/mux_broker_test.go index 88739a0ff..53f398e53 100644 --- a/packer/rpc/mux_broker_test.go +++ b/packer/rpc/mux_broker_test.go @@ -17,15 +17,20 @@ func TestMuxBroker(t *testing.T) { go bc.Run() go bs.Run() + errChan := make(chan error, 1) go func() { c, err := bc.Dial(5) if err != nil { - t.Fatalf("err: %s", err) + errChan <- fmt.Errorf("err dialing: %s", err) + close(errChan) + return } if _, err := c.Write([]byte{42}); err != nil { - t.Fatalf("err: %s", err) + errChan <- fmt.Errorf("err writing: %s", err) } + + close(errChan) }() client, err := bs.Accept(5) @@ -41,6 +46,15 @@ func TestMuxBroker(t *testing.T) { if data[0] != 42 { t.Fatalf("bad: %d", data[0]) } + + for { + err, open := <-errChan + if !open { + if err != nil { + t.Fatalf(err) + } + } + } } func testYamux(t *testing.T) (client *yamux.Session, server *yamux.Session) { From f6070de070a07b46e066ff8f3d327ea8e004edb5 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Fri, 14 Dec 2018 13:59:26 -0800 Subject: [PATCH 26/87] fix test --- packer/rpc/mux_broker_test.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packer/rpc/mux_broker_test.go b/packer/rpc/mux_broker_test.go index 53f398e53..8f8a993b9 100644 --- a/packer/rpc/mux_broker_test.go +++ b/packer/rpc/mux_broker_test.go @@ -1,6 +1,7 @@ package rpc import ( + "fmt" "net" "testing" @@ -21,13 +22,13 @@ func TestMuxBroker(t *testing.T) { go func() { c, err := bc.Dial(5) if err != nil { - errChan <- fmt.Errorf("err dialing: %s", err) + errChan <- fmt.Errorf("err dialing: %s", err.Error()) close(errChan) return } if _, err := c.Write([]byte{42}); err != nil { - errChan <- fmt.Errorf("err writing: %s", err) + errChan <- fmt.Errorf("err writing: %s", err.Error()) } close(errChan) @@ -51,8 +52,9 @@ func TestMuxBroker(t *testing.T) { err, open := <-errChan if !open { if err != nil { - t.Fatalf(err) + t.Fatalf(err.Error()) } + break } } } From d75a5809521878e5a765ebea144d1d0fa7324f2c Mon Sep 17 00:00:00 2001 From: DanHam Date: Sat, 15 Dec 2018 11:14:01 +0000 Subject: [PATCH 27/87] Fix link --- .github/CONTRIBUTING.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index da9e2501b..87a822e91 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -107,7 +107,9 @@ From there, open your fork in your browser to open a new pull-request. will break if you `git clone` your fork instead of using `go get` on the main Packer project. -**Note:** See [Working on forks](#Working on forks) for a better way to use `git push ...`. +**Note:** See '[Working with +forks](https://help.github.com/articles/working-with-forks/)' for a better way +to use `git push ...`. ### Pull Request Lifecycle From 9a31d0de5895fd5a9b12e06cbe6f3b4d4b5dd026 Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Mon, 17 Dec 2018 10:58:32 +0100 Subject: [PATCH 28/87] mux_broker_test.go: defer close chan --- packer/rpc/mux_broker_test.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packer/rpc/mux_broker_test.go b/packer/rpc/mux_broker_test.go index 8f8a993b9..9d6aeee75 100644 --- a/packer/rpc/mux_broker_test.go +++ b/packer/rpc/mux_broker_test.go @@ -20,18 +20,16 @@ func TestMuxBroker(t *testing.T) { errChan := make(chan error, 1) go func() { + defer close(errChan) c, err := bc.Dial(5) if err != nil { errChan <- fmt.Errorf("err dialing: %s", err.Error()) - close(errChan) return } if _, err := c.Write([]byte{42}); err != nil { errChan <- fmt.Errorf("err writing: %s", err.Error()) } - - close(errChan) }() client, err := bs.Accept(5) From 2944030daf4d52284ab66d1084b07683aa42d885 Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Mon, 17 Dec 2018 11:01:46 +0100 Subject: [PATCH 29/87] mux_broker_test.go: range over chan for simplicity --- packer/rpc/mux_broker_test.go | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/packer/rpc/mux_broker_test.go b/packer/rpc/mux_broker_test.go index 9d6aeee75..fe0a6118a 100644 --- a/packer/rpc/mux_broker_test.go +++ b/packer/rpc/mux_broker_test.go @@ -46,13 +46,9 @@ func TestMuxBroker(t *testing.T) { t.Fatalf("bad: %d", data[0]) } - for { - err, open := <-errChan - if !open { - if err != nil { - t.Fatalf(err.Error()) - } - break + for err := range errChan { + if err != nil { + t.Fatalf(err.Error()) } } } From d9e32d437cfff8764ac0b9682d1fe3796e57be06 Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Mon, 17 Dec 2018 11:09:56 +0100 Subject: [PATCH 30/87] mux_broker_test.go: make non blocking errChan * in case of Dial errors to avoid a deadlocks --- packer/rpc/mux_broker_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packer/rpc/mux_broker_test.go b/packer/rpc/mux_broker_test.go index fe0a6118a..ac5d9cbd2 100644 --- a/packer/rpc/mux_broker_test.go +++ b/packer/rpc/mux_broker_test.go @@ -18,7 +18,7 @@ func TestMuxBroker(t *testing.T) { go bc.Run() go bs.Run() - errChan := make(chan error, 1) + errChan := make(chan error, 2) go func() { defer close(errChan) c, err := bc.Dial(5) From 06152d2c83b3695894a9e36bf5ef4c51cb9d4f4a Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Mon, 17 Dec 2018 12:36:15 +0100 Subject: [PATCH 31/87] Update CHANGELOG.md --- CHANGELOG.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a8f517f6..9a7754798 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,28 @@ +## 1.3.4 (upcoming) +### IMPROVEMENTS: +* builder/alicloud: delete copied image and snapshots if corresponding options + are specified [GH-7050] +* builder/amazon: allow to interpolate more variables [GH-7059] +* builder/amazon: Check that the KMS key ID is valid [GH-7090] +* builder/amazon: Clean up logging for aws waiters so that it only runs once + per builder [GH-7080] +* builder/amazon: don't Cleanup Temp Keys when there is no communicator to + avoid a panic [GH-7100] [GH-7095] +* builder/azure: allow to configure disk caching [GH-7061] +* core/shell: Add env vars "PACKER_HTTP_IP" and "PACKER_HTTP_PORT" to shell + provisioners [GH-7075] +* core: Deprecate mitchellh/go-homedir package in favor of os/user [GH-7062] +* core: make packer inspect not print sensitive variables [GH-7084] +* provisioner/ansible-remote: add `-o IdentitiesOnly=yes`as a default flag + [GH-7115] +* provisioner/windows-restart: wait for already-scheduled reboot [GH-7056] and + ignore reboot specific errors [GH-7071] + +### BUG FIXES: +* builder/hcloud: fix go mod dependency [GH-7099] +* builder/hcloud: prevent panic when ssh key was not passed [GH-7118] +* core: removed a flaky race condition in tests [GH-7119] + ## 1.3.3 (December 5, 2018) ### IMPROVEMENTS: * builder/alicloud: Add options for system disk properties [GH-6939] From 7857a0d4045b7a4809a1a4191f2ab6eb718a7c54 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Mon, 17 Dec 2018 11:40:27 -0800 Subject: [PATCH 32/87] clarify use of split function in docs --- website/source/docs/templates/engine.html.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/website/source/docs/templates/engine.html.md b/website/source/docs/templates/engine.html.md index e1b59cdff..aae419098 100644 --- a/website/source/docs/templates/engine.html.md +++ b/website/source/docs/templates/engine.html.md @@ -272,6 +272,11 @@ builder in this example. The function `split` takes an input string, a seperator string, and a numeric component value and returns the requested substring. +Please note that you cannot use the `split` function on user variables, +because we can't nest the functions currently. This function is indended to +be used on builder variables like build_name. If you need a split user +variable, the best way to do it is to create a separate variable. + Here are some examples using the above options: ``` liquid @@ -292,7 +297,7 @@ this case, on the `fixed-string` value): "type": "vagrant", "compression_level": 9, "keep_input_artifact": false, - "vagrantfile_template": "tpl/{{split build_name \"-\" 1}.rb", + "vagrantfile_template": "tpl/{{split build_name \"-\" 1}}.rb", "output": "output/{{build_name}}.box", "only": [ "org-name-provider" From a734aa22555db94178d33a1d624c3a808b0cdd00 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Mon, 17 Dec 2018 13:49:47 -0800 Subject: [PATCH 33/87] Revert "mux_broker_test.go: make non blocking errChan" This reverts commit d9e32d437cfff8764ac0b9682d1fe3796e57be06. It turns out that it was already non-blocking with a length of one. --- packer/rpc/mux_broker_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packer/rpc/mux_broker_test.go b/packer/rpc/mux_broker_test.go index ac5d9cbd2..fe0a6118a 100644 --- a/packer/rpc/mux_broker_test.go +++ b/packer/rpc/mux_broker_test.go @@ -18,7 +18,7 @@ func TestMuxBroker(t *testing.T) { go bc.Run() go bs.Run() - errChan := make(chan error, 2) + errChan := make(chan error, 1) go func() { defer close(errChan) c, err := bc.Dial(5) From 19144111dd263c9686dab6088c0d23b6e3fd33c7 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Mon, 17 Dec 2018 14:54:27 -0800 Subject: [PATCH 34/87] fix packer crash that occurs when image is nil --- builder/oracle/oci/builder.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/builder/oracle/oci/builder.go b/builder/oracle/oci/builder.go index e3989a23a..5bfc392d8 100644 --- a/builder/oracle/oci/builder.go +++ b/builder/oracle/oci/builder.go @@ -89,9 +89,14 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe return nil, err } + image, ok := state.GetOk("image") + if !ok { + return nil, err + } + // Build the artifact and return it artifact := &Artifact{ - Image: state.Get("image").(core.Image), + Image: image.(core.Image), Region: region, driver: driver, } From 050f809a1cedb6bf7decb9ba739973be09866466 Mon Sep 17 00:00:00 2001 From: Ladar Levison Date: Mon, 17 Dec 2018 22:04:43 -0600 Subject: [PATCH 35/87] Add changes var to docker driver import func. --- builder/docker/driver_docker.go | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/builder/docker/driver_docker.go b/builder/docker/driver_docker.go index 50a2b9920..c052131f8 100644 --- a/builder/docker/driver_docker.go +++ b/builder/docker/driver_docker.go @@ -97,16 +97,26 @@ func (d *DockerDriver) Export(id string, dst io.Writer) error { return nil } -func (d *DockerDriver) Import(path string, repo string) (string, error) { +func (d *DockerDriver) Import(path string, changes []string, repo string) (string, error) { var stdout, stderr bytes.Buffer - cmd := exec.Command("docker", "import", "-", repo) cmd.Stdout = &stdout cmd.Stderr = &stderr stdin, err := cmd.StdinPipe() - if err != nil { + + if err != nil { return "", err } + args := []string{"import"} + + for _, change := range changes { + args = append(args, "--change", change) + } + + args = append(args, "-") + args = append(args, repo) + cmd := exec.Command("docker", args...) + // There should be only one artifact of the Docker builder file, err := os.Open(path) if err != nil { @@ -114,6 +124,8 @@ func (d *DockerDriver) Import(path string, repo string) (string, error) { } defer file.Close() + log.Printf("Importing container with args: %v", args) + if err := cmd.Start(); err != nil { return "", err } From 21fdbadf043769d1ffa421db04dd3b2a2d7eb3e6 Mon Sep 17 00:00:00 2001 From: Ladar Levison Date: Mon, 17 Dec 2018 22:13:40 -0600 Subject: [PATCH 36/87] Adding changes to import prototype. --- builder/docker/driver.go | 2 +- builder/docker/driver_mock.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/docker/driver.go b/builder/docker/driver.go index 09da054f3..7359a667d 100644 --- a/builder/docker/driver.go +++ b/builder/docker/driver.go @@ -20,7 +20,7 @@ type Driver interface { Export(id string, dst io.Writer) error // Import imports a container from a tar file - Import(path, repo string) (string, error) + Import(path string, changes []string, repo string) (string, error) // IPAddress returns the address of the container that can be used // for external access. diff --git a/builder/docker/driver_mock.go b/builder/docker/driver_mock.go index 5193f21ee..4cca3325b 100644 --- a/builder/docker/driver_mock.go +++ b/builder/docker/driver_mock.go @@ -101,7 +101,7 @@ func (d *MockDriver) Export(id string, dst io.Writer) error { return d.ExportError } -func (d *MockDriver) Import(path, repo string) (string, error) { +func (d *MockDriver) Import(path string, changes []string, repo string) (string, error) { d.ImportCalled = true d.ImportPath = path d.ImportRepo = repo From 10095678c8b82b6fe172ee1f3e2a6c6b0ebf0d58 Mon Sep 17 00:00:00 2001 From: Ladar Levison Date: Mon, 17 Dec 2018 22:37:32 -0600 Subject: [PATCH 37/87] Adding driver changes. --- builder/docker/driver_docker.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/builder/docker/driver_docker.go b/builder/docker/driver_docker.go index c052131f8..59fb8f9c3 100644 --- a/builder/docker/driver_docker.go +++ b/builder/docker/driver_docker.go @@ -103,19 +103,19 @@ func (d *DockerDriver) Import(path string, changes []string, repo string) (strin cmd.Stderr = &stderr stdin, err := cmd.StdinPipe() - if err != nil { + if err != nil { return "", err } args := []string{"import"} - for _, change := range changes { - args = append(args, "--change", change) - } + for _, change := range changes { + args = append(args, "--change", change) + } - args = append(args, "-") + args = append(args, "-") args = append(args, repo) - cmd := exec.Command("docker", args...) + cmd := exec.Command("docker", args...) // There should be only one artifact of the Docker builder file, err := os.Open(path) @@ -124,8 +124,8 @@ func (d *DockerDriver) Import(path string, changes []string, repo string) (strin } defer file.Close() - log.Printf("Importing container with args: %v", args) - + log.Printf("Importing container with args: %v", args) + if err := cmd.Start(); err != nil { return "", err } From 6ac597128828ecde1e59cd66980378649bbfb799 Mon Sep 17 00:00:00 2001 From: Ladar Levison Date: Mon, 17 Dec 2018 22:59:41 -0600 Subject: [PATCH 38/87] Fixed cmd order for docker driver. Added config to post proc. --- builder/docker/driver_docker.go | 17 +++++++++-------- post-processor/docker-import/post-processor.go | 3 ++- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/builder/docker/driver_docker.go b/builder/docker/driver_docker.go index 59fb8f9c3..918dfdb2c 100644 --- a/builder/docker/driver_docker.go +++ b/builder/docker/driver_docker.go @@ -99,13 +99,6 @@ func (d *DockerDriver) Export(id string, dst io.Writer) error { func (d *DockerDriver) Import(path string, changes []string, repo string) (string, error) { var stdout, stderr bytes.Buffer - cmd.Stdout = &stdout - cmd.Stderr = &stderr - stdin, err := cmd.StdinPipe() - - if err != nil { - return "", err - } args := []string{"import"} @@ -115,7 +108,15 @@ func (d *DockerDriver) Import(path string, changes []string, repo string) (strin args = append(args, "-") args = append(args, repo) + cmd := exec.Command("docker", args...) + cmd.Stdout = &stdout + cmd.Stderr = &stderr + stdin, err := cmd.StdinPipe() + + if err != nil { + return "", err + } // There should be only one artifact of the Docker builder file, err := os.Open(path) @@ -124,7 +125,7 @@ func (d *DockerDriver) Import(path string, changes []string, repo string) (strin } defer file.Close() - log.Printf("Importing container with args: %v", args) + log.Printf("Importing tarball with args: %v", args) if err := cmd.Start(); err != nil { return "", err diff --git a/post-processor/docker-import/post-processor.go b/post-processor/docker-import/post-processor.go index 80b99c8b3..c3488b22a 100644 --- a/post-processor/docker-import/post-processor.go +++ b/post-processor/docker-import/post-processor.go @@ -18,6 +18,7 @@ type Config struct { Repository string `mapstructure:"repository"` Tag string `mapstructure:"tag"` + Changes []string ctx interpolate.Context } @@ -62,7 +63,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac ui.Message("Importing image: " + artifact.Id()) ui.Message("Repository: " + importRepo) - id, err := driver.Import(artifact.Files()[0], importRepo) + id, err := driver.Import(artifact.Files()[0], p.config.Changes, importRepo) if err != nil { return nil, false, err } From 3cc83167c8c077b2e3e64ec21ca42af214314139 Mon Sep 17 00:00:00 2001 From: Ladar Levison Date: Tue, 18 Dec 2018 00:48:58 -0600 Subject: [PATCH 39/87] Added map structure type to config changes. --- post-processor/docker-import/post-processor.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/post-processor/docker-import/post-processor.go b/post-processor/docker-import/post-processor.go index c3488b22a..eac920f06 100644 --- a/post-processor/docker-import/post-processor.go +++ b/post-processor/docker-import/post-processor.go @@ -16,9 +16,9 @@ const BuilderId = "packer.post-processor.docker-import" type Config struct { common.PackerConfig `mapstructure:",squash"` - Repository string `mapstructure:"repository"` - Tag string `mapstructure:"tag"` - Changes []string + Repository string `mapstructure:"repository"` + Tag string `mapstructure:"tag"` + Changes []string `mapstructure:"changes"` ctx interpolate.Context } From 6d10badc70579f5defa94559291dc06cc7c82eb8 Mon Sep 17 00:00:00 2001 From: Ladar Levison Date: Tue, 18 Dec 2018 02:00:21 -0600 Subject: [PATCH 40/87] Adding documentation for import changes. --- command/plugin.go | 186 +++++++++--------- common/bootcommand/boot_command.go | 11 -- .../post-processors/docker-import.html.md | 74 +++++++ 3 files changed, 169 insertions(+), 102 deletions(-) diff --git a/command/plugin.go b/command/plugin.go index d0cd68153..1a87c35f3 100644 --- a/command/plugin.go +++ b/command/plugin.go @@ -14,22 +14,41 @@ import ( "github.com/hashicorp/packer/packer/plugin" alicloudecsbuilder "github.com/hashicorp/packer/builder/alicloud/ecs" + alicloudimportpostprocessor "github.com/hashicorp/packer/post-processor/alicloud-import" amazonchrootbuilder "github.com/hashicorp/packer/builder/amazon/chroot" amazonebsbuilder "github.com/hashicorp/packer/builder/amazon/ebs" amazonebssurrogatebuilder "github.com/hashicorp/packer/builder/amazon/ebssurrogate" amazonebsvolumebuilder "github.com/hashicorp/packer/builder/amazon/ebsvolume" + amazonimportpostprocessor "github.com/hashicorp/packer/post-processor/amazon-import" amazoninstancebuilder "github.com/hashicorp/packer/builder/amazon/instance" + ansiblelocalprovisioner "github.com/hashicorp/packer/provisioner/ansible-local" + ansibleprovisioner "github.com/hashicorp/packer/provisioner/ansible" + artificepostprocessor "github.com/hashicorp/packer/post-processor/artifice" azurearmbuilder "github.com/hashicorp/packer/builder/azure/arm" + breakpointprovisioner "github.com/hashicorp/packer/provisioner/breakpoint" + checksumpostprocessor "github.com/hashicorp/packer/post-processor/checksum" + chefclientprovisioner "github.com/hashicorp/packer/provisioner/chef-client" + chefsoloprovisioner "github.com/hashicorp/packer/provisioner/chef-solo" cloudstackbuilder "github.com/hashicorp/packer/builder/cloudstack" + compresspostprocessor "github.com/hashicorp/packer/post-processor/compress" + convergeprovisioner "github.com/hashicorp/packer/provisioner/converge" digitaloceanbuilder "github.com/hashicorp/packer/builder/digitalocean" dockerbuilder "github.com/hashicorp/packer/builder/docker" + dockerimportpostprocessor "github.com/hashicorp/packer/post-processor/docker-import" + dockerpushpostprocessor "github.com/hashicorp/packer/post-processor/docker-push" + dockersavepostprocessor "github.com/hashicorp/packer/post-processor/docker-save" + dockertagpostprocessor "github.com/hashicorp/packer/post-processor/docker-tag" filebuilder "github.com/hashicorp/packer/builder/file" + fileprovisioner "github.com/hashicorp/packer/provisioner/file" googlecomputebuilder "github.com/hashicorp/packer/builder/googlecompute" + googlecomputeexportpostprocessor "github.com/hashicorp/packer/post-processor/googlecompute-export" + googlecomputeimportpostprocessor "github.com/hashicorp/packer/post-processor/googlecompute-import" hcloudbuilder "github.com/hashicorp/packer/builder/hcloud" hypervisobuilder "github.com/hashicorp/packer/builder/hyperv/iso" hypervvmcxbuilder "github.com/hashicorp/packer/builder/hyperv/vmcx" lxcbuilder "github.com/hashicorp/packer/builder/lxc" lxdbuilder "github.com/hashicorp/packer/builder/lxd" + manifestpostprocessor "github.com/hashicorp/packer/post-processor/manifest" ncloudbuilder "github.com/hashicorp/packer/builder/ncloud" nullbuilder "github.com/hashicorp/packer/builder/null" oneandonebuilder "github.com/hashicorp/packer/builder/oneandone" @@ -38,46 +57,28 @@ import ( oracleocibuilder "github.com/hashicorp/packer/builder/oracle/oci" parallelsisobuilder "github.com/hashicorp/packer/builder/parallels/iso" parallelspvmbuilder "github.com/hashicorp/packer/builder/parallels/pvm" + powershellprovisioner "github.com/hashicorp/packer/provisioner/powershell" profitbricksbuilder "github.com/hashicorp/packer/builder/profitbricks" + puppetmasterlessprovisioner "github.com/hashicorp/packer/provisioner/puppet-masterless" + puppetserverprovisioner "github.com/hashicorp/packer/provisioner/puppet-server" qemubuilder "github.com/hashicorp/packer/builder/qemu" + saltmasterlessprovisioner "github.com/hashicorp/packer/provisioner/salt-masterless" scalewaybuilder "github.com/hashicorp/packer/builder/scaleway" + shelllocalpostprocessor "github.com/hashicorp/packer/post-processor/shell-local" + shelllocalprovisioner "github.com/hashicorp/packer/provisioner/shell-local" + shellprovisioner "github.com/hashicorp/packer/provisioner/shell" tritonbuilder "github.com/hashicorp/packer/builder/triton" + vagrantcloudpostprocessor "github.com/hashicorp/packer/post-processor/vagrant-cloud" + vagrantpostprocessor "github.com/hashicorp/packer/post-processor/vagrant" virtualboxisobuilder "github.com/hashicorp/packer/builder/virtualbox/iso" virtualboxovfbuilder "github.com/hashicorp/packer/builder/virtualbox/ovf" vmwareisobuilder "github.com/hashicorp/packer/builder/vmware/iso" vmwarevmxbuilder "github.com/hashicorp/packer/builder/vmware/vmx" - alicloudimportpostprocessor "github.com/hashicorp/packer/post-processor/alicloud-import" - amazonimportpostprocessor "github.com/hashicorp/packer/post-processor/amazon-import" - artificepostprocessor "github.com/hashicorp/packer/post-processor/artifice" - checksumpostprocessor "github.com/hashicorp/packer/post-processor/checksum" - compresspostprocessor "github.com/hashicorp/packer/post-processor/compress" - dockerimportpostprocessor "github.com/hashicorp/packer/post-processor/docker-import" - dockerpushpostprocessor "github.com/hashicorp/packer/post-processor/docker-push" - 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" - vagrantcloudpostprocessor "github.com/hashicorp/packer/post-processor/vagrant-cloud" vspherepostprocessor "github.com/hashicorp/packer/post-processor/vsphere" vspheretemplatepostprocessor "github.com/hashicorp/packer/post-processor/vsphere-template" - ansibleprovisioner "github.com/hashicorp/packer/provisioner/ansible" - ansiblelocalprovisioner "github.com/hashicorp/packer/provisioner/ansible-local" - breakpointprovisioner "github.com/hashicorp/packer/provisioner/breakpoint" - chefclientprovisioner "github.com/hashicorp/packer/provisioner/chef-client" - chefsoloprovisioner "github.com/hashicorp/packer/provisioner/chef-solo" - convergeprovisioner "github.com/hashicorp/packer/provisioner/converge" - fileprovisioner "github.com/hashicorp/packer/provisioner/file" - powershellprovisioner "github.com/hashicorp/packer/provisioner/powershell" - puppetmasterlessprovisioner "github.com/hashicorp/packer/provisioner/puppet-masterless" - puppetserverprovisioner "github.com/hashicorp/packer/provisioner/puppet-server" - saltmasterlessprovisioner "github.com/hashicorp/packer/provisioner/salt-masterless" - shellprovisioner "github.com/hashicorp/packer/provisioner/shell" - shelllocalprovisioner "github.com/hashicorp/packer/provisioner/shell-local" windowsrestartprovisioner "github.com/hashicorp/packer/provisioner/windows-restart" windowsshellprovisioner "github.com/hashicorp/packer/provisioner/windows-shell" + ) type PluginCommand struct { @@ -85,79 +86,82 @@ type PluginCommand struct { } var Builders = map[string]packer.Builder{ - "alicloud-ecs": new(alicloudecsbuilder.Builder), - "amazon-chroot": new(amazonchrootbuilder.Builder), - "amazon-ebs": new(amazonebsbuilder.Builder), - "amazon-ebssurrogate": new(amazonebssurrogatebuilder.Builder), - "amazon-ebsvolume": new(amazonebsvolumebuilder.Builder), - "amazon-instance": new(amazoninstancebuilder.Builder), - "azure-arm": new(azurearmbuilder.Builder), - "cloudstack": new(cloudstackbuilder.Builder), - "digitalocean": new(digitaloceanbuilder.Builder), - "docker": new(dockerbuilder.Builder), - "file": new(filebuilder.Builder), - "googlecompute": new(googlecomputebuilder.Builder), - "hcloud": new(hcloudbuilder.Builder), - "hyperv-iso": new(hypervisobuilder.Builder), - "hyperv-vmcx": new(hypervvmcxbuilder.Builder), - "lxc": new(lxcbuilder.Builder), - "lxd": new(lxdbuilder.Builder), - "ncloud": new(ncloudbuilder.Builder), - "null": new(nullbuilder.Builder), - "oneandone": new(oneandonebuilder.Builder), - "openstack": new(openstackbuilder.Builder), - "oracle-classic": new(oracleclassicbuilder.Builder), - "oracle-oci": new(oracleocibuilder.Builder), - "parallels-iso": new(parallelsisobuilder.Builder), - "parallels-pvm": new(parallelspvmbuilder.Builder), - "profitbricks": new(profitbricksbuilder.Builder), - "qemu": new(qemubuilder.Builder), - "scaleway": new(scalewaybuilder.Builder), - "triton": new(tritonbuilder.Builder), - "virtualbox-iso": new(virtualboxisobuilder.Builder), - "virtualbox-ovf": new(virtualboxovfbuilder.Builder), - "vmware-iso": new(vmwareisobuilder.Builder), - "vmware-vmx": new(vmwarevmxbuilder.Builder), + "alicloud-ecs": new(alicloudecsbuilder.Builder), + "amazon-chroot": new(amazonchrootbuilder.Builder), + "amazon-ebs": new(amazonebsbuilder.Builder), + "amazon-ebssurrogate": new(amazonebssurrogatebuilder.Builder), + "amazon-ebsvolume": new(amazonebsvolumebuilder.Builder), + "amazon-instance": new(amazoninstancebuilder.Builder), + "azure-arm": new(azurearmbuilder.Builder), + "cloudstack": new(cloudstackbuilder.Builder), + "digitalocean": new(digitaloceanbuilder.Builder), + "docker": new(dockerbuilder.Builder), + "file": new(filebuilder.Builder), + "googlecompute": new(googlecomputebuilder.Builder), + "hcloud": new(hcloudbuilder.Builder), + "hyperv-iso": new(hypervisobuilder.Builder), + "hyperv-vmcx": new(hypervvmcxbuilder.Builder), + "lxc": new(lxcbuilder.Builder), + "lxd": new(lxdbuilder.Builder), + "ncloud": new(ncloudbuilder.Builder), + "null": new(nullbuilder.Builder), + "oneandone": new(oneandonebuilder.Builder), + "openstack": new(openstackbuilder.Builder), + "oracle-classic": new(oracleclassicbuilder.Builder), + "oracle-oci": new(oracleocibuilder.Builder), + "parallels-iso": new(parallelsisobuilder.Builder), + "parallels-pvm": new(parallelspvmbuilder.Builder), + "profitbricks": new(profitbricksbuilder.Builder), + "qemu": new(qemubuilder.Builder), + "scaleway": new(scalewaybuilder.Builder), + "triton": new(tritonbuilder.Builder), + "virtualbox-iso": new(virtualboxisobuilder.Builder), + "virtualbox-ovf": new(virtualboxovfbuilder.Builder), + "vmware-iso": new(vmwareisobuilder.Builder), + "vmware-vmx": new(vmwarevmxbuilder.Builder), } + var Provisioners = map[string]packer.Provisioner{ - "ansible": new(ansibleprovisioner.Provisioner), - "ansible-local": new(ansiblelocalprovisioner.Provisioner), - "breakpoint": new(breakpointprovisioner.Provisioner), - "chef-client": new(chefclientprovisioner.Provisioner), - "chef-solo": new(chefsoloprovisioner.Provisioner), - "converge": new(convergeprovisioner.Provisioner), - "file": new(fileprovisioner.Provisioner), - "powershell": new(powershellprovisioner.Provisioner), - "puppet-masterless": new(puppetmasterlessprovisioner.Provisioner), - "puppet-server": new(puppetserverprovisioner.Provisioner), + "ansible": new(ansibleprovisioner.Provisioner), + "ansible-local": new(ansiblelocalprovisioner.Provisioner), + "breakpoint": new(breakpointprovisioner.Provisioner), + "chef-client": new(chefclientprovisioner.Provisioner), + "chef-solo": new(chefsoloprovisioner.Provisioner), + "converge": new(convergeprovisioner.Provisioner), + "file": new(fileprovisioner.Provisioner), + "powershell": new(powershellprovisioner.Provisioner), + "puppet-masterless": new(puppetmasterlessprovisioner.Provisioner), + "puppet-server": new(puppetserverprovisioner.Provisioner), "salt-masterless": new(saltmasterlessprovisioner.Provisioner), - "shell": new(shellprovisioner.Provisioner), - "shell-local": new(shelllocalprovisioner.Provisioner), + "shell": new(shellprovisioner.Provisioner), + "shell-local": new(shelllocalprovisioner.Provisioner), "windows-restart": new(windowsrestartprovisioner.Provisioner), - "windows-shell": new(windowsshellprovisioner.Provisioner), + "windows-shell": new(windowsshellprovisioner.Provisioner), } + var PostProcessors = map[string]packer.PostProcessor{ - "alicloud-import": new(alicloudimportpostprocessor.PostProcessor), - "amazon-import": new(amazonimportpostprocessor.PostProcessor), - "artifice": new(artificepostprocessor.PostProcessor), - "checksum": new(checksumpostprocessor.PostProcessor), - "compress": new(compresspostprocessor.PostProcessor), - "docker-import": new(dockerimportpostprocessor.PostProcessor), - "docker-push": new(dockerpushpostprocessor.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), - "vagrant-cloud": new(vagrantcloudpostprocessor.PostProcessor), - "vsphere": new(vspherepostprocessor.PostProcessor), - "vsphere-template": new(vspheretemplatepostprocessor.PostProcessor), + "alicloud-import": new(alicloudimportpostprocessor.PostProcessor), + "amazon-import": new(amazonimportpostprocessor.PostProcessor), + "artifice": new(artificepostprocessor.PostProcessor), + "checksum": new(checksumpostprocessor.PostProcessor), + "compress": new(compresspostprocessor.PostProcessor), + "docker-import": new(dockerimportpostprocessor.PostProcessor), + "docker-push": new(dockerpushpostprocessor.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), + "vagrant-cloud": new(vagrantcloudpostprocessor.PostProcessor), + "vsphere": new(vspherepostprocessor.PostProcessor), + "vsphere-template": new(vspheretemplatepostprocessor.PostProcessor), } + var pluginRegexp = regexp.MustCompile("packer-(builder|post-processor|provisioner)-(.+)") func (c *PluginCommand) Run(args []string) int { diff --git a/common/bootcommand/boot_command.go b/common/bootcommand/boot_command.go index 95133f334..1447a4337 100644 --- a/common/bootcommand/boot_command.go +++ b/common/bootcommand/boot_command.go @@ -1190,7 +1190,6 @@ func newParser(filename string, b []byte, opts ...Option) *parser { Stats: &stats, // start rule is rule [0] unless an alternate entrypoint is specified entrypoint: g.rules[0].name, - emptyState: make(storeDict), } p.setOptions(opts) @@ -1279,9 +1278,6 @@ type parser struct { choiceNoMatch string // recovery expression stack, keeps track of the currently available recovery expression, these are traversed in reverse recoveryStack []map[string]interface{} - - // emptyState contains an empty storeDict, which is used to optimize cloneState if global "state" store is not used. - emptyState storeDict } // push a variable set on the vstack. @@ -1455,13 +1451,6 @@ func (p *parser) cloneState() storeDict { defer p.out(p.in("cloneState")) } - if len(p.cur.state) == 0 { - if len(p.emptyState) > 0 { - p.emptyState = make(storeDict) - } - return p.emptyState - } - state := make(storeDict, len(p.cur.state)) for k, v := range p.cur.state { if c, ok := v.(Cloner); ok { diff --git a/website/source/docs/post-processors/docker-import.html.md b/website/source/docs/post-processors/docker-import.html.md index 00add79e6..1d3e413d7 100644 --- a/website/source/docs/post-processors/docker-import.html.md +++ b/website/source/docs/post-processors/docker-import.html.md @@ -25,11 +25,20 @@ registry. The configuration for this post-processor only requires a `repository`, a `tag` is optional. +### Required: + - `repository` (string) - The repository of the imported image. - `tag` (string) - The tag for the imported image. By default this is not set. +### Optional: + +- `changes` (array of strings) - Dockerfile instructions to add to the + commit. Example of instructions are `CMD`, `ENTRYPOINT`, `ENV`, and + `EXPOSE`. Example: `[ "USER ubuntu", "WORKDIR /app", "EXPOSE 8080" ]` + + ## Example An example is shown below, showing only the post-processor configuration: @@ -48,3 +57,68 @@ into the local Docker process with a name of `hashicorp/packer:0.7`. Following this, you can use the [docker-push](/docs/post-processors/docker-push.html) post-processor to push it to a registry, if you want. + +## Changing Metadata + +Below is an example using the changes argument of the post-processor. This +feature allows the tarball metadata to be changed when imported into the +Docker environment. It is derived from the `docker import --change` command +line [option to +Docker](https://docs.docker.com/engine/reference/commandline/import/). + +Example uses of all of the options, assuming one is building an NGINX image +from ubuntu as an simple example: + +``` json +{ + "type": "docker-import", + "repository": "local/centos6", + "tag": "latest", + "changes": [ + "USER www-data", + "WORKDIR /var/www", + "ENV HOSTNAME www.example.com", + "VOLUME /test1 /test2", + "EXPOSE 80 443", + "LABEL version=1.0", + "ONBUILD RUN date", + "CMD [\"nginx\", \"-g\", \"daemon off;\"]", + "ENTRYPOINT /var/www/start.sh" + ] +} +``` + +Allowed metadata fields that can be changed are: + +- CMD + - String, supports both array (escaped) and string form + - EX: `"CMD [\"nginx\", \"-g\", \"daemon off;\"]"` + - EX: `"CMD nginx -g daemon off;"` +- ENTRYPOINT + - String + - EX: `"ENTRYPOINT /var/www/start.sh"` +- ENV + - String, note there is no equal sign: + - EX: `"ENV HOSTNAME www.example.com"` not + `"ENV HOSTNAME=www.example.com"` +- EXPOSE + - String, space separated ports + - EX: `"EXPOSE 80 443"` +- LABEL + - String, space separated key=value pairs + - EX: `"LABEL version=1.0"` +- ONBUILD + - String + - EX: `"ONBUILD RUN date"` +- MAINTAINER + - String, deprecated in Docker version 1.13.0 + - EX: `"MAINTAINER NAME"` +- USER + - String + - EX: `"USER USERNAME"` +- VOLUME + - String + - EX: `"VOLUME FROM TO"` +- WORKDIR + - String + - EX: `"WORKDIR PATH"` From 0f8f58371e9c26cc2d057a0e2907a0297ad8db2f Mon Sep 17 00:00:00 2001 From: Ladar Levison Date: Tue, 18 Dec 2018 02:13:43 -0600 Subject: [PATCH 41/87] Reverting accidental changes to boot command/plugin go files. --- command/plugin.go | 186 ++++++++++++++--------------- common/bootcommand/boot_command.go | 11 ++ 2 files changed, 102 insertions(+), 95 deletions(-) diff --git a/command/plugin.go b/command/plugin.go index 1a87c35f3..d0cd68153 100644 --- a/command/plugin.go +++ b/command/plugin.go @@ -14,41 +14,22 @@ import ( "github.com/hashicorp/packer/packer/plugin" alicloudecsbuilder "github.com/hashicorp/packer/builder/alicloud/ecs" - alicloudimportpostprocessor "github.com/hashicorp/packer/post-processor/alicloud-import" amazonchrootbuilder "github.com/hashicorp/packer/builder/amazon/chroot" amazonebsbuilder "github.com/hashicorp/packer/builder/amazon/ebs" amazonebssurrogatebuilder "github.com/hashicorp/packer/builder/amazon/ebssurrogate" amazonebsvolumebuilder "github.com/hashicorp/packer/builder/amazon/ebsvolume" - amazonimportpostprocessor "github.com/hashicorp/packer/post-processor/amazon-import" amazoninstancebuilder "github.com/hashicorp/packer/builder/amazon/instance" - ansiblelocalprovisioner "github.com/hashicorp/packer/provisioner/ansible-local" - ansibleprovisioner "github.com/hashicorp/packer/provisioner/ansible" - artificepostprocessor "github.com/hashicorp/packer/post-processor/artifice" azurearmbuilder "github.com/hashicorp/packer/builder/azure/arm" - breakpointprovisioner "github.com/hashicorp/packer/provisioner/breakpoint" - checksumpostprocessor "github.com/hashicorp/packer/post-processor/checksum" - chefclientprovisioner "github.com/hashicorp/packer/provisioner/chef-client" - chefsoloprovisioner "github.com/hashicorp/packer/provisioner/chef-solo" cloudstackbuilder "github.com/hashicorp/packer/builder/cloudstack" - compresspostprocessor "github.com/hashicorp/packer/post-processor/compress" - convergeprovisioner "github.com/hashicorp/packer/provisioner/converge" digitaloceanbuilder "github.com/hashicorp/packer/builder/digitalocean" dockerbuilder "github.com/hashicorp/packer/builder/docker" - dockerimportpostprocessor "github.com/hashicorp/packer/post-processor/docker-import" - dockerpushpostprocessor "github.com/hashicorp/packer/post-processor/docker-push" - dockersavepostprocessor "github.com/hashicorp/packer/post-processor/docker-save" - dockertagpostprocessor "github.com/hashicorp/packer/post-processor/docker-tag" filebuilder "github.com/hashicorp/packer/builder/file" - fileprovisioner "github.com/hashicorp/packer/provisioner/file" googlecomputebuilder "github.com/hashicorp/packer/builder/googlecompute" - googlecomputeexportpostprocessor "github.com/hashicorp/packer/post-processor/googlecompute-export" - googlecomputeimportpostprocessor "github.com/hashicorp/packer/post-processor/googlecompute-import" hcloudbuilder "github.com/hashicorp/packer/builder/hcloud" hypervisobuilder "github.com/hashicorp/packer/builder/hyperv/iso" hypervvmcxbuilder "github.com/hashicorp/packer/builder/hyperv/vmcx" lxcbuilder "github.com/hashicorp/packer/builder/lxc" lxdbuilder "github.com/hashicorp/packer/builder/lxd" - manifestpostprocessor "github.com/hashicorp/packer/post-processor/manifest" ncloudbuilder "github.com/hashicorp/packer/builder/ncloud" nullbuilder "github.com/hashicorp/packer/builder/null" oneandonebuilder "github.com/hashicorp/packer/builder/oneandone" @@ -57,28 +38,46 @@ import ( oracleocibuilder "github.com/hashicorp/packer/builder/oracle/oci" parallelsisobuilder "github.com/hashicorp/packer/builder/parallels/iso" parallelspvmbuilder "github.com/hashicorp/packer/builder/parallels/pvm" - powershellprovisioner "github.com/hashicorp/packer/provisioner/powershell" profitbricksbuilder "github.com/hashicorp/packer/builder/profitbricks" - puppetmasterlessprovisioner "github.com/hashicorp/packer/provisioner/puppet-masterless" - puppetserverprovisioner "github.com/hashicorp/packer/provisioner/puppet-server" qemubuilder "github.com/hashicorp/packer/builder/qemu" - saltmasterlessprovisioner "github.com/hashicorp/packer/provisioner/salt-masterless" scalewaybuilder "github.com/hashicorp/packer/builder/scaleway" - shelllocalpostprocessor "github.com/hashicorp/packer/post-processor/shell-local" - shelllocalprovisioner "github.com/hashicorp/packer/provisioner/shell-local" - shellprovisioner "github.com/hashicorp/packer/provisioner/shell" tritonbuilder "github.com/hashicorp/packer/builder/triton" - vagrantcloudpostprocessor "github.com/hashicorp/packer/post-processor/vagrant-cloud" - vagrantpostprocessor "github.com/hashicorp/packer/post-processor/vagrant" virtualboxisobuilder "github.com/hashicorp/packer/builder/virtualbox/iso" virtualboxovfbuilder "github.com/hashicorp/packer/builder/virtualbox/ovf" vmwareisobuilder "github.com/hashicorp/packer/builder/vmware/iso" vmwarevmxbuilder "github.com/hashicorp/packer/builder/vmware/vmx" + alicloudimportpostprocessor "github.com/hashicorp/packer/post-processor/alicloud-import" + amazonimportpostprocessor "github.com/hashicorp/packer/post-processor/amazon-import" + artificepostprocessor "github.com/hashicorp/packer/post-processor/artifice" + checksumpostprocessor "github.com/hashicorp/packer/post-processor/checksum" + compresspostprocessor "github.com/hashicorp/packer/post-processor/compress" + dockerimportpostprocessor "github.com/hashicorp/packer/post-processor/docker-import" + dockerpushpostprocessor "github.com/hashicorp/packer/post-processor/docker-push" + 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" + vagrantcloudpostprocessor "github.com/hashicorp/packer/post-processor/vagrant-cloud" vspherepostprocessor "github.com/hashicorp/packer/post-processor/vsphere" vspheretemplatepostprocessor "github.com/hashicorp/packer/post-processor/vsphere-template" + ansibleprovisioner "github.com/hashicorp/packer/provisioner/ansible" + ansiblelocalprovisioner "github.com/hashicorp/packer/provisioner/ansible-local" + breakpointprovisioner "github.com/hashicorp/packer/provisioner/breakpoint" + chefclientprovisioner "github.com/hashicorp/packer/provisioner/chef-client" + chefsoloprovisioner "github.com/hashicorp/packer/provisioner/chef-solo" + convergeprovisioner "github.com/hashicorp/packer/provisioner/converge" + fileprovisioner "github.com/hashicorp/packer/provisioner/file" + powershellprovisioner "github.com/hashicorp/packer/provisioner/powershell" + puppetmasterlessprovisioner "github.com/hashicorp/packer/provisioner/puppet-masterless" + puppetserverprovisioner "github.com/hashicorp/packer/provisioner/puppet-server" + saltmasterlessprovisioner "github.com/hashicorp/packer/provisioner/salt-masterless" + shellprovisioner "github.com/hashicorp/packer/provisioner/shell" + shelllocalprovisioner "github.com/hashicorp/packer/provisioner/shell-local" windowsrestartprovisioner "github.com/hashicorp/packer/provisioner/windows-restart" windowsshellprovisioner "github.com/hashicorp/packer/provisioner/windows-shell" - ) type PluginCommand struct { @@ -86,82 +85,79 @@ type PluginCommand struct { } var Builders = map[string]packer.Builder{ - "alicloud-ecs": new(alicloudecsbuilder.Builder), - "amazon-chroot": new(amazonchrootbuilder.Builder), - "amazon-ebs": new(amazonebsbuilder.Builder), - "amazon-ebssurrogate": new(amazonebssurrogatebuilder.Builder), - "amazon-ebsvolume": new(amazonebsvolumebuilder.Builder), - "amazon-instance": new(amazoninstancebuilder.Builder), - "azure-arm": new(azurearmbuilder.Builder), - "cloudstack": new(cloudstackbuilder.Builder), - "digitalocean": new(digitaloceanbuilder.Builder), - "docker": new(dockerbuilder.Builder), - "file": new(filebuilder.Builder), - "googlecompute": new(googlecomputebuilder.Builder), - "hcloud": new(hcloudbuilder.Builder), - "hyperv-iso": new(hypervisobuilder.Builder), - "hyperv-vmcx": new(hypervvmcxbuilder.Builder), - "lxc": new(lxcbuilder.Builder), - "lxd": new(lxdbuilder.Builder), - "ncloud": new(ncloudbuilder.Builder), - "null": new(nullbuilder.Builder), - "oneandone": new(oneandonebuilder.Builder), - "openstack": new(openstackbuilder.Builder), - "oracle-classic": new(oracleclassicbuilder.Builder), - "oracle-oci": new(oracleocibuilder.Builder), - "parallels-iso": new(parallelsisobuilder.Builder), - "parallels-pvm": new(parallelspvmbuilder.Builder), - "profitbricks": new(profitbricksbuilder.Builder), - "qemu": new(qemubuilder.Builder), - "scaleway": new(scalewaybuilder.Builder), - "triton": new(tritonbuilder.Builder), - "virtualbox-iso": new(virtualboxisobuilder.Builder), - "virtualbox-ovf": new(virtualboxovfbuilder.Builder), - "vmware-iso": new(vmwareisobuilder.Builder), - "vmware-vmx": new(vmwarevmxbuilder.Builder), + "alicloud-ecs": new(alicloudecsbuilder.Builder), + "amazon-chroot": new(amazonchrootbuilder.Builder), + "amazon-ebs": new(amazonebsbuilder.Builder), + "amazon-ebssurrogate": new(amazonebssurrogatebuilder.Builder), + "amazon-ebsvolume": new(amazonebsvolumebuilder.Builder), + "amazon-instance": new(amazoninstancebuilder.Builder), + "azure-arm": new(azurearmbuilder.Builder), + "cloudstack": new(cloudstackbuilder.Builder), + "digitalocean": new(digitaloceanbuilder.Builder), + "docker": new(dockerbuilder.Builder), + "file": new(filebuilder.Builder), + "googlecompute": new(googlecomputebuilder.Builder), + "hcloud": new(hcloudbuilder.Builder), + "hyperv-iso": new(hypervisobuilder.Builder), + "hyperv-vmcx": new(hypervvmcxbuilder.Builder), + "lxc": new(lxcbuilder.Builder), + "lxd": new(lxdbuilder.Builder), + "ncloud": new(ncloudbuilder.Builder), + "null": new(nullbuilder.Builder), + "oneandone": new(oneandonebuilder.Builder), + "openstack": new(openstackbuilder.Builder), + "oracle-classic": new(oracleclassicbuilder.Builder), + "oracle-oci": new(oracleocibuilder.Builder), + "parallels-iso": new(parallelsisobuilder.Builder), + "parallels-pvm": new(parallelspvmbuilder.Builder), + "profitbricks": new(profitbricksbuilder.Builder), + "qemu": new(qemubuilder.Builder), + "scaleway": new(scalewaybuilder.Builder), + "triton": new(tritonbuilder.Builder), + "virtualbox-iso": new(virtualboxisobuilder.Builder), + "virtualbox-ovf": new(virtualboxovfbuilder.Builder), + "vmware-iso": new(vmwareisobuilder.Builder), + "vmware-vmx": new(vmwarevmxbuilder.Builder), } - var Provisioners = map[string]packer.Provisioner{ - "ansible": new(ansibleprovisioner.Provisioner), - "ansible-local": new(ansiblelocalprovisioner.Provisioner), - "breakpoint": new(breakpointprovisioner.Provisioner), - "chef-client": new(chefclientprovisioner.Provisioner), - "chef-solo": new(chefsoloprovisioner.Provisioner), - "converge": new(convergeprovisioner.Provisioner), - "file": new(fileprovisioner.Provisioner), - "powershell": new(powershellprovisioner.Provisioner), - "puppet-masterless": new(puppetmasterlessprovisioner.Provisioner), - "puppet-server": new(puppetserverprovisioner.Provisioner), + "ansible": new(ansibleprovisioner.Provisioner), + "ansible-local": new(ansiblelocalprovisioner.Provisioner), + "breakpoint": new(breakpointprovisioner.Provisioner), + "chef-client": new(chefclientprovisioner.Provisioner), + "chef-solo": new(chefsoloprovisioner.Provisioner), + "converge": new(convergeprovisioner.Provisioner), + "file": new(fileprovisioner.Provisioner), + "powershell": new(powershellprovisioner.Provisioner), + "puppet-masterless": new(puppetmasterlessprovisioner.Provisioner), + "puppet-server": new(puppetserverprovisioner.Provisioner), "salt-masterless": new(saltmasterlessprovisioner.Provisioner), - "shell": new(shellprovisioner.Provisioner), - "shell-local": new(shelllocalprovisioner.Provisioner), + "shell": new(shellprovisioner.Provisioner), + "shell-local": new(shelllocalprovisioner.Provisioner), "windows-restart": new(windowsrestartprovisioner.Provisioner), - "windows-shell": new(windowsshellprovisioner.Provisioner), + "windows-shell": new(windowsshellprovisioner.Provisioner), } - var PostProcessors = map[string]packer.PostProcessor{ - "alicloud-import": new(alicloudimportpostprocessor.PostProcessor), - "amazon-import": new(amazonimportpostprocessor.PostProcessor), - "artifice": new(artificepostprocessor.PostProcessor), - "checksum": new(checksumpostprocessor.PostProcessor), - "compress": new(compresspostprocessor.PostProcessor), - "docker-import": new(dockerimportpostprocessor.PostProcessor), - "docker-push": new(dockerpushpostprocessor.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), - "vagrant-cloud": new(vagrantcloudpostprocessor.PostProcessor), - "vsphere": new(vspherepostprocessor.PostProcessor), - "vsphere-template": new(vspheretemplatepostprocessor.PostProcessor), + "alicloud-import": new(alicloudimportpostprocessor.PostProcessor), + "amazon-import": new(amazonimportpostprocessor.PostProcessor), + "artifice": new(artificepostprocessor.PostProcessor), + "checksum": new(checksumpostprocessor.PostProcessor), + "compress": new(compresspostprocessor.PostProcessor), + "docker-import": new(dockerimportpostprocessor.PostProcessor), + "docker-push": new(dockerpushpostprocessor.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), + "vagrant-cloud": new(vagrantcloudpostprocessor.PostProcessor), + "vsphere": new(vspherepostprocessor.PostProcessor), + "vsphere-template": new(vspheretemplatepostprocessor.PostProcessor), } - var pluginRegexp = regexp.MustCompile("packer-(builder|post-processor|provisioner)-(.+)") func (c *PluginCommand) Run(args []string) int { diff --git a/common/bootcommand/boot_command.go b/common/bootcommand/boot_command.go index 1447a4337..95133f334 100644 --- a/common/bootcommand/boot_command.go +++ b/common/bootcommand/boot_command.go @@ -1190,6 +1190,7 @@ func newParser(filename string, b []byte, opts ...Option) *parser { Stats: &stats, // start rule is rule [0] unless an alternate entrypoint is specified entrypoint: g.rules[0].name, + emptyState: make(storeDict), } p.setOptions(opts) @@ -1278,6 +1279,9 @@ type parser struct { choiceNoMatch string // recovery expression stack, keeps track of the currently available recovery expression, these are traversed in reverse recoveryStack []map[string]interface{} + + // emptyState contains an empty storeDict, which is used to optimize cloneState if global "state" store is not used. + emptyState storeDict } // push a variable set on the vstack. @@ -1451,6 +1455,13 @@ func (p *parser) cloneState() storeDict { defer p.out(p.in("cloneState")) } + if len(p.cur.state) == 0 { + if len(p.emptyState) > 0 { + p.emptyState = make(storeDict) + } + return p.emptyState + } + state := make(storeDict, len(p.cur.state)) for k, v := range p.cur.state { if c, ok := v.(Cloner); ok { From 348c26705472e124a4a5c3df4801b793237ba490 Mon Sep 17 00:00:00 2001 From: Ladar Levison Date: Tue, 18 Dec 2018 04:59:00 -0600 Subject: [PATCH 42/87] Updated support for legacy network adapters on Hyper-V. --- builder/hyperv/common/driver.go | 3 ++ builder/hyperv/common/driver_ps_4.go | 5 ++++ builder/hyperv/common/step_create_vm.go | 11 +++++++ builder/hyperv/iso/builder.go | 6 ++++ builder/hyperv/iso/builder_test.go | 29 +++++++++++++++++++ common/powershell/hyperv/hyperv.go | 18 ++++++++++++ .../docs/builders/hyperv-iso.html.md.erb | 5 ++++ 7 files changed, 77 insertions(+) diff --git a/builder/hyperv/common/driver.go b/builder/hyperv/common/driver.go index 5f96398ae..e93d6a5de 100644 --- a/builder/hyperv/common/driver.go +++ b/builder/hyperv/common/driver.go @@ -58,6 +58,9 @@ type Driver interface { SetVmNetworkAdapterMacAddress(string, string) error + //Replace the network adapter with a (non-)legacy adapter + ReplaceVirtualMachineNetworkAdapter(string, bool) error + UntagVirtualMachineNetworkAdapterVlan(string, string) error CreateExternalVirtualSwitch(string, string) error diff --git a/builder/hyperv/common/driver_ps_4.go b/builder/hyperv/common/driver_ps_4.go index 0ef7accf4..38952e723 100644 --- a/builder/hyperv/common/driver_ps_4.go +++ b/builder/hyperv/common/driver_ps_4.go @@ -151,6 +151,11 @@ func (d *HypervPS4Driver) SetVmNetworkAdapterMacAddress(vmName string, mac strin return hyperv.SetVmNetworkAdapterMacAddress(vmName, mac) } +//Replace the network adapter with a (non-)legacy adapter +func (d *HypervPS4Driver) ReplaceVirtualMachineNetworkAdapter(vmName string, virtual bool) error { + return hyperv.ReplaceVirtualMachineNetworkAdapter(vmName, virtual) +} + func (d *HypervPS4Driver) UntagVirtualMachineNetworkAdapterVlan(vmName string, switchName string) error { return hyperv.UntagVirtualMachineNetworkAdapterVlan(vmName, switchName) } diff --git a/builder/hyperv/common/step_create_vm.go b/builder/hyperv/common/step_create_vm.go index b5b36ddaf..67ef7b9aa 100644 --- a/builder/hyperv/common/step_create_vm.go +++ b/builder/hyperv/common/step_create_vm.go @@ -22,6 +22,7 @@ type StepCreateVM struct { RamSize uint DiskSize uint DiskBlockSize uint + UseLegacyNetworkAdapter bool Generation uint Cpu uint EnableMacSpoofing bool @@ -72,6 +73,16 @@ func (s *StepCreateVM) Run(_ context.Context, state multistep.StateBag) multiste return multistep.ActionHalt } + if s.UseLegacyNetworkAdapter { + err := driver.ReplaceVirtualMachineNetworkAdapter(s.VMName, true) + if err != nil { + err := fmt.Errorf("Error creating legacy network adapter: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + err = driver.SetVirtualMachineCpuCount(s.VMName, s.Cpu) if err != nil { err := fmt.Errorf("Error setting virtual machine cpu count: %s", err) diff --git a/builder/hyperv/iso/builder.go b/builder/hyperv/iso/builder.go index 682e2cb30..697cc33be 100644 --- a/builder/hyperv/iso/builder.go +++ b/builder/hyperv/iso/builder.go @@ -90,6 +90,7 @@ type Config struct { Cpu uint `mapstructure:"cpu"` Generation uint `mapstructure:"generation"` EnableMacSpoofing bool `mapstructure:"enable_mac_spoofing"` + UseLegacyNetworkAdapter bool `mapstructure:"use_legacy_network_adapter"` EnableDynamicMemory bool `mapstructure:"enable_dynamic_memory"` EnableSecureBoot bool `mapstructure:"enable_secure_boot"` SecureBootTemplate string `mapstructure:"secure_boot_template"` @@ -188,6 +189,10 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { err = errors.New("Generation 2 vms don't support floppy drives. Use ISO image instead.") errs = packer.MultiErrorAppend(errs, err) } + if b.config.UseLegacyNetworkAdapter { + err = errors.New("Generation 2 vms don't support legacy network adapters.") + errs = packer.MultiErrorAppend(errs, err) + } } if len(b.config.AdditionalDiskSize) > 64 { @@ -408,6 +413,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe EnableSecureBoot: b.config.EnableSecureBoot, SecureBootTemplate: b.config.SecureBootTemplate, EnableVirtualizationExtensions: b.config.EnableVirtualizationExtensions, + UseLegacyNetworkAdapter: b.config.UseLegacyNetworkAdapter, AdditionalDiskSize: b.config.AdditionalDiskSize, DifferencingDisk: b.config.DifferencingDisk, MacAddress: b.config.MacAddress, diff --git a/builder/hyperv/iso/builder_test.go b/builder/hyperv/iso/builder_test.go index 0369c0df7..9520db8c3 100644 --- a/builder/hyperv/iso/builder_test.go +++ b/builder/hyperv/iso/builder_test.go @@ -632,3 +632,32 @@ func TestUserVariablesInBootCommand(t *testing.T) { t.Fatalf("should not have error: %#v", ret) } } + +func TestBuilderPrepare_UseLegacyNetworkAdapter(t *testing.T) { + var b Builder + config := testConfig() + + // should be allowed for default config + config["use_legacy_network_adapter"] = true + + b = Builder{} + warns, err := b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Errorf("should not have error: %s", err) + } + + // should not be allowed for gen 2 + config["generation"] = 2 + + b = Builder{} + warns, err = b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err == nil { + t.Fatal("should have error") + } +} diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index 89489f8d9..23e5f505f 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -955,6 +955,24 @@ Hyper-V\Set-VMNetworkAdapterVlan -VMName $vmName -Access -VlanId $vlanId return err } +func ReplaceVirtualMachineNetworkAdapter(vmName string, legacy bool) error { + + var script = ` +param([string]$vmName,[string]$legacyString) +$legacy = [System.Boolean]::Parse($legacyString) +$switch = (Get-VMNetworkAdapter -VMName $vmName).SwitchName +Remove-VMNetworkAdapter -VMName $vmName +Add-VMNetworkAdapter -VMName $vmName -SwitchName $switch -Name $vmName -IsLegacy $legacy +` + legacyString := "False" + if legacy { + legacyString = "True" + } + var ps powershell.PowerShellCmd + err := ps.Run(script, vmName, legacyString) + return err +} + func GetExternalOnlineVirtualSwitch() (string, error) { var script = ` diff --git a/website/source/docs/builders/hyperv-iso.html.md.erb b/website/source/docs/builders/hyperv-iso.html.md.erb index 6960a3148..c0547cdba 100644 --- a/website/source/docs/builders/hyperv-iso.html.md.erb +++ b/website/source/docs/builders/hyperv-iso.html.md.erb @@ -282,6 +282,11 @@ builder. without the file extension. By default this is "packer-BUILDNAME", where "BUILDNAME" is the name of the build. +- `use_legacy_network_adapter` (bool) - If true use a legacy network adapter as the NIC. + This defaults to false. A legacy network adapter is fully emulated NIC, and is thus + supported by various exotic operating systems, but this emulation requires + additional overhead and should only be used if absolutely necessary. + ## Boot Command The `boot_command` configuration is very important: it specifies the keys to From da8b140bcabe691be45dc144b464672c06016f8a Mon Sep 17 00:00:00 2001 From: Ladar Levison Date: Tue, 18 Dec 2018 05:50:16 -0600 Subject: [PATCH 43/87] Fix Hyper-V builder formatting. --- builder/hyperv/iso/builder.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/builder/hyperv/iso/builder.go b/builder/hyperv/iso/builder.go index 697cc33be..b21f2f385 100644 --- a/builder/hyperv/iso/builder.go +++ b/builder/hyperv/iso/builder.go @@ -189,10 +189,10 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { err = errors.New("Generation 2 vms don't support floppy drives. Use ISO image instead.") errs = packer.MultiErrorAppend(errs, err) } - if b.config.UseLegacyNetworkAdapter { - err = errors.New("Generation 2 vms don't support legacy network adapters.") - errs = packer.MultiErrorAppend(errs, err) - } + if b.config.UseLegacyNetworkAdapter { + err = errors.New("Generation 2 vms don't support legacy network adapters.") + errs = packer.MultiErrorAppend(errs, err) + } } if len(b.config.AdditionalDiskSize) > 64 { @@ -413,7 +413,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe EnableSecureBoot: b.config.EnableSecureBoot, SecureBootTemplate: b.config.SecureBootTemplate, EnableVirtualizationExtensions: b.config.EnableVirtualizationExtensions, - UseLegacyNetworkAdapter: b.config.UseLegacyNetworkAdapter, + UseLegacyNetworkAdapter: b.config.UseLegacyNetworkAdapter, AdditionalDiskSize: b.config.AdditionalDiskSize, DifferencingDisk: b.config.DifferencingDisk, MacAddress: b.config.MacAddress, From 31d03fb48e5ce72f2358da883759a0d6ea13ae3c Mon Sep 17 00:00:00 2001 From: Ladar Levison Date: Tue, 18 Dec 2018 06:12:05 -0600 Subject: [PATCH 44/87] Added legacy network adapter driver mock up. --- builder/hyperv/common/driver_mock.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/builder/hyperv/common/driver_mock.go b/builder/hyperv/common/driver_mock.go index 71b7a0750..7a3e6bcab 100644 --- a/builder/hyperv/common/driver_mock.go +++ b/builder/hyperv/common/driver_mock.go @@ -66,6 +66,11 @@ type DriverMock struct { GetVirtualMachineNetworkAdapterAddress_Return string GetVirtualMachineNetworkAdapterAddress_Err error + ReplaceVirtualMachineNetworkAdapter_Called bool + ReplaceVirtualMachineNetworkAdapter_VmName string + ReplaceVirtualMachineNetworkAdapter_Replace bool + ReplaceVirtualMachineNetworkAdapter_Err error + SetNetworkAdapterVlanId_Called bool SetNetworkAdapterVlanId_SwitchName string SetNetworkAdapterVlanId_VlanId string @@ -335,6 +340,13 @@ func (d *DriverMock) GetVirtualMachineNetworkAdapterAddress(vmName string) (stri return d.GetVirtualMachineNetworkAdapterAddress_Return, d.GetVirtualMachineNetworkAdapterAddress_Err } +func (d *DriverMock) ReplaceVirtualMachineNetworkAdapter(vmName string, replace bool) error { + d.ReplaceVirtualMachineNetworkAdapter_Called = true + d.ReplaceVirtualMachineNetworkAdapter_VmName = vmName + d.ReplaceVirtualMachineNetworkAdapter_Replace = vmName + return d.ReplaceVirtualMachineNetworkAdapter_Err +} + func (d *DriverMock) SetNetworkAdapterVlanId(switchName string, vlanId string) error { d.SetNetworkAdapterVlanId_Called = true d.SetNetworkAdapterVlanId_SwitchName = switchName From fa154f529855a8ce85e1e7d0b6fdff84ce262335 Mon Sep 17 00:00:00 2001 From: Ladar Levison Date: Tue, 18 Dec 2018 06:14:38 -0600 Subject: [PATCH 45/87] Fixed driver mock up formatting. --- builder/hyperv/common/driver_mock.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/builder/hyperv/common/driver_mock.go b/builder/hyperv/common/driver_mock.go index 7a3e6bcab..ac1f80ddf 100644 --- a/builder/hyperv/common/driver_mock.go +++ b/builder/hyperv/common/driver_mock.go @@ -341,10 +341,10 @@ func (d *DriverMock) GetVirtualMachineNetworkAdapterAddress(vmName string) (stri } func (d *DriverMock) ReplaceVirtualMachineNetworkAdapter(vmName string, replace bool) error { - d.ReplaceVirtualMachineNetworkAdapter_Called = true - d.ReplaceVirtualMachineNetworkAdapter_VmName = vmName - d.ReplaceVirtualMachineNetworkAdapter_Replace = vmName - return d.ReplaceVirtualMachineNetworkAdapter_Err + d.ReplaceVirtualMachineNetworkAdapter_Called = true + d.ReplaceVirtualMachineNetworkAdapter_VmName = vmName + d.ReplaceVirtualMachineNetworkAdapter_Replace = vmName + return d.ReplaceVirtualMachineNetworkAdapter_Err } func (d *DriverMock) SetNetworkAdapterVlanId(switchName string, vlanId string) error { From bdcbf61aded93a499c5adc93d2e0bfdd8334c714 Mon Sep 17 00:00:00 2001 From: Ladar Levison Date: Tue, 18 Dec 2018 06:18:51 -0600 Subject: [PATCH 46/87] Fixed replace variable name. --- builder/hyperv/common/driver_mock.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/hyperv/common/driver_mock.go b/builder/hyperv/common/driver_mock.go index ac1f80ddf..78be67196 100644 --- a/builder/hyperv/common/driver_mock.go +++ b/builder/hyperv/common/driver_mock.go @@ -343,7 +343,7 @@ func (d *DriverMock) GetVirtualMachineNetworkAdapterAddress(vmName string) (stri func (d *DriverMock) ReplaceVirtualMachineNetworkAdapter(vmName string, replace bool) error { d.ReplaceVirtualMachineNetworkAdapter_Called = true d.ReplaceVirtualMachineNetworkAdapter_VmName = vmName - d.ReplaceVirtualMachineNetworkAdapter_Replace = vmName + d.ReplaceVirtualMachineNetworkAdapter_Replace = replace return d.ReplaceVirtualMachineNetworkAdapter_Err } From 336c11c54a056466ef2ecbb2ec5a09910669f51e Mon Sep 17 00:00:00 2001 From: "Johannes J. Schmidt" Date: Tue, 18 Dec 2018 23:58:27 +0100 Subject: [PATCH 47/87] add openstack volume_size option Adds an option to OpenStack, `volume_size` (int), which is the size of the Block Storage service volume in GB. --- builder/openstack/run_config.go | 1 + website/source/docs/builders/openstack.html.md | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/builder/openstack/run_config.go b/builder/openstack/run_config.go index 56fccb4f3..5a2efd023 100644 --- a/builder/openstack/run_config.go +++ b/builder/openstack/run_config.go @@ -40,6 +40,7 @@ type RunConfig struct { UseBlockStorageVolume bool `mapstructure:"use_blockstorage_volume"` VolumeName string `mapstructure:"volume_name"` VolumeType string `mapstructure:"volume_type"` + VolumeSize int `mapstructure:"volume_size"` VolumeAvailabilityZone string `mapstructure:"volume_availability_zone"` // Not really used, but here for BC diff --git a/website/source/docs/builders/openstack.html.md b/website/source/docs/builders/openstack.html.md index 263610c0f..3320f7ea2 100644 --- a/website/source/docs/builders/openstack.html.md +++ b/website/source/docs/builders/openstack.html.md @@ -275,6 +275,11 @@ builder. isn't specified, the default enforced by your OpenStack cluster will be used. +- `volume_size` (int) - Size of the Block Storage service volume in GB. If this + isn't specified, it is set to source image min disk value (if set) or + calculated from the source image bytes size. Note that in some cases this + needs to be specified, if `use_blockstorage_volume` is true. + - `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 From a545caa24a3ebfb9b12ea124f17686aeb9ac871d Mon Sep 17 00:00:00 2001 From: "Johannes J. Schmidt" Date: Tue, 18 Dec 2018 23:59:54 +0100 Subject: [PATCH 48/87] use openstack volume_size option on creation if present. Otherwise fallback to to source image min disk value (if set) or calculated from the source image bytes size. Note that in some cases this needs to be specified, if `use_blockstorage_volume` is true. See #6957 for the discussion. --- builder/openstack/step_create_volume.go | 29 +++++++++++++++---------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/builder/openstack/step_create_volume.go b/builder/openstack/step_create_volume.go index 28b01c0b4..ec1734a06 100644 --- a/builder/openstack/step_create_volume.go +++ b/builder/openstack/step_create_volume.go @@ -35,20 +35,25 @@ func (s *StepCreateVolume) Run(_ context.Context, state multistep.StateBag) mult 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 - } + + volumeSize := config.VolumeSize // Get needed volume size from the source image. - volumeSize, err := GetVolumeSize(imageClient, sourceImage) - if err != nil { - err := fmt.Errorf("Error creating volume: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt + if volumeSize == 0 { + imageClient, err := config.imageV2Client() + if err != nil { + err = fmt.Errorf("Error initializing image client: %s", err) + state.Put("error", err) + return multistep.ActionHalt + } + + volumeSize, err = GetVolumeSize(imageClient, 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...") From 006682a09ccf65931497f645e2dec62bbf1f98ee Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Wed, 19 Dec 2018 16:30:57 -0800 Subject: [PATCH 49/87] add version option and also refactor powershell script to use golang templates for ease of testing and variable passing. --- builder/hyperv/common/driver.go | 2 +- builder/hyperv/common/driver_mock.go | 4 +- builder/hyperv/common/driver_ps_4.go | 4 +- builder/hyperv/common/step_create_vm.go | 3 +- builder/hyperv/iso/builder.go | 2 + builder/hyperv/vmcx/builder.go | 1 + common/powershell/hyperv/hyperv.go | 149 ++++++++++++++---------- 7 files changed, 99 insertions(+), 66 deletions(-) diff --git a/builder/hyperv/common/driver.go b/builder/hyperv/common/driver.go index e93d6a5de..c8bf506aa 100644 --- a/builder/hyperv/common/driver.go +++ b/builder/hyperv/common/driver.go @@ -73,7 +73,7 @@ type Driver interface { DeleteVirtualSwitch(string) error - CreateVirtualMachine(string, string, string, int64, int64, int64, string, uint, bool, bool) error + CreateVirtualMachine(string, string, string, int64, int64, int64, string, uint, bool, bool, string) error AddVirtualMachineHardDrive(string, string, string, int64, int64, string) error diff --git a/builder/hyperv/common/driver_mock.go b/builder/hyperv/common/driver_mock.go index 78be67196..290687829 100644 --- a/builder/hyperv/common/driver_mock.go +++ b/builder/hyperv/common/driver_mock.go @@ -136,6 +136,7 @@ type DriverMock struct { CreateVirtualMachine_Generation uint CreateVirtualMachine_DifferentialDisk bool CreateVirtualMachine_FixedVHD bool + CreateVirtualMachine_Version string CreateVirtualMachine_Err error CloneVirtualMachine_Called bool @@ -422,7 +423,7 @@ func (d *DriverMock) AddVirtualMachineHardDrive(vmName string, vhdFile string, v func (d *DriverMock) CreateVirtualMachine(vmName string, path string, harddrivePath string, ram int64, diskSize int64, diskBlockSize int64, switchName string, generation uint, - diffDisks bool, fixedVHD bool) error { + diffDisks bool, fixedVHD bool, version string) error { d.CreateVirtualMachine_Called = true d.CreateVirtualMachine_VmName = vmName d.CreateVirtualMachine_Path = path @@ -433,6 +434,7 @@ func (d *DriverMock) CreateVirtualMachine(vmName string, path string, harddriveP d.CreateVirtualMachine_SwitchName = switchName d.CreateVirtualMachine_Generation = generation d.CreateVirtualMachine_DifferentialDisk = diffDisks + d.CreateVirtualMachine_Version = version return d.CreateVirtualMachine_Err } diff --git a/builder/hyperv/common/driver_ps_4.go b/builder/hyperv/common/driver_ps_4.go index 38952e723..118c429ec 100644 --- a/builder/hyperv/common/driver_ps_4.go +++ b/builder/hyperv/common/driver_ps_4.go @@ -188,9 +188,9 @@ func (d *HypervPS4Driver) AddVirtualMachineHardDrive(vmName string, vhdFile stri func (d *HypervPS4Driver) CreateVirtualMachine(vmName string, path string, harddrivePath string, ram int64, diskSize int64, diskBlockSize int64, switchName string, generation uint, diffDisks bool, - fixedVHD bool) error { + fixedVHD bool, version string) error { return hyperv.CreateVirtualMachine(vmName, path, harddrivePath, ram, diskSize, diskBlockSize, switchName, - generation, diffDisks, fixedVHD) + generation, diffDisks, fixedVHD, version) } func (d *HypervPS4Driver) CloneVirtualMachine(cloneFromVmcxPath string, cloneFromVmName string, diff --git a/builder/hyperv/common/step_create_vm.go b/builder/hyperv/common/step_create_vm.go index 67ef7b9aa..252a2664b 100644 --- a/builder/hyperv/common/step_create_vm.go +++ b/builder/hyperv/common/step_create_vm.go @@ -34,6 +34,7 @@ type StepCreateVM struct { DifferencingDisk bool MacAddress string FixedVHD bool + Version string } func (s *StepCreateVM) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { @@ -65,7 +66,7 @@ func (s *StepCreateVM) Run(_ context.Context, state multistep.StateBag) multiste diskBlockSize := int64(s.DiskBlockSize * 1024 * 1024) err := driver.CreateVirtualMachine(s.VMName, path, harddrivePath, ramSize, diskSize, diskBlockSize, - s.SwitchName, s.Generation, s.DifferencingDisk, s.FixedVHD) + s.SwitchName, s.Generation, s.DifferencingDisk, s.FixedVHD, s.Version) if err != nil { err := fmt.Errorf("Error creating virtual machine: %s", err) state.Put("error", err) diff --git a/builder/hyperv/iso/builder.go b/builder/hyperv/iso/builder.go index b21f2f385..a9ea6e7a4 100644 --- a/builder/hyperv/iso/builder.go +++ b/builder/hyperv/iso/builder.go @@ -96,6 +96,7 @@ type Config struct { SecureBootTemplate string `mapstructure:"secure_boot_template"` EnableVirtualizationExtensions bool `mapstructure:"enable_virtualization_extensions"` TempPath string `mapstructure:"temp_path"` + Version string `mapstructure:"configuration_version"` Communicator string `mapstructure:"communicator"` @@ -418,6 +419,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe DifferencingDisk: b.config.DifferencingDisk, MacAddress: b.config.MacAddress, FixedVHD: b.config.FixedVHD, + Version: b.config.Version, }, &hypervcommon.StepEnableIntegrationService{}, diff --git a/builder/hyperv/vmcx/builder.go b/builder/hyperv/vmcx/builder.go index e207c548f..5e9754ccc 100644 --- a/builder/hyperv/vmcx/builder.go +++ b/builder/hyperv/vmcx/builder.go @@ -93,6 +93,7 @@ type Config struct { SecureBootTemplate string `mapstructure:"secure_boot_template"` EnableVirtualizationExtensions bool `mapstructure:"enable_virtualization_extensions"` TempPath string `mapstructure:"temp_path"` + Version string `mapstructure:"configuration_version"` Communicator string `mapstructure:"communicator"` diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index 23e5f505f..729dadb3b 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -3,9 +3,11 @@ package hyperv import ( "context" "errors" + "fmt" "os/exec" "strconv" "strings" + "text/template" "github.com/hashicorp/packer/common/powershell" ) @@ -204,75 +206,100 @@ Hyper-V\Set-VMFloppyDiskDrive -VMName $vmName -Path $null func CreateVirtualMachine(vmName string, path string, harddrivePath string, ram int64, diskSize int64, diskBlockSize int64, switchName string, generation uint, - diffDisks bool, fixedVHD bool) error { + diffDisks bool, fixedVHD bool, version string) error { + type scriptOptions struct { + VersionTag string + VMName string + Path string + HardDrivePath string + MemoryStartupBytes int64 + NewVHDSizeBytes int64 + VHDBlockSizeBytes int64 + SwitchName string + Generation uint + DiffDisks bool + FixedVHD bool + } + + versionTag := "" + if version != "" { + versionTag = fmt.Sprintf("-Version %s", version) + } + + var scriptBuilder strings.Builder + + scriptTemplate := template.Must(template.New("psScript").Parse(` +param([string]$fixedVHD) + +{{if .FixedVHD}} +$vhdx = {{ .VMName }} + '.vhd' +{{- else}} +$vhdx = {{ .VMName }} + '.vhdx' +{{- end}} + +$vhdPath = Join-Path -Path {{ .Path }} -ChildPath $vhdx +if ({{ .HardDrivePath }}){ + {{if .DiffDisks}} + New-VHD -Path $vhdPath -ParentPath {{ .HardDrivePath }} -Differencing -BlockSizeBytes {{ .VHDBlockSizeBytes }} + {{- else}} + Copy-Item -Path {{ .HardDrivePath }} -Destination $vhdPath + {{- end}} + Hyper-V\New-VM -Name {{ .VMName }} -Path {{ .Path }} -MemoryStartupBytes {{ .MemoryStartupBytes }} -VHDPath $vhdPath -SwitchName {{ .SwitchName }} {{ .VersionTag }} +} else { + {{if .FixedVHD}} + Hyper-V\New-VHD -Path $vhdPath -Fixed -SizeBytes {{ .NewVHDSizeBytes }} + {{- else}} + Hyper-V\New-VHD -Path $vhdPath -SizeBytes {{ .NewVHDSizeBytes }} -BlockSizeBytes {{ .VHDBlockSizeBytes }} + {{- end}} + Hyper-V\New-VM -Name {{ .VMName }} -Path {{ .Path }} -MemoryStartupBytes {{ .MemoryStartupBytes }} -VHDPath $vhdPath -SwitchName {{ .SwitchName }} {{ .VersionTag }} +} +`)) if generation == 2 { - var script = ` -param([string]$vmName, [string]$path, [string]$harddrivePath, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [long]$vhdBlockSizeBytes, [string]$switchName, [int]$generation, [string]$diffDisks) -$vhdx = $vmName + '.vhdx' -$vhdPath = Join-Path -Path $path -ChildPath $vhdx -if ($harddrivePath){ - if($diffDisks -eq "true"){ - New-VHD -Path $vhdPath -ParentPath $harddrivePath -Differencing -BlockSizeBytes $vhdBlockSizeBytes - } else { - Copy-Item -Path $harddrivePath -Destination $vhdPath - } - Hyper-V\New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -VHDPath $vhdPath -SwitchName $switchName -Generation $generation -} else { - Hyper-V\New-VHD -Path $vhdPath -SizeBytes $newVHDSizeBytes -BlockSizeBytes $vhdBlockSizeBytes - Hyper-V\New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -VHDPath $vhdPath -SwitchName $switchName -Generation $generation + scriptTemplate = template.Must(template.New("psScript").Parse(` +$vhdx = {{ .VMName }} + '.vhdx' +$vhdPath = Join-Path -Path {{ .Path }} -ChildPath $vhdx +if ({{ .HardDrivePath }}){ + {{if .DiffDisks}} + New-VHD -Path $vhdPath -ParentPath {{ .HardDrivePath }} -Differencing -BlockSizeBytes {{ .VHDBlockSizeBytes }} + {{- else}} + Copy-Item -Path {{ .HardDrivePath }} -Destination $vhdPath + {{- end}} + Hyper-V\New-VM -Name {{ .VMName }} -Path {{ .Path }} -MemoryStartupBytes {{ .MemoryStartupBytes }} -VHDPath $vhdPath -SwitchName {{ .SwitchName }} -Generation {{ .Generation }} {{ .VersionTag }} } -` - var ps powershell.PowerShellCmd - if err := ps.Run(script, vmName, path, harddrivePath, strconv.FormatInt(ram, 10), - strconv.FormatInt(diskSize, 10), strconv.FormatInt(diskBlockSize, 10), - switchName, strconv.FormatInt(int64(generation), 10), - strconv.FormatBool(diffDisks)); err != nil { - return err - } +else { + Hyper-V\New-VHD -Path $vhdPath -SizeBytes {{ .NewVHDSizeBytes }} -BlockSizeBytes {{ .VHDBlockSizeBytes }} + Hyper-V\New-VM -Name {{ .VMName }} -Path {{ .Path }} -MemoryStartupBytes {{ .MemoryStartupBytes }} -VHDPath $vhdPath -SwitchName {{ .SwitchName }} -Generation {{ .Generation }} {{ .VersionTag }} +} +`)) + } - return DisableAutomaticCheckpoints(vmName) - } else { - var script = ` -param([string]$vmName, [string]$path, [string]$harddrivePath, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [long]$vhdBlockSizeBytes, [string]$switchName, [string]$diffDisks, [string]$fixedVHD) -if($fixedVHD -eq "true"){ - $vhdx = $vmName + '.vhd' -} -else{ - $vhdx = $vmName + '.vhdx' -} -$vhdPath = Join-Path -Path $path -ChildPath $vhdx -if ($harddrivePath){ - if($diffDisks -eq "true"){ - New-VHD -Path $vhdPath -ParentPath $harddrivePath -Differencing -BlockSizeBytes $vhdBlockSizeBytes + scriptTemplate.Execute(&scriptBuilder, scriptOptions{ + VersionTag: versionTag, + VMName: vmName, + Path: path, + HardDrivePath: harddrivePath, + MemoryStartupBytes: ram, + NewVHDSizeBytes: diskSize, + VHDBlockSizeBytes: diskBlockSize, + SwitchName: switchName, + Generation: generation, + DiffDisks: diffDisks, + FixedVHD: fixedVHD, + }) + script := scriptBuilder.String() + var ps powershell.PowerShellCmd + if err := ps.Run(script); err != nil { + return err } - else{ - Copy-Item -Path $harddrivePath -Destination $vhdPath - } - Hyper-V\New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -VHDPath $vhdPath -SwitchName $switchName -} else { - if($fixedVHD -eq "true"){ - Hyper-V\New-VHD -Path $vhdPath -Fixed -SizeBytes $newVHDSizeBytes - } - else { - Hyper-V\New-VHD -Path $vhdPath -SizeBytes $newVHDSizeBytes -BlockSizeBytes $vhdBlockSizeBytes - } - Hyper-V\New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -VHDPath $vhdPath -SwitchName $switchName -} -` - var ps powershell.PowerShellCmd - if err := ps.Run(script, vmName, path, harddrivePath, strconv.FormatInt(ram, 10), - strconv.FormatInt(diskSize, 10), strconv.FormatInt(diskBlockSize, 10), - switchName, strconv.FormatBool(diffDisks), strconv.FormatBool(fixedVHD)); err != nil { - return err - } - - if err := DisableAutomaticCheckpoints(vmName); err != nil { - return err - } + if err := DisableAutomaticCheckpoints(vmName); err != nil { + return err + } + if generation != 2 { return DeleteAllDvdDrives(vmName) } + return nil } func DisableAutomaticCheckpoints(vmName string) error { From d4de89e0575e050fdd1962b81c166d0e438d85cd Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Wed, 19 Dec 2018 16:35:02 -0800 Subject: [PATCH 50/87] move powershell templating into separate script so we can test it --- common/powershell/hyperv/hyperv.go | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index 729dadb3b..1c4201c96 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -204,10 +204,9 @@ Hyper-V\Set-VMFloppyDiskDrive -VMName $vmName -Path $null return err } -func CreateVirtualMachine(vmName string, path string, harddrivePath string, ram int64, +func getCreateVMScript(vmName string, path string, harddrivePath string, ram int64, diskSize int64, diskBlockSize int64, switchName string, generation uint, - diffDisks bool, fixedVHD bool, version string) error { - + diffDisks bool, fixedVHD bool, version string) string { type scriptOptions struct { VersionTag string VMName string @@ -287,7 +286,18 @@ else { DiffDisks: diffDisks, FixedVHD: fixedVHD, }) - script := scriptBuilder.String() + + return scriptBuilder.String() +} + +func CreateVirtualMachine(vmName string, path string, harddrivePath string, ram int64, + diskSize int64, diskBlockSize int64, switchName string, generation uint, + diffDisks bool, fixedVHD bool, version string) error { + + script := getCreateVMScript(vmName, path, harddrivePath, ram, + diskSize, diskBlockSize, switchName, generation, + diffDisks, fixedVHD, version) + var ps powershell.PowerShellCmd if err := ps.Run(script); err != nil { return err From 7655d2efb27ad49ca0c09a63916918e8884ddeab Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Thu, 20 Dec 2018 17:09:44 +0100 Subject: [PATCH 51/87] Add tencent cloud builder (#7135 & #6839) --- builder/tencentcloud/cvm/access_config.go | 127 + .../tencentcloud/cvm/access_config_test.go | 31 + builder/tencentcloud/cvm/artifact.go | 124 + builder/tencentcloud/cvm/builder.go | 150 + builder/tencentcloud/cvm/common.go | 103 + builder/tencentcloud/cvm/image_config.go | 74 + builder/tencentcloud/cvm/image_config_test.go | 35 + builder/tencentcloud/cvm/run_config.go | 133 + builder/tencentcloud/cvm/run_config_test.go | 127 + .../cvm/step_check_source_image.go | 45 + .../tencentcloud/cvm/step_config_key_pair.go | 132 + .../cvm/step_config_security_group.go | 127 + .../tencentcloud/cvm/step_config_subnet.go | 103 + builder/tencentcloud/cvm/step_config_vpc.go | 92 + builder/tencentcloud/cvm/step_copy_image.go | 47 + builder/tencentcloud/cvm/step_create_image.go | 116 + builder/tencentcloud/cvm/step_pre_validate.go | 21 + builder/tencentcloud/cvm/step_run_instance.go | 158 + builder/tencentcloud/cvm/step_share_image.go | 68 + command/plugin.go | 2 + examples/tencentcloud/basic.json | 26 + examples/tencentcloud/centos.json | 35 + go.mod | 1 + go.sum | 2 + .../tencentcloud/tencentcloud-sdk-go/LICENSE | 201 + .../tencentcloud/common/client.go | 88 + .../tencentcloud/common/credentials.go | 40 + .../tencentcloud/common/errors/errors.go | 35 + .../tencentcloud/common/http/request.go | 231 + .../tencentcloud/common/http/response.go | 69 + .../common/profile/client_profile.go | 13 + .../common/profile/http_profile.go | 17 + .../tencentcloud/common/sign.go | 75 + .../tencentcloud/common/types.go | 47 + .../tencentcloud/cvm/v20170312/client.go | 1679 ++++++ .../tencentcloud/cvm/v20170312/models.go | 2771 +++++++++ .../tencentcloud/vpc/v20170312/client.go | 3079 ++++++++++ .../tencentcloud/vpc/v20170312/models.go | 5024 +++++++++++++++++ vendor/vendor.json | 36 + .../docs/builders/tencentcloud-cvm.html.md | 154 + 40 files changed, 15438 insertions(+) create mode 100644 builder/tencentcloud/cvm/access_config.go create mode 100644 builder/tencentcloud/cvm/access_config_test.go create mode 100644 builder/tencentcloud/cvm/artifact.go create mode 100644 builder/tencentcloud/cvm/builder.go create mode 100644 builder/tencentcloud/cvm/common.go create mode 100644 builder/tencentcloud/cvm/image_config.go create mode 100644 builder/tencentcloud/cvm/image_config_test.go create mode 100644 builder/tencentcloud/cvm/run_config.go create mode 100644 builder/tencentcloud/cvm/run_config_test.go create mode 100644 builder/tencentcloud/cvm/step_check_source_image.go create mode 100644 builder/tencentcloud/cvm/step_config_key_pair.go create mode 100644 builder/tencentcloud/cvm/step_config_security_group.go create mode 100644 builder/tencentcloud/cvm/step_config_subnet.go create mode 100644 builder/tencentcloud/cvm/step_config_vpc.go create mode 100644 builder/tencentcloud/cvm/step_copy_image.go create mode 100644 builder/tencentcloud/cvm/step_create_image.go create mode 100644 builder/tencentcloud/cvm/step_pre_validate.go create mode 100644 builder/tencentcloud/cvm/step_run_instance.go create mode 100644 builder/tencentcloud/cvm/step_share_image.go create mode 100644 examples/tencentcloud/basic.json create mode 100644 examples/tencentcloud/centos.json create mode 100644 vendor/github.com/tencentcloud/tencentcloud-sdk-go/LICENSE create mode 100644 vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/client.go create mode 100644 vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/credentials.go create mode 100644 vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors/errors.go create mode 100644 vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http/request.go create mode 100644 vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http/response.go create mode 100644 vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile/client_profile.go create mode 100644 vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile/http_profile.go create mode 100644 vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/sign.go create mode 100644 vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/types.go create mode 100644 vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312/client.go create mode 100644 vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312/models.go create mode 100644 vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312/client.go create mode 100644 vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312/models.go create mode 100644 website/source/docs/builders/tencentcloud-cvm.html.md diff --git a/builder/tencentcloud/cvm/access_config.go b/builder/tencentcloud/cvm/access_config.go new file mode 100644 index 000000000..d7bb800bd --- /dev/null +++ b/builder/tencentcloud/cvm/access_config.go @@ -0,0 +1,127 @@ +package cvm + +import ( + "fmt" + "os" + + "github.com/hashicorp/packer/template/interpolate" + "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" + "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" + cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" + vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" +) + +type Region string + +// below would be moved to tencentcloud sdk git repo +const ( + Bangkok = Region("ap-bangkok") + Beijing = Region("ap-beijing") + Chengdu = Region("ap-chengdu") + Chongqing = Region("ap-chongqing") + Guangzhou = Region("ap-guangzhou") + GuangzhouOpen = Region("ap-guangzhou-open") + Hongkong = Region("ap-hongkong") + Mumbai = Region("ap-mumbai") + Seoul = Region("ap-seoul") + Shanghai = Region("ap-shanghai") + ShanghaiFsi = Region("ap-shanghai-fsi") + ShenzhenFsi = Region("ap-shenzhen-fsi") + Singapore = Region("ap-singapore") + Tokyo = Region("ap-tokyo") + Frankfurt = Region("eu-frankfurt") + Moscow = Region("eu-moscow") + Ashburn = Region("na-ashburn") + Siliconvalley = Region("na-siliconvalley") + Toronto = Region("na-toronto") +) + +var ValidRegions = []Region{ + Bangkok, Beijing, Chengdu, Chongqing, Guangzhou, GuangzhouOpen, Hongkong, Shanghai, + ShanghaiFsi, ShenzhenFsi, + Mumbai, Seoul, Singapore, Tokyo, Moscow, + Frankfurt, Ashburn, Siliconvalley, Toronto, +} + +type TencentCloudAccessConfig struct { + SecretId string `mapstructure:"secret_id"` + SecretKey string `mapstructure:"secret_key"` + Region string `mapstructure:"region"` + Zone string `mapstructure:"zone"` + SkipValidation bool `mapstructure:"skip_region_validation"` +} + +func (cf *TencentCloudAccessConfig) Client() (*cvm.Client, *vpc.Client, error) { + var ( + err error + cvm_client *cvm.Client + vpc_client *vpc.Client + resp *cvm.DescribeZonesResponse + ) + if err = cf.validateRegion(); err != nil { + return nil, nil, err + } + credential := common.NewCredential( + cf.SecretId, cf.SecretKey) + cpf := profile.NewClientProfile() + if cvm_client, err = cvm.NewClient(credential, cf.Region, cpf); err != nil { + return nil, nil, err + } + if vpc_client, err = vpc.NewClient(credential, cf.Region, cpf); err != nil { + return nil, nil, err + } + if resp, err = cvm_client.DescribeZones(nil); err != nil { + return nil, nil, err + } + if cf.Zone != "" { + for _, zone := range resp.Response.ZoneSet { + if cf.Zone == *zone.Zone { + return cvm_client, vpc_client, nil + } + } + return nil, nil, fmt.Errorf("unknown zone: %s", cf.Zone) + } else { + return nil, nil, fmt.Errorf("zone must be set") + } +} + +func (cf *TencentCloudAccessConfig) Prepare(ctx *interpolate.Context) []error { + var errs []error + if err := cf.Config(); err != nil { + errs = append(errs, err) + } + + if cf.Region == "" { + errs = append(errs, fmt.Errorf("region must be set")) + } else if !cf.SkipValidation { + if err := cf.validateRegion(); err != nil { + errs = append(errs, err) + } + } + if len(errs) > 0 { + return errs + } + return nil +} + +func (cf *TencentCloudAccessConfig) Config() error { + if cf.SecretId == "" { + cf.SecretId = os.Getenv("TENCENTCLOUD_SECRET_ID") + } + if cf.SecretKey == "" { + cf.SecretKey = os.Getenv("TENCENTCLOUD_SECRET_KEY") + } + if cf.SecretId == "" || cf.SecretKey == "" { + return fmt.Errorf("TENCENTCLOUD_SECRET_ID and TENCENTCLOUD_SECRET_KEY must be set") + } + return nil +} + +func (cf *TencentCloudAccessConfig) validateRegion() error { + for _, valid := range ValidRegions { + if valid == Region(cf.Region) { + return nil + } + } + return fmt.Errorf("unknown region: %s", cf.Region) +} diff --git a/builder/tencentcloud/cvm/access_config_test.go b/builder/tencentcloud/cvm/access_config_test.go new file mode 100644 index 000000000..4d0a79cd1 --- /dev/null +++ b/builder/tencentcloud/cvm/access_config_test.go @@ -0,0 +1,31 @@ +package cvm + +import ( + "testing" +) + +func TestTencentCloudAccessConfig_Prepare(t *testing.T) { + cf := TencentCloudAccessConfig{ + SecretId: "secret-id", + SecretKey: "secret-key", + } + + if err := cf.Prepare(nil); err == nil { + t.Fatal("should raise error: region not set") + } + + cf.Region = "ap-guangzhou" + if err := cf.Prepare(nil); err != nil { + t.Fatalf("shouldn't raise error: %v", err) + } + + cf.Region = "unknown-region" + if err := cf.Prepare(nil); err == nil { + t.Fatal("should raise error: unknown region") + } + + cf.SkipValidation = true + if err := cf.Prepare(nil); err != nil { + t.Fatalf("shouldn't raise error: %v", err) + } +} diff --git a/builder/tencentcloud/cvm/artifact.go b/builder/tencentcloud/cvm/artifact.go new file mode 100644 index 000000000..964f8c8a7 --- /dev/null +++ b/builder/tencentcloud/cvm/artifact.go @@ -0,0 +1,124 @@ +package cvm + +import ( + "fmt" + "log" + "sort" + "strings" + + "github.com/hashicorp/packer/packer" + cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" +) + +type Artifact struct { + TencentCloudImages map[string]string + BuilderIdValue string + Client *cvm.Client +} + +func (a *Artifact) BuilderId() string { + return a.BuilderIdValue +} + +func (*Artifact) Files() []string { + return nil +} + +func (a *Artifact) Id() string { + parts := make([]string, 0, len(a.TencentCloudImages)) + for region, imageId := range a.TencentCloudImages { + parts = append(parts, fmt.Sprintf("%s:%s", region, imageId)) + } + + sort.Strings(parts) + return strings.Join(parts, ",") +} + +func (a *Artifact) String() string { + parts := make([]string, 0, len(a.TencentCloudImages)) + for region, imageId := range a.TencentCloudImages { + parts = append(parts, fmt.Sprintf("%s: %s", region, imageId)) + } + sort.Strings(parts) + return fmt.Sprintf("Tencentcloud images(%s) were created:\n\n", strings.Join(parts, "\n")) +} + +func (a *Artifact) State(name string) interface{} { + switch name { + case "atlas.artifact.metadata": + return a.stateAtlasMetadata() + default: + return nil + } +} + +func (a *Artifact) Destroy() error { + errors := make([]error, 0) + + for region, imageId := range a.TencentCloudImages { + log.Printf("Delete tencentcloud image ID(%s) from region(%s)", imageId, region) + + describeReq := cvm.NewDescribeImagesRequest() + describeReq.ImageIds = []*string{&imageId} + + describeResp, err := a.Client.DescribeImages(describeReq) + if err != nil { + errors = append(errors, err) + continue + } + if *describeResp.Response.TotalCount == 0 { + errors = append(errors, fmt.Errorf( + "describe images failed, region(%s) ImageId(%s)", region, imageId)) + } + + describeShareReq := cvm.NewDescribeImageSharePermissionRequest() + describeShareReq.ImageId = &imageId + + describeShareResp, err := a.Client.DescribeImageSharePermission(describeShareReq) + var shareAccountIds []*string = nil + if err != nil { + errors = append(errors, err) + } else { + for _, sharePermission := range describeShareResp.Response.SharePermissionSet { + shareAccountIds = append(shareAccountIds, sharePermission.AccountId) + } + } + + if shareAccountIds != nil && len(shareAccountIds) != 0 { + cancelShareReq := cvm.NewModifyImageSharePermissionRequest() + cancelShareReq.ImageId = &imageId + cancelShareReq.AccountIds = shareAccountIds + CANCEL := "CANCEL" + cancelShareReq.Permission = &CANCEL + _, err := a.Client.ModifyImageSharePermission(cancelShareReq) + if err != nil { + errors = append(errors, err) + } + } + + deleteReq := cvm.NewDeleteImagesRequest() + deleteReq.ImageIds = []*string{&imageId} + + _, err = a.Client.DeleteImages(deleteReq) + if err != nil { + errors = append(errors, err) + } + } + + if len(errors) == 1 { + return errors[0] + } else if len(errors) > 1 { + return &packer.MultiError{Errors: errors} + } else { + return nil + } +} + +func (a *Artifact) stateAtlasMetadata() interface{} { + metadata := make(map[string]string) + for region, imageId := range a.TencentCloudImages { + k := fmt.Sprintf("region.%s", region) + metadata[k] = imageId + } + return metadata +} diff --git a/builder/tencentcloud/cvm/builder.go b/builder/tencentcloud/cvm/builder.go new file mode 100644 index 000000000..d3b130495 --- /dev/null +++ b/builder/tencentcloud/cvm/builder.go @@ -0,0 +1,150 @@ +package cvm + +import ( + "fmt" + "log" + + "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/config" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/hashicorp/packer/template/interpolate" +) + +const BuilderId = "tencent.cloud" + +type Config struct { + common.PackerConfig `mapstructure:",squash"` + TencentCloudAccessConfig `mapstructure:",squash"` + TencentCloudImageConfig `mapstructure:",squash"` + TencentCloudRunConfig `mapstructure:",squash"` + + ctx interpolate.Context +} + +type Builder struct { + config Config + runner multistep.Runner +} + +func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { + err := config.Decode(&b.config, &config.DecodeOpts{ + Interpolate: true, + InterpolateContext: &b.config.ctx, + InterpolateFilter: &interpolate.RenderFilter{ + Exclude: []string{ + "run_command", + }, + }, + }, raws...) + b.config.ctx.EnableEnv = true + if err != nil { + return nil, err + } + + // Accumulate any errors + var errs *packer.MultiError + errs = packer.MultiErrorAppend(errs, b.config.TencentCloudAccessConfig.Prepare(&b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, b.config.TencentCloudImageConfig.Prepare(&b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, b.config.TencentCloudRunConfig.Prepare(&b.config.ctx)...) + + if errs != nil && len(errs.Errors) > 0 { + return nil, errs + } + + packer.LogSecretFilter.Set(b.config.SecretId, b.config.SecretKey) + log.Println(b.config) + return nil, nil +} + +func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { + cvmClient, vpcClient, err := b.config.Client() + if err != nil { + return nil, err + } + state := new(multistep.BasicStateBag) + state.Put("config", &b.config) + state.Put("cvm_client", cvmClient) + state.Put("vpc_client", vpcClient) + state.Put("hook", hook) + state.Put("ui", ui) + var steps []multistep.Step + + // Build the steps + steps = []multistep.Step{ + &stepCheckSourceImage{b.config.SourceImageId}, + &stepConfigKeyPair{ + Debug: b.config.PackerDebug, + Comm: &b.config.Comm, + DebugKeyPath: fmt.Sprintf("cvm_%s.pem", b.config.PackerBuildName), + }, + &stepConfigVPC{ + VpcId: b.config.VpcId, + CidrBlock: b.config.CidrBlock, + VpcName: b.config.VpcName, + }, + &stepConfigSubnet{ + SubnetId: b.config.SubnetId, + SubnetCidrBlock: b.config.SubnectCidrBlock, + SubnetName: b.config.SubnetName, + Zone: b.config.Zone, + }, + &stepConfigSecurityGroup{ + SecurityGroupId: b.config.SecurityGroupId, + SecurityGroupName: b.config.SecurityGroupName, + Description: "a simple security group", + }, + &stepRunInstance{ + InstanceType: b.config.InstanceType, + UserData: b.config.UserData, + UserDataFile: b.config.UserDataFile, + ZoneId: b.config.Zone, + InstanceName: b.config.InstanceName, + DiskType: b.config.DiskType, + DiskSize: b.config.DiskSize, + HostName: b.config.HostName, + InternetMaxBandwidthOut: b.config.InternetMaxBandwidthOut, + AssociatePublicIpAddress: b.config.AssociatePublicIpAddress, + }, + &communicator.StepConnect{ + Config: &b.config.TencentCloudRunConfig.Comm, + SSHConfig: b.config.TencentCloudRunConfig.Comm.SSHConfigFunc(), + Host: SSHHost(b.config.AssociatePublicIpAddress), + }, + &common.StepProvision{}, + &common.StepCleanupTempKeys{ + Comm: &b.config.TencentCloudRunConfig.Comm}, + &stepCreateImage{}, + &stepShareImage{b.config.ImageShareAccounts}, + &stepCopyImage{ + DesinationRegions: b.config.ImageCopyRegions, + SourceRegion: b.config.Region, + }, + } + + b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) + b.runner.Run(state) + + if rawErr, ok := state.GetOk("error"); ok { + return nil, rawErr.(error) + } + + if _, ok := state.GetOk("image"); !ok { + return nil, nil + } + + artifact := &Artifact{ + TencentCloudImages: state.Get("tencentcloudimages").(map[string]string), + BuilderIdValue: BuilderId, + Client: cvmClient, + } + return artifact, nil +} + +func (b *Builder) Cancel() { + if b.runner != nil { + log.Println("Cancelling the step runner...") + b.runner.Cancel() + } +} diff --git a/builder/tencentcloud/cvm/common.go b/builder/tencentcloud/cvm/common.go new file mode 100644 index 000000000..209ae6319 --- /dev/null +++ b/builder/tencentcloud/cvm/common.go @@ -0,0 +1,103 @@ +package cvm + +import ( + "fmt" + "regexp" + "time" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" +) + +func CheckResourceIdFormat(resource string, id string) bool { + regex := regexp.MustCompile(fmt.Sprintf("%s-[0-9a-z]{8}$", resource)) + if !regex.MatchString(id) { + return false + } + return true +} + +func MessageClean(state multistep.StateBag, module string) { + _, cancelled := state.GetOk(multistep.StateCancelled) + _, halted := state.GetOk(multistep.StateHalted) + + ui := state.Get("ui").(packer.Ui) + + if cancelled || halted { + ui.Say(fmt.Sprintf("Deleting %s because of cancellation or error...", module)) + } else { + ui.Say(fmt.Sprintf("Cleaning up '%s'", module)) + } + +} + +const DefaultWaitForInterval = 5 + +func WaitForInstance(client *cvm.Client, instanceId string, status string, timeout int) error { + req := cvm.NewDescribeInstancesRequest() + req.InstanceIds = []*string{&instanceId} + for { + resp, err := client.DescribeInstances(req) + if err != nil { + return err + } + if *resp.Response.TotalCount == 0 { + return fmt.Errorf("instance(%s) not exist", instanceId) + } + if *resp.Response.InstanceSet[0].InstanceState == status { + break + } + time.Sleep(DefaultWaitForInterval * time.Second) + timeout = timeout - DefaultWaitForInterval + if timeout <= 0 { + return fmt.Errorf("wait instance(%s) status(%s) timeout", instanceId, status) + } + } + return nil +} + +func WaitForImageReady(client *cvm.Client, imageName string, status string, timeout int) error { + req := cvm.NewDescribeImagesRequest() + FILTER_IMAGE_NAME := "image-name" + req.Filters = []*cvm.Filter{ + { + Name: &FILTER_IMAGE_NAME, + Values: []*string{&imageName}, + }, + } + for { + resp, err := client.DescribeImages(req) + if err != nil { + return err + } + find := false + for _, image := range resp.Response.ImageSet { + if *image.ImageName == imageName && *image.ImageState == status { + find = true + break + } + } + if find { + break + } + time.Sleep(DefaultWaitForInterval * time.Second) + timeout = timeout - DefaultWaitForInterval + if timeout <= 0 { + return fmt.Errorf("wait image(%s) ready timeout", imageName) + } + } + return nil +} + +// SSHHost returns a function that can be given to the SSH communicator +func SSHHost(pubilcIp bool) func(multistep.StateBag) (string, error) { + return func(state multistep.StateBag) (string, error) { + instance := state.Get("instance").(*cvm.Instance) + if pubilcIp { + return *instance.PublicIpAddresses[0], nil + } else { + return *instance.PrivateIpAddresses[0], nil + } + } +} diff --git a/builder/tencentcloud/cvm/image_config.go b/builder/tencentcloud/cvm/image_config.go new file mode 100644 index 000000000..c0e9386d8 --- /dev/null +++ b/builder/tencentcloud/cvm/image_config.go @@ -0,0 +1,74 @@ +package cvm + +import ( + "fmt" + "regexp" + + "github.com/hashicorp/packer/template/interpolate" +) + +type TencentCloudImageConfig struct { + ImageName string `mapstructure:"image_name"` + ImageDescription string `mapstructure:"image_description"` + Reboot bool `mapstructure:"reboot"` + ForcePoweroff bool `mapstructure:"force_poweroff"` + Sysprep bool `mapstructure:"sysprep"` + ImageForceDelete bool `mapstructure:"image_force_delete"` + ImageCopyRegions []string `mapstructure:"image_copy_regions"` + ImageShareAccounts []string `mapstructure:"image_share_accounts"` + SkipValidation bool `mapstructure:"skip_region_validation"` +} + +func (cf *TencentCloudImageConfig) Prepare(ctx *interpolate.Context) []error { + var errs []error + cf.ForcePoweroff = true + if cf.ImageName == "" { + errs = append(errs, fmt.Errorf("image_name must be set")) + } else if len(cf.ImageName) > 20 { + errs = append(errs, fmt.Errorf("image_num length should not exceed 20 characters")) + } else { + regex := regexp.MustCompile("^[0-9a-zA-Z\\-]+$") + if !regex.MatchString(cf.ImageName) { + errs = append(errs, fmt.Errorf("image_name can only be composed of letters, numbers and minus sign")) + } + } + + if len(cf.ImageDescription) > 60 { + errs = append(errs, fmt.Errorf("image_description length should not exceed 60 characters")) + } + + if len(cf.ImageCopyRegions) > 0 { + regionSet := make(map[string]struct{}) + regions := make([]string, 0, len(cf.ImageCopyRegions)) + + for _, region := range cf.ImageCopyRegions { + if _, ok := regionSet[region]; ok { + continue + } + + regionSet[region] = struct{}{} + + if !cf.SkipValidation { + if err := validRegion(region); err != nil { + errs = append(errs, err) + continue + } + } + regions = append(regions, region) + } + cf.ImageCopyRegions = regions + } + if len(errs) > 0 { + return errs + } + return nil +} + +func validRegion(region string) error { + for _, valid := range ValidRegions { + if Region(region) == valid { + return nil + } + } + return fmt.Errorf("unknown region: %s", region) +} diff --git a/builder/tencentcloud/cvm/image_config_test.go b/builder/tencentcloud/cvm/image_config_test.go new file mode 100644 index 000000000..a6e441fc3 --- /dev/null +++ b/builder/tencentcloud/cvm/image_config_test.go @@ -0,0 +1,35 @@ +package cvm + +import "testing" + +func TestTencentCloudImageConfig_Prepare(t *testing.T) { + cf := &TencentCloudImageConfig{ + ImageName: "foo", + } + + if err := cf.Prepare(nil); err != nil { + t.Fatalf("shouldn't have err: %v", err) + } + + cf.ImageName = "foo:" + if err := cf.Prepare(nil); err == nil { + t.Fatal("should have error") + } + + cf.ImageName = "foo" + cf.ImageCopyRegions = []string{"ap-guangzhou", "ap-hongkong"} + if err := cf.Prepare(nil); err != nil { + t.Fatalf("shouldn't have err: %v", err) + } + + cf.ImageCopyRegions = []string{"unknown"} + if err := cf.Prepare(nil); err == nil { + t.Fatal("should have err") + } + + cf.SkipValidation = true + if err := cf.Prepare(nil); err != nil { + t.Fatalf("shouldn't have err:%v", err) + } + +} diff --git a/builder/tencentcloud/cvm/run_config.go b/builder/tencentcloud/cvm/run_config.go new file mode 100644 index 000000000..a4f9320d0 --- /dev/null +++ b/builder/tencentcloud/cvm/run_config.go @@ -0,0 +1,133 @@ +package cvm + +import ( + "fmt" + "os" + + "github.com/hashicorp/packer/common/uuid" + "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/template/interpolate" + "github.com/pkg/errors" +) + +type TencentCloudRunConfig struct { + AssociatePublicIpAddress bool `mapstructure:"associate_public_ip_address"` + SourceImageId string `mapstructure:"source_image_id"` + InstanceType string `mapstructure:"instance_type"` + InstanceName string `mapstructure:"instance_name"` + DiskType string `mapstructure:"disk_type"` + DiskSize int64 `mapstructure:"disk_size"` + VpcId string `mapstructure:"vpc_id"` + VpcName string `mapstructure:"vpc_name"` + VpcIp string `mapstructure:"vpc_ip"` + SubnetId string `mapstructure:"subnet_id"` + SubnetName string `mapstructure:"subnet_name"` + CidrBlock string `mapstructure:"cidr_block"` // 10.0.0.0/16(default), 172.16.0.0/12, 192.168.0.0/16 + SubnectCidrBlock string `mapstructure:"subnect_cidr_block"` + InternetChargeType string `mapstructure:"internet_charge_type"` + InternetMaxBandwidthOut int64 `mapstructure:"internet_max_bandwidth_out"` + SecurityGroupId string `mapstructure:"security_group_id"` + SecurityGroupName string `mapstructure:"security_group_name"` + UserData string `mapstructure:"user_data"` + UserDataFile string `mapstructure:"user_data_file"` + HostName string `mapstructure:"host_name"` + + // Communicator settings + Comm communicator.Config `mapstructure:",squash"` + SSHPrivateIp bool `mapstructure:"ssh_private_ip"` +} + +var ValidCBSType = []string{ + "LOCAL_BASIC", "LOCAL_SSD", "CLOUD_BASIC", "CLOUD_SSD", "CLOUD_PREMIUM", +} + +func (cf *TencentCloudRunConfig) Prepare(ctx *interpolate.Context) []error { + if cf.Comm.SSHKeyPairName == "" && cf.Comm.SSHTemporaryKeyPairName == "" && + cf.Comm.SSHPrivateKeyFile == "" && cf.Comm.SSHPassword == "" && cf.Comm.WinRMPassword == "" { + //tencentcloud support key pair name length max to 25 + cf.Comm.SSHTemporaryKeyPairName = fmt.Sprintf("packer_%s", uuid.TimeOrderedUUID()[:8]) + } + + errs := cf.Comm.Prepare(ctx) + if cf.SourceImageId == "" { + errs = append(errs, errors.New("source_image_id must be specified")) + } + + if !CheckResourceIdFormat("img", cf.SourceImageId) { + errs = append(errs, errors.New("source_image_id wrong format")) + } + + if cf.InstanceType == "" { + errs = append(errs, errors.New("instance_type must be specified")) + } + + if cf.UserData != "" && cf.UserDataFile != "" { + errs = append(errs, errors.New("only one of user_data or user_data_file can be specified")) + } else if cf.UserDataFile != "" { + if _, err := os.Stat(cf.UserDataFile); err != nil { + errs = append(errs, errors.New("user_data_file not exist")) + } + } + + if (cf.VpcId != "" || cf.CidrBlock != "") && cf.SubnetId == "" && cf.SubnectCidrBlock == "" { + errs = append(errs, errors.New("if vpc cidr_block is specified, then "+ + "subnet_cidr_block must also be specified.")) + } + + if cf.VpcId == "" { + if cf.VpcName == "" { + cf.VpcName = fmt.Sprintf("packer_%s", uuid.TimeOrderedUUID()) + } + if cf.CidrBlock == "" { + cf.CidrBlock = "10.0.0.0/16" + } + if cf.SubnetId != "" { + errs = append(errs, errors.New("can't set subnet_id without set vpc_id")) + } + } + if cf.SubnetId == "" { + if cf.SubnetName == "" { + cf.SubnetName = fmt.Sprintf("packer_%s", uuid.TimeOrderedUUID()) + } + if cf.SubnectCidrBlock == "" { + cf.SubnectCidrBlock = "10.0.8.0/24" + } + } + + if cf.SecurityGroupId == "" && cf.SecurityGroupName == "" { + cf.SecurityGroupName = fmt.Sprintf("packer_%s", uuid.TimeOrderedUUID()) + } + + if cf.DiskType != "" && !checkDiskType(cf.DiskType) { + errs = append(errs, errors.New(fmt.Sprintf("specified disk_type(%s) is invalid", cf.DiskType))) + } else if cf.DiskType == "" { + cf.DiskType = "CLOUD_BASIC" + } + + if cf.DiskSize <= 0 { + cf.DiskSize = 50 + } + + if cf.AssociatePublicIpAddress && cf.InternetMaxBandwidthOut <= 0 { + cf.InternetMaxBandwidthOut = 1 + } + + if cf.InstanceName == "" { + cf.InstanceName = fmt.Sprintf("packer-%s", uuid.TimeOrderedUUID()) + } + + if cf.HostName == "" { + cf.HostName = cf.InstanceName[:15] + } + + return errs +} + +func checkDiskType(diskType string) bool { + for _, valid := range ValidCBSType { + if valid == diskType { + return true + } + } + return false +} diff --git a/builder/tencentcloud/cvm/run_config_test.go b/builder/tencentcloud/cvm/run_config_test.go new file mode 100644 index 000000000..7657f2d2e --- /dev/null +++ b/builder/tencentcloud/cvm/run_config_test.go @@ -0,0 +1,127 @@ +package cvm + +import ( + "github.com/hashicorp/packer/helper/communicator" + "io/ioutil" + "os" + "testing" +) + +func testConfig() *TencentCloudRunConfig { + return &TencentCloudRunConfig{ + SourceImageId: "img-qwer1234", + InstanceType: "S3.SMALL2", + Comm: communicator.Config{ + SSHUsername: "tencentcloud", + }, + } +} + +func TestTencentCloudRunConfig_Prepare(t *testing.T) { + cf := testConfig() + + if err := cf.Prepare(nil); err != nil { + t.Fatalf("shouldn't have err: %v", err) + } + + cf.InstanceType = "" + if err := cf.Prepare(nil); err == nil { + t.Fatal("should have err") + } + + cf.InstanceType = "S3.SMALL2" + cf.SourceImageId = "" + if err := cf.Prepare(nil); err == nil { + t.Fatal("should have err") + } + + cf.SourceImageId = "img-qwer1234" + cf.Comm.SSHPort = 0 + if err := cf.Prepare(nil); err != nil { + t.Fatalf("shouldn't have err: %v", err) + } + + if cf.Comm.SSHPort != 22 { + t.Fatalf("invalid ssh port value: %v", cf.Comm.SSHPort) + } + + cf.Comm.SSHPort = 44 + if err := cf.Prepare(nil); err != nil { + t.Fatalf("shouldn't have err: %v", err) + } + + if cf.Comm.SSHPort != 44 { + t.Fatalf("invalid ssh port value: %v", cf.Comm.SSHPort) + } +} + +func TestTencentCloudRunConfigPrepare_UserData(t *testing.T) { + cf := testConfig() + tf, err := ioutil.TempFile("", "packer") + if err != nil { + t.Fatalf("new temp file failed: %v", err) + } + defer os.Remove(tf.Name()) + defer tf.Close() + + cf.UserData = "text user_data" + cf.UserDataFile = tf.Name() + if err := cf.Prepare(nil); err == nil { + t.Fatal("should have error") + } +} + +func TestTencentCloudRunConfigPrepare_UserDataFile(t *testing.T) { + cf := testConfig() + cf.UserDataFile = "not-exist-file" + if err := cf.Prepare(nil); err == nil { + t.Fatal("should have error") + } + + tf, err := ioutil.TempFile("", "packer") + if err != nil { + t.Fatalf("new temp file failed: %v", err) + } + defer os.Remove(tf.Name()) + defer tf.Close() + + cf.UserDataFile = tf.Name() + if err := cf.Prepare(nil); err != nil { + t.Fatalf("shouldn't have error: %v", err) + } +} + +func TestTencentCloudRunConfigPrepare_TemporaryKeyPairName(t *testing.T) { + cf := testConfig() + cf.Comm.SSHTemporaryKeyPairName = "" + if err := cf.Prepare(nil); err != nil { + t.Fatalf("shouldn't have error: %v", err) + } + + if cf.Comm.SSHTemporaryKeyPairName == "" { + t.Fatal("invalid ssh key pair value") + } + + cf.Comm.SSHTemporaryKeyPairName = "ssh-key-123" + if err := cf.Prepare(nil); err != nil { + t.Fatalf("shouldn't have error: %v", err) + } + + if cf.Comm.SSHTemporaryKeyPairName != "ssh-key-123" { + t.Fatalf("invalid ssh key pair value: %v", cf.Comm.SSHTemporaryKeyPairName) + } +} + +func TestTencentCloudRunConfigPrepare_SSHPrivateIp(t *testing.T) { + cf := testConfig() + if cf.SSHPrivateIp != false { + t.Fatalf("invalid ssh_private_ip value: %v", cf.SSHPrivateIp) + } + cf.SSHPrivateIp = true + if err := cf.Prepare(nil); err != nil { + t.Fatalf("shouldn't have error: %v", err) + } + if cf.SSHPrivateIp != true { + t.Fatalf("invalud ssh_private_ip value: %v", cf.SSHPrivateIp) + } +} diff --git a/builder/tencentcloud/cvm/step_check_source_image.go b/builder/tencentcloud/cvm/step_check_source_image.go new file mode 100644 index 000000000..de67d85a2 --- /dev/null +++ b/builder/tencentcloud/cvm/step_check_source_image.go @@ -0,0 +1,45 @@ +package cvm + +import ( + "context" + "fmt" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" +) + +type stepCheckSourceImage struct { + sourceImageId string +} + +func (s *stepCheckSourceImage) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + client := state.Get("cvm_client").(*cvm.Client) + config := state.Get("config").(*Config) + ui := state.Get("ui").(packer.Ui) + + req := cvm.NewDescribeImagesRequest() + req.ImageIds = []*string{&config.SourceImageId} + req.InstanceType = &config.InstanceType + + resp, err := client.DescribeImages(req) + if err != nil { + err := fmt.Errorf("querying image info failed: %s", err.Error()) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + if *resp.Response.TotalCount > 0 { // public image or private image. + state.Put("source_image", resp.Response.ImageSet[0]) + ui.Message(fmt.Sprintf("Image found: %s", *resp.Response.ImageSet[0].ImageId)) + return multistep.ActionContinue + } + // later market image will be included. + err = fmt.Errorf("no image founded under current instance_type(%s) restriction", config.InstanceType) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt +} + +func (s *stepCheckSourceImage) Cleanup(bag multistep.StateBag) {} diff --git a/builder/tencentcloud/cvm/step_config_key_pair.go b/builder/tencentcloud/cvm/step_config_key_pair.go new file mode 100644 index 000000000..a4c33472e --- /dev/null +++ b/builder/tencentcloud/cvm/step_config_key_pair.go @@ -0,0 +1,132 @@ +package cvm + +import ( + "context" + "fmt" + "io/ioutil" + "os" + "runtime" + "strings" + + "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" +) + +type stepConfigKeyPair struct { + Debug bool + Comm *communicator.Config + DebugKeyPath string + + keyID string +} + +func (s *stepConfigKeyPair) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + ui := state.Get("ui").(packer.Ui) + + if s.Comm.SSHPrivateKeyFile != "" { + ui.Say("Using existing SSH private key") + privateKeyBytes, err := ioutil.ReadFile(s.Comm.SSHPrivateKeyFile) + if err != nil { + state.Put("error", fmt.Errorf( + "loading configured private key file failed: %s", err)) + return multistep.ActionHalt + } + + s.Comm.SSHPrivateKey = privateKeyBytes + + return multistep.ActionContinue + } + + if s.Comm.SSHAgentAuth && s.Comm.SSHKeyPairName == "" { + ui.Say("Using SSH Agent with key pair in source image") + return multistep.ActionContinue + } + + if s.Comm.SSHAgentAuth && s.Comm.SSHKeyPairName != "" { + ui.Say(fmt.Sprintf("Using SSH Agent for existing key pair %s", s.Comm.SSHKeyPairName)) + return multistep.ActionContinue + } + + if s.Comm.SSHTemporaryKeyPairName == "" { + ui.Say("Not using temporary keypair") + s.Comm.SSHKeyPairName = "" + return multistep.ActionContinue + } + + client := state.Get("cvm_client").(*cvm.Client) + ui.Say(fmt.Sprintf("Creating temporary keypair: %s", s.Comm.SSHTemporaryKeyPairName)) + req := cvm.NewCreateKeyPairRequest() + req.KeyName = &s.Comm.SSHTemporaryKeyPairName + defaultProjectId := int64(0) + req.ProjectId = &defaultProjectId + resp, err := client.CreateKeyPair(req) + if err != nil { + state.Put("error", fmt.Errorf("creating temporary keypair failed: %s", err.Error())) + return multistep.ActionHalt + } + + // set keyId to delete when Cleanup + s.keyID = *resp.Response.KeyPair.KeyId + + s.Comm.SSHKeyPairName = *resp.Response.KeyPair.KeyId + s.Comm.SSHPrivateKey = []byte(*resp.Response.KeyPair.PrivateKey) + + if s.Debug { + ui.Message(fmt.Sprintf("Saving key for debug purposes: %s", s.DebugKeyPath)) + f, err := os.Create(s.DebugKeyPath) + if err != nil { + state.Put("error", fmt.Errorf("creating debug key file failed:%s", err.Error())) + return multistep.ActionHalt + } + defer f.Close() + + if _, err := f.Write([]byte(*resp.Response.KeyPair.PrivateKey)); err != nil { + state.Put("error", fmt.Errorf("writing debug key file failed:%s", err.Error())) + return multistep.ActionHalt + } + + if runtime.GOOS != "windows" { + if err := f.Chmod(0600); err != nil { + state.Put("error", fmt.Errorf("setting debug key file's permission failed:%s", err.Error())) + return multistep.ActionHalt + } + } + } + return multistep.ActionContinue +} + +func (s *stepConfigKeyPair) Cleanup(state multistep.StateBag) { + if s.Comm.SSHPrivateKeyFile != "" || (s.Comm.SSHKeyPairName == "" && s.keyID == "") { + return + } + + client := state.Get("cvm_client").(*cvm.Client) + ui := state.Get("ui").(packer.Ui) + + ui.Say("Deleting temporary keypair...") + req := cvm.NewDeleteKeyPairsRequest() + req.KeyIds = []*string{&s.keyID} + err := common.Retry(5, 5, 60, func(u uint) (bool, error) { + _, err := client.DeleteKeyPairs(req) + if err == nil { + return true, nil + } + if strings.Index(err.Error(), "NotSupported") != -1 { + return false, nil + } else { + return false, err + } + }) + if err != nil { + ui.Error(fmt.Sprintf( + "delete keypair failed, please delete it manually, keyId: %s, err: %s", s.keyID, err.Error())) + } + if s.Debug { + if err := os.Remove(s.DebugKeyPath); err != nil { + ui.Error(fmt.Sprintf("delete debug key file %s failed: %s", s.DebugKeyPath, err.Error())) + } + } +} diff --git a/builder/tencentcloud/cvm/step_config_security_group.go b/builder/tencentcloud/cvm/step_config_security_group.go new file mode 100644 index 000000000..4dbcfba3a --- /dev/null +++ b/builder/tencentcloud/cvm/step_config_security_group.go @@ -0,0 +1,127 @@ +package cvm + +import ( + "context" + + "fmt" + "strings" + + "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/pkg/errors" + vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" +) + +type stepConfigSecurityGroup struct { + SecurityGroupId string + SecurityGroupName string + Description string + isCreate bool +} + +func (s *stepConfigSecurityGroup) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + vpcClient := state.Get("vpc_client").(*vpc.Client) + ui := state.Get("ui").(packer.Ui) + + if len(s.SecurityGroupId) != 0 { // use existing security group + req := vpc.NewDescribeSecurityGroupsRequest() + req.SecurityGroupIds = []*string{&s.SecurityGroupId} + resp, err := vpcClient.DescribeSecurityGroups(req) + if err != nil { + ui.Error(fmt.Sprintf("query security group failed: %s", err.Error())) + state.Put("error", err) + return multistep.ActionHalt + } + if *resp.Response.TotalCount > 0 { + state.Put("security_group_id", s.SecurityGroupId) + s.isCreate = false + return multistep.ActionContinue + } + message := fmt.Sprintf("the specified security group(%s) does not exist", s.SecurityGroupId) + ui.Error(message) + state.Put("error", errors.New(message)) + return multistep.ActionHalt + } + // create a new security group + req := vpc.NewCreateSecurityGroupRequest() + req.GroupName = &s.SecurityGroupName + req.GroupDescription = &s.Description + resp, err := vpcClient.CreateSecurityGroup(req) + if err != nil { + ui.Error(fmt.Sprintf("create security group failed: %s", err.Error())) + state.Put("error", err) + return multistep.ActionHalt + } + s.SecurityGroupId = *resp.Response.SecurityGroup.SecurityGroupId + state.Put("security_group_id", s.SecurityGroupId) + s.isCreate = true + + // bind security group ingress police + pReq := vpc.NewCreateSecurityGroupPoliciesRequest() + ACCEPT := "ACCEPT" + DEFAULT_CIDR := "0.0.0.0/0" + pReq.SecurityGroupId = &s.SecurityGroupId + pReq.SecurityGroupPolicySet = &vpc.SecurityGroupPolicySet{ + Ingress: []*vpc.SecurityGroupPolicy{ + { + CidrBlock: &DEFAULT_CIDR, + Action: &ACCEPT, + }, + }, + } + _, err = vpcClient.CreateSecurityGroupPolicies(pReq) + if err != nil { + ui.Error(fmt.Sprintf("bind security group police failed: %s", err.Error())) + state.Put("error", err) + return multistep.ActionHalt + } + + // bind security group engress police + pReq = vpc.NewCreateSecurityGroupPoliciesRequest() + pReq.SecurityGroupId = &s.SecurityGroupId + pReq.SecurityGroupPolicySet = &vpc.SecurityGroupPolicySet{ + Egress: []*vpc.SecurityGroupPolicy{ + { + CidrBlock: &DEFAULT_CIDR, + Action: &ACCEPT, + }, + }, + } + _, err = vpcClient.CreateSecurityGroupPolicies(pReq) + if err != nil { + ui.Error(fmt.Sprintf("bind security group police failed: %s", err.Error())) + state.Put("error", err) + return multistep.ActionHalt + } + + return multistep.ActionContinue +} + +func (s *stepConfigSecurityGroup) Cleanup(state multistep.StateBag) { + if !s.isCreate { + return + } + vpcClient := state.Get("vpc_client").(*vpc.Client) + ui := state.Get("ui").(packer.Ui) + + MessageClean(state, "VPC") + req := vpc.NewDeleteSecurityGroupRequest() + req.SecurityGroupId = &s.SecurityGroupId + err := common.Retry(5, 5, 60, func(u uint) (bool, error) { + _, err := vpcClient.DeleteSecurityGroup(req) + if err == nil { + return true, nil + } + if strings.Index(err.Error(), "ResourceInUse") != -1 { + return false, nil + } else { + return false, err + } + }) + if err != nil { + ui.Error(fmt.Sprintf("delete security group(%s) failed: %s, you need to delete it by hand", + s.SecurityGroupId, err.Error())) + return + } +} diff --git a/builder/tencentcloud/cvm/step_config_subnet.go b/builder/tencentcloud/cvm/step_config_subnet.go new file mode 100644 index 000000000..f77f1e84d --- /dev/null +++ b/builder/tencentcloud/cvm/step_config_subnet.go @@ -0,0 +1,103 @@ +package cvm + +import ( + "context" + "fmt" + "strings" + + "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/pkg/errors" + vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" +) + +type stepConfigSubnet struct { + SubnetId string + SubnetCidrBlock string + SubnetName string + Zone string + isCreate bool +} + +func (s *stepConfigSubnet) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + vpcClient := state.Get("vpc_client").(*vpc.Client) + ui := state.Get("ui").(packer.Ui) + vpcId := state.Get("vpc_id").(string) + + if len(s.SubnetId) != 0 { // exist subnet + ui.Say(fmt.Sprintf("Trying to use existing subnet(%s)", s.SubnetId)) + req := vpc.NewDescribeSubnetsRequest() + req.SubnetIds = []*string{&s.SubnetId} + resp, err := vpcClient.DescribeSubnets(req) + if err != nil { + ui.Error(fmt.Sprintf("query subnet failed: %s", err.Error())) + state.Put("error", err) + return multistep.ActionHalt + } + if *resp.Response.TotalCount > 0 { + subnet0 := *resp.Response.SubnetSet[0] + if *subnet0.VpcId != vpcId { + message := fmt.Sprintf("the specified subnet(%s) does not belong to "+ + "the specified vpc(%s)", s.SubnetId, vpcId) + ui.Error(message) + state.Put("error", errors.New(message)) + return multistep.ActionHalt + } + state.Put("subnet_id", *subnet0.SubnetId) + s.isCreate = false + return multistep.ActionContinue + } + message := fmt.Sprintf("the specified subnet(%s) does not exist", s.SubnetId) + state.Put("error", errors.New(message)) + ui.Error(message) + return multistep.ActionHalt + } else { // create a new subnet, tencentcloud create subnet api is synchronous, no need to wait for create. + ui.Say(fmt.Sprintf("Trying to create a new subnet")) + req := vpc.NewCreateSubnetRequest() + req.VpcId = &vpcId + req.SubnetName = &s.SubnetName + req.CidrBlock = &s.SubnetCidrBlock + req.Zone = &s.Zone + resp, err := vpcClient.CreateSubnet(req) + if err != nil { + ui.Error(fmt.Sprintf("create subnet failed: %s", err.Error())) + state.Put("error", err) + return multistep.ActionHalt + } + subnet0 := *resp.Response.Subnet + state.Put("subnet_id", *subnet0.SubnetId) + s.SubnetId = *subnet0.SubnetId + s.isCreate = true + return multistep.ActionContinue + } +} + +func (s *stepConfigSubnet) Cleanup(state multistep.StateBag) { + if !s.isCreate { + return + } + + vpcClient := state.Get("vpc_client").(*vpc.Client) + ui := state.Get("ui").(packer.Ui) + + MessageClean(state, "SUBNET") + req := vpc.NewDeleteSubnetRequest() + req.SubnetId = &s.SubnetId + err := common.Retry(5, 5, 60, func(u uint) (bool, error) { + _, err := vpcClient.DeleteSubnet(req) + if err == nil { + return true, nil + } + if strings.Index(err.Error(), "ResourceInUse") != -1 { + return false, nil + } else { + return false, err + } + }) + if err != nil { + ui.Error(fmt.Sprintf("delete subnet(%s) failed: %s, you need to delete it by hand", + s.SubnetId, err.Error())) + return + } +} diff --git a/builder/tencentcloud/cvm/step_config_vpc.go b/builder/tencentcloud/cvm/step_config_vpc.go new file mode 100644 index 000000000..65a9299c6 --- /dev/null +++ b/builder/tencentcloud/cvm/step_config_vpc.go @@ -0,0 +1,92 @@ +package cvm + +import ( + "context" + "fmt" + "strings" + + "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/pkg/errors" + vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" +) + +type stepConfigVPC struct { + VpcId string + CidrBlock string + VpcName string + isCreate bool +} + +func (s *stepConfigVPC) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + vpcClient := state.Get("vpc_client").(*vpc.Client) + ui := state.Get("ui").(packer.Ui) + + if len(s.VpcId) != 0 { // exist vpc + ui.Say(fmt.Sprintf("Trying to use existing vpc(%s)", s.VpcId)) + req := vpc.NewDescribeVpcsRequest() + req.VpcIds = []*string{&s.VpcId} + resp, err := vpcClient.DescribeVpcs(req) + if err != nil { + ui.Error(fmt.Sprintf("query vpc failed: %s", err.Error())) + state.Put("error", err) + return multistep.ActionHalt + } + if *resp.Response.TotalCount > 0 { + vpc0 := *resp.Response.VpcSet[0] + state.Put("vpc_id", *vpc0.VpcId) + s.isCreate = false + return multistep.ActionContinue + } + message := fmt.Sprintf("the specified vpc(%s) does not exist", s.VpcId) + state.Put("error", errors.New(message)) + ui.Error(message) + return multistep.ActionHalt + } else { // create a new vpc, tencentcloud create vpc api is synchronous, no need to wait for create. + ui.Say(fmt.Sprintf("Trying to create a new vpc")) + req := vpc.NewCreateVpcRequest() + req.VpcName = &s.VpcName + req.CidrBlock = &s.CidrBlock + resp, err := vpcClient.CreateVpc(req) + if err != nil { + ui.Error(fmt.Sprintf("create vpc failed: %s", err.Error())) + state.Put("error", err) + return multistep.ActionHalt + } + vpc0 := *resp.Response.Vpc + state.Put("vpc_id", *vpc0.VpcId) + s.VpcId = *vpc0.VpcId + s.isCreate = true + return multistep.ActionContinue + } +} + +func (s *stepConfigVPC) Cleanup(state multistep.StateBag) { + if !s.isCreate { + return + } + + vpcClient := state.Get("vpc_client").(*vpc.Client) + ui := state.Get("ui").(packer.Ui) + + MessageClean(state, "VPC") + req := vpc.NewDeleteVpcRequest() + req.VpcId = &s.VpcId + err := common.Retry(5, 5, 60, func(u uint) (bool, error) { + _, err := vpcClient.DeleteVpc(req) + if err == nil { + return true, nil + } + if strings.Index(err.Error(), "ResourceInUse") != -1 { + return false, nil + } else { + return false, err + } + }) + if err != nil { + ui.Error(fmt.Sprintf("delete vpc(%s) failed: %s, you need to delete it by hand", + s.VpcId, err.Error())) + return + } +} diff --git a/builder/tencentcloud/cvm/step_copy_image.go b/builder/tencentcloud/cvm/step_copy_image.go new file mode 100644 index 000000000..97feef048 --- /dev/null +++ b/builder/tencentcloud/cvm/step_copy_image.go @@ -0,0 +1,47 @@ +package cvm + +import ( + "context" + "fmt" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" +) + +type stepCopyImage struct { + DesinationRegions []string + SourceRegion string +} + +func (s *stepCopyImage) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + if len(s.DesinationRegions) == 0 || (len(s.DesinationRegions) == 1 && s.DesinationRegions[0] == s.SourceRegion) { + return multistep.ActionContinue + } + + client := state.Get("cvm_client").(*cvm.Client) + ui := state.Get("ui").(packer.Ui) + imageId := state.Get("image").(*cvm.Image).ImageId + + req := cvm.NewSyncImagesRequest() + req.ImageIds = []*string{imageId} + copyRegions := make([]*string, 0, len(s.DesinationRegions)) + for _, region := range s.DesinationRegions { + if region != s.SourceRegion { + copyRegions = append(copyRegions, ®ion) + } + } + req.DestinationRegions = copyRegions + + _, err := client.SyncImages(req) + if err != nil { + state.Put("error", err) + ui.Error(fmt.Sprintf("copy image failed: %s", err.Error())) + return multistep.ActionHalt + } + return multistep.ActionContinue +} + +func (s *stepCopyImage) Cleanup(state multistep.StateBag) { + // just do nothing +} diff --git a/builder/tencentcloud/cvm/step_create_image.go b/builder/tencentcloud/cvm/step_create_image.go new file mode 100644 index 000000000..7a8555be0 --- /dev/null +++ b/builder/tencentcloud/cvm/step_create_image.go @@ -0,0 +1,116 @@ +package cvm + +import ( + "context" + "fmt" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" +) + +type stepCreateImage struct { + imageId string +} + +func (s *stepCreateImage) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + config := state.Get("config").(*Config) + client := state.Get("cvm_client").(*cvm.Client) + ui := state.Get("ui").(packer.Ui) + instance := state.Get("instance").(*cvm.Instance) + + ui.Say(fmt.Sprintf("Creating image %s", config.ImageName)) + + req := cvm.NewCreateImageRequest() + req.ImageName = &config.ImageName + req.ImageDescription = &config.ImageDescription + req.InstanceId = instance.InstanceId + + True := "True" + False := "False" + if config.ForcePoweroff { + req.ForcePoweroff = &True + } else { + req.ForcePoweroff = &False + } + + if config.Reboot { + req.Reboot = &True + } else { + req.Reboot = &False + } + + if config.Sysprep { + req.Sysprep = &True + } else { + req.Sysprep = &False + } + + _, err := client.CreateImage(req) + if err != nil { + err := fmt.Errorf("create image failed: %s", err.Error()) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + err = WaitForImageReady(client, config.ImageName, "NORMAL", 3600) + if err != nil { + err := fmt.Errorf("create image failed: %s", err.Error()) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + describeReq := cvm.NewDescribeImagesRequest() + FILTER_IMAGE_NAME := "image-name" + describeReq.Filters = []*cvm.Filter{ + { + Name: &FILTER_IMAGE_NAME, + Values: []*string{&config.ImageName}, + }, + } + describeResp, err := client.DescribeImages(describeReq) + if err != nil { + err := fmt.Errorf("wait image ready failed: %s", err.Error()) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + if *describeResp.Response.TotalCount == 0 { + err := fmt.Errorf("create image(%s) failed", config.ImageName) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + s.imageId = *describeResp.Response.ImageSet[0].ImageId + state.Put("image", describeResp.Response.ImageSet[0]) + + tencentCloudImages := make(map[string]string) + tencentCloudImages[config.Region] = s.imageId + state.Put("tencentcloudimages", tencentCloudImages) + + return multistep.ActionContinue +} + +func (s *stepCreateImage) Cleanup(state multistep.StateBag) { + if s.imageId == "" { + return + } + _, cancelled := state.GetOk(multistep.StateCancelled) + _, halted := state.GetOk(multistep.StateHalted) + if !cancelled && !halted { + return + } + + client := state.Get("cvm_client").(*cvm.Client) + ui := state.Get("ui").(packer.Ui) + + ui.Say("Delete image because of cancellation or error...") + req := cvm.NewDeleteImagesRequest() + req.ImageIds = []*string{&s.imageId} + _, err := client.DeleteImages(req) + if err != nil { + ui.Error(fmt.Sprintf("delete image(%s) failed", s.imageId)) + } +} diff --git a/builder/tencentcloud/cvm/step_pre_validate.go b/builder/tencentcloud/cvm/step_pre_validate.go new file mode 100644 index 000000000..0a07b45f1 --- /dev/null +++ b/builder/tencentcloud/cvm/step_pre_validate.go @@ -0,0 +1,21 @@ +package cvm + +import ( + "context" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" +) + +type stepPreValidate struct { + DestImageName string + ForceDelete bool +} + +func (s *stepPreValidate) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + ui := state.Get("ui").(packer.Ui) + ui.Say("TencentCloud support images with same name, image_name check is not required.") + return multistep.ActionContinue +} + +func (s *stepPreValidate) Cleanup(multistep.StateBag) {} diff --git a/builder/tencentcloud/cvm/step_run_instance.go b/builder/tencentcloud/cvm/step_run_instance.go new file mode 100644 index 000000000..40713e25d --- /dev/null +++ b/builder/tencentcloud/cvm/step_run_instance.go @@ -0,0 +1,158 @@ +package cvm + +import ( + "context" + "encoding/base64" + "fmt" + "io/ioutil" + "log" + "time" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" +) + +type stepRunInstance struct { + InstanceType string + UserData string + UserDataFile string + instanceId string + ZoneId string + InstanceName string + DiskType string + DiskSize int64 + HostName string + InternetMaxBandwidthOut int64 + AssociatePublicIpAddress bool +} + +func (s *stepRunInstance) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + client := state.Get("cvm_client").(*cvm.Client) + config := state.Get("config").(*Config) + ui := state.Get("ui").(packer.Ui) + source_image := state.Get("source_image").(*cvm.Image) + vpc_id := state.Get("vpc_id").(string) + subnet_id := state.Get("subnet_id").(string) + security_group_id := state.Get("security_group_id").(string) + + password := config.Comm.SSHPassword + if password == "" && config.Comm.WinRMPassword != "" { + password = config.Comm.WinRMPassword + } + userData, err := s.getUserData(state) + if err != nil { + err := fmt.Errorf("get user_data failed: %s", err.Error()) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + ui.Say("Creating Instance.") + // config RunInstances parameters + POSTPAID_BY_HOUR := "POSTPAID_BY_HOUR" + req := cvm.NewRunInstancesRequest() + if s.ZoneId != "" { + req.Placement = &cvm.Placement{ + Zone: &s.ZoneId, + } + } + req.ImageId = source_image.ImageId + req.InstanceChargeType = &POSTPAID_BY_HOUR + req.InstanceType = &s.InstanceType + req.SystemDisk = &cvm.SystemDisk{ + DiskType: &s.DiskType, + DiskSize: &s.DiskSize, + } + req.VirtualPrivateCloud = &cvm.VirtualPrivateCloud{ + VpcId: &vpc_id, + SubnetId: &subnet_id, + } + TRAFFIC_POSTPAID_BY_HOUR := "TRAFFIC_POSTPAID_BY_HOUR" + if s.AssociatePublicIpAddress { + req.InternetAccessible = &cvm.InternetAccessible{ + InternetChargeType: &TRAFFIC_POSTPAID_BY_HOUR, + InternetMaxBandwidthOut: &s.InternetMaxBandwidthOut, + } + } + req.InstanceName = &s.InstanceName + loginSettings := cvm.LoginSettings{} + if password != "" { + loginSettings.Password = &password + } + if config.Comm.SSHKeyPairName != "" { + loginSettings.KeyIds = []*string{&config.Comm.SSHKeyPairName} + } + req.LoginSettings = &loginSettings + req.SecurityGroupIds = []*string{&security_group_id} + req.ClientToken = &s.InstanceName + req.HostName = &s.HostName + req.UserData = &userData + + resp, err := client.RunInstances(req) + if err != nil { + err := fmt.Errorf("create instance failed: %s", err.Error()) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + if len(resp.Response.InstanceIdSet) != 1 { + err := fmt.Errorf("create instance failed: %d instance(s) created", len(resp.Response.InstanceIdSet)) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + s.instanceId = *resp.Response.InstanceIdSet[0] + + err = WaitForInstance(client, s.instanceId, "RUNNING", 1800) + if err != nil { + err := fmt.Errorf("wait instance launch failed: %s", err.Error()) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + describeReq := cvm.NewDescribeInstancesRequest() + describeReq.InstanceIds = []*string{&s.instanceId} + describeResp, err := client.DescribeInstances(describeReq) + if err != nil { + err := fmt.Errorf("wait instance launch failed: %s", err.Error()) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + state.Put("instance", describeResp.Response.InstanceSet[0]) + return multistep.ActionContinue +} + +func (s *stepRunInstance) getUserData(state multistep.StateBag) (string, error) { + userData := s.UserData + if userData == "" && s.UserDataFile != "" { + data, err := ioutil.ReadFile(s.UserDataFile) + if err != nil { + return "", err + } + userData = string(data) + } + userData = base64.StdEncoding.EncodeToString([]byte(userData)) + log.Printf(fmt.Sprintf("user_data: %s", userData)) + return userData, nil +} + +func (s *stepRunInstance) Cleanup(state multistep.StateBag) { + if s.instanceId == "" { + return + } + MessageClean(state, "instance") + client := state.Get("cvm_client").(*cvm.Client) + ui := state.Get("ui").(packer.Ui) + req := cvm.NewTerminateInstancesRequest() + req.InstanceIds = []*string{&s.instanceId} + _, err := client.TerminateInstances(req) + // The binding relation between instance and vpc would last few minutes after + // instance terminate, we sleep here to give more time + time.Sleep(2 * time.Minute) + if err != nil { + ui.Error(fmt.Sprintf("terminate instance(%s) failed: %s", s.instanceId, err.Error())) + } +} diff --git a/builder/tencentcloud/cvm/step_share_image.go b/builder/tencentcloud/cvm/step_share_image.go new file mode 100644 index 000000000..1f4bfd464 --- /dev/null +++ b/builder/tencentcloud/cvm/step_share_image.go @@ -0,0 +1,68 @@ +package cvm + +import ( + "context" + "fmt" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" +) + +type stepShareImage struct { + ShareAccounts []string +} + +func (s *stepShareImage) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + if len(s.ShareAccounts) == 0 { + return multistep.ActionContinue + } + + client := state.Get("cvm_client").(*cvm.Client) + ui := state.Get("ui").(packer.Ui) + imageId := state.Get("image").(*cvm.Image).ImageId + + req := cvm.NewModifyImageSharePermissionRequest() + req.ImageId = imageId + SHARE := "SHARE" + req.Permission = &SHARE + accounts := make([]*string, 0, len(s.ShareAccounts)) + for _, account := range s.ShareAccounts { + accounts = append(accounts, &account) + } + req.AccountIds = accounts + + _, err := client.ModifyImageSharePermission(req) + if err != nil { + state.Put("error", err) + ui.Error(fmt.Sprintf("share image failed: %s", err.Error())) + return multistep.ActionHalt + } + return multistep.ActionContinue +} + +func (s *stepShareImage) Cleanup(state multistep.StateBag) { + _, cancelled := state.GetOk(multistep.StateCancelled) + _, halted := state.GetOk(multistep.StateHalted) + if cancelled || halted { + ui := state.Get("ui").(packer.Ui) + client := state.Get("cvm_client").(*cvm.Client) + imageId := state.Get("image").(*cvm.Image).ImageId + ui.Say("Cancel share image due to action cancelled or halted.") + + req := cvm.NewModifyImageSharePermissionRequest() + req.ImageId = imageId + CANCEL := "CANCEL" + req.Permission = &CANCEL + accounts := make([]*string, 0, len(s.ShareAccounts)) + for _, account := range s.ShareAccounts { + accounts = append(accounts, &account) + } + req.AccountIds = accounts + + _, err := client.ModifyImageSharePermission(req) + if err != nil { + ui.Error(fmt.Sprintf("Cancel share image failed: %s", err.Error())) + } + } +} diff --git a/command/plugin.go b/command/plugin.go index d0cd68153..825f06683 100644 --- a/command/plugin.go +++ b/command/plugin.go @@ -41,6 +41,7 @@ import ( profitbricksbuilder "github.com/hashicorp/packer/builder/profitbricks" qemubuilder "github.com/hashicorp/packer/builder/qemu" scalewaybuilder "github.com/hashicorp/packer/builder/scaleway" + tencentcloudbuilder "github.com/hashicorp/packer/builder/tencentcloud/cvm" tritonbuilder "github.com/hashicorp/packer/builder/triton" virtualboxisobuilder "github.com/hashicorp/packer/builder/virtualbox/iso" virtualboxovfbuilder "github.com/hashicorp/packer/builder/virtualbox/ovf" @@ -113,6 +114,7 @@ var Builders = map[string]packer.Builder{ "profitbricks": new(profitbricksbuilder.Builder), "qemu": new(qemubuilder.Builder), "scaleway": new(scalewaybuilder.Builder), + "tencentcloud-cvm": new(tencentcloudbuilder.Builder), "triton": new(tritonbuilder.Builder), "virtualbox-iso": new(virtualboxisobuilder.Builder), "virtualbox-ovf": new(virtualboxovfbuilder.Builder), diff --git a/examples/tencentcloud/basic.json b/examples/tencentcloud/basic.json new file mode 100644 index 000000000..62423d9ab --- /dev/null +++ b/examples/tencentcloud/basic.json @@ -0,0 +1,26 @@ +{ + "variables": { + "secret_id": "{{env `TENCENTCLOUD_ACCESS_KEY`}}", + "secret_key": "{{env `TENCENTCLOUD_SECRET_KEY`}}" + }, + "builders": [{ + "type": "tencentcloud-cvm", + "secret_id": "{{user `secret_id`}}", + "secret_key": "{{user `secret_key`}}", + "region": "ap-guangzhou", + "zone": "ap-guangzhou-3", + "instance_type": "S3.SMALL1", + "source_image_id": "img-oikl1tzv", + "ssh_username" : "root", + "image_name": "packerTest2", + "packer_debug": true, + "associate_public_ip_address": true + }], + "provisioners": [{ + "type": "shell", + "inline": [ + "sleep 30", + "yum install redis.x86_64 -y" + ] + }] +} \ No newline at end of file diff --git a/examples/tencentcloud/centos.json b/examples/tencentcloud/centos.json new file mode 100644 index 000000000..6b4d13bd5 --- /dev/null +++ b/examples/tencentcloud/centos.json @@ -0,0 +1,35 @@ +{ + "variables": { + "secret_id": "{{env `TENCENTCLOUD_ACCESS_KEY`}}", + "secret_key": "{{env `TENCENTCLOUD_SECRET_KEY`}}" + }, + "builders": [{ + "type": "tencentcloud-cvm", + "secret_id": "{{user `secret_id`}}", + "secret_key": "{{user `secret_key`}}", + "region": "ap-guangzhou", + "zone": "ap-guangzhou-3", + "instance_type": "S3.SMALL1", + "source_image_id": "img-oikl1tzv", + "vpc_id": "vpc-gjusx3kd", + "subnet_id": "subnet-pfditepm", + "internet_max_bandwidth_out": 2, + "security_group_id": "sg-rypoiksl", + "ssh_username" : "root", + "image_name": "packerTest", + "host_name": "packerTest", + "associate_public_ip_address": true, + "image_description": "centosPacker", + "image_copy_regions": ["ap-beijing"] + }], + "provisioners": [{ + "execute_command": "echo '{{user `ssh_pass`}}' | {{ .Vars }} sudo -S -E sh '{{ .Path }}'", + "inline": [ + "yum update -y", + "/usr/sbin/waagent -force -deprovision+user && export HISTSIZE=0 && sync" + ], + "inline_shebang": "/bin/sh -x", + "type": "shell", + "skip_clean": true + }] +} \ No newline at end of file diff --git a/go.mod b/go.mod index 58785da5f..c5aa3571c 100644 --- a/go.mod +++ b/go.mod @@ -154,6 +154,7 @@ require ( github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c // indirect github.com/stretchr/testify v1.2.2 + github.com/tencentcloud/tencentcloud-sdk-go v0.0.0-20181220135002-f1744d40d346 github.com/tent/http-link-go v0.0.0-20130702225549-ac974c61c2f9 // indirect github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 // indirect github.com/ugorji/go v0.0.0-20151218193438-646ae4a518c1 diff --git a/go.sum b/go.sum index a01b7317c..89b849f17 100644 --- a/go.sum +++ b/go.sum @@ -345,6 +345,8 @@ github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c h1:Ho+uVpke github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/tencentcloud/tencentcloud-sdk-go v0.0.0-20181220135002-f1744d40d346 h1:a014AaXz7AISMePv8xKRffUZZkr5z2XmSDf41gRV3+A= +github.com/tencentcloud/tencentcloud-sdk-go v0.0.0-20181220135002-f1744d40d346/go.mod h1:0PfYow01SHPMhKY31xa+EFz2RStxIqj6JFAJS+IkCi4= github.com/tent/http-link-go v0.0.0-20130702225549-ac974c61c2f9 h1:/Bsw4C+DEdqPjt8vAqaC9LAqpAQnaCQQqmolqq3S1T4= github.com/tent/http-link-go v0.0.0-20130702225549-ac974c61c2f9/go.mod h1:RHkNRtSLfOK7qBTHaeSX1D6BNpI3qw7NTxsmNr4RvN8= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8= diff --git a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/LICENSE b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/LICENSE new file mode 100644 index 000000000..efc75a225 --- /dev/null +++ b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright (c) 2017-2018 Tencent Ltd. + + 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. diff --git a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/client.go b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/client.go new file mode 100644 index 000000000..78f3ce7c7 --- /dev/null +++ b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/client.go @@ -0,0 +1,88 @@ +package common + +import ( + "log" + "net/http" + "time" + + tchttp "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http" + "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" +) + +type Client struct { + region string + httpClient *http.Client + httpProfile *profile.HttpProfile + credential *Credential + signMethod string + debug bool +} + +func (c *Client) Send(request tchttp.Request, response tchttp.Response) (err error) { + if request.GetDomain() == "" { + domain := c.httpProfile.Endpoint + if domain == "" { + domain = tchttp.GetServiceDomain(request.GetService()) + } + request.SetDomain(domain) + } + err = tchttp.ConstructParams(request) + if err != nil { + return + } + tchttp.CompleteCommonParams(request, c.GetRegion()) + err = signRequest(request, c.credential, c.signMethod) + if err != nil { + return + } + httpRequest, err := http.NewRequest(request.GetHttpMethod(), request.GetUrl(), request.GetBodyReader()) + if err != nil { + return + } + if request.GetHttpMethod() == "POST" { + httpRequest.Header["Content-Type"] = []string{"application/x-www-form-urlencoded"} + } + //log.Printf("[DEBUG] http request=%v", httpRequest) + httpResponse, err := c.httpClient.Do(httpRequest) + if err != nil { + return err + } + err = tchttp.ParseFromHttpResponse(httpResponse, response) + return +} + +func (c *Client) GetRegion() string { + return c.region +} + +func (c *Client) Init(region string) *Client { + c.httpClient = &http.Client{} + c.region = region + c.signMethod = "HmacSHA256" + c.debug = false + log.SetFlags(log.LstdFlags | log.Lshortfile) + return c +} + +func (c *Client) WithSecretId(secretId, secretKey string) *Client { + c.credential = NewCredential(secretId, secretKey) + return c +} + +func (c *Client) WithProfile(clientProfile *profile.ClientProfile) *Client { + c.signMethod = clientProfile.SignMethod + c.httpProfile = clientProfile.HttpProfile + c.httpClient.Timeout = time.Duration(c.httpProfile.ReqTimeout) * time.Second + return c +} + +func (c *Client) WithSignatureMethod(method string) *Client { + c.signMethod = method + return c +} + +func NewClientWithSecretId(secretId, secretKey, region string) (client *Client, err error) { + client = &Client{} + client.Init(region).WithSecretId(secretId, secretKey) + return +} diff --git a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/credentials.go b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/credentials.go new file mode 100644 index 000000000..19f0722de --- /dev/null +++ b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/credentials.go @@ -0,0 +1,40 @@ +package common + +type Credential struct { + SecretId string + SecretKey string +} + +func NewCredential(secretId, secretKey string) *Credential { + return &Credential{ + SecretId: secretId, + SecretKey: secretKey, + } +} + +func (c *Credential) GetCredentialParams() map[string]string { + return map[string]string{ + "SecretId": c.SecretId, + } +} + +type TokenCredential struct { + SecretId string + SecretKey string + Token string +} + +func NewTokenCredential(secretId, secretKey, token string) *TokenCredential { + return &TokenCredential{ + SecretId: secretId, + SecretKey: secretKey, + Token: token, + } +} + +func (c *TokenCredential) GetCredentialParams() map[string]string { + return map[string]string{ + "SecretId": c.SecretId, + "Token": c.Token, + } +} diff --git a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors/errors.go b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors/errors.go new file mode 100644 index 000000000..27589e59a --- /dev/null +++ b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors/errors.go @@ -0,0 +1,35 @@ +package errors + +import ( + "fmt" +) + +type TencentCloudSDKError struct { + Code string + Message string + RequestId string +} + +func (e *TencentCloudSDKError) Error() string { + return fmt.Sprintf("[TencentCloudSDKError] Code=%s, Message=%s, RequestId=%s", e.Code, e.Message, e.RequestId) +} + +func NewTencentCloudSDKError(code, message, requestId string) error { + return &TencentCloudSDKError{ + Code: code, + Message: message, + RequestId: requestId, + } +} + +func (e *TencentCloudSDKError) GetCode() string { + return e.Code +} + +func (e *TencentCloudSDKError) GetMessage() string { + return e.Message +} + +func (e *TencentCloudSDKError) GetRequestId() string { + return e.RequestId +} diff --git a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http/request.go b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http/request.go new file mode 100644 index 000000000..a092a7f72 --- /dev/null +++ b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http/request.go @@ -0,0 +1,231 @@ +package common + +import ( + "io" + //"log" + "math/rand" + "net/url" + "reflect" + "strconv" + "strings" + "time" +) + +const ( + POST = "POST" + GET = "GET" + + RootDomain = "tencentcloudapi.com" + Path = "/" +) + +type Request interface { + GetAction() string + GetBodyReader() io.Reader + GetDomain() string + GetHttpMethod() string + GetParams() map[string]string + GetPath() string + GetService() string + GetUrl() string + GetVersion() string + SetDomain(string) + SetHttpMethod(string) +} + +type BaseRequest struct { + httpMethod string + domain string + path string + params map[string]string + formParams map[string]string + + service string + version string + action string +} + +func (r *BaseRequest) GetAction() string { + return r.action +} + +func (r *BaseRequest) GetHttpMethod() string { + return r.httpMethod +} + +func (r *BaseRequest) GetParams() map[string]string { + return r.params +} + +func (r *BaseRequest) GetPath() string { + return r.path +} + +func (r *BaseRequest) GetDomain() string { + return r.domain +} + +func (r *BaseRequest) SetDomain(domain string) { + r.domain = domain +} + +func (r *BaseRequest) SetHttpMethod(method string) { + switch strings.ToUpper(method) { + case POST: + { + r.httpMethod = POST + } + case GET: + { + r.httpMethod = GET + } + default: + { + r.httpMethod = GET + } + } +} + +func (r *BaseRequest) GetService() string { + return r.service +} + +func (r *BaseRequest) GetUrl() string { + if r.httpMethod == GET { + return "https://" + r.domain + r.path + "?" + getUrlQueriesEncoded(r.params) + } else if r.httpMethod == POST { + return "https://" + r.domain + r.path + } else { + return "" + } +} + +func (r *BaseRequest) GetVersion() string { + return r.version +} + +func getUrlQueriesEncoded(params map[string]string) string { + values := url.Values{} + for key, value := range params { + if value != "" { + values.Add(key, value) + } + } + return values.Encode() +} + +func (r *BaseRequest) GetBodyReader() io.Reader { + if r.httpMethod == POST { + s := getUrlQueriesEncoded(r.params) + //log.Printf("[DEBUG] body: %s", s) + return strings.NewReader(s) + } else { + return strings.NewReader("") + } +} + +func (r *BaseRequest) Init() *BaseRequest { + r.httpMethod = GET + r.domain = "" + r.path = Path + r.params = make(map[string]string) + r.formParams = make(map[string]string) + return r +} + +func (r *BaseRequest) WithApiInfo(service, version, action string) *BaseRequest { + r.service = service + r.version = version + r.action = action + return r +} + +func GetServiceDomain(service string) (domain string) { + domain = service + "." + RootDomain + return +} + +func CompleteCommonParams(request Request, region string) { + params := request.GetParams() + params["Region"] = region + if request.GetVersion() != "" { + params["Version"] = request.GetVersion() + } + params["Action"] = request.GetAction() + params["Timestamp"] = strconv.FormatInt(time.Now().Unix(), 10) + params["Nonce"] = strconv.Itoa(rand.Int()) + params["RequestClient"] = "SDK_GO_3.0.26" +} + +func ConstructParams(req Request) (err error) { + value := reflect.ValueOf(req).Elem() + err = flatStructure(value, req, "") + //log.Printf("[DEBUG] params=%s", req.GetParams()) + return +} + +func flatStructure(value reflect.Value, request Request, prefix string) (err error) { + //log.Printf("[DEBUG] reflect value: %v", value.Type()) + valueType := value.Type() + for i := 0; i < valueType.NumField(); i++ { + tag := valueType.Field(i).Tag + nameTag, hasNameTag := tag.Lookup("name") + if !hasNameTag { + continue + } + field := value.Field(i) + kind := field.Kind() + if kind == reflect.Ptr && field.IsNil() { + continue + } + if kind == reflect.Ptr { + field = field.Elem() + kind = field.Kind() + } + key := prefix + nameTag + if kind == reflect.String { + s := field.String() + if s != "" { + request.GetParams()[key] = s + } + } else if kind == reflect.Bool { + request.GetParams()[key] = strconv.FormatBool(field.Bool()) + } else if kind == reflect.Int || kind == reflect.Int64 { + request.GetParams()[key] = strconv.FormatInt(field.Int(), 10) + } else if kind == reflect.Uint || kind == reflect.Uint64 { + request.GetParams()[key] = strconv.FormatUint(field.Uint(), 10) + } else if kind == reflect.Float64 { + request.GetParams()[key] = strconv.FormatFloat(field.Float(), 'f', -1, 64) + } else if kind == reflect.Slice { + list := value.Field(i) + for j := 0; j < list.Len(); j++ { + vj := list.Index(j) + key := prefix + nameTag + "." + strconv.Itoa(j) + kind = vj.Kind() + if kind == reflect.Ptr && vj.IsNil() { + continue + } + if kind == reflect.Ptr { + vj = vj.Elem() + kind = vj.Kind() + } + if kind == reflect.String { + request.GetParams()[key] = vj.String() + } else if kind == reflect.Bool { + request.GetParams()[key] = strconv.FormatBool(vj.Bool()) + } else if kind == reflect.Int || kind == reflect.Int64 { + request.GetParams()[key] = strconv.FormatInt(vj.Int(), 10) + } else if kind == reflect.Uint || kind == reflect.Uint64 { + request.GetParams()[key] = strconv.FormatUint(vj.Uint(), 10) + } else if kind == reflect.Float64 { + request.GetParams()[key] = strconv.FormatFloat(vj.Float(), 'f', -1, 64) + } else { + flatStructure(vj, request, key+".") + } + } + } else { + flatStructure(reflect.ValueOf(field.Interface()), request, prefix+nameTag+".") + } + } + return +} diff --git a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http/response.go b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http/response.go new file mode 100644 index 000000000..100fca110 --- /dev/null +++ b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http/response.go @@ -0,0 +1,69 @@ +package common + +import ( + "encoding/json" + "io/ioutil" + // "log" + "net/http" + + "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" +) + +type Response interface { + ParseErrorFromHTTPResponse(body []byte) error +} + +type BaseResponse struct { +} + +type ErrorResponse struct { + Response struct { + Error struct { + Code string `json:"Code"` + Message string `json:"Message"` + } `json:"Error" omitempty` + RequestId string `json:"RequestId"` + } `json:"Response"` +} + +type DeprecatedAPIErrorResponse struct { + Code int `json:"code"` + Message string `json:"message"` + CodeDesc string `json:"codeDesc"` +} + +func (r *BaseResponse) ParseErrorFromHTTPResponse(body []byte) (err error) { + resp := &ErrorResponse{} + err = json.Unmarshal(body, resp) + if err != nil { + return + } + if resp.Response.Error.Code != "" { + return errors.NewTencentCloudSDKError(resp.Response.Error.Code, resp.Response.Error.Message, resp.Response.RequestId) + } + + deprecated := &DeprecatedAPIErrorResponse{} + err = json.Unmarshal(body, deprecated) + if err != nil { + return + } + if deprecated.Code != 0 { + return errors.NewTencentCloudSDKError(deprecated.CodeDesc, deprecated.Message, "") + } + return nil +} + +func ParseFromHttpResponse(hr *http.Response, response Response) (err error) { + defer hr.Body.Close() + body, err := ioutil.ReadAll(hr.Body) + if err != nil { + return + } + //log.Printf("[DEBUG] Response Body=%s", body) + err = response.ParseErrorFromHTTPResponse(body) + if err != nil { + return + } + err = json.Unmarshal(body, &response) + return +} diff --git a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile/client_profile.go b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile/client_profile.go new file mode 100644 index 000000000..94c63b2f0 --- /dev/null +++ b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile/client_profile.go @@ -0,0 +1,13 @@ +package profile + +type ClientProfile struct { + HttpProfile *HttpProfile + SignMethod string +} + +func NewClientProfile() *ClientProfile { + return &ClientProfile{ + HttpProfile: NewHttpProfile(), + SignMethod: "HmacSHA256", + } +} diff --git a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile/http_profile.go b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile/http_profile.go new file mode 100644 index 000000000..8d4bf8f57 --- /dev/null +++ b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile/http_profile.go @@ -0,0 +1,17 @@ +package profile + +type HttpProfile struct { + ReqMethod string + ReqTimeout int + Endpoint string + Protocol string +} + +func NewHttpProfile() *HttpProfile { + return &HttpProfile{ + ReqMethod: "POST", + ReqTimeout: 60, + Endpoint: "", + Protocol: "HTTPS", + } +} diff --git a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/sign.go b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/sign.go new file mode 100644 index 000000000..450fe2ccd --- /dev/null +++ b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/sign.go @@ -0,0 +1,75 @@ +package common + +import ( + "crypto/hmac" + "crypto/sha1" + "crypto/sha256" + "encoding/base64" + "fmt" + "sort" + "strings" + + tchttp "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http" +) + +const ( + SHA256 = "HmacSHA256" + SHA1 = "HmacSHA1" +) + +func Sign(s, secretKey, method string) string { + hashed := hmac.New(sha1.New, []byte(secretKey)) + if method == SHA256 { + hashed = hmac.New(sha256.New, []byte(secretKey)) + } + hashed.Write([]byte(s)) + + return base64.StdEncoding.EncodeToString(hashed.Sum(nil)) +} + +func signRequest(request tchttp.Request, credential *Credential, method string) (err error) { + if method != SHA256 { + method = SHA1 + } + checkAuthParams(request, credential, method) + s := getStringToSign(request) + signature := Sign(s, credential.SecretKey, method) + request.GetParams()["Signature"] = signature + return +} + +func checkAuthParams(request tchttp.Request, credential *Credential, method string) { + params := request.GetParams() + credentialParams := credential.GetCredentialParams() + for key, value := range credentialParams { + params[key] = value + } + params["SignatureMethod"] = method + delete(params, "Signature") +} + +func getStringToSign(request tchttp.Request) string { + method := request.GetHttpMethod() + domain := request.GetDomain() + path := request.GetPath() + + text := method + domain + path + "?" + + params := request.GetParams() + // sort params + keys := make([]string, 0, len(params)) + for k, _ := range params { + keys = append(keys, k) + } + sort.Strings(keys) + + for i := range keys { + k := keys[i] + if params[k] == "" { + continue + } + text += fmt.Sprintf("%v=%v&", strings.Replace(k, "_", ".", -1), params[k]) + } + text = text[:len(text)-1] + return text +} diff --git a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/types.go b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/types.go new file mode 100644 index 000000000..ec2c786db --- /dev/null +++ b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/types.go @@ -0,0 +1,47 @@ +package common + +func IntPtr(v int) *int { + return &v +} + +func Int64Ptr(v int64) *int64 { + return &v +} + +func UintPtr(v uint) *uint { + return &v +} + +func Uint64Ptr(v uint64) *uint64 { + return &v +} + +func Float64Ptr(v float64) *float64 { + return &v +} + +func StringPtr(v string) *string { + return &v +} + +func StringValues(ptrs []*string) []string { + values := make([]string, len(ptrs)) + for i := 0; i < len(ptrs); i++ { + if ptrs[i] != nil { + values[i] = *ptrs[i] + } + } + return values +} + +func StringPtrs(vals []string) []*string { + ptrs := make([]*string, len(vals)) + for i := 0; i < len(vals); i++ { + ptrs[i] = &vals[i] + } + return ptrs +} + +func BoolPtr(v bool) *bool { + return &v +} diff --git a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312/client.go b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312/client.go new file mode 100644 index 000000000..b7585cbf5 --- /dev/null +++ b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312/client.go @@ -0,0 +1,1679 @@ +// Copyright (c) 2017-2018 THL A29 Limited, a Tencent company. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v20170312 + +import ( + "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" + tchttp "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http" + "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" +) + +const APIVersion = "2017-03-12" + +type Client struct { + common.Client +} + +func NewClientWithSecretId(secretId, secretKey, region string) (client *Client, err error) { + cpf := profile.NewClientProfile() + client = &Client{} + client.Init(region).WithSecretId(secretId, secretKey).WithProfile(cpf) + return +} + +func NewClient(credential *common.Credential, region string, clientProfile *profile.ClientProfile) (client *Client, err error) { + client = &Client{} + client.Init(region). + WithSecretId(credential.SecretId, credential.SecretKey). + WithProfile(clientProfile) + return +} + + +func NewAllocateHostsRequest() (request *AllocateHostsRequest) { + request = &AllocateHostsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "AllocateHosts") + return +} + +func NewAllocateHostsResponse() (response *AllocateHostsResponse) { + response = &AllocateHostsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (AllocateHosts) 用于创建一个或多个指定配置的CDH实例。 +// * 当HostChargeType为PREPAID时,必须指定HostChargePrepaid参数。 +func (c *Client) AllocateHosts(request *AllocateHostsRequest) (response *AllocateHostsResponse, err error) { + if request == nil { + request = NewAllocateHostsRequest() + } + response = NewAllocateHostsResponse() + err = c.Send(request, response) + return +} + +func NewAssociateInstancesKeyPairsRequest() (request *AssociateInstancesKeyPairsRequest) { + request = &AssociateInstancesKeyPairsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "AssociateInstancesKeyPairs") + return +} + +func NewAssociateInstancesKeyPairsResponse() (response *AssociateInstancesKeyPairsResponse) { + response = &AssociateInstancesKeyPairsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (AssociateInstancesKeyPairs) 用于将密钥绑定到实例上。 +// +// * 将密钥的公钥写入到实例的`SSH`配置当中,用户就可以通过该密钥的私钥来登录实例。 +// * 如果实例原来绑定过密钥,那么原来的密钥将失效。 +// * 如果实例原来是通过密码登录,绑定密钥后无法使用密码登录。 +// * 支持批量操作。每次请求批量实例的上限为100。如果批量实例存在不允许操作的实例,操作会以特定错误码返回。 +func (c *Client) AssociateInstancesKeyPairs(request *AssociateInstancesKeyPairsRequest) (response *AssociateInstancesKeyPairsResponse, err error) { + if request == nil { + request = NewAssociateInstancesKeyPairsRequest() + } + response = NewAssociateInstancesKeyPairsResponse() + err = c.Send(request, response) + return +} + +func NewCreateDisasterRecoverGroupRequest() (request *CreateDisasterRecoverGroupRequest) { + request = &CreateDisasterRecoverGroupRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "CreateDisasterRecoverGroup") + return +} + +func NewCreateDisasterRecoverGroupResponse() (response *CreateDisasterRecoverGroupResponse) { + response = &CreateDisasterRecoverGroupResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (CreateDisasterRecoverGroup)用于创建[分散置放群组](https://cloud.tencent.com/document/product/213/15486)。创建好的置放群组,可在[创建实例](https://cloud.tencent.com/document/api/213/15730)时指定。 +func (c *Client) CreateDisasterRecoverGroup(request *CreateDisasterRecoverGroupRequest) (response *CreateDisasterRecoverGroupResponse, err error) { + if request == nil { + request = NewCreateDisasterRecoverGroupRequest() + } + response = NewCreateDisasterRecoverGroupResponse() + err = c.Send(request, response) + return +} + +func NewCreateImageRequest() (request *CreateImageRequest) { + request = &CreateImageRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "CreateImage") + return +} + +func NewCreateImageResponse() (response *CreateImageResponse) { + response = &CreateImageResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(CreateImage)用于将实例的系统盘制作为新镜像,创建后的镜像可以用于创建实例。 +func (c *Client) CreateImage(request *CreateImageRequest) (response *CreateImageResponse, err error) { + if request == nil { + request = NewCreateImageRequest() + } + response = NewCreateImageResponse() + err = c.Send(request, response) + return +} + +func NewCreateKeyPairRequest() (request *CreateKeyPairRequest) { + request = &CreateKeyPairRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "CreateKeyPair") + return +} + +func NewCreateKeyPairResponse() (response *CreateKeyPairResponse) { + response = &CreateKeyPairResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (CreateKeyPair) 用于创建一个 `OpenSSH RSA` 密钥对,可以用于登录 `Linux` 实例。 +// +// * 开发者只需指定密钥对名称,即可由系统自动创建密钥对,并返回所生成的密钥对的 `ID` 及其公钥、私钥的内容。 +// * 密钥对名称不能和已经存在的密钥对的名称重复。 +// * 私钥的内容可以保存到文件中作为 `SSH` 的一种认证方式。 +// * 腾讯云不会保存用户的私钥,请妥善保管。 +func (c *Client) CreateKeyPair(request *CreateKeyPairRequest) (response *CreateKeyPairResponse, err error) { + if request == nil { + request = NewCreateKeyPairRequest() + } + response = NewCreateKeyPairResponse() + err = c.Send(request, response) + return +} + +func NewDeleteDisasterRecoverGroupsRequest() (request *DeleteDisasterRecoverGroupsRequest) { + request = &DeleteDisasterRecoverGroupsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "DeleteDisasterRecoverGroups") + return +} + +func NewDeleteDisasterRecoverGroupsResponse() (response *DeleteDisasterRecoverGroupsResponse) { + response = &DeleteDisasterRecoverGroupsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (DeleteDisasterRecoverGroups)用于删除[分散置放群组](https://cloud.tencent.com/document/product/213/15486)。只有空的置放群组才能被删除,非空的群组需要先销毁组内所有云主机,才能执行删除操作,不然会产生删除置放群组失败的错误。 +func (c *Client) DeleteDisasterRecoverGroups(request *DeleteDisasterRecoverGroupsRequest) (response *DeleteDisasterRecoverGroupsResponse, err error) { + if request == nil { + request = NewDeleteDisasterRecoverGroupsRequest() + } + response = NewDeleteDisasterRecoverGroupsResponse() + err = c.Send(request, response) + return +} + +func NewDeleteImagesRequest() (request *DeleteImagesRequest) { + request = &DeleteImagesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "DeleteImages") + return +} + +func NewDeleteImagesResponse() (response *DeleteImagesResponse) { + response = &DeleteImagesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DeleteImages)用于删除一个或多个镜像。 +// +// * 当[镜像状态](https://cloud.tencent.com/document/api/213/9452#image_state)为`创建中`和`使用中`时, 不允许删除。镜像状态可以通过[DescribeImages](https://cloud.tencent.com/document/api/213/9418)获取。 +// * 每个地域最多只支持创建10个自定义镜像,删除镜像可以释放账户的配额。 +// * 当镜像正在被其它账户分享时,不允许删除。 +func (c *Client) DeleteImages(request *DeleteImagesRequest) (response *DeleteImagesResponse, err error) { + if request == nil { + request = NewDeleteImagesRequest() + } + response = NewDeleteImagesResponse() + err = c.Send(request, response) + return +} + +func NewDeleteKeyPairsRequest() (request *DeleteKeyPairsRequest) { + request = &DeleteKeyPairsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "DeleteKeyPairs") + return +} + +func NewDeleteKeyPairsResponse() (response *DeleteKeyPairsResponse) { + response = &DeleteKeyPairsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (DeleteKeyPairs) 用于删除已在腾讯云托管的密钥对。 +// +// * 可以同时删除多个密钥对。 +// * 不能删除已被实例或镜像引用的密钥对,所以需要独立判断是否所有密钥对都被成功删除。 +func (c *Client) DeleteKeyPairs(request *DeleteKeyPairsRequest) (response *DeleteKeyPairsResponse, err error) { + if request == nil { + request = NewDeleteKeyPairsRequest() + } + response = NewDeleteKeyPairsResponse() + err = c.Send(request, response) + return +} + +func NewDescribeDisasterRecoverGroupQuotaRequest() (request *DescribeDisasterRecoverGroupQuotaRequest) { + request = &DescribeDisasterRecoverGroupQuotaRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "DescribeDisasterRecoverGroupQuota") + return +} + +func NewDescribeDisasterRecoverGroupQuotaResponse() (response *DescribeDisasterRecoverGroupQuotaResponse) { + response = &DescribeDisasterRecoverGroupQuotaResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (DescribeDisasterRecoverGroupQuota)用于查询[分散置放群组](https://cloud.tencent.com/document/product/213/15486)配额。 +func (c *Client) DescribeDisasterRecoverGroupQuota(request *DescribeDisasterRecoverGroupQuotaRequest) (response *DescribeDisasterRecoverGroupQuotaResponse, err error) { + if request == nil { + request = NewDescribeDisasterRecoverGroupQuotaRequest() + } + response = NewDescribeDisasterRecoverGroupQuotaResponse() + err = c.Send(request, response) + return +} + +func NewDescribeDisasterRecoverGroupsRequest() (request *DescribeDisasterRecoverGroupsRequest) { + request = &DescribeDisasterRecoverGroupsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "DescribeDisasterRecoverGroups") + return +} + +func NewDescribeDisasterRecoverGroupsResponse() (response *DescribeDisasterRecoverGroupsResponse) { + response = &DescribeDisasterRecoverGroupsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (DescribeDisasterRecoverGroups)用于查询[分散置放群组](https://cloud.tencent.com/document/product/213/15486)信息。 +func (c *Client) DescribeDisasterRecoverGroups(request *DescribeDisasterRecoverGroupsRequest) (response *DescribeDisasterRecoverGroupsResponse, err error) { + if request == nil { + request = NewDescribeDisasterRecoverGroupsRequest() + } + response = NewDescribeDisasterRecoverGroupsResponse() + err = c.Send(request, response) + return +} + +func NewDescribeHostsRequest() (request *DescribeHostsRequest) { + request = &DescribeHostsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "DescribeHosts") + return +} + +func NewDescribeHostsResponse() (response *DescribeHostsResponse) { + response = &DescribeHostsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (DescribeHosts) 用于获取一个或多个CDH实例的详细信息。 +func (c *Client) DescribeHosts(request *DescribeHostsRequest) (response *DescribeHostsResponse, err error) { + if request == nil { + request = NewDescribeHostsRequest() + } + response = NewDescribeHostsResponse() + err = c.Send(request, response) + return +} + +func NewDescribeImageQuotaRequest() (request *DescribeImageQuotaRequest) { + request = &DescribeImageQuotaRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "DescribeImageQuota") + return +} + +func NewDescribeImageQuotaResponse() (response *DescribeImageQuotaResponse) { + response = &DescribeImageQuotaResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeImageQuota)用于查询用户帐号的镜像配额。 +func (c *Client) DescribeImageQuota(request *DescribeImageQuotaRequest) (response *DescribeImageQuotaResponse, err error) { + if request == nil { + request = NewDescribeImageQuotaRequest() + } + response = NewDescribeImageQuotaResponse() + err = c.Send(request, response) + return +} + +func NewDescribeImageSharePermissionRequest() (request *DescribeImageSharePermissionRequest) { + request = &DescribeImageSharePermissionRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "DescribeImageSharePermission") + return +} + +func NewDescribeImageSharePermissionResponse() (response *DescribeImageSharePermissionResponse) { + response = &DescribeImageSharePermissionResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeImageSharePermission)用于查询镜像分享信息。 +func (c *Client) DescribeImageSharePermission(request *DescribeImageSharePermissionRequest) (response *DescribeImageSharePermissionResponse, err error) { + if request == nil { + request = NewDescribeImageSharePermissionRequest() + } + response = NewDescribeImageSharePermissionResponse() + err = c.Send(request, response) + return +} + +func NewDescribeImagesRequest() (request *DescribeImagesRequest) { + request = &DescribeImagesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "DescribeImages") + return +} + +func NewDescribeImagesResponse() (response *DescribeImagesResponse) { + response = &DescribeImagesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeImages) 用于查看镜像列表。 +// +// * 可以通过指定镜像ID来查询指定镜像的详细信息,或通过设定过滤器来查询满足过滤条件的镜像的详细信息。 +// * 指定偏移(Offset)和限制(Limit)来选择结果中的一部分,默认返回满足条件的前20个镜像信息。 +func (c *Client) DescribeImages(request *DescribeImagesRequest) (response *DescribeImagesResponse, err error) { + if request == nil { + request = NewDescribeImagesRequest() + } + response = NewDescribeImagesResponse() + err = c.Send(request, response) + return +} + +func NewDescribeImportImageOsRequest() (request *DescribeImportImageOsRequest) { + request = &DescribeImportImageOsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "DescribeImportImageOs") + return +} + +func NewDescribeImportImageOsResponse() (response *DescribeImportImageOsResponse) { + response = &DescribeImportImageOsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 查看可以导入的镜像操作系统信息。 +func (c *Client) DescribeImportImageOs(request *DescribeImportImageOsRequest) (response *DescribeImportImageOsResponse, err error) { + if request == nil { + request = NewDescribeImportImageOsRequest() + } + response = NewDescribeImportImageOsResponse() + err = c.Send(request, response) + return +} + +func NewDescribeInstanceFamilyConfigsRequest() (request *DescribeInstanceFamilyConfigsRequest) { + request = &DescribeInstanceFamilyConfigsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "DescribeInstanceFamilyConfigs") + return +} + +func NewDescribeInstanceFamilyConfigsResponse() (response *DescribeInstanceFamilyConfigsResponse) { + response = &DescribeInstanceFamilyConfigsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeInstanceFamilyConfigs)查询当前用户和地域所支持的机型族列表信息。 +func (c *Client) DescribeInstanceFamilyConfigs(request *DescribeInstanceFamilyConfigsRequest) (response *DescribeInstanceFamilyConfigsResponse, err error) { + if request == nil { + request = NewDescribeInstanceFamilyConfigsRequest() + } + response = NewDescribeInstanceFamilyConfigsResponse() + err = c.Send(request, response) + return +} + +func NewDescribeInstanceInternetBandwidthConfigsRequest() (request *DescribeInstanceInternetBandwidthConfigsRequest) { + request = &DescribeInstanceInternetBandwidthConfigsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "DescribeInstanceInternetBandwidthConfigs") + return +} + +func NewDescribeInstanceInternetBandwidthConfigsResponse() (response *DescribeInstanceInternetBandwidthConfigsResponse) { + response = &DescribeInstanceInternetBandwidthConfigsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (DescribeInstanceInternetBandwidthConfigs) 用于查询实例带宽配置。 +// +// * 只支持查询`BANDWIDTH_PREPAID`计费模式的带宽配置。 +// * 接口返回实例的所有带宽配置信息(包含历史的带宽配置信息)。 +func (c *Client) DescribeInstanceInternetBandwidthConfigs(request *DescribeInstanceInternetBandwidthConfigsRequest) (response *DescribeInstanceInternetBandwidthConfigsResponse, err error) { + if request == nil { + request = NewDescribeInstanceInternetBandwidthConfigsRequest() + } + response = NewDescribeInstanceInternetBandwidthConfigsResponse() + err = c.Send(request, response) + return +} + +func NewDescribeInstanceTypeConfigsRequest() (request *DescribeInstanceTypeConfigsRequest) { + request = &DescribeInstanceTypeConfigsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "DescribeInstanceTypeConfigs") + return +} + +func NewDescribeInstanceTypeConfigsResponse() (response *DescribeInstanceTypeConfigsResponse) { + response = &DescribeInstanceTypeConfigsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (DescribeInstanceTypeConfigs) 用于查询实例机型配置。 +// +// * 可以根据`zone`、`instance-family`来查询实例机型配置。过滤条件详见过滤器`Filter`。 +// * 如果参数为空,返回指定地域的所有实例机型配置。 +func (c *Client) DescribeInstanceTypeConfigs(request *DescribeInstanceTypeConfigsRequest) (response *DescribeInstanceTypeConfigsResponse, err error) { + if request == nil { + request = NewDescribeInstanceTypeConfigsRequest() + } + response = NewDescribeInstanceTypeConfigsResponse() + err = c.Send(request, response) + return +} + +func NewDescribeInstanceVncUrlRequest() (request *DescribeInstanceVncUrlRequest) { + request = &DescribeInstanceVncUrlRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "DescribeInstanceVncUrl") + return +} + +func NewDescribeInstanceVncUrlResponse() (response *DescribeInstanceVncUrlResponse) { + response = &DescribeInstanceVncUrlResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 ( DescribeInstanceVncUrl ) 用于查询实例管理终端地址。 +// +// * 处于 `STOPPED` 状态的机器无法使用此功能。 +// * 管理终端地址的有效期为 15 秒,调用接口成功后如果 15 秒内不使用该链接进行访问,管理终端地址自动失效,您需要重新查询。 +// * 管理终端地址一旦被访问,将自动失效,您需要重新查询。 +// * 如果连接断开,每分钟内重新连接的次数不能超过 30 次。 +// * 获取到 `InstanceVncUrl` 后,您需要在在链接 末尾加上参数 `InstanceVncUrl=xxxx` 。 +// - 参数 `InstanceVncUrl` :调用接口成功后会返回的 `InstanceVncUrl` 的值。 +// +// 最后组成的 URL 格式如下: +// +// ``` +// https://img.qcloud.com/qcloud/app/active_vnc/index.html?InstanceVncUrl=wss%3A%2F%2Fbjvnc.qcloud.com%3A26789%2Fvnc%3Fs%3DaHpjWnRVMFNhYmxKdDM5MjRHNlVTSVQwajNUSW0wb2tBbmFtREFCTmFrcy8vUUNPMG0wSHZNOUUxRm5PMmUzWmFDcWlOdDJIbUJxSTZDL0RXcHZxYnZZMmRkWWZWcEZia2lyb09XMzdKNmM9 +// ``` +func (c *Client) DescribeInstanceVncUrl(request *DescribeInstanceVncUrlRequest) (response *DescribeInstanceVncUrlResponse, err error) { + if request == nil { + request = NewDescribeInstanceVncUrlRequest() + } + response = NewDescribeInstanceVncUrlResponse() + err = c.Send(request, response) + return +} + +func NewDescribeInstancesRequest() (request *DescribeInstancesRequest) { + request = &DescribeInstancesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "DescribeInstances") + return +} + +func NewDescribeInstancesResponse() (response *DescribeInstancesResponse) { + response = &DescribeInstancesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (DescribeInstances) 用于查询一个或多个实例的详细信息。 +// +// * 可以根据实例`ID`、实例名称或者实例计费模式等信息来查询实例的详细信息。过滤信息详细请见过滤器`Filter`。 +// * 如果参数为空,返回当前用户一定数量(`Limit`所指定的数量,默认为20)的实例。 +func (c *Client) DescribeInstances(request *DescribeInstancesRequest) (response *DescribeInstancesResponse, err error) { + if request == nil { + request = NewDescribeInstancesRequest() + } + response = NewDescribeInstancesResponse() + err = c.Send(request, response) + return +} + +func NewDescribeInstancesStatusRequest() (request *DescribeInstancesStatusRequest) { + request = &DescribeInstancesStatusRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "DescribeInstancesStatus") + return +} + +func NewDescribeInstancesStatusResponse() (response *DescribeInstancesStatusResponse) { + response = &DescribeInstancesStatusResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (DescribeInstancesStatus) 用于查询一个或多个实例的状态。 +// +// * 可以根据实例`ID`来查询实例的状态。 +// * 如果参数为空,返回当前用户一定数量(Limit所指定的数量,默认为20)的实例状态。 +func (c *Client) DescribeInstancesStatus(request *DescribeInstancesStatusRequest) (response *DescribeInstancesStatusResponse, err error) { + if request == nil { + request = NewDescribeInstancesStatusRequest() + } + response = NewDescribeInstancesStatusResponse() + err = c.Send(request, response) + return +} + +func NewDescribeInternetChargeTypeConfigsRequest() (request *DescribeInternetChargeTypeConfigsRequest) { + request = &DescribeInternetChargeTypeConfigsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "DescribeInternetChargeTypeConfigs") + return +} + +func NewDescribeInternetChargeTypeConfigsResponse() (response *DescribeInternetChargeTypeConfigsResponse) { + response = &DescribeInternetChargeTypeConfigsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeInternetChargeTypeConfigs)用于查询网络的计费类型。 +func (c *Client) DescribeInternetChargeTypeConfigs(request *DescribeInternetChargeTypeConfigsRequest) (response *DescribeInternetChargeTypeConfigsResponse, err error) { + if request == nil { + request = NewDescribeInternetChargeTypeConfigsRequest() + } + response = NewDescribeInternetChargeTypeConfigsResponse() + err = c.Send(request, response) + return +} + +func NewDescribeKeyPairsRequest() (request *DescribeKeyPairsRequest) { + request = &DescribeKeyPairsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "DescribeKeyPairs") + return +} + +func NewDescribeKeyPairsResponse() (response *DescribeKeyPairsResponse) { + response = &DescribeKeyPairsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (DescribeKeyPairs) 用于查询密钥对信息。 +// +// * 密钥对是通过一种算法生成的一对密钥,在生成的密钥对中,一个向外界公开,称为公钥;另一个用户自己保留,称为私钥。密钥对的公钥内容可以通过这个接口查询,但私钥内容系统不保留。 +func (c *Client) DescribeKeyPairs(request *DescribeKeyPairsRequest) (response *DescribeKeyPairsResponse, err error) { + if request == nil { + request = NewDescribeKeyPairsRequest() + } + response = NewDescribeKeyPairsResponse() + err = c.Send(request, response) + return +} + +func NewDescribeRegionsRequest() (request *DescribeRegionsRequest) { + request = &DescribeRegionsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "DescribeRegions") + return +} + +func NewDescribeRegionsResponse() (response *DescribeRegionsResponse) { + response = &DescribeRegionsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeRegions)用于查询地域信息。 +func (c *Client) DescribeRegions(request *DescribeRegionsRequest) (response *DescribeRegionsResponse, err error) { + if request == nil { + request = NewDescribeRegionsRequest() + } + response = NewDescribeRegionsResponse() + err = c.Send(request, response) + return +} + +func NewDescribeZoneInstanceConfigInfosRequest() (request *DescribeZoneInstanceConfigInfosRequest) { + request = &DescribeZoneInstanceConfigInfosRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "DescribeZoneInstanceConfigInfos") + return +} + +func NewDescribeZoneInstanceConfigInfosResponse() (response *DescribeZoneInstanceConfigInfosResponse) { + response = &DescribeZoneInstanceConfigInfosResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeZoneInstanceConfigInfos) 获取可用区的机型信息。 +func (c *Client) DescribeZoneInstanceConfigInfos(request *DescribeZoneInstanceConfigInfosRequest) (response *DescribeZoneInstanceConfigInfosResponse, err error) { + if request == nil { + request = NewDescribeZoneInstanceConfigInfosRequest() + } + response = NewDescribeZoneInstanceConfigInfosResponse() + err = c.Send(request, response) + return +} + +func NewDescribeZonesRequest() (request *DescribeZonesRequest) { + request = &DescribeZonesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "DescribeZones") + return +} + +func NewDescribeZonesResponse() (response *DescribeZonesResponse) { + response = &DescribeZonesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeZones)用于查询可用区信息。 +func (c *Client) DescribeZones(request *DescribeZonesRequest) (response *DescribeZonesResponse, err error) { + if request == nil { + request = NewDescribeZonesRequest() + } + response = NewDescribeZonesResponse() + err = c.Send(request, response) + return +} + +func NewDisassociateInstancesKeyPairsRequest() (request *DisassociateInstancesKeyPairsRequest) { + request = &DisassociateInstancesKeyPairsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "DisassociateInstancesKeyPairs") + return +} + +func NewDisassociateInstancesKeyPairsResponse() (response *DisassociateInstancesKeyPairsResponse) { + response = &DisassociateInstancesKeyPairsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (DisassociateInstancesKeyPairs) 用于解除实例的密钥绑定关系。 +// +// * 只支持[`STOPPED`](https://cloud.tencent.com/document/api/213/9452#INSTANCE_STATE)状态的`Linux`操作系统的实例。 +// * 解绑密钥后,实例可以通过原来设置的密码登录。 +// * 如果原来没有设置密码,解绑后将无法使用 `SSH` 登录。可以调用 [ResetInstancesPassword](https://cloud.tencent.com/document/api/213/9397) 接口来设置登陆密码。 +// * 支持批量操作。每次请求批量实例的上限为100。如果批量实例存在不允许操作的实例,操作会以特定错误码返回。 +func (c *Client) DisassociateInstancesKeyPairs(request *DisassociateInstancesKeyPairsRequest) (response *DisassociateInstancesKeyPairsResponse, err error) { + if request == nil { + request = NewDisassociateInstancesKeyPairsRequest() + } + response = NewDisassociateInstancesKeyPairsResponse() + err = c.Send(request, response) + return +} + +func NewImportImageRequest() (request *ImportImageRequest) { + request = &ImportImageRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "ImportImage") + return +} + +func NewImportImageResponse() (response *ImportImageResponse) { + response = &ImportImageResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ImportImage)用于导入镜像,导入后的镜像可用于创建实例。 +func (c *Client) ImportImage(request *ImportImageRequest) (response *ImportImageResponse, err error) { + if request == nil { + request = NewImportImageRequest() + } + response = NewImportImageResponse() + err = c.Send(request, response) + return +} + +func NewImportKeyPairRequest() (request *ImportKeyPairRequest) { + request = &ImportKeyPairRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "ImportKeyPair") + return +} + +func NewImportKeyPairResponse() (response *ImportKeyPairResponse) { + response = &ImportKeyPairResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (ImportKeyPair) 用于导入密钥对。 +// +// * 本接口的功能是将密钥对导入到用户账户,并不会自动绑定到实例。如需绑定可以使用[AssociasteInstancesKeyPair](https://cloud.tencent.com/document/api/213/9404)接口。 +// * 需指定密钥对名称以及该密钥对的公钥文本。 +// * 如果用户只有私钥,可以通过 `SSL` 工具将私钥转换成公钥后再导入。 +func (c *Client) ImportKeyPair(request *ImportKeyPairRequest) (response *ImportKeyPairResponse, err error) { + if request == nil { + request = NewImportKeyPairRequest() + } + response = NewImportKeyPairResponse() + err = c.Send(request, response) + return +} + +func NewInquiryPriceModifyInstancesChargeTypeRequest() (request *InquiryPriceModifyInstancesChargeTypeRequest) { + request = &InquiryPriceModifyInstancesChargeTypeRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "InquiryPriceModifyInstancesChargeType") + return +} + +func NewInquiryPriceModifyInstancesChargeTypeResponse() (response *InquiryPriceModifyInstancesChargeTypeResponse) { + response = &InquiryPriceModifyInstancesChargeTypeResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (InquiryPriceModifyInstancesChargeType) 用于切换实例的计费模式询价。 +// +// * 只支持从 `POSTPAID_BY_HOUR` 计费模式切换为`PREPAID`计费模式。 +// * 关机不收费的实例、`BC1`和`BS1`机型族的实例、设置定时销毁的实例不支持该操作。 +func (c *Client) InquiryPriceModifyInstancesChargeType(request *InquiryPriceModifyInstancesChargeTypeRequest) (response *InquiryPriceModifyInstancesChargeTypeResponse, err error) { + if request == nil { + request = NewInquiryPriceModifyInstancesChargeTypeRequest() + } + response = NewInquiryPriceModifyInstancesChargeTypeResponse() + err = c.Send(request, response) + return +} + +func NewInquiryPriceRenewInstancesRequest() (request *InquiryPriceRenewInstancesRequest) { + request = &InquiryPriceRenewInstancesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "InquiryPriceRenewInstances") + return +} + +func NewInquiryPriceRenewInstancesResponse() (response *InquiryPriceRenewInstancesResponse) { + response = &InquiryPriceRenewInstancesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (InquiryPriceRenewInstances) 用于续费包年包月实例询价。 +// +// * 只支持查询包年包月实例的续费价格。 +func (c *Client) InquiryPriceRenewInstances(request *InquiryPriceRenewInstancesRequest) (response *InquiryPriceRenewInstancesResponse, err error) { + if request == nil { + request = NewInquiryPriceRenewInstancesRequest() + } + response = NewInquiryPriceRenewInstancesResponse() + err = c.Send(request, response) + return +} + +func NewInquiryPriceResetInstanceRequest() (request *InquiryPriceResetInstanceRequest) { + request = &InquiryPriceResetInstanceRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "InquiryPriceResetInstance") + return +} + +func NewInquiryPriceResetInstanceResponse() (response *InquiryPriceResetInstanceResponse) { + response = &InquiryPriceResetInstanceResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (InquiryPriceResetInstance) 用于重装实例询价。* 如果指定了`ImageId`参数,则使用指定的镜像进行重装询价;否则按照当前实例使用的镜像进行重装询价。* 目前只支持[系统盘类型](/document/api/213/9452#block_device)是`CLOUD_BASIC`、`CLOUD_PREMIUM`、`CLOUD_SSD`类型的实例使用该接口实现`Linux`和`Windows`操作系统切换的重装询价。* 目前不支持海外地域的实例使用该接口实现`Linux`和`Windows`操作系统切换的重装询价。 +func (c *Client) InquiryPriceResetInstance(request *InquiryPriceResetInstanceRequest) (response *InquiryPriceResetInstanceResponse, err error) { + if request == nil { + request = NewInquiryPriceResetInstanceRequest() + } + response = NewInquiryPriceResetInstanceResponse() + err = c.Send(request, response) + return +} + +func NewInquiryPriceResetInstancesInternetMaxBandwidthRequest() (request *InquiryPriceResetInstancesInternetMaxBandwidthRequest) { + request = &InquiryPriceResetInstancesInternetMaxBandwidthRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "InquiryPriceResetInstancesInternetMaxBandwidth") + return +} + +func NewInquiryPriceResetInstancesInternetMaxBandwidthResponse() (response *InquiryPriceResetInstancesInternetMaxBandwidthResponse) { + response = &InquiryPriceResetInstancesInternetMaxBandwidthResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (InquiryPriceResetInstancesInternetMaxBandwidth) 用于调整实例公网带宽上限询价。 +// +// * 不同机型带宽上限范围不一致,具体限制详见[购买网络带宽](https://cloud.tencent.com/document/product/213/509)。 +// * 对于`BANDWIDTH_PREPAID`计费方式的带宽,需要输入参数`StartTime`和`EndTime`,指定调整后的带宽的生效时间段。在这种场景下目前不支持调小带宽,会涉及扣费,请确保账户余额充足。可通过[`DescribeAccountBalance`](https://cloud.tencent.com/document/product/378/4397)接口查询账户余额。 +// * 对于 `TRAFFIC_POSTPAID_BY_HOUR`、 `BANDWIDTH_POSTPAID_BY_HOUR` 和 `BANDWIDTH_PACKAGE` 计费方式的带宽,使用该接口调整带宽上限是实时生效的,可以在带宽允许的范围内调大或者调小带宽,不支持输入参数 `StartTime` 和 `EndTime` 。 +// * 接口不支持调整`BANDWIDTH_POSTPAID_BY_MONTH`计费方式的带宽。 +// * 接口不支持批量调整 `BANDWIDTH_PREPAID` 和 `BANDWIDTH_POSTPAID_BY_HOUR` 计费方式的带宽。 +// * 接口不支持批量调整混合计费方式的带宽。例如不支持同时调整`TRAFFIC_POSTPAID_BY_HOUR`和`BANDWIDTH_PACKAGE`计费方式的带宽。 +func (c *Client) InquiryPriceResetInstancesInternetMaxBandwidth(request *InquiryPriceResetInstancesInternetMaxBandwidthRequest) (response *InquiryPriceResetInstancesInternetMaxBandwidthResponse, err error) { + if request == nil { + request = NewInquiryPriceResetInstancesInternetMaxBandwidthRequest() + } + response = NewInquiryPriceResetInstancesInternetMaxBandwidthResponse() + err = c.Send(request, response) + return +} + +func NewInquiryPriceResetInstancesTypeRequest() (request *InquiryPriceResetInstancesTypeRequest) { + request = &InquiryPriceResetInstancesTypeRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "InquiryPriceResetInstancesType") + return +} + +func NewInquiryPriceResetInstancesTypeResponse() (response *InquiryPriceResetInstancesTypeResponse) { + response = &InquiryPriceResetInstancesTypeResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (InquiryPriceResetInstancesType) 用于调整实例的机型询价。 +// +// * 目前只支持[系统盘类型](https://cloud.tencent.com/document/api/213/9452#block_device)是`CLOUD_BASIC`、`CLOUD_PREMIUM`、`CLOUD_SSD`类型的实例使用该接口进行调整机型询价。 +// * 目前不支持[CDH](https://cloud.tencent.com/document/product/416)实例使用该接口调整机型询价。 +// * 目前不支持跨机型系统来调整机型,即使用该接口时指定的`InstanceType`和实例原来的机型需要属于同一系列。 +// * 对于包年包月实例,使用该接口会涉及扣费,请确保账户余额充足。可通过[`DescribeAccountBalance`](https://cloud.tencent.com/document/product/378/4397)接口查询账户余额。 +func (c *Client) InquiryPriceResetInstancesType(request *InquiryPriceResetInstancesTypeRequest) (response *InquiryPriceResetInstancesTypeResponse, err error) { + if request == nil { + request = NewInquiryPriceResetInstancesTypeRequest() + } + response = NewInquiryPriceResetInstancesTypeResponse() + err = c.Send(request, response) + return +} + +func NewInquiryPriceResizeInstanceDisksRequest() (request *InquiryPriceResizeInstanceDisksRequest) { + request = &InquiryPriceResizeInstanceDisksRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "InquiryPriceResizeInstanceDisks") + return +} + +func NewInquiryPriceResizeInstanceDisksResponse() (response *InquiryPriceResizeInstanceDisksResponse) { + response = &InquiryPriceResizeInstanceDisksResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (InquiryPriceResizeInstanceDisks) 用于扩容实例的数据盘询价。 +// +// * 目前只支持扩容随实例购买的数据盘询价,且[数据盘类型](/document/api/213/9452#block_device)为:`CLOUD_BASIC`、`CLOUD_PREMIUM`、`CLOUD_SSD`。 +// * 目前不支持[CDH](https://cloud.tencent.com/document/product/416)实例使用该接口扩容数据盘询价。* 仅支持包年包月实例随机器购买的数据盘。* 目前只支持扩容一块数据盘询价。 +func (c *Client) InquiryPriceResizeInstanceDisks(request *InquiryPriceResizeInstanceDisksRequest) (response *InquiryPriceResizeInstanceDisksResponse, err error) { + if request == nil { + request = NewInquiryPriceResizeInstanceDisksRequest() + } + response = NewInquiryPriceResizeInstanceDisksResponse() + err = c.Send(request, response) + return +} + +func NewInquiryPriceRunInstancesRequest() (request *InquiryPriceRunInstancesRequest) { + request = &InquiryPriceRunInstancesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "InquiryPriceRunInstances") + return +} + +func NewInquiryPriceRunInstancesResponse() (response *InquiryPriceRunInstancesResponse) { + response = &InquiryPriceRunInstancesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(InquiryPriceRunInstances)用于创建实例询价。本接口仅允许针对购买限制范围内的实例配置进行询价, 详见:[创建实例](https://cloud.tencent.com/document/api/213/15730)。 +func (c *Client) InquiryPriceRunInstances(request *InquiryPriceRunInstancesRequest) (response *InquiryPriceRunInstancesResponse, err error) { + if request == nil { + request = NewInquiryPriceRunInstancesRequest() + } + response = NewInquiryPriceRunInstancesResponse() + err = c.Send(request, response) + return +} + +func NewModifyDisasterRecoverGroupAttributeRequest() (request *ModifyDisasterRecoverGroupAttributeRequest) { + request = &ModifyDisasterRecoverGroupAttributeRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "ModifyDisasterRecoverGroupAttribute") + return +} + +func NewModifyDisasterRecoverGroupAttributeResponse() (response *ModifyDisasterRecoverGroupAttributeResponse) { + response = &ModifyDisasterRecoverGroupAttributeResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (ModifyDisasterRecoverGroupAttribute)用于修改[分散置放群组](https://cloud.tencent.com/document/product/213/15486)属性。 +func (c *Client) ModifyDisasterRecoverGroupAttribute(request *ModifyDisasterRecoverGroupAttributeRequest) (response *ModifyDisasterRecoverGroupAttributeResponse, err error) { + if request == nil { + request = NewModifyDisasterRecoverGroupAttributeRequest() + } + response = NewModifyDisasterRecoverGroupAttributeResponse() + err = c.Send(request, response) + return +} + +func NewModifyHostsAttributeRequest() (request *ModifyHostsAttributeRequest) { + request = &ModifyHostsAttributeRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "ModifyHostsAttribute") + return +} + +func NewModifyHostsAttributeResponse() (response *ModifyHostsAttributeResponse) { + response = &ModifyHostsAttributeResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ModifyHostsAttribute)用于修改CDH实例的属性,如实例名称和续费标记等。参数HostName和RenewFlag必须设置其中一个,但不能同时设置。 +func (c *Client) ModifyHostsAttribute(request *ModifyHostsAttributeRequest) (response *ModifyHostsAttributeResponse, err error) { + if request == nil { + request = NewModifyHostsAttributeRequest() + } + response = NewModifyHostsAttributeResponse() + err = c.Send(request, response) + return +} + +func NewModifyImageAttributeRequest() (request *ModifyImageAttributeRequest) { + request = &ModifyImageAttributeRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "ModifyImageAttribute") + return +} + +func NewModifyImageAttributeResponse() (response *ModifyImageAttributeResponse) { + response = &ModifyImageAttributeResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ModifyImageAttribute)用于修改镜像属性。 +// +// * 已分享的镜像无法修改属性。 +func (c *Client) ModifyImageAttribute(request *ModifyImageAttributeRequest) (response *ModifyImageAttributeResponse, err error) { + if request == nil { + request = NewModifyImageAttributeRequest() + } + response = NewModifyImageAttributeResponse() + err = c.Send(request, response) + return +} + +func NewModifyImageSharePermissionRequest() (request *ModifyImageSharePermissionRequest) { + request = &ModifyImageSharePermissionRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "ModifyImageSharePermission") + return +} + +func NewModifyImageSharePermissionResponse() (response *ModifyImageSharePermissionResponse) { + response = &ModifyImageSharePermissionResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ModifyImageSharePermission)用于修改镜像分享信息。 +// +// * 分享镜像后,被分享账户可以通过该镜像创建实例。 +// * 每个自定义镜像最多可共享给50个账户。 +// * 分享镜像无法更改名称,描述,仅可用于创建实例。 +// * 只支持分享到对方账户相同地域。 +func (c *Client) ModifyImageSharePermission(request *ModifyImageSharePermissionRequest) (response *ModifyImageSharePermissionResponse, err error) { + if request == nil { + request = NewModifyImageSharePermissionRequest() + } + response = NewModifyImageSharePermissionResponse() + err = c.Send(request, response) + return +} + +func NewModifyInstancesAttributeRequest() (request *ModifyInstancesAttributeRequest) { + request = &ModifyInstancesAttributeRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "ModifyInstancesAttribute") + return +} + +func NewModifyInstancesAttributeResponse() (response *ModifyInstancesAttributeResponse) { + response = &ModifyInstancesAttributeResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (ModifyInstancesAttribute) 用于修改实例的属性(目前只支持修改实例的名称)。 +// +// * “实例名称”仅为方便用户自己管理之用,腾讯云并不以此名称作为提交工单或是进行实例管理操作的依据。 +// * 支持批量操作。每次请求批量实例的上限为100。 +func (c *Client) ModifyInstancesAttribute(request *ModifyInstancesAttributeRequest) (response *ModifyInstancesAttributeResponse, err error) { + if request == nil { + request = NewModifyInstancesAttributeRequest() + } + response = NewModifyInstancesAttributeResponse() + err = c.Send(request, response) + return +} + +func NewModifyInstancesChargeTypeRequest() (request *ModifyInstancesChargeTypeRequest) { + request = &ModifyInstancesChargeTypeRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "ModifyInstancesChargeType") + return +} + +func NewModifyInstancesChargeTypeResponse() (response *ModifyInstancesChargeTypeResponse) { + response = &ModifyInstancesChargeTypeResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (ModifyInstancesChargeType) 用于切换实例的计费模式。 +// +// * 只支持从 `POSTPAID_BY_HOUR` 计费模式切换为`PREPAID`计费模式。 +// * 关机不收费的实例、`BC1`和`BS1`机型族的实例、设置定时销毁的实例不支持该操作。 +func (c *Client) ModifyInstancesChargeType(request *ModifyInstancesChargeTypeRequest) (response *ModifyInstancesChargeTypeResponse, err error) { + if request == nil { + request = NewModifyInstancesChargeTypeRequest() + } + response = NewModifyInstancesChargeTypeResponse() + err = c.Send(request, response) + return +} + +func NewModifyInstancesProjectRequest() (request *ModifyInstancesProjectRequest) { + request = &ModifyInstancesProjectRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "ModifyInstancesProject") + return +} + +func NewModifyInstancesProjectResponse() (response *ModifyInstancesProjectResponse) { + response = &ModifyInstancesProjectResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (ModifyInstancesProject) 用于修改实例所属项目。 +// +// * 项目为一个虚拟概念,用户可以在一个账户下面建立多个项目,每个项目中管理不同的资源;将多个不同实例分属到不同项目中,后续使用 [`DescribeInstances`](https://cloud.tencent.com/document/api/213/9388)接口查询实例,项目ID可用于过滤结果。 +// * 绑定负载均衡的实例不支持修改实例所属项目,请先使用[`DeregisterInstancesFromLoadBalancer`](https://cloud.tencent.com/document/api/214/1258)接口解绑负载均衡。 +// * 修改实例所属项目会自动解关联实例原来关联的安全组,修改完成后可能使用[`ModifySecurityGroupsOfInstance`](https://cloud.tencent.com/document/api/213/1367)接口关联安全组。 +// * 支持批量操作。每次请求批量实例的上限为100。 +func (c *Client) ModifyInstancesProject(request *ModifyInstancesProjectRequest) (response *ModifyInstancesProjectResponse, err error) { + if request == nil { + request = NewModifyInstancesProjectRequest() + } + response = NewModifyInstancesProjectResponse() + err = c.Send(request, response) + return +} + +func NewModifyInstancesRenewFlagRequest() (request *ModifyInstancesRenewFlagRequest) { + request = &ModifyInstancesRenewFlagRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "ModifyInstancesRenewFlag") + return +} + +func NewModifyInstancesRenewFlagResponse() (response *ModifyInstancesRenewFlagResponse) { + response = &ModifyInstancesRenewFlagResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (ModifyInstancesRenewFlag) 用于修改包年包月实例续费标识。 +// +// * 实例被标识为自动续费后,每次在实例到期时,会自动续费一个月。 +// * 支持批量操作。每次请求批量实例的上限为100。 +func (c *Client) ModifyInstancesRenewFlag(request *ModifyInstancesRenewFlagRequest) (response *ModifyInstancesRenewFlagResponse, err error) { + if request == nil { + request = NewModifyInstancesRenewFlagRequest() + } + response = NewModifyInstancesRenewFlagResponse() + err = c.Send(request, response) + return +} + +func NewModifyInstancesVpcAttributeRequest() (request *ModifyInstancesVpcAttributeRequest) { + request = &ModifyInstancesVpcAttributeRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "ModifyInstancesVpcAttribute") + return +} + +func NewModifyInstancesVpcAttributeResponse() (response *ModifyInstancesVpcAttributeResponse) { + response = &ModifyInstancesVpcAttributeResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ModifyInstancesVpcAttribute)用于修改实例vpc属性,如私有网络ip。 +// * 此操作默认会关闭实例,完成后再启动。 +// * 当指定私有网络ID和子网ID(子网必须在实例所在的可用区)与指定实例所在私有网络不一致时,会将实例迁移至指定的私有网络的子网下。执行此操作前请确保指定的实例上没有绑定[弹性网卡](https://cloud.tencent.com/document/product/576)和[负载均衡](https://cloud.tencent.com/document/product/214)。 +func (c *Client) ModifyInstancesVpcAttribute(request *ModifyInstancesVpcAttributeRequest) (response *ModifyInstancesVpcAttributeResponse, err error) { + if request == nil { + request = NewModifyInstancesVpcAttributeRequest() + } + response = NewModifyInstancesVpcAttributeResponse() + err = c.Send(request, response) + return +} + +func NewModifyKeyPairAttributeRequest() (request *ModifyKeyPairAttributeRequest) { + request = &ModifyKeyPairAttributeRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "ModifyKeyPairAttribute") + return +} + +func NewModifyKeyPairAttributeResponse() (response *ModifyKeyPairAttributeResponse) { + response = &ModifyKeyPairAttributeResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (ModifyKeyPairAttribute) 用于修改密钥对属性。 +// +// * 修改密钥对ID所指定的密钥对的名称和描述信息。 +// * 密钥对名称不能和已经存在的密钥对的名称重复。 +// * 密钥对ID是密钥对的唯一标识,不可修改。 +func (c *Client) ModifyKeyPairAttribute(request *ModifyKeyPairAttributeRequest) (response *ModifyKeyPairAttributeResponse, err error) { + if request == nil { + request = NewModifyKeyPairAttributeRequest() + } + response = NewModifyKeyPairAttributeResponse() + err = c.Send(request, response) + return +} + +func NewRebootInstancesRequest() (request *RebootInstancesRequest) { + request = &RebootInstancesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "RebootInstances") + return +} + +func NewRebootInstancesResponse() (response *RebootInstancesResponse) { + response = &RebootInstancesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (RebootInstances) 用于重启实例。 +// +// * 只有状态为`RUNNING`的实例才可以进行此操作。 +// * 接口调用成功时,实例会进入`REBOOTING`状态;重启实例成功时,实例会进入`RUNNING`状态。 +// * 支持强制重启。强制重启的效果等同于关闭物理计算机的电源开关再重新启动。强制重启可能会导致数据丢失或文件系统损坏,请仅在服务器不能正常重启时使用。 +// * 支持批量操作,每次请求批量实例的上限为100。 +func (c *Client) RebootInstances(request *RebootInstancesRequest) (response *RebootInstancesResponse, err error) { + if request == nil { + request = NewRebootInstancesRequest() + } + response = NewRebootInstancesResponse() + err = c.Send(request, response) + return +} + +func NewRenewHostsRequest() (request *RenewHostsRequest) { + request = &RenewHostsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "RenewHosts") + return +} + +func NewRenewHostsResponse() (response *RenewHostsResponse) { + response = &RenewHostsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (RenewHosts) 用于续费包年包月CDH实例。 +// +// * 只支持操作包年包月实例,否则操作会以特定[错误码](#4.-.E9.94.99.E8.AF.AF.E7.A0.81)返回。 +// * 续费时请确保账户余额充足。可通过[`DescribeAccountBalance`](https://cloud.tencent.com/document/product/378/4397)接口查询账户余额。 +func (c *Client) RenewHosts(request *RenewHostsRequest) (response *RenewHostsResponse, err error) { + if request == nil { + request = NewRenewHostsRequest() + } + response = NewRenewHostsResponse() + err = c.Send(request, response) + return +} + +func NewRenewInstancesRequest() (request *RenewInstancesRequest) { + request = &RenewInstancesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "RenewInstances") + return +} + +func NewRenewInstancesResponse() (response *RenewInstancesResponse) { + response = &RenewInstancesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (RenewInstances) 用于续费包年包月实例。 +// +// * 只支持操作包年包月实例。 +// * 续费时请确保账户余额充足。可通过[`DescribeAccountBalance`](https://cloud.tencent.com/document/product/378/4397)接口查询账户余额。 +func (c *Client) RenewInstances(request *RenewInstancesRequest) (response *RenewInstancesResponse, err error) { + if request == nil { + request = NewRenewInstancesRequest() + } + response = NewRenewInstancesResponse() + err = c.Send(request, response) + return +} + +func NewResetInstanceRequest() (request *ResetInstanceRequest) { + request = &ResetInstanceRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "ResetInstance") + return +} + +func NewResetInstanceResponse() (response *ResetInstanceResponse) { + response = &ResetInstanceResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (ResetInstance) 用于重装指定实例上的操作系统。 +// +// * 如果指定了`ImageId`参数,则使用指定的镜像重装;否则按照当前实例使用的镜像进行重装。 +// * 系统盘将会被格式化,并重置;请确保系统盘中无重要文件。 +// * `Linux`和`Windows`系统互相切换时,该实例系统盘`ID`将发生变化,系统盘关联快照将无法回滚、恢复数据。 +// * 密码不指定将会通过站内信下发随机密码。 +// * 目前只支持[系统盘类型](https://cloud.tencent.com/document/api/213/9452#block_device)是`CLOUD_BASIC`、`CLOUD_PREMIUM`、`CLOUD_SSD`类型的实例使用该接口实现`Linux`和`Windows`操作系统切换。 +// * 目前不支持海外地域的实例使用该接口实现`Linux`和`Windows`操作系统切换。 +func (c *Client) ResetInstance(request *ResetInstanceRequest) (response *ResetInstanceResponse, err error) { + if request == nil { + request = NewResetInstanceRequest() + } + response = NewResetInstanceResponse() + err = c.Send(request, response) + return +} + +func NewResetInstancesInternetMaxBandwidthRequest() (request *ResetInstancesInternetMaxBandwidthRequest) { + request = &ResetInstancesInternetMaxBandwidthRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "ResetInstancesInternetMaxBandwidth") + return +} + +func NewResetInstancesInternetMaxBandwidthResponse() (response *ResetInstancesInternetMaxBandwidthResponse) { + response = &ResetInstancesInternetMaxBandwidthResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (ResetInstancesInternetMaxBandwidth) 用于调整实例公网带宽上限。 +// +// * 不同机型带宽上限范围不一致,具体限制详见[购买网络带宽](https://cloud.tencent.com/document/product/213/509)。 +// * 对于 `BANDWIDTH_PREPAID` 计费方式的带宽,需要输入参数 `StartTime` 和 `EndTime` ,指定调整后的带宽的生效时间段。在这种场景下目前不支持调小带宽,会涉及扣费,请确保账户余额充足。可通过 [`DescribeAccountBalance`](https://cloud.tencent.com/document/product/378/4397) 接口查询账户余额。 +// * 对于 `TRAFFIC_POSTPAID_BY_HOUR` 、 `BANDWIDTH_POSTPAID_BY_HOUR` 和 `BANDWIDTH_PACKAGE` 计费方式的带宽,使用该接口调整带宽上限是实时生效的,可以在带宽允许的范围内调大或者调小带宽,不支持输入参数 `StartTime` 和 `EndTime` 。 +// * 接口不支持调整 `BANDWIDTH_POSTPAID_BY_MONTH` 计费方式的带宽。 +// * 接口不支持批量调整 `BANDWIDTH_PREPAID` 和 `BANDWIDTH_POSTPAID_BY_HOUR` 计费方式的带宽。 +// * 接口不支持批量调整混合计费方式的带宽。例如不支持同时调整 `TRAFFIC_POSTPAID_BY_HOUR` 和 `BANDWIDTH_PACKAGE` 计费方式的带宽。 +func (c *Client) ResetInstancesInternetMaxBandwidth(request *ResetInstancesInternetMaxBandwidthRequest) (response *ResetInstancesInternetMaxBandwidthResponse, err error) { + if request == nil { + request = NewResetInstancesInternetMaxBandwidthRequest() + } + response = NewResetInstancesInternetMaxBandwidthResponse() + err = c.Send(request, response) + return +} + +func NewResetInstancesPasswordRequest() (request *ResetInstancesPasswordRequest) { + request = &ResetInstancesPasswordRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "ResetInstancesPassword") + return +} + +func NewResetInstancesPasswordResponse() (response *ResetInstancesPasswordResponse) { + response = &ResetInstancesPasswordResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (ResetInstancesPassword) 用于将实例操作系统的密码重置为用户指定的密码。 +// +// * 只修改管理员帐号的密码。实例的操作系统不同,管理员帐号也会不一样(`Windows`为`Administrator`,`Ubuntu`为`ubuntu`,其它系统为`root`)。 +// * 重置处于运行中状态的实例,需要显式指定强制关机参数`ForceStop`。如果没有显式指定强制关机参数,则只有处于关机状态的实例才允许执行重置密码操作。 +// * 支持批量操作。将多个实例操作系统的密码重置为相同的密码。每次请求批量实例的上限为100。 +func (c *Client) ResetInstancesPassword(request *ResetInstancesPasswordRequest) (response *ResetInstancesPasswordResponse, err error) { + if request == nil { + request = NewResetInstancesPasswordRequest() + } + response = NewResetInstancesPasswordResponse() + err = c.Send(request, response) + return +} + +func NewResetInstancesTypeRequest() (request *ResetInstancesTypeRequest) { + request = &ResetInstancesTypeRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "ResetInstancesType") + return +} + +func NewResetInstancesTypeResponse() (response *ResetInstancesTypeResponse) { + response = &ResetInstancesTypeResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (ResetInstancesType) 用于调整实例的机型。 +// * 目前只支持[系统盘类型](/document/api/213/9452#block_device)是`CLOUD_BASIC`、`CLOUD_PREMIUM`、`CLOUD_SSD`类型的实例使用该接口进行机型调整。 +// * 目前不支持[CDH](https://cloud.tencent.com/document/product/416)实例使用该接口调整机型。* 目前不支持跨机型系统来调整机型,即使用该接口时指定的`InstanceType`和实例原来的机型需要属于同一系列。* 对于包年包月实例,使用该接口会涉及扣费,请确保账户余额充足。可通过[`DescribeAccountBalance`](https://cloud.tencent.com/document/product/378/4397)接口查询账户余额。 +func (c *Client) ResetInstancesType(request *ResetInstancesTypeRequest) (response *ResetInstancesTypeResponse, err error) { + if request == nil { + request = NewResetInstancesTypeRequest() + } + response = NewResetInstancesTypeResponse() + err = c.Send(request, response) + return +} + +func NewResizeInstanceDisksRequest() (request *ResizeInstanceDisksRequest) { + request = &ResizeInstanceDisksRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "ResizeInstanceDisks") + return +} + +func NewResizeInstanceDisksResponse() (response *ResizeInstanceDisksResponse) { + response = &ResizeInstanceDisksResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (ResizeInstanceDisks) 用于扩容实例的数据盘。 +// +// * 目前只支持扩容随实例购买的数据盘,且[数据盘类型](/document/api/213/9452#block_device)为:`CLOUD_BASIC`、`CLOUD_PREMIUM`、`CLOUD_SSD`。* 目前不支持[CDH](https://cloud.tencent.com/document/product/416)实例使用该接口扩容数据盘。 +// * 对于包年包月实例,使用该接口会涉及扣费,请确保账户余额充足。可通过[`DescribeAccountBalance`](https://cloud.tencent.com/document/product/378/4397)接口查询账户余额。 +// * 目前只支持扩容一块数据盘。 +func (c *Client) ResizeInstanceDisks(request *ResizeInstanceDisksRequest) (response *ResizeInstanceDisksResponse, err error) { + if request == nil { + request = NewResizeInstanceDisksRequest() + } + response = NewResizeInstanceDisksResponse() + err = c.Send(request, response) + return +} + +func NewRunInstancesRequest() (request *RunInstancesRequest) { + request = &RunInstancesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "RunInstances") + return +} + +func NewRunInstancesResponse() (response *RunInstancesResponse) { + response = &RunInstancesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (RunInstances) 用于创建一个或多个指定配置的实例。 +// +// * 实例创建成功后将自动开机启动,[实例状态](/document/api/213/9452#instance_state)变为“运行中”。 +// * 预付费实例的购买会预先扣除本次实例购买所需金额,按小时后付费实例购买会预先冻结本次实例购买一小时内所需金额,在调用本接口前请确保账户余额充足。 +// * 本接口允许购买的实例数量遵循[CVM实例购买限制](https://cloud.tencent.com/document/product/213/2664),所创建的实例和官网入口创建的实例共用配额。 +// * 本接口为异步接口,当创建请求下发成功后会返回一个实例`ID`列表,此时实例的创建并立即未完成。在此期间实例的状态将会处于“准备中”,可以通过调用 [DescribeInstances](https://cloud.tencent.com/document/api/213/15728) 接口查询对应实例的状态,来判断创建有没有最终成功。如果实例的状态由“准备中”变为“运行中”,则为创建成功。 +func (c *Client) RunInstances(request *RunInstancesRequest) (response *RunInstancesResponse, err error) { + if request == nil { + request = NewRunInstancesRequest() + } + response = NewRunInstancesResponse() + err = c.Send(request, response) + return +} + +func NewStartInstancesRequest() (request *StartInstancesRequest) { + request = &StartInstancesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "StartInstances") + return +} + +func NewStartInstancesResponse() (response *StartInstancesResponse) { + response = &StartInstancesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (StartInstances) 用于启动一个或多个实例。 +// +// * 只有状态为`STOPPED`的实例才可以进行此操作。 +// * 接口调用成功时,实例会进入`STARTING`状态;启动实例成功时,实例会进入`RUNNING`状态。 +// * 支持批量操作。每次请求批量实例的上限为100。 +func (c *Client) StartInstances(request *StartInstancesRequest) (response *StartInstancesResponse, err error) { + if request == nil { + request = NewStartInstancesRequest() + } + response = NewStartInstancesResponse() + err = c.Send(request, response) + return +} + +func NewStopInstancesRequest() (request *StopInstancesRequest) { + request = &StopInstancesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "StopInstances") + return +} + +func NewStopInstancesResponse() (response *StopInstancesResponse) { + response = &StopInstancesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (StopInstances) 用于关闭一个或多个实例。 +// +// * 只有状态为`RUNNING`的实例才可以进行此操作。 +// * 接口调用成功时,实例会进入`STOPPING`状态;关闭实例成功时,实例会进入`STOPPED`状态。 +// * 支持强制关闭。强制关机的效果等同于关闭物理计算机的电源开关。强制关机可能会导致数据丢失或文件系统损坏,请仅在服务器不能正常关机时使用。 +// * 支持批量操作。每次请求批量实例的上限为100。 +func (c *Client) StopInstances(request *StopInstancesRequest) (response *StopInstancesResponse, err error) { + if request == nil { + request = NewStopInstancesRequest() + } + response = NewStopInstancesResponse() + err = c.Send(request, response) + return +} + +func NewSyncImagesRequest() (request *SyncImagesRequest) { + request = &SyncImagesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "SyncImages") + return +} + +func NewSyncImagesResponse() (response *SyncImagesResponse) { + response = &SyncImagesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(SyncImages)用于将自定义镜像同步到其它地区。 +// +// * 该接口每次调用只支持同步一个镜像。 +// * 该接口支持多个同步地域。 +// * 单个帐号在每个地域最多支持存在10个自定义镜像。 +func (c *Client) SyncImages(request *SyncImagesRequest) (response *SyncImagesResponse, err error) { + if request == nil { + request = NewSyncImagesRequest() + } + response = NewSyncImagesResponse() + err = c.Send(request, response) + return +} + +func NewTerminateInstancesRequest() (request *TerminateInstancesRequest) { + request = &TerminateInstancesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cvm", APIVersion, "TerminateInstances") + return +} + +func NewTerminateInstancesResponse() (response *TerminateInstancesResponse) { + response = &TerminateInstancesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (TerminateInstances) 用于主动退还实例。 +// +// * 不再使用的实例,可通过本接口主动退还。 +// * 按量计费的实例通过本接口可直接退还;包年包月实例如符合[退还规则](https://cloud.tencent.com/document/product/213/9711),也可通过本接口主动退还。 +// * 支持批量操作,每次请求批量实例的上限为100。 +func (c *Client) TerminateInstances(request *TerminateInstancesRequest) (response *TerminateInstancesResponse, err error) { + if request == nil { + request = NewTerminateInstancesRequest() + } + response = NewTerminateInstancesResponse() + err = c.Send(request, response) + return +} diff --git a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312/models.go b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312/models.go new file mode 100644 index 000000000..d204279d9 --- /dev/null +++ b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312/models.go @@ -0,0 +1,2771 @@ +// Copyright (c) 2017-2018 THL A29 Limited, a Tencent company. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v20170312 + +import ( + "encoding/json" + + tchttp "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http" +) + +type ActionTimer struct { + // 扩展数据 + Externals *Externals `json:"Externals" name:"Externals"` + // 定时器名称,目前仅支持销毁一个值:TerminateInstances。 + TimerAction *string `json:"TimerAction" name:"TimerAction"` + // 执行时间,格式形如:2018-5-29 11:26:40,执行时间必须大于当前时间5分钟。 + ActionTime *string `json:"ActionTime" name:"ActionTime"` +} + +type AllocateHostsRequest struct { + *tchttp.BaseRequest + // 实例所在的位置。通过该参数可以指定实例所属可用区,所属项目等属性。 + Placement *Placement `json:"Placement" name:"Placement"` + // 用于保证请求幂等性的字符串。 + ClientToken *string `json:"ClientToken" name:"ClientToken"` + // 预付费模式,即包年包月相关参数设置。通过该参数可以指定包年包月实例的购买时长、是否设置自动续费等属性。若指定实例的付费模式为预付费则该参数必传。 + HostChargePrepaid *ChargePrepaid `json:"HostChargePrepaid" name:"HostChargePrepaid"` + // 实例计费类型。目前仅支持:PREPAID(预付费,即包年包月模式)。 + HostChargeType *string `json:"HostChargeType" name:"HostChargeType"` + // CDH实例机型,默认为:'HS1'。 + HostType *string `json:"HostType" name:"HostType"` + // 购买CDH实例数量。 + HostCount *uint64 `json:"HostCount" name:"HostCount"` +} + +func (r *AllocateHostsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AllocateHostsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type AllocateHostsResponse struct { + *tchttp.BaseResponse + Response *struct { + // 新创建云子机的实例id列表。 + HostIdSet []*string `json:"HostIdSet" name:"HostIdSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *AllocateHostsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AllocateHostsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type AssociateInstancesKeyPairsRequest struct { + *tchttp.BaseRequest + // 一个或多个待操作的实例ID,每次请求批量实例的上限为100。
可以通过以下方式获取可用的实例ID:
  • 通过登录[控制台](https://console.cloud.tencent.com/cvm/index)查询实例ID。
  • 通过调用接口 [DescribeInstances](https://cloud.tencent.com/document/api/213/15728) ,取返回信息中的`InstanceId`获取实例ID。 + InstanceIds []*string `json:"InstanceIds" name:"InstanceIds" list` + // 一个或多个待操作的密钥对ID,每次请求批量密钥对的上限为100。密钥对ID形如:`skey-3glfot13`。
    可以通过以下方式获取可用的密钥ID:
  • 通过登录[控制台](https://console.cloud.tencent.com/cvm/sshkey)查询密钥ID。
  • 通过调用接口 [DescribeKeyPairs](https://cloud.tencent.com/document/api/213/15699) ,取返回信息中的`KeyId`获取密钥对ID。 + KeyIds []*string `json:"KeyIds" name:"KeyIds" list` + // 是否对运行中的实例选择强制关机。建议对运行中的实例先手动关机,然后再重置用户密码。取值范围:
  • TRUE:表示在正常关机失败后进行强制关机。
  • FALSE:表示在正常关机失败后不进行强制关机。
    默认取值:FALSE。 + ForceStop *bool `json:"ForceStop" name:"ForceStop"` +} + +func (r *AssociateInstancesKeyPairsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AssociateInstancesKeyPairsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type AssociateInstancesKeyPairsResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *AssociateInstancesKeyPairsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AssociateInstancesKeyPairsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ChargePrepaid struct { + // 购买实例的时长,单位:月。取值范围:1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 24, 36。 + Period *uint64 `json:"Period" name:"Period"` + // 自动续费标识。取值范围:
  • NOTIFY_AND_AUTO_RENEW:通知过期且自动续费
  • NOTIFY_AND_MANUAL_RENEW:通知过期不自动续费
  • DISABLE_NOTIFY_AND_MANUAL_RENEW:不通知过期不自动续费

    默认取值:NOTIFY_AND_AUTO_RENEW。若该参数指定为NOTIFY_AND_AUTO_RENEW,在账户余额充足的情况下,实例到期后将按月自动续费。 + RenewFlag *string `json:"RenewFlag" name:"RenewFlag"` +} + +type CreateDisasterRecoverGroupRequest struct { + *tchttp.BaseRequest + // 分散置放群组名称,长度1-60个字符,支持中、英文。 + Name *string `json:"Name" name:"Name"` + // 分散置放群组类型,取值范围:
  • HOST:物理机
  • SW:交换机
  • RACK:机架 + Type *string `json:"Type" name:"Type"` + // 用于保证请求幂等性的字符串。该字符串由客户生成,需保证不同请求之间唯一,最大值不超过64个ASCII字符。若不指定该参数,则无法保证请求的幂等性。
    更多详细信息请参阅:如何保证幂等性。 + ClientToken *string `json:"ClientToken" name:"ClientToken"` +} + +func (r *CreateDisasterRecoverGroupRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateDisasterRecoverGroupRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateDisasterRecoverGroupResponse struct { + *tchttp.BaseResponse + Response *struct { + // 分散置放群组ID列表。 + DisasterRecoverGroupId *string `json:"DisasterRecoverGroupId" name:"DisasterRecoverGroupId"` + // 分散置放群组类型,取值范围:
  • HOST:物理机
  • SW:交换机
  • RACK:机架 + Type *string `json:"Type" name:"Type"` + // 分散置放群组名称,长度1-60个字符,支持中、英文。 + Name *string `json:"Name" name:"Name"` + // 置放群组内可容纳的云主机数量。 + CvmQuotaTotal *int64 `json:"CvmQuotaTotal" name:"CvmQuotaTotal"` + // 置放群组内已有的云主机数量。 + CurrentNum *int64 `json:"CurrentNum" name:"CurrentNum"` + // 置放群组创建时间。 + CreateTime *string `json:"CreateTime" name:"CreateTime"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *CreateDisasterRecoverGroupResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateDisasterRecoverGroupResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateImageRequest struct { + *tchttp.BaseRequest + // 需要制作镜像的实例ID + InstanceId *string `json:"InstanceId" name:"InstanceId"` + // 镜像名称 + ImageName *string `json:"ImageName" name:"ImageName"` + // 镜像描述 + ImageDescription *string `json:"ImageDescription" name:"ImageDescription"` + // 软关机失败时是否执行强制关机以制作镜像 + ForcePoweroff *string `json:"ForcePoweroff" name:"ForcePoweroff"` + // 创建Windows镜像时是否启用Sysprep + Sysprep *string `json:"Sysprep" name:"Sysprep"` + // 实例处于运行中时,是否允许关机执行制作镜像任务。 + Reboot *string `json:"Reboot" name:"Reboot"` +} + +func (r *CreateImageRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateImageRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateImageResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *CreateImageResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateImageResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateKeyPairRequest struct { + *tchttp.BaseRequest + // 密钥对名称,可由数字,字母和下划线组成,长度不超过25个字符。 + KeyName *string `json:"KeyName" name:"KeyName"` + // 密钥对创建后所属的项目ID。 + // 可以通过以下方式获取项目ID: + //
  • 通过项目列表查询项目ID。 + //
  • 通过调用接口DescribeProject,取返回信息中的`projectId `获取项目ID。 + ProjectId *int64 `json:"ProjectId" name:"ProjectId"` +} + +func (r *CreateKeyPairRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateKeyPairRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateKeyPairResponse struct { + *tchttp.BaseResponse + Response *struct { + // 密钥对信息。 + KeyPair *KeyPair `json:"KeyPair" name:"KeyPair"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *CreateKeyPairResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateKeyPairResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DataDisk struct { + // 数据盘大小,单位:GB。最小调整步长为10G,不同数据盘类型取值范围不同,具体限制详见:[CVM实例配置](/document/product/213/2177)。默认值为0,表示不购买数据盘。更多限制详见产品文档。 + DiskSize *int64 `json:"DiskSize" name:"DiskSize"` + // 数据盘类型。数据盘类型限制详见[CVM实例配置](/document/product/213/2177)。取值范围:
  • LOCAL_BASIC:本地硬盘
  • LOCAL_SSD:本地SSD硬盘
  • CLOUD_BASIC:普通云硬盘
  • CLOUD_PREMIUM:高性能云硬盘
  • CLOUD_SSD:SSD云硬盘

    默认取值:LOCAL_BASIC。

    该参数对`ResizeInstanceDisk`接口无效。 + DiskType *string `json:"DiskType" name:"DiskType"` + // 数据盘ID。LOCAL_BASIC 和 LOCAL_SSD 类型没有ID。暂时不支持该参数。 + DiskId *string `json:"DiskId" name:"DiskId"` + // 数据盘是否随子机销毁。取值范围: + //
  • TRUE:子机销毁时,销毁数据盘 + //
  • FALSE:子机销毁时,保留数据盘
    + // 默认取值:TRUE
    + // 该参数目前仅用于 `RunInstances` 接口。 + DeleteWithInstance *bool `json:"DeleteWithInstance" name:"DeleteWithInstance"` +} + +type DeleteDisasterRecoverGroupsRequest struct { + *tchttp.BaseRequest + // 分散置放群组ID列表,可通过[DescribeDisasterRecoverGroups](https://cloud.tencent.com/document/api/213/17810)接口获取。 + DisasterRecoverGroupIds []*string `json:"DisasterRecoverGroupIds" name:"DisasterRecoverGroupIds" list` +} + +func (r *DeleteDisasterRecoverGroupsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteDisasterRecoverGroupsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteDisasterRecoverGroupsResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DeleteDisasterRecoverGroupsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteDisasterRecoverGroupsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteImagesRequest struct { + *tchttp.BaseRequest + // 准备删除的镜像Id列表 + ImageIds []*string `json:"ImageIds" name:"ImageIds" list` +} + +func (r *DeleteImagesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteImagesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteImagesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DeleteImagesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteImagesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteKeyPairsRequest struct { + *tchttp.BaseRequest + // 一个或多个待操作的密钥对ID。每次请求批量密钥对的上限为100。
    可以通过以下方式获取可用的密钥ID:
  • 通过登录[控制台](https://console.cloud.tencent.com/cvm/sshkey)查询密钥ID。
  • 通过调用接口 [DescribeKeyPairs](https://cloud.tencent.com/document/api/213/15699) ,取返回信息中的 `KeyId` 获取密钥对ID。 + KeyIds []*string `json:"KeyIds" name:"KeyIds" list` +} + +func (r *DeleteKeyPairsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteKeyPairsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteKeyPairsResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DeleteKeyPairsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteKeyPairsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeDisasterRecoverGroupQuotaRequest struct { + *tchttp.BaseRequest +} + +func (r *DescribeDisasterRecoverGroupQuotaRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeDisasterRecoverGroupQuotaRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeDisasterRecoverGroupQuotaResponse struct { + *tchttp.BaseResponse + Response *struct { + // 可创建置放群组数量的上限。 + GroupQuota *int64 `json:"GroupQuota" name:"GroupQuota"` + // 当前用户已经创建的置放群组数量。 + CurrentNum *int64 `json:"CurrentNum" name:"CurrentNum"` + // 物理机类型容灾组内实例的配额数。 + CvmInHostGroupQuota *int64 `json:"CvmInHostGroupQuota" name:"CvmInHostGroupQuota"` + // 交换机类型容灾组内实例的配额数。 + CvmInSwGroupQuota *int64 `json:"CvmInSwGroupQuota" name:"CvmInSwGroupQuota"` + // 机架类型容灾组内实例的配额数。 + CvmInRackGroupQuota *int64 `json:"CvmInRackGroupQuota" name:"CvmInRackGroupQuota"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeDisasterRecoverGroupQuotaResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeDisasterRecoverGroupQuotaResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeDisasterRecoverGroupsRequest struct { + *tchttp.BaseRequest + // 分散置放群组ID列表。 + DisasterRecoverGroupIds []*string `json:"DisasterRecoverGroupIds" name:"DisasterRecoverGroupIds" list` + // 分散置放群组名称,支持模糊匹配。 + Name *string `json:"Name" name:"Name"` + // 偏移量,默认为0。关于`Offset`的更进一步介绍请参考 API [简介](https://cloud.tencent.com/document/api/213/15688)中的相关小节。 + Offset *int64 `json:"Offset" name:"Offset"` + // 返回数量,默认为20,最大值为100。关于`Limit`的更进一步介绍请参考 API [简介](https://cloud.tencent.com/document/api/213/15688)中的相关小节。 + Limit *int64 `json:"Limit" name:"Limit"` +} + +func (r *DescribeDisasterRecoverGroupsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeDisasterRecoverGroupsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeDisasterRecoverGroupsResponse struct { + *tchttp.BaseResponse + Response *struct { + // 分散置放群组信息列表。 + DisasterRecoverGroupSet []*DisasterRecoverGroup `json:"DisasterRecoverGroupSet" name:"DisasterRecoverGroupSet" list` + // 用户置放群组总量。 + TotalCount *int64 `json:"TotalCount" name:"TotalCount"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeDisasterRecoverGroupsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeDisasterRecoverGroupsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeHostsRequest struct { + *tchttp.BaseRequest + // 过滤条件。 + //
  • zone - String - 是否必填:否 - (过滤条件)按照可用区过滤。
  • + //
  • project-id - Integer - 是否必填:否 - (过滤条件)按照项目ID过滤。可通过调用 DescribeProject 查询已创建的项目列表或登录控制台进行查看;也可以调用 AddProject 创建新的项目。
  • + //
  • host-id - String - 是否必填:否 - (过滤条件)按照CDH ID过滤。CDH ID形如:host-11112222。
  • + //
  • host-name - String - 是否必填:否 - (过滤条件)按照CDH实例名称过滤。
  • + //
  • host-state - String - 是否必填:否 - (过滤条件)按照CDH实例状态进行过滤。(PENDING:创建中|LAUNCH_FAILURE:创建失败|RUNNING:运行中|EXPIRED:已过期)
  • + Filters []*Filter `json:"Filters" name:"Filters" list` + // 偏移量,默认为0。 + Offset *uint64 `json:"Offset" name:"Offset"` + // 返回数量,默认为20,最大值为100。 + Limit *uint64 `json:"Limit" name:"Limit"` +} + +func (r *DescribeHostsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeHostsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeHostsResponse struct { + *tchttp.BaseResponse + Response *struct { + // 符合查询条件的cdh实例总数 + TotalCount *uint64 `json:"TotalCount" name:"TotalCount"` + // cdh实例详细信息列表 + HostSet []*HostItem `json:"HostSet" name:"HostSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeHostsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeHostsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeImageQuotaRequest struct { + *tchttp.BaseRequest +} + +func (r *DescribeImageQuotaRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeImageQuotaRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeImageQuotaResponse struct { + *tchttp.BaseResponse + Response *struct { + // 账户的镜像配额 + ImageNumQuota *int64 `json:"ImageNumQuota" name:"ImageNumQuota"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeImageQuotaResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeImageQuotaResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeImageSharePermissionRequest struct { + *tchttp.BaseRequest + // 需要共享的镜像Id + ImageId *string `json:"ImageId" name:"ImageId"` +} + +func (r *DescribeImageSharePermissionRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeImageSharePermissionRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeImageSharePermissionResponse struct { + *tchttp.BaseResponse + Response *struct { + // 镜像共享信息 + SharePermissionSet []*SharePermission `json:"SharePermissionSet" name:"SharePermissionSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeImageSharePermissionResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeImageSharePermissionResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeImagesRequest struct { + *tchttp.BaseRequest + // 镜像ID列表 。镜像ID如:`img-gvbnzy6f`。array型参数的格式可以参考[API简介](https://cloud.tencent.com/document/api/213/15688)。镜像ID可以通过如下方式获取:
  • 通过[DescribeImages](https://cloud.tencent.com/document/api/213/15715)接口返回的`ImageId`获取。
  • 通过[镜像控制台](https://console.cloud.tencent.com/cvm/image)获取。 + ImageIds []*string `json:"ImageIds" name:"ImageIds" list` + // 过滤条件,每次请求的`Filters`的上限为0,`Filters.Values`的上限为5。参数不可以同时指定`ImageIds`和`Filters`。详细的过滤条件如下: + //
  • image-id - String - 是否必填: 否 - (过滤条件)按照镜像ID进行过滤
  • + //
  • image-type - String - 是否必填: 否 - (过滤条件)按照镜像类型进行过滤。取值范围:详见[镜像类型](https://cloud.tencent.com/document/product/213/9452#image_type)。
  • + //
  • image-state - String - 是否必填: 否 - (过滤条件)按照镜像状态进行过滤。取值范围:详见[镜像状态](https://cloud.tencent.com/document/product/213/9452#image_state)。
  • + Filters []*Filter `json:"Filters" name:"Filters" list` + // 偏移量,默认为0。关于Offset详见[API简介](/document/api/213/568#.E8.BE.93.E5.85.A5.E5.8F.82.E6.95.B0.E4.B8.8E.E8.BF.94.E5.9B.9E.E5.8F.82.E6.95.B0.E9.87.8A.E4.B9.89)。 + Offset *uint64 `json:"Offset" name:"Offset"` + // 数量限制,默认为20,最大值为100。关于Limit详见[API简介](/document/api/213/568#.E8.BE.93.E5.85.A5.E5.8F.82.E6.95.B0.E4.B8.8E.E8.BF.94.E5.9B.9E.E5.8F.82.E6.95.B0.E9.87.8A.E4.B9.89)。 + Limit *uint64 `json:"Limit" name:"Limit"` + // 实例类型,如 `S1.SMALL1` + InstanceType *string `json:"InstanceType" name:"InstanceType"` +} + +func (r *DescribeImagesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeImagesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeImagesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 一个关于镜像详细信息的结构体,主要包括镜像的主要状态与属性。 + ImageSet []*Image `json:"ImageSet" name:"ImageSet" list` + // 符合要求的镜像数量。 + TotalCount *int64 `json:"TotalCount" name:"TotalCount"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeImagesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeImagesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeImportImageOsRequest struct { + *tchttp.BaseRequest +} + +func (r *DescribeImportImageOsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeImportImageOsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeImportImageOsResponse struct { + *tchttp.BaseResponse + Response *struct { + // 支持的导入镜像的操作系统类型。 + ImportImageOsListSupported *ImageOsList `json:"ImportImageOsListSupported" name:"ImportImageOsListSupported"` + // 支持的导入镜像的操作系统版本。 + ImportImageOsVersionSet []*OsVersion `json:"ImportImageOsVersionSet" name:"ImportImageOsVersionSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeImportImageOsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeImportImageOsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeInstanceFamilyConfigsRequest struct { + *tchttp.BaseRequest +} + +func (r *DescribeInstanceFamilyConfigsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeInstanceFamilyConfigsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeInstanceFamilyConfigsResponse struct { + *tchttp.BaseResponse + Response *struct { + // 实例机型组配置的列表信息 + InstanceFamilyConfigSet []*InstanceFamilyConfig `json:"InstanceFamilyConfigSet" name:"InstanceFamilyConfigSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeInstanceFamilyConfigsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeInstanceFamilyConfigsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeInstanceInternetBandwidthConfigsRequest struct { + *tchttp.BaseRequest + // 待操作的实例ID。可通过[`DescribeInstances`](https://cloud.tencent.com/document/api/213/15728)接口返回值中的`InstanceId`获取。 + InstanceId *string `json:"InstanceId" name:"InstanceId"` +} + +func (r *DescribeInstanceInternetBandwidthConfigsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeInstanceInternetBandwidthConfigsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeInstanceInternetBandwidthConfigsResponse struct { + *tchttp.BaseResponse + Response *struct { + // 带宽配置信息列表。 + InternetBandwidthConfigSet []*InternetBandwidthConfig `json:"InternetBandwidthConfigSet" name:"InternetBandwidthConfigSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeInstanceInternetBandwidthConfigsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeInstanceInternetBandwidthConfigsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeInstanceTypeConfigsRequest struct { + *tchttp.BaseRequest + // 过滤条件。 + //
  • zone - String - 是否必填:否 -(过滤条件)按照[可用区](https://cloud.tencent.com/document/api/213/9452#zone)过滤。
  • + //
  • instance-family - String - 是否必填:否 -(过滤条件)按照实例机型系列过滤。实例机型系列形如:S1、I1、M1等。
  • + // 每次请求的`Filters`的上限为10,`Filter.Values`的上限为1。 + Filters []*Filter `json:"Filters" name:"Filters" list` +} + +func (r *DescribeInstanceTypeConfigsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeInstanceTypeConfigsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeInstanceTypeConfigsResponse struct { + *tchttp.BaseResponse + Response *struct { + // 实例机型配置列表。 + InstanceTypeConfigSet []*InstanceTypeConfig `json:"InstanceTypeConfigSet" name:"InstanceTypeConfigSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeInstanceTypeConfigsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeInstanceTypeConfigsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeInstanceVncUrlRequest struct { + *tchttp.BaseRequest + // 一个操作的实例ID。可通过[`DescribeInstances`](https://cloud.tencent.com/document/api/213/15728) API返回值中的`InstanceId`获取。 + InstanceId *string `json:"InstanceId" name:"InstanceId"` +} + +func (r *DescribeInstanceVncUrlRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeInstanceVncUrlRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeInstanceVncUrlResponse struct { + *tchttp.BaseResponse + Response *struct { + // 实例的管理终端地址。 + InstanceVncUrl *string `json:"InstanceVncUrl" name:"InstanceVncUrl"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeInstanceVncUrlResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeInstanceVncUrlResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeInstancesRequest struct { + *tchttp.BaseRequest + // 按照一个或者多个实例ID查询。实例ID形如:`ins-xxxxxxxx`。(此参数的具体格式可参考API[简介](https://cloud.tencent.com/document/api/213/15688)的`id.N`一节)。每次请求的实例的上限为100。参数不支持同时指定`InstanceIds`和`Filters`。 + InstanceIds []*string `json:"InstanceIds" name:"InstanceIds" list` + // 过滤条件。 + //
  • zone - String - 是否必填:否 -(过滤条件)按照可用区过滤。
  • + //
  • project-id - Integer - 是否必填:否 -(过滤条件)按照项目ID过滤。可通过调用[DescribeProject](https://cloud.tencent.com/document/api/378/4400)查询已创建的项目列表或登录[控制台](https://console.cloud.tencent.com/cvm/index)进行查看;也可以调用[AddProject](https://cloud.tencent.com/document/api/378/4398)创建新的项目。
  • + //
  • host-id - String - 是否必填:否 - (过滤条件)按照[CDH](https://cloud.tencent.com/document/product/416) ID过滤。[CDH](https://cloud.tencent.com/document/product/416) ID形如:host-xxxxxxxx。
  • + //
  • vpc-id - String - 是否必填:否 - (过滤条件)按照VPC ID进行过滤。VPC ID形如:vpc-xxxxxxxx。
  • + //
  • instance-id - String - 是否必填:否 - (过滤条件)按照实例ID过滤。实例ID形如:ins-xxxxxxxx。
  • + //
  • security-group-id - String - 是否必填:否 - (过滤条件)按照安全组ID过滤,安全组ID形如: sg-8jlk3f3r。
  • + //
  • instance-name - String - 是否必填:否 - (过滤条件)按照实例名称过滤。
  • + //
  • instance-charge-type - String - 是否必填:否 -(过滤条件)按照实例计费模式过滤。 (PREPAID:表示预付费,即包年包月 | POSTPAID_BY_HOUR:表示后付费,即按量计费 | CDHPAID:表示[CDH](https://cloud.tencent.com/document/product/416)付费,即只对[CDH](https://cloud.tencent.com/document/product/416)计费,不对[CDH](https://cloud.tencent.com/document/product/416)上的实例计费。 )
  • + //
  • private-ip-address - String - 是否必填:否 - (过滤条件)按照实例主网卡的内网IP过滤。
  • + //
  • public-ip-address - String - 是否必填:否 - (过滤条件)按照实例主网卡的公网IP过滤,包含实例创建时自动分配的IP和实例创建后手动绑定的弹性IP。
  • + //
  • tag-key - String - 是否必填:否 - (过滤条件)按照标签键进行过滤。
  • + //
  • tag-value - String - 是否必填:否 - (过滤条件)按照标签值进行过滤。
  • + //
  • tag:tag-key - String - 是否必填:否 - (过滤条件)按照标签键值对进行过滤。 tag-key使用具体的标签键进行替换。使用请参考示例2。
  • + // 每次请求的`Filters`的上限为10,`Filter.Values`的上限为5。参数不支持同时指定`InstanceIds`和`Filters`。 + Filters []*Filter `json:"Filters" name:"Filters" list` + // 偏移量,默认为0。关于`Offset`的更进一步介绍请参考 API [简介](https://cloud.tencent.com/document/api/213/15688)中的相关小节。 + Offset *int64 `json:"Offset" name:"Offset"` + // 返回数量,默认为20,最大值为100。关于`Limit`的更进一步介绍请参考 API [简介](https://cloud.tencent.com/document/api/213/15688)中的相关小节。 + Limit *int64 `json:"Limit" name:"Limit"` +} + +func (r *DescribeInstancesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeInstancesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeInstancesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 符合条件的实例数量。 + TotalCount *int64 `json:"TotalCount" name:"TotalCount"` + // 实例详细信息列表。 + InstanceSet []*Instance `json:"InstanceSet" name:"InstanceSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeInstancesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeInstancesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeInstancesStatusRequest struct { + *tchttp.BaseRequest + // 按照一个或者多个实例ID查询。实例ID形如:`ins-11112222`。此参数的具体格式可参考API[简介](https://cloud.tencent.com/document/api/213/15688)的`id.N`一节)。每次请求的实例的上限为100。 + InstanceIds []*string `json:"InstanceIds" name:"InstanceIds" list` + // 偏移量,默认为0。关于`Offset`的更进一步介绍请参考 API [简介](https://cloud.tencent.com/document/api/213/15688)中的相关小节。 + Offset *int64 `json:"Offset" name:"Offset"` + // 返回数量,默认为20,最大值为100。关于`Limit`的更进一步介绍请参考 API [简介](https://cloud.tencent.com/document/api/213/15688)中的相关小节。 + Limit *int64 `json:"Limit" name:"Limit"` +} + +func (r *DescribeInstancesStatusRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeInstancesStatusRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeInstancesStatusResponse struct { + *tchttp.BaseResponse + Response *struct { + // 符合条件的实例状态数量。 + TotalCount *int64 `json:"TotalCount" name:"TotalCount"` + // [实例状态](https://cloud.tencent.com/document/api/213/15738) 列表。 + InstanceStatusSet []*InstanceStatus `json:"InstanceStatusSet" name:"InstanceStatusSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeInstancesStatusResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeInstancesStatusResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeInternetChargeTypeConfigsRequest struct { + *tchttp.BaseRequest +} + +func (r *DescribeInternetChargeTypeConfigsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeInternetChargeTypeConfigsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeInternetChargeTypeConfigsResponse struct { + *tchttp.BaseResponse + Response *struct { + // 网络计费类型配置。 + InternetChargeTypeConfigSet []*InternetChargeTypeConfig `json:"InternetChargeTypeConfigSet" name:"InternetChargeTypeConfigSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeInternetChargeTypeConfigsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeInternetChargeTypeConfigsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeKeyPairsRequest struct { + *tchttp.BaseRequest + // 密钥对ID,密钥对ID形如:`skey-11112222`(此接口支持同时传入多个ID进行过滤。此参数的具体格式可参考 API [简介](https://cloud.tencent.com/document/api/213/15688)的 `id.N` 一节)。参数不支持同时指定 `KeyIds` 和 `Filters`。密钥对ID可以通过登录[控制台](https://console.cloud.tencent.com/cvm/index)查询。 + KeyIds []*string `json:"KeyIds" name:"KeyIds" list` + // 过滤条件。 + //
  • project-id - Integer - 是否必填:否 -(过滤条件)按照项目ID过滤。可以通过[项目列表](https://console.cloud.tencent.com/project)查询项目ID,或者调用接口 [DescribeProject](https://cloud.tencent.com/document/api/378/4400),取返回信息中的projectId获取项目ID。
  • + //
  • key-name - String - 是否必填:否 -(过滤条件)按照密钥对名称过滤。
  • 参数不支持同时指定 `KeyIds` 和 `Filters`。 + Filters []*Filter `json:"Filters" name:"Filters" list` + // 偏移量,默认为0。关于 `Offset` 的更进一步介绍请参考 API [简介](https://cloud.tencent.com/document/api/213/15688)中的相关小节。返回数量,默认为20,最大值为100。关于 `Limit` 的更进一步介绍请参考 API [简介](https://cloud.tencent.com/document/api/213/15688)中的相关小节。 + Offset *int64 `json:"Offset" name:"Offset"` + // 返回数量,默认为20,最大值为100。关于 `Limit` 的更进一步介绍请参考 API [简介](https://cloud.tencent.com/document/api/213/15688)中的相关小节。 + Limit *int64 `json:"Limit" name:"Limit"` +} + +func (r *DescribeKeyPairsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeKeyPairsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeKeyPairsResponse struct { + *tchttp.BaseResponse + Response *struct { + // 符合条件的密钥对数量。 + TotalCount *int64 `json:"TotalCount" name:"TotalCount"` + // 密钥对详细信息列表。 + KeyPairSet []*KeyPair `json:"KeyPairSet" name:"KeyPairSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeKeyPairsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeKeyPairsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeRegionsRequest struct { + *tchttp.BaseRequest +} + +func (r *DescribeRegionsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeRegionsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeRegionsResponse struct { + *tchttp.BaseResponse + Response *struct { + // 地域数量 + TotalCount *uint64 `json:"TotalCount" name:"TotalCount"` + // 地域列表信息 + RegionSet []*RegionInfo `json:"RegionSet" name:"RegionSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeRegionsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeRegionsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeZoneInstanceConfigInfosRequest struct { + *tchttp.BaseRequest + // 过滤条件。 + // + //
  • zone - String - 是否必填:否 -(过滤条件)按照可用区过滤。
  • + // + //
  • instance-family String - 是否必填:否 -(过滤条件)按照机型系列过滤。按照实例机型系列过滤。实例机型系列形如:S1、I1、M1等。
  • + // + //
  • instance-type - String - 是否必填:否 - (过滤条件)按照机型过滤。按照实例机型过滤。不同实例机型指定了不同的资源规格,具体取值可通过调用接口 DescribeInstanceTypeConfigs 来获得最新的规格表或参见实例类型描述。若不指定该参数,则默认机型为S1.SMALL1。
  • + // + //
  • instance-charge-type - String - 是否必填:否 -(过滤条件)按照实例计费模式过滤。 (PREPAID:表示预付费,即包年包月 | POSTPAID_BY_HOUR:表示后付费,即按量计费 | CDHPAID:表示CDH付费,即只对CDH计费,不对CDH上的实例计费。 )
  • + Filters []*Filter `json:"Filters" name:"Filters" list` +} + +func (r *DescribeZoneInstanceConfigInfosRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeZoneInstanceConfigInfosRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeZoneInstanceConfigInfosResponse struct { + *tchttp.BaseResponse + Response *struct { + // 可用区机型配置列表。 + InstanceTypeQuotaSet []*InstanceTypeQuotaItem `json:"InstanceTypeQuotaSet" name:"InstanceTypeQuotaSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeZoneInstanceConfigInfosResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeZoneInstanceConfigInfosResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeZonesRequest struct { + *tchttp.BaseRequest +} + +func (r *DescribeZonesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeZonesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeZonesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 可用区数量 + TotalCount *uint64 `json:"TotalCount" name:"TotalCount"` + // 可用区列表信息 + ZoneSet []*ZoneInfo `json:"ZoneSet" name:"ZoneSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeZonesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeZonesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DisassociateInstancesKeyPairsRequest struct { + *tchttp.BaseRequest + // 一个或多个待操作的实例ID,每次请求批量实例的上限为100。

    可以通过以下方式获取可用的实例ID:
  • 通过登录[控制台](https://console.cloud.tencent.com/cvm/index)查询实例ID。
  • 通过调用接口 [DescribeInstances](https://cloud.tencent.com/document/api/213/15728) ,取返回信息中的 `InstanceId` 获取实例ID。 + InstanceIds []*string `json:"InstanceIds" name:"InstanceIds" list` + // 密钥对ID列表,每次请求批量密钥对的上限为100。密钥对ID形如:`skey-11112222`。

    可以通过以下方式获取可用的密钥ID:
  • 通过登录[控制台](https://console.cloud.tencent.com/cvm/sshkey)查询密钥ID。
  • 通过调用接口 [DescribeKeyPairs](https://cloud.tencent.com/document/api/213/15699) ,取返回信息中的 `KeyId` 获取密钥对ID。 + KeyIds []*string `json:"KeyIds" name:"KeyIds" list` + // 是否对运行中的实例选择强制关机。建议对运行中的实例先手动关机,然后再重置用户密码。取值范围:
  • TRUE:表示在正常关机失败后进行强制关机。
  • FALSE:表示在正常关机失败后不进行强制关机。

    默认取值:FALSE。 + ForceStop *bool `json:"ForceStop" name:"ForceStop"` +} + +func (r *DisassociateInstancesKeyPairsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DisassociateInstancesKeyPairsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DisassociateInstancesKeyPairsResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DisassociateInstancesKeyPairsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DisassociateInstancesKeyPairsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DisasterRecoverGroup struct { + // 分散置放群组id。 + DisasterRecoverGroupId *string `json:"DisasterRecoverGroupId" name:"DisasterRecoverGroupId"` + // 分散置放群组名称,长度1-60个字符。 + Name *string `json:"Name" name:"Name"` + // 分散置放群组类型,取值范围:
  • HOST:物理机
  • SW:交换机
  • RACK:机架 + Type *string `json:"Type" name:"Type"` + // 分散置放群组内最大容纳云主机数量。 + CvmQuotaTotal *int64 `json:"CvmQuotaTotal" name:"CvmQuotaTotal"` + // 分散置放群组内云主机当前数量。 + CurrentNum *int64 `json:"CurrentNum" name:"CurrentNum"` + // 分散置放群组内,云主机id列表。 + InstanceIds []*string `json:"InstanceIds" name:"InstanceIds" list` + // 分散置放群组创建时间。 + CreateTime *string `json:"CreateTime" name:"CreateTime"` +} + +type EnhancedService struct { + // 开启云安全服务。若不指定该参数,则默认开启云安全服务。 + SecurityService *RunSecurityServiceEnabled `json:"SecurityService" name:"SecurityService"` + // 开启云监控服务。若不指定该参数,则默认开启云监控服务。 + MonitorService *RunMonitorServiceEnabled `json:"MonitorService" name:"MonitorService"` +} + +type Externals struct { + // 释放地址 + ReleaseAddress *bool `json:"ReleaseAddress" name:"ReleaseAddress"` + // 不支持的网络类型 + UnsupportNetworks []*string `json:"UnsupportNetworks" name:"UnsupportNetworks" list` + // HDD本地存储属性 + StorageBlockAttr *StorageBlock `json:"StorageBlockAttr" name:"StorageBlockAttr"` +} + +type Filter struct { + // 需要过滤的字段。 + Name *string `json:"Name" name:"Name"` + // 字段的过滤值。 + Values []*string `json:"Values" name:"Values" list` +} + +type HostItem struct { + // cdh实例所在的位置。通过该参数可以指定实例所属可用区,所属项目等属性。 + Placement *Placement `json:"Placement" name:"Placement"` + // cdh实例id + HostId *string `json:"HostId" name:"HostId"` + // cdh实例类型 + HostType *string `json:"HostType" name:"HostType"` + // cdh实例名称 + HostName *string `json:"HostName" name:"HostName"` + // cdh实例付费模式 + HostChargeType *string `json:"HostChargeType" name:"HostChargeType"` + // cdh实例自动续费标记 + RenewFlag *string `json:"RenewFlag" name:"RenewFlag"` + // cdh实例创建时间 + CreatedTime *string `json:"CreatedTime" name:"CreatedTime"` + // cdh实例过期时间 + ExpiredTime *string `json:"ExpiredTime" name:"ExpiredTime"` + // cdh实例上已创建云子机的实例id列表 + InstanceIds []*string `json:"InstanceIds" name:"InstanceIds" list` + // cdh实例状态 + HostState *string `json:"HostState" name:"HostState"` + // cdh实例ip + HostIp *string `json:"HostIp" name:"HostIp"` + // cdh实例资源信息 + HostResource *HostResource `json:"HostResource" name:"HostResource"` +} + +type HostResource struct { + // cdh实例总cpu核数 + CpuTotal *uint64 `json:"CpuTotal" name:"CpuTotal"` + // cdh实例可用cpu核数 + CpuAvailable *uint64 `json:"CpuAvailable" name:"CpuAvailable"` + // cdh实例总内存大小(单位为:GiB) + MemTotal *float64 `json:"MemTotal" name:"MemTotal"` + // cdh实例可用内存大小(单位为:GiB) + MemAvailable *float64 `json:"MemAvailable" name:"MemAvailable"` + // cdh实例总磁盘大小(单位为:GiB) + DiskTotal *uint64 `json:"DiskTotal" name:"DiskTotal"` + // cdh实例可用磁盘大小(单位为:GiB) + DiskAvailable *uint64 `json:"DiskAvailable" name:"DiskAvailable"` +} + +type Image struct { + // 镜像ID + ImageId *string `json:"ImageId" name:"ImageId"` + // 镜像操作系统 + OsName *string `json:"OsName" name:"OsName"` + // 镜像类型 + ImageType *string `json:"ImageType" name:"ImageType"` + // 镜像创建时间 + CreatedTime *string `json:"CreatedTime" name:"CreatedTime"` + // 镜像名称 + ImageName *string `json:"ImageName" name:"ImageName"` + // 镜像描述 + ImageDescription *string `json:"ImageDescription" name:"ImageDescription"` + // 镜像大小 + ImageSize *int64 `json:"ImageSize" name:"ImageSize"` + // 镜像架构 + Architecture *string `json:"Architecture" name:"Architecture"` + // 镜像状态 + ImageState *string `json:"ImageState" name:"ImageState"` + // 镜像来源平台 + Platform *string `json:"Platform" name:"Platform"` + // 镜像创建者 + ImageCreator *string `json:"ImageCreator" name:"ImageCreator"` + // 镜像来源 + ImageSource *string `json:"ImageSource" name:"ImageSource"` + // 同步百分比 + SyncPercent *int64 `json:"SyncPercent" name:"SyncPercent"` + // 镜像是否支持cloud-init + IsSupportCloudinit *bool `json:"IsSupportCloudinit" name:"IsSupportCloudinit"` +} + +type ImageOsList struct { + // 支持的windows操作系统。 + Windows []*string `json:"Windows" name:"Windows" list` + // 支持的linux操作系统 + Linux []*string `json:"Linux" name:"Linux" list` +} + +type ImportImageRequest struct { + *tchttp.BaseRequest + // 导入镜像的操作系统架构,`x86_64` 或 `i386` + Architecture *string `json:"Architecture" name:"Architecture"` + // 导入镜像的操作系统类型,通过`DescribeImportImageOs`获取 + OsType *string `json:"OsType" name:"OsType"` + // 导入镜像的操作系统版本,通过`DescribeImportImageOs`获取 + OsVersion *string `json:"OsVersion" name:"OsVersion"` + // 导入镜像存放的cos地址 + ImageUrl *string `json:"ImageUrl" name:"ImageUrl"` + // 镜像名称 + ImageName *string `json:"ImageName" name:"ImageName"` + // 镜像描述 + ImageDescription *string `json:"ImageDescription" name:"ImageDescription"` + // 只检查参数,不执行任务 + DryRun *bool `json:"DryRun" name:"DryRun"` + // 是否强制导入,参考[强制导入镜像](https://cloud.tencent.com/document/product/213/12849) + Force *bool `json:"Force" name:"Force"` +} + +func (r *ImportImageRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ImportImageRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ImportImageResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ImportImageResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ImportImageResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ImportKeyPairRequest struct { + *tchttp.BaseRequest + // 密钥对名称,可由数字,字母和下划线组成,长度不超过25个字符。 + KeyName *string `json:"KeyName" name:"KeyName"` + // 密钥对创建后所属的[项目](/document/product/378/10863)ID。

    可以通过以下方式获取项目ID:
  • 通过[项目列表](https://console.cloud.tencent.com/project)查询项目ID。
  • 通过调用接口 [DescribeProject](https://cloud.tencent.com/document/api/378/4400),取返回信息中的 `projectId ` 获取项目ID。 + // + // 如果是默认项目,直接填0就可以。 + ProjectId *int64 `json:"ProjectId" name:"ProjectId"` + // 密钥对的公钥内容,`OpenSSH RSA` 格式。 + PublicKey *string `json:"PublicKey" name:"PublicKey"` +} + +func (r *ImportKeyPairRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ImportKeyPairRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ImportKeyPairResponse struct { + *tchttp.BaseResponse + Response *struct { + // 密钥对ID。 + KeyId *string `json:"KeyId" name:"KeyId"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ImportKeyPairResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ImportKeyPairResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type InquiryPriceModifyInstancesChargeTypeRequest struct { + *tchttp.BaseRequest + // 一个或多个待操作的实例ID。可通过[`DescribeInstances`](https://cloud.tencent.com/document/api/213/15728)接口返回值中的`InstanceId`获取。每次请求批量实例的上限为100。 + InstanceIds []*string `json:"InstanceIds" name:"InstanceIds" list` + // 实例[计费类型](https://cloud.tencent.com/document/product/213/2180)。
  • PREPAID:预付费,即包年包月。 + InstanceChargeType *string `json:"InstanceChargeType" name:"InstanceChargeType"` + // 预付费模式,即包年包月相关参数设置。通过该参数可以指定包年包月实例的续费时长、是否设置自动续费等属性。 + InstanceChargePrepaid *InstanceChargePrepaid `json:"InstanceChargePrepaid" name:"InstanceChargePrepaid"` +} + +func (r *InquiryPriceModifyInstancesChargeTypeRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *InquiryPriceModifyInstancesChargeTypeRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type InquiryPriceModifyInstancesChargeTypeResponse struct { + *tchttp.BaseResponse + Response *struct { + // 该参数表示对应配置实例转换计费模式的价格。 + Price *Price `json:"Price" name:"Price"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *InquiryPriceModifyInstancesChargeTypeResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *InquiryPriceModifyInstancesChargeTypeResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type InquiryPriceRenewInstancesRequest struct { + *tchttp.BaseRequest + // 一个或多个待操作的实例ID。可通过[`DescribeInstances`](https://cloud.tencent.com/document/api/213/15728)接口返回值中的`InstanceId`获取。每次请求批量实例的上限为100。 + InstanceIds []*string `json:"InstanceIds" name:"InstanceIds" list` + // 预付费模式,即包年包月相关参数设置。通过该参数可以指定包年包月实例的续费时长、是否设置自动续费等属性。 + InstanceChargePrepaid *InstanceChargePrepaid `json:"InstanceChargePrepaid" name:"InstanceChargePrepaid"` + // 试运行。 + DryRun *bool `json:"DryRun" name:"DryRun"` + // 是否续费弹性数据盘。取值范围:
  • TRUE:表示续费包年包月实例同时续费其挂载的弹性数据盘
  • FALSE:表示续费包年包月实例同时不再续费其挂载的弹性数据盘

    默认取值:TRUE。 + RenewPortableDataDisk *bool `json:"RenewPortableDataDisk" name:"RenewPortableDataDisk"` +} + +func (r *InquiryPriceRenewInstancesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *InquiryPriceRenewInstancesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type InquiryPriceRenewInstancesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 该参数表示对应配置实例的价格。 + Price *Price `json:"Price" name:"Price"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *InquiryPriceRenewInstancesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *InquiryPriceRenewInstancesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type InquiryPriceResetInstanceRequest struct { + *tchttp.BaseRequest + // 实例ID。可通过 [DescribeInstances](https://cloud.tencent.com/document/api/213/15728) API返回值中的`InstanceId`获取。 + InstanceId *string `json:"InstanceId" name:"InstanceId"` + // 指定有效的[镜像](/document/product/213/4940)ID,格式形如`img-xxx`。镜像类型分为四种:
  • 公共镜像
  • 自定义镜像
  • 共享镜像
  • 服务市场镜像

  • 可通过以下方式获取可用的镜像ID:
  • `公共镜像`、`自定义镜像`、`共享镜像`的镜像ID可通过登录[控制台](https://console.cloud.tencent.com/cvm/image?rid=1&imageType=PUBLIC_IMAGE)查询;`服务镜像市场`的镜像ID可通过[云市场](https://market.cloud.tencent.com/list)查询。
  • 通过调用接口 [DescribeImages](https://cloud.tencent.com/document/api/213/15715) ,取返回信息中的`ImageId`字段。
  • + ImageId *string `json:"ImageId" name:"ImageId"` + // 实例系统盘配置信息。系统盘为云盘的实例可以通过该参数指定重装后的系统盘大小来实现对系统盘的扩容操作,若不指定则默认系统盘大小保持不变。系统盘大小只支持扩容不支持缩容;重装只支持修改系统盘的大小,不能修改系统盘的类型。 + SystemDisk *SystemDisk `json:"SystemDisk" name:"SystemDisk"` + // 实例登录设置。通过该参数可以设置实例的登录方式密码、密钥或保持镜像的原始登录设置。默认情况下会随机生成密码,并以站内信方式知会到用户。 + LoginSettings *LoginSettings `json:"LoginSettings" name:"LoginSettings"` + // 增强服务。通过该参数可以指定是否开启云安全、云监控等服务。若不指定该参数,则默认开启云监控、云安全服务。 + EnhancedService *EnhancedService `json:"EnhancedService" name:"EnhancedService"` +} + +func (r *InquiryPriceResetInstanceRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *InquiryPriceResetInstanceRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type InquiryPriceResetInstanceResponse struct { + *tchttp.BaseResponse + Response *struct { + // 该参数表示重装成对应配置实例的价格。 + Price *Price `json:"Price" name:"Price"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *InquiryPriceResetInstanceResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *InquiryPriceResetInstanceResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type InquiryPriceResetInstancesInternetMaxBandwidthRequest struct { + *tchttp.BaseRequest + // 一个或多个待操作的实例ID。可通过[`DescribeInstances`](https://cloud.tencent.com/document/api/213/15728)接口返回值中的`InstanceId`获取。每次请求批量实例的上限为100。当调整 `BANDWIDTH_PREPAID` 和 `BANDWIDTH_POSTPAID_BY_HOUR` 计费方式的带宽时,只支持一个实例。 + InstanceIds []*string `json:"InstanceIds" name:"InstanceIds" list` + // 公网出带宽配置。不同机型带宽上限范围不一致,具体限制详见带宽限制对账表。暂时只支持`InternetMaxBandwidthOut`参数。 + InternetAccessible *InternetAccessible `json:"InternetAccessible" name:"InternetAccessible"` + // 带宽生效的起始时间。格式:`YYYY-MM-DD`,例如:`2016-10-30`。起始时间不能早于当前时间。如果起始时间是今天则新设置的带宽立即生效。该参数只对包年包月带宽有效,其他模式带宽不支持该参数,否则接口会以相应错误码返回。 + StartTime *string `json:"StartTime" name:"StartTime"` + // 带宽生效的终止时间。格式:`YYYY-MM-DD`,例如:`2016-10-30`。新设置的带宽的有效期包含终止时间此日期。终止时间不能晚于包年包月实例的到期时间。实例的到期时间可通过[`DescribeInstances`](https://cloud.tencent.com/document/api/213/15728)接口返回值中的`ExpiredTime`获取。该参数只对包年包月带宽有效,其他模式带宽不支持该参数,否则接口会以相应错误码返回。 + EndTime *string `json:"EndTime" name:"EndTime"` +} + +func (r *InquiryPriceResetInstancesInternetMaxBandwidthRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *InquiryPriceResetInstancesInternetMaxBandwidthRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type InquiryPriceResetInstancesInternetMaxBandwidthResponse struct { + *tchttp.BaseResponse + Response *struct { + // 该参数表示带宽调整为对应大小之后的价格。 + Price *Price `json:"Price" name:"Price"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *InquiryPriceResetInstancesInternetMaxBandwidthResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *InquiryPriceResetInstancesInternetMaxBandwidthResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type InquiryPriceResetInstancesTypeRequest struct { + *tchttp.BaseRequest + // 一个或多个待操作的实例ID。可通过[`DescribeInstances`](https://cloud.tencent.com/document/api/213/15728)接口返回值中的`InstanceId`获取。每次请求批量实例的上限为1。 + InstanceIds []*string `json:"InstanceIds" name:"InstanceIds" list` + // 实例机型。不同实例机型指定了不同的资源规格,具体取值可参见附表实例资源规格对照表,也可以调用查询实例资源规格列表接口获得最新的规格表。 + InstanceType *string `json:"InstanceType" name:"InstanceType"` + // 是否对运行中的实例选择强制关机。建议对运行中的实例先手动关机,然后再重置用户密码。取值范围:
  • TRUE:表示在正常关机失败后进行强制关机
  • FALSE:表示在正常关机失败后不进行强制关机

    默认取值:FALSE。

    强制关机的效果等同于关闭物理计算机的电源开关。强制关机可能会导致数据丢失或文件系统损坏,请仅在服务器不能正常关机时使用。 + ForceStop *bool `json:"ForceStop" name:"ForceStop"` +} + +func (r *InquiryPriceResetInstancesTypeRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *InquiryPriceResetInstancesTypeRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type InquiryPriceResetInstancesTypeResponse struct { + *tchttp.BaseResponse + Response *struct { + // 该参数表示调整成对应机型实例的价格。 + Price *Price `json:"Price" name:"Price"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *InquiryPriceResetInstancesTypeResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *InquiryPriceResetInstancesTypeResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type InquiryPriceResizeInstanceDisksRequest struct { + *tchttp.BaseRequest + // 待操作的实例ID。可通过[`DescribeInstances`](https://cloud.tencent.com/document/api/213/15728)接口返回值中的`InstanceId`获取。 + InstanceId *string `json:"InstanceId" name:"InstanceId"` + // 待扩容的数据盘配置信息。只支持扩容随实例购买的数据盘,且[数据盘类型](/document/api/213/9452#block_device)为:`CLOUD_BASIC`、`CLOUD_PREMIUM`、`CLOUD_SSD`。数据盘容量单位:GB。最小扩容步长:10G。关于数据盘类型的选择请参考硬盘产品简介。可选数据盘类型受到实例类型`InstanceType`限制。另外允许扩容的最大容量也因数据盘类型的不同而有所差异。 + DataDisks []*DataDisk `json:"DataDisks" name:"DataDisks" list` + // 是否对运行中的实例选择强制关机。建议对运行中的实例先手动关机,然后再重置用户密码。取值范围:
  • TRUE:表示在正常关机失败后进行强制关机
  • FALSE:表示在正常关机失败后不进行强制关机

    默认取值:FALSE。

    强制关机的效果等同于关闭物理计算机的电源开关。强制关机可能会导致数据丢失或文件系统损坏,请仅在服务器不能正常关机时使用。 + ForceStop *bool `json:"ForceStop" name:"ForceStop"` +} + +func (r *InquiryPriceResizeInstanceDisksRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *InquiryPriceResizeInstanceDisksRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type InquiryPriceResizeInstanceDisksResponse struct { + *tchttp.BaseResponse + Response *struct { + // 该参数表示磁盘扩容成对应配置的价格。 + Price *Price `json:"Price" name:"Price"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *InquiryPriceResizeInstanceDisksResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *InquiryPriceResizeInstanceDisksResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type InquiryPriceRunInstancesRequest struct { + *tchttp.BaseRequest + // 实例所在的位置。通过该参数可以指定实例所属可用区,所属项目等属性。 + Placement *Placement `json:"Placement" name:"Placement"` + // 指定有效的[镜像](https://cloud.tencent.com/document/product/213/4940)ID,格式形如`img-xxx`。镜像类型分为四种:
  • 公共镜像
  • 自定义镜像
  • 共享镜像
  • 服务市场镜像

  • 可通过以下方式获取可用的镜像ID:
  • `公共镜像`、`自定义镜像`、`共享镜像`的镜像ID可通过登录[控制台](https://console.cloud.tencent.com/cvm/image?rid=1&imageType=PUBLIC_IMAGE)查询;`服务镜像市场`的镜像ID可通过[云市场](https://market.cloud.tencent.com/list)查询。
  • 通过调用接口 [DescribeImages](https://cloud.tencent.com/document/api/213/15715) ,取返回信息中的`ImageId`字段。
  • + ImageId *string `json:"ImageId" name:"ImageId"` + // 实例[计费类型](https://cloud.tencent.com/document/product/213/2180)。
  • PREPAID:预付费,即包年包月
  • POSTPAID_BY_HOUR:按小时后付费
    默认值:POSTPAID_BY_HOUR。 + InstanceChargeType *string `json:"InstanceChargeType" name:"InstanceChargeType"` + // 预付费模式,即包年包月相关参数设置。通过该参数可以指定包年包月实例的购买时长、是否设置自动续费等属性。若指定实例的付费模式为预付费则该参数必传。 + InstanceChargePrepaid *InstanceChargePrepaid `json:"InstanceChargePrepaid" name:"InstanceChargePrepaid"` + // 实例机型。不同实例机型指定了不同的资源规格,具体取值可通过调用接口[DescribeInstanceTypeConfigs](https://cloud.tencent.com/document/api/213/15749)来获得最新的规格表或参见[CVM实例配置](https://cloud.tencent.com/document/product/213/2177)描述。若不指定该参数,则默认机型为S1.SMALL1。 + InstanceType *string `json:"InstanceType" name:"InstanceType"` + // 实例系统盘配置信息。若不指定该参数,则按照系统默认值进行分配。 + SystemDisk *SystemDisk `json:"SystemDisk" name:"SystemDisk"` + // 实例数据盘配置信息。若不指定该参数,则默认不购买数据盘。支持购买的时候指定11块数据盘,其中最多包含1块LOCAL_BASIC数据盘或者LOCAL_SSD数据盘,最多包含10块CLOUD_BASIC数据盘、CLOUD_PREMIUM数据盘或者CLOUD_SSD数据盘。 + DataDisks []*DataDisk `json:"DataDisks" name:"DataDisks" list` + // 私有网络相关信息配置。通过该参数可以指定私有网络的ID,子网ID等信息。若不指定该参数,则默认使用基础网络。若在此参数中指定了私有网络ip,那么InstanceCount参数只能为1。 + VirtualPrivateCloud *VirtualPrivateCloud `json:"VirtualPrivateCloud" name:"VirtualPrivateCloud"` + // 公网带宽相关信息设置。若不指定该参数,则默认公网带宽为0Mbps。 + InternetAccessible *InternetAccessible `json:"InternetAccessible" name:"InternetAccessible"` + // 购买实例数量。取值范围:[1,100]。默认取值:1。指定购买实例的数量不能超过用户所能购买的剩余配额数量,具体配额相关限制详见[CVM实例购买限制](https://cloud.tencent.com/document/product/213/2664)。 + InstanceCount *int64 `json:"InstanceCount" name:"InstanceCount"` + // 实例显示名称。
  • 不指定实例显示名称则默认显示‘未命名’。
  • 购买多台实例,如果指定模式串`{R:x}`,表示生成数字`[x, x+n-1]`,其中`n`表示购买实例的数量,例如`server_{R:3}`,购买1台时,实例显示名称为`server_3`;购买2台时,实例显示名称分别为`server_3`,`server_4`。支持指定多个模式串`{R:x}`。
  • 购买多台实例,如果不指定模式串,则在实例显示名称添加后缀`1、2...n`,其中`n`表示购买实例的数量,例如`server_`,购买2台时,实例显示名称分别为`server_1`,`server_2`。 + InstanceName *string `json:"InstanceName" name:"InstanceName"` + // 实例登录设置。通过该参数可以设置实例的登录方式密码、密钥或保持镜像的原始登录设置。默认情况下会随机生成密码,并以站内信方式知会到用户。 + LoginSettings *LoginSettings `json:"LoginSettings" name:"LoginSettings"` + // 实例所属安全组。该参数可以通过调用 [DescribeSecurityGroups](https://cloud.tencent.com/document/api/215/15808) 的返回值中的sgId字段来获取。若不指定该参数,则默认不绑定安全组。 + SecurityGroupIds []*string `json:"SecurityGroupIds" name:"SecurityGroupIds" list` + // 增强服务。通过该参数可以指定是否开启云安全、云监控等服务。若不指定该参数,则默认开启云监控、云安全服务。 + EnhancedService *EnhancedService `json:"EnhancedService" name:"EnhancedService"` + // 用于保证请求幂等性的字符串。该字符串由客户生成,需保证不同请求之间唯一,最大值不超过64个ASCII字符。若不指定该参数,则无法保证请求的幂等性。
    更多详细信息请参阅:如何保证幂等性。 + ClientToken *string `json:"ClientToken" name:"ClientToken"` + // 云服务器的主机名。
  • 点号(.)和短横线(-)不能作为 HostName 的首尾字符,不能连续使用。
  • Windows 实例:名字符长度为[2, 15],允许字母(不限制大小写)、数字和短横线(-)组成,不支持点号(.),不能全是数字。
  • 其他类型(Linux 等)实例:字符长度为[2, 30],允许支持多个点号,点之间为一段,每段允许字母(不限制大小写)、数字和短横线(-)组成。 + HostName *string `json:"HostName" name:"HostName"` + // 标签描述列表。通过指定该参数可以同时绑定标签到相应的资源实例,当前仅支持绑定标签到云主机实例。 + TagSpecification []*TagSpecification `json:"TagSpecification" name:"TagSpecification" list` + // 实例的市场相关选项,如竞价实例相关参数 + InstanceMarketOptions *InstanceMarketOptionsRequest `json:"InstanceMarketOptions" name:"InstanceMarketOptions"` +} + +func (r *InquiryPriceRunInstancesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *InquiryPriceRunInstancesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type InquiryPriceRunInstancesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 该参数表示对应配置实例的价格。 + Price *Price `json:"Price" name:"Price"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *InquiryPriceRunInstancesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *InquiryPriceRunInstancesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type Instance struct { + // 实例所在的位置。 + Placement *Placement `json:"Placement" name:"Placement"` + // 实例`ID`。 + InstanceId *string `json:"InstanceId" name:"InstanceId"` + // 实例机型。 + InstanceType *string `json:"InstanceType" name:"InstanceType"` + // 实例的CPU核数,单位:核。 + CPU *int64 `json:"CPU" name:"CPU"` + // 实例内存容量,单位:`GB`。 + Memory *int64 `json:"Memory" name:"Memory"` + // 实例业务状态。取值范围:
  • NORMAL:表示正常状态的实例
  • EXPIRED:表示过期的实例
  • PROTECTIVELY_ISOLATED:表示被安全隔离的实例。 + RestrictState *string `json:"RestrictState" name:"RestrictState"` + // 实例名称。 + InstanceName *string `json:"InstanceName" name:"InstanceName"` + // 实例计费模式。取值范围:
  • `PREPAID`:表示预付费,即包年包月
  • `POSTPAID_BY_HOUR`:表示后付费,即按量计费
  • `CDHPAID`:`CDH`付费,即只对`CDH`计费,不对`CDH`上的实例计费。 + InstanceChargeType *string `json:"InstanceChargeType" name:"InstanceChargeType"` + // 实例系统盘信息。 + SystemDisk *SystemDisk `json:"SystemDisk" name:"SystemDisk"` + // 实例数据盘信息。只包含随实例购买的数据盘。 + DataDisks []*DataDisk `json:"DataDisks" name:"DataDisks" list` + // 实例主网卡的内网`IP`列表。 + PrivateIpAddresses []*string `json:"PrivateIpAddresses" name:"PrivateIpAddresses" list` + // 实例主网卡的公网`IP`列表。 + PublicIpAddresses []*string `json:"PublicIpAddresses" name:"PublicIpAddresses" list` + // 实例带宽信息。 + InternetAccessible *InternetAccessible `json:"InternetAccessible" name:"InternetAccessible"` + // 实例所属虚拟私有网络信息。 + VirtualPrivateCloud *VirtualPrivateCloud `json:"VirtualPrivateCloud" name:"VirtualPrivateCloud"` + // 生产实例所使用的镜像`ID`。 + ImageId *string `json:"ImageId" name:"ImageId"` + // 自动续费标识。取值范围:
  • `NOTIFY_AND_MANUAL_RENEW`:表示通知即将过期,但不自动续费
  • `NOTIFY_AND_AUTO_RENEW`:表示通知即将过期,而且自动续费
  • `DISABLE_NOTIFY_AND_MANUAL_RENEW`:表示不通知即将过期,也不自动续费。 + RenewFlag *string `json:"RenewFlag" name:"RenewFlag"` + // 创建时间。按照`ISO8601`标准表示,并且使用`UTC`时间。格式为:`YYYY-MM-DDThh:mm:ssZ`。 + CreatedTime *string `json:"CreatedTime" name:"CreatedTime"` + // 到期时间。按照`ISO8601`标准表示,并且使用`UTC`时间。格式为:`YYYY-MM-DDThh:mm:ssZ`。 + ExpiredTime *string `json:"ExpiredTime" name:"ExpiredTime"` + // 操作系统名称。 + OsName *string `json:"OsName" name:"OsName"` + // 实例所属安全组。该参数可以通过调用 [DescribeSecurityGroups](https://cloud.tencent.com/document/api/215/15808) 的返回值中的sgId字段来获取。 + SecurityGroupIds []*string `json:"SecurityGroupIds" name:"SecurityGroupIds" list` + // 实例登录设置。目前只返回实例所关联的密钥。 + LoginSettings *LoginSettings `json:"LoginSettings" name:"LoginSettings"` + // 实例状态。取值范围:
  • PENDING:表示创建中
  • LAUNCH_FAILED:表示创建失败
  • RUNNING:表示运行中
  • STOPPED:表示关机
  • STARTING:表示开机中
  • STOPPING:表示关机中
  • REBOOTING:表示重启中
  • SHUTDOWN:表示停止待销毁
  • TERMINATING:表示销毁中。
  • + InstanceState *string `json:"InstanceState" name:"InstanceState"` + // 实例关联的标签列表。 + Tags []*Tag `json:"Tags" name:"Tags" list` +} + +type InstanceChargePrepaid struct { + // 购买实例的时长,单位:月。取值范围:1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 24, 36。 + Period *int64 `json:"Period" name:"Period"` + // 自动续费标识。取值范围:
  • NOTIFY_AND_AUTO_RENEW:通知过期且自动续费
  • NOTIFY_AND_MANUAL_RENEW:通知过期不自动续费
  • DISABLE_NOTIFY_AND_MANUAL_RENEW:不通知过期不自动续费

    默认取值:NOTIFY_AND_MANUAL_RENEW。若该参数指定为NOTIFY_AND_AUTO_RENEW,在账户余额充足的情况下,实例到期后将按月自动续费。 + RenewFlag *string `json:"RenewFlag" name:"RenewFlag"` +} + +type InstanceFamilyConfig struct { + // 机型族名称的中文全称。 + InstanceFamilyName *string `json:"InstanceFamilyName" name:"InstanceFamilyName"` + // 机型族名称的英文简称。 + InstanceFamily *string `json:"InstanceFamily" name:"InstanceFamily"` +} + +type InstanceMarketOptionsRequest struct { + *tchttp.BaseRequest + // 市场选项类型,当前只支持取值:spot + MarketType *string `json:"MarketType" name:"MarketType"` + // 竞价相关选项 + SpotOptions *SpotMarketOptions `json:"SpotOptions" name:"SpotOptions"` +} + +func (r *InstanceMarketOptionsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *InstanceMarketOptionsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type InstanceStatus struct { + // 实例`ID`。 + InstanceId *string `json:"InstanceId" name:"InstanceId"` + // [实例状态](/document/api/213/9452#INSTANCE_STATE)。 + InstanceState *string `json:"InstanceState" name:"InstanceState"` +} + +type InstanceTypeConfig struct { + // 可用区。 + Zone *string `json:"Zone" name:"Zone"` + // 实例机型。 + InstanceType *string `json:"InstanceType" name:"InstanceType"` + // 实例机型系列。 + InstanceFamily *string `json:"InstanceFamily" name:"InstanceFamily"` + // GPU核数,单位:核。 + GPU *int64 `json:"GPU" name:"GPU"` + // CPU核数,单位:核。 + CPU *int64 `json:"CPU" name:"CPU"` + // 内存容量,单位:`GB`。 + Memory *int64 `json:"Memory" name:"Memory"` + // 是否支持云硬盘。取值范围:
  • `TRUE`:表示支持云硬盘;
  • `FALSE`:表示不支持云硬盘。 + CbsSupport *string `json:"CbsSupport" name:"CbsSupport"` + // 机型状态。取值范围:
  • `AVAILABLE`:表示机型可用;
  • `UNAVAILABLE`:表示机型不可用。 + InstanceTypeState *string `json:"InstanceTypeState" name:"InstanceTypeState"` +} + +type InstanceTypeQuotaItem struct { + // 可用区。 + Zone *string `json:"Zone" name:"Zone"` + // 实例机型。 + InstanceType *string `json:"InstanceType" name:"InstanceType"` + // 实例计费模式。取值范围:
  • PREPAID:表示预付费,即包年包月
  • POSTPAID_BY_HOUR:表示后付费,即按量计费
  • CDHPAID:表示[CDH](https://cloud.tencent.com/document/product/416)付费,即只对CDH计费,不对CDH上的实例计费。 + InstanceChargeType *string `json:"InstanceChargeType" name:"InstanceChargeType"` + // 网卡类型,例如:25代表25G网卡 + NetworkCard *int64 `json:"NetworkCard" name:"NetworkCard"` + // 扩展属性。 + Externals *Externals `json:"Externals" name:"Externals"` + // 实例的CPU核数,单位:核。 + Cpu *int64 `json:"Cpu" name:"Cpu"` + // 实例内存容量,单位:`GB`。 + Memory *int64 `json:"Memory" name:"Memory"` + // 实例机型系列。 + InstanceFamily *string `json:"InstanceFamily" name:"InstanceFamily"` + // 机型名称。 + TypeName *string `json:"TypeName" name:"TypeName"` + // 本地磁盘规格列表。 + LocalDiskTypeList []*LocalDiskType `json:"LocalDiskTypeList" name:"LocalDiskTypeList" list` + // 实例是否售卖。 + Status *string `json:"Status" name:"Status"` + // 实例的售卖价格。 + Price *ItemPrice `json:"Price" name:"Price"` +} + +type InternetAccessible struct { + // 网络计费类型。取值范围:
  • BANDWIDTH_PREPAID:预付费按带宽结算
  • TRAFFIC_POSTPAID_BY_HOUR:流量按小时后付费
  • BANDWIDTH_POSTPAID_BY_HOUR:带宽按小时后付费
  • BANDWIDTH_PACKAGE:带宽包用户
    默认取值:非带宽包用户默认与子机付费类型保持一致。 + InternetChargeType *string `json:"InternetChargeType" name:"InternetChargeType"` + // 公网出带宽上限,单位:Mbps。默认值:0Mbps。不同机型带宽上限范围不一致,具体限制详见[购买网络带宽](/document/product/213/509)。 + InternetMaxBandwidthOut *int64 `json:"InternetMaxBandwidthOut" name:"InternetMaxBandwidthOut"` + // 是否分配公网IP。取值范围:
  • TRUE:表示分配公网IP
  • FALSE:表示不分配公网IP

    当公网带宽大于0Mbps时,可自由选择开通与否,默认开通公网IP;当公网带宽为0,则不允许分配公网IP。 + PublicIpAssigned *bool `json:"PublicIpAssigned" name:"PublicIpAssigned"` +} + +type InternetBandwidthConfig struct { + // 开始时间。按照`ISO8601`标准表示,并且使用`UTC`时间。格式为:`YYYY-MM-DDThh:mm:ssZ`。 + StartTime *string `json:"StartTime" name:"StartTime"` + // 结束时间。按照`ISO8601`标准表示,并且使用`UTC`时间。格式为:`YYYY-MM-DDThh:mm:ssZ`。 + EndTime *string `json:"EndTime" name:"EndTime"` + // 实例带宽信息。 + InternetAccessible *InternetAccessible `json:"InternetAccessible" name:"InternetAccessible"` +} + +type InternetChargeTypeConfig struct { + // 网络计费模式。 + InternetChargeType *string `json:"InternetChargeType" name:"InternetChargeType"` + // 网络计费模式描述信息。 + Description *string `json:"Description" name:"Description"` +} + +type ItemPrice struct { + // 后续单价,单位:元。 + UnitPrice *float64 `json:"UnitPrice" name:"UnitPrice"` + // 后续计价单元,可取值范围:
  • HOUR:表示计价单元是按每小时来计算。当前涉及该计价单元的场景有:实例按小时后付费(POSTPAID_BY_HOUR)、带宽按小时后付费(BANDWIDTH_POSTPAID_BY_HOUR):
  • GB:表示计价单元是按每GB来计算。当前涉及该计价单元的场景有:流量按小时后付费(TRAFFIC_POSTPAID_BY_HOUR)。 + ChargeUnit *string `json:"ChargeUnit" name:"ChargeUnit"` + // 预支费用的原价,单位:元。 + OriginalPrice *float64 `json:"OriginalPrice" name:"OriginalPrice"` + // 预支费用的折扣价,单位:元。 + DiscountPrice *float64 `json:"DiscountPrice" name:"DiscountPrice"` +} + +type KeyPair struct { + // 密钥对的`ID`,是密钥对的唯一标识。 + KeyId *string `json:"KeyId" name:"KeyId"` + // 密钥对名称。 + KeyName *string `json:"KeyName" name:"KeyName"` + // 密钥对所属的项目`ID`。 + ProjectId *int64 `json:"ProjectId" name:"ProjectId"` + // 密钥对描述信息。 + Description *string `json:"Description" name:"Description"` + // 密钥对的纯文本公钥。 + PublicKey *string `json:"PublicKey" name:"PublicKey"` + // 密钥对的纯文本私钥。腾讯云不会保管私钥,请用户自行妥善保存。 + PrivateKey *string `json:"PrivateKey" name:"PrivateKey"` + // 密钥关联的实例`ID`列表。 + AssociatedInstanceIds []*string `json:"AssociatedInstanceIds" name:"AssociatedInstanceIds" list` + // 创建时间。按照`ISO8601`标准表示,并且使用`UTC`时间。格式为:`YYYY-MM-DDThh:mm:ssZ`。 + CreatedTime *string `json:"CreatedTime" name:"CreatedTime"` +} + +type LocalDiskType struct { + // 本地磁盘类型。 + Type *string `json:"Type" name:"Type"` + // 本地磁盘属性。 + PartitionType *string `json:"PartitionType" name:"PartitionType"` + // 本地磁盘最小值。 + MinSize *int64 `json:"MinSize" name:"MinSize"` + // 本地磁盘最大值。 + MaxSize *int64 `json:"MaxSize" name:"MaxSize"` +} + +type LoginSettings struct { + // 实例登录密码。不同操作系统类型密码复杂度限制不一样,具体如下:
  • Linux实例密码必须8到16位,至少包括两项[a-z,A-Z]、[0-9] 和 [( ) ` ~ ! @ # $ % ^ & * - + = | { } [ ] : ; ' , . ? / ]中的特殊符号。
  • Windows实例密码必须12到16位,至少包括三项[a-z],[A-Z],[0-9] 和 [( ) ` ~ ! @ # $ % ^ & * - + = { } [ ] : ; ' , . ? /]中的特殊符号。

    若不指定该参数,则由系统随机生成密码,并通过站内信方式通知到用户。 + Password *string `json:"Password" name:"Password"` + // 密钥ID列表。关联密钥后,就可以通过对应的私钥来访问实例;KeyId可通过接口DescribeKeyPairs获取,密钥与密码不能同时指定,同时Windows操作系统不支持指定密钥。当前仅支持购买的时候指定一个密钥。 + KeyIds []*string `json:"KeyIds" name:"KeyIds" list` + // 保持镜像的原始设置。该参数与Password或KeyIds.N不能同时指定。只有使用自定义镜像、共享镜像或外部导入镜像创建实例时才能指定该参数为TRUE。取值范围:
  • TRUE:表示保持镜像的登录设置
  • FALSE:表示不保持镜像的登录设置

    默认取值:FALSE。 + KeepImageLogin *string `json:"KeepImageLogin" name:"KeepImageLogin"` +} + +type ModifyDisasterRecoverGroupAttributeRequest struct { + *tchttp.BaseRequest + // 分散置放群组ID,可使用[DescribeDisasterRecoverGroups](https://cloud.tencent.com/document/api/213/17810)接口获取。 + DisasterRecoverGroupId *string `json:"DisasterRecoverGroupId" name:"DisasterRecoverGroupId"` + // 分散置放群组名称,长度1-60个字符,支持中、英文。 + Name *string `json:"Name" name:"Name"` +} + +func (r *ModifyDisasterRecoverGroupAttributeRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyDisasterRecoverGroupAttributeRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyDisasterRecoverGroupAttributeResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifyDisasterRecoverGroupAttributeResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyDisasterRecoverGroupAttributeResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyHostsAttributeRequest struct { + *tchttp.BaseRequest + // 一个或多个待操作的CDH实例ID。 + HostIds []*string `json:"HostIds" name:"HostIds" list` + // CDH实例显示名称。可任意命名,但不得超过60个字符。 + HostName *string `json:"HostName" name:"HostName"` + // 自动续费标识。取值范围:
  • NOTIFY_AND_AUTO_RENEW:通知过期且自动续费
  • NOTIFY_AND_MANUAL_RENEW:通知过期不自动续费
  • DISABLE_NOTIFY_AND_MANUAL_RENEW:不通知过期不自动续费

    若该参数指定为NOTIFY_AND_AUTO_RENEW,在账户余额充足的情况下,实例到期后将按月自动续费。 + RenewFlag *string `json:"RenewFlag" name:"RenewFlag"` +} + +func (r *ModifyHostsAttributeRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyHostsAttributeRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyHostsAttributeResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifyHostsAttributeResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyHostsAttributeResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyImageAttributeRequest struct { + *tchttp.BaseRequest + // 镜像ID,形如`img-gvbnzy6f`。镜像ID可以通过如下方式获取:
  • 通过[DescribeImages](https://cloud.tencent.com/document/api/213/15715)接口返回的`ImageId`获取。
  • 通过[镜像控制台](https://console.cloud.tencent.com/cvm/image)获取。 + ImageId *string `json:"ImageId" name:"ImageId"` + // 设置新的镜像名称;必须满足下列限制:
  • 不得超过20个字符。
  • 镜像名称不能与已有镜像重复。 + ImageName *string `json:"ImageName" name:"ImageName"` + // 设置新的镜像描述;必须满足下列限制:
  • 不得超过60个字符。 + ImageDescription *string `json:"ImageDescription" name:"ImageDescription"` +} + +func (r *ModifyImageAttributeRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyImageAttributeRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyImageAttributeResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifyImageAttributeResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyImageAttributeResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyImageSharePermissionRequest struct { + *tchttp.BaseRequest + // 镜像ID,形如`img-gvbnzy6f`。镜像Id可以通过如下方式获取:
  • 通过[DescribeImages](https://cloud.tencent.com/document/api/213/15715)接口返回的`ImageId`获取。
  • 通过[镜像控制台](https://console.cloud.tencent.com/cvm/image)获取。
    镜像ID必须指定为状态为`NORMAL`的镜像。镜像状态请参考[镜像数据表](/document/api/213/9452#image_state)。 + ImageId *string `json:"ImageId" name:"ImageId"` + // 接收分享镜像的账号Id列表,array型参数的格式可以参考[API简介](/document/api/213/568)。帐号ID不同于QQ号,查询用户帐号ID请查看[帐号信息](https://console.cloud.tencent.com/developer)中的帐号ID栏。 + AccountIds []*string `json:"AccountIds" name:"AccountIds" list` + // 操作,包括 `SHARE`,`CANCEL`。其中`SHARE`代表分享操作,`CANCEL`代表取消分享操作。 + Permission *string `json:"Permission" name:"Permission"` +} + +func (r *ModifyImageSharePermissionRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyImageSharePermissionRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyImageSharePermissionResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifyImageSharePermissionResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyImageSharePermissionResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyInstancesAttributeRequest struct { + *tchttp.BaseRequest + // 一个或多个待操作的实例ID。可通过[`DescribeInstances`](https://cloud.tencent.com/document/api/213/9388) API返回值中的`InstanceId`获取。每次请求允许操作的实例数量上限是100。 + InstanceIds []*string `json:"InstanceIds" name:"InstanceIds" list` + // 实例名称。可任意命名,但不得超过60个字符。 + InstanceName *string `json:"InstanceName" name:"InstanceName"` + // 指定实例的安全组Id列表。 + SecurityGroups []*string `json:"SecurityGroups" name:"SecurityGroups" list` +} + +func (r *ModifyInstancesAttributeRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyInstancesAttributeRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyInstancesAttributeResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifyInstancesAttributeResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyInstancesAttributeResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyInstancesChargeTypeRequest struct { + *tchttp.BaseRequest + // 一个或多个待操作的实例ID。可通过[`DescribeInstances`](https://cloud.tencent.com/document/api/213/9388)接口返回值中的`InstanceId`获取。每次请求批量实例的上限为100。 + InstanceIds []*string `json:"InstanceIds" name:"InstanceIds" list` + // 实例[计费类型](https://cloud.tencent.com/document/product/213/2180)。
  • PREPAID:预付费,即包年包月。 + InstanceChargeType *string `json:"InstanceChargeType" name:"InstanceChargeType"` + // 预付费模式,即包年包月相关参数设置。通过该参数可以指定包年包月实例的购买时长、是否设置自动续费等属性。若指定实例的付费模式为预付费则该参数必传。 + InstanceChargePrepaid *InstanceChargePrepaid `json:"InstanceChargePrepaid" name:"InstanceChargePrepaid"` +} + +func (r *ModifyInstancesChargeTypeRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyInstancesChargeTypeRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyInstancesChargeTypeResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifyInstancesChargeTypeResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyInstancesChargeTypeResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyInstancesProjectRequest struct { + *tchttp.BaseRequest + // 一个或多个待操作的实例ID。可通过[`DescribeInstances`](https://cloud.tencent.com/document/api/213/9388) API返回值中的`InstanceId`获取。每次请求允许操作的实例数量上限是100。 + InstanceIds []*string `json:"InstanceIds" name:"InstanceIds" list` + // 项目ID。项目可以使用[AddProject](https://cloud.tencent.com/doc/api/403/4398)接口创建。后续使用[DescribeInstances](https://cloud.tencent.com/document/api/213/9388)接口查询实例时,项目ID可用于过滤结果。 + ProjectId *int64 `json:"ProjectId" name:"ProjectId"` +} + +func (r *ModifyInstancesProjectRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyInstancesProjectRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyInstancesProjectResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifyInstancesProjectResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyInstancesProjectResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyInstancesRenewFlagRequest struct { + *tchttp.BaseRequest + // 一个或多个待操作的实例ID。可通过[`DescribeInstances`](https://cloud.tencent.com/document/api/213/9388) API返回值中的`InstanceId`获取。每次请求允许操作的实例数量上限是100。 + InstanceIds []*string `json:"InstanceIds" name:"InstanceIds" list` + // 自动续费标识。取值范围:
  • NOTIFY_AND_AUTO_RENEW:通知过期且自动续费
  • NOTIFY_AND_MANUAL_RENEW:通知过期不自动续费
  • DISABLE_NOTIFY_AND_MANUAL_RENEW:不通知过期不自动续费

    若该参数指定为NOTIFY_AND_AUTO_RENEW,在账户余额充足的情况下,实例到期后将按月自动续费。 + RenewFlag *string `json:"RenewFlag" name:"RenewFlag"` +} + +func (r *ModifyInstancesRenewFlagRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyInstancesRenewFlagRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyInstancesRenewFlagResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifyInstancesRenewFlagResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyInstancesRenewFlagResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyInstancesVpcAttributeRequest struct { + *tchttp.BaseRequest + // 待操作的实例ID数组。可通过[`DescribeInstances`](document/api/213/9388)接口返回值中的`InstanceId`获取。 + InstanceIds []*string `json:"InstanceIds" name:"InstanceIds" list` + // 私有网络相关信息配置。通过该参数指定私有网络的ID,子网ID,私有网络ip等信息。当指定私有网络ID和子网ID(子网必须在实例所在的可用区)与指定实例所在私有网络不一致时,会将实例迁移至指定的私有网络的子网下。可通过`PrivateIpAddresses`指定私有网络子网IP,若需指定则所有已指定的实例均需要指定子网IP,此时`InstanceIds`与`PrivateIpAddresses`一一对应。不指定`PrivateIpAddresses`时随机分配私有网络子网IP。 + VirtualPrivateCloud *VirtualPrivateCloud `json:"VirtualPrivateCloud" name:"VirtualPrivateCloud"` + // 是否对运行中的实例选择强制关机。默认为TRUE。 + ForceStop *bool `json:"ForceStop" name:"ForceStop"` +} + +func (r *ModifyInstancesVpcAttributeRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyInstancesVpcAttributeRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyInstancesVpcAttributeResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifyInstancesVpcAttributeResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyInstancesVpcAttributeResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyKeyPairAttributeRequest struct { + *tchttp.BaseRequest + // 密钥对ID,密钥对ID形如:`skey-xxxxxxxx`。

    可以通过以下方式获取可用的密钥 ID:
  • 通过登录[控制台](https://console.cloud.tencent.com/cvm/sshkey)查询密钥 ID。
  • 通过调用接口 [DescribeKeyPairs](https://cloud.tencent.com/document/api/213/9403) ,取返回信息中的 `KeyId` 获取密钥对 ID。 + KeyId *string `json:"KeyId" name:"KeyId"` + // 修改后的密钥对名称,可由数字,字母和下划线组成,长度不超过25个字符。 + KeyName *string `json:"KeyName" name:"KeyName"` + // 修改后的密钥对描述信息。可任意命名,但不得超过60个字符。 + Description *string `json:"Description" name:"Description"` +} + +func (r *ModifyKeyPairAttributeRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyKeyPairAttributeRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyKeyPairAttributeResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifyKeyPairAttributeResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyKeyPairAttributeResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type OsVersion struct { + // 操作系统类型 + OsName *string `json:"OsName" name:"OsName"` + // 支持的操作系统版本 + OsVersions []*string `json:"OsVersions" name:"OsVersions" list` + // 支持的操作系统架构 + Architecture []*string `json:"Architecture" name:"Architecture" list` +} + +type Placement struct { + // 实例所属的[可用区](/document/product/213/9452#zone)ID。该参数也可以通过调用 [DescribeZones](/document/api/213/9455) 的返回值中的Zone字段来获取。 + Zone *string `json:"Zone" name:"Zone"` + // 实例所属项目ID。该参数可以通过调用 [DescribeProject](/document/api/378/4400) 的返回值中的 projectId 字段来获取。不填为默认项目。 + ProjectId *int64 `json:"ProjectId" name:"ProjectId"` + // 实例所属的专用宿主机ID列表。如果您有购买专用宿主机并且指定了该参数,则您购买的实例就会随机的部署在这些专用宿主机上。 + HostIds []*string `json:"HostIds" name:"HostIds" list` +} + +type Price struct { + // 描述了实例价格。 + InstancePrice *ItemPrice `json:"InstancePrice" name:"InstancePrice"` + // 描述了网络价格。 + BandwidthPrice *ItemPrice `json:"BandwidthPrice" name:"BandwidthPrice"` +} + +type RebootInstancesRequest struct { + *tchttp.BaseRequest + // 一个或多个待操作的实例ID。可通过[`DescribeInstances`](https://cloud.tencent.com/document/api/213/9388)接口返回值中的`InstanceId`获取。每次请求批量实例的上限为100。 + InstanceIds []*string `json:"InstanceIds" name:"InstanceIds" list` + // 是否在正常重启失败后选择强制重启实例。取值范围:
  • TRUE:表示在正常重启失败后进行强制重启
  • FALSE:表示在正常重启失败后不进行强制重启

    默认取值:FALSE。 + ForceReboot *bool `json:"ForceReboot" name:"ForceReboot"` +} + +func (r *RebootInstancesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *RebootInstancesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type RebootInstancesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *RebootInstancesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *RebootInstancesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type RegionInfo struct { + // 地域名称,例如,ap-guangzhou + Region *string `json:"Region" name:"Region"` + // 地域描述,例如,华南地区(广州) + RegionName *string `json:"RegionName" name:"RegionName"` + // 地域是否可用状态 + RegionState *string `json:"RegionState" name:"RegionState"` +} + +type RenewHostsRequest struct { + *tchttp.BaseRequest + // 一个或多个待操作的CDH实例ID。 + HostIds []*string `json:"HostIds" name:"HostIds" list` + // 预付费模式,即包年包月相关参数设置。通过该参数可以指定包年包月实例的购买时长、是否设置自动续费等属性。若指定实例的付费模式为预付费则该参数必传。 + HostChargePrepaid *ChargePrepaid `json:"HostChargePrepaid" name:"HostChargePrepaid"` +} + +func (r *RenewHostsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *RenewHostsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type RenewHostsResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *RenewHostsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *RenewHostsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type RenewInstancesRequest struct { + *tchttp.BaseRequest + // 一个或多个待操作的实例ID。可通过[`DescribeInstances`](https://cloud.tencent.com/document/api/213/9388)接口返回值中的`InstanceId`获取。每次请求批量实例的上限为100。 + InstanceIds []*string `json:"InstanceIds" name:"InstanceIds" list` + // 预付费模式,即包年包月相关参数设置。通过该参数可以指定包年包月实例的续费时长、是否设置自动续费等属性。 + InstanceChargePrepaid *InstanceChargePrepaid `json:"InstanceChargePrepaid" name:"InstanceChargePrepaid"` + // 是否续费弹性数据盘。取值范围:
  • TRUE:表示续费包年包月实例同时续费其挂载的弹性数据盘
  • FALSE:表示续费包年包月实例同时不再续费其挂载的弹性数据盘

    默认取值:TRUE。 + RenewPortableDataDisk *bool `json:"RenewPortableDataDisk" name:"RenewPortableDataDisk"` +} + +func (r *RenewInstancesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *RenewInstancesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type RenewInstancesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *RenewInstancesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *RenewInstancesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ResetInstanceRequest struct { + *tchttp.BaseRequest + // 实例ID。可通过 [DescribeInstances](https://cloud.tencent.com/document/api/213/9388) API返回值中的`InstanceId`获取。 + InstanceId *string `json:"InstanceId" name:"InstanceId"` + // 指定有效的[镜像](https://cloud.tencent.com/document/product/213/4940)ID,格式形如`img-xxx`。镜像类型分为四种:
  • 公共镜像
  • 自定义镜像
  • 共享镜像
  • 服务市场镜像

  • 可通过以下方式获取可用的镜像ID:
  • `公共镜像`、`自定义镜像`、`共享镜像`的镜像ID可通过登录[控制台](https://console.cloud.tencent.com/cvm/image?rid=1&imageType=PUBLIC_IMAGE)查询;`服务镜像市场`的镜像ID可通过[云市场](https://market.cloud.tencent.com/list)查询。
  • 通过调用接口 [DescribeImages](https://cloud.tencent.com/document/api/213/9418) ,取返回信息中的`ImageId`字段。
  • + ImageId *string `json:"ImageId" name:"ImageId"` + // 实例系统盘配置信息。系统盘为云盘的实例可以通过该参数指定重装后的系统盘大小来实现对系统盘的扩容操作,若不指定则默认系统盘大小保持不变。系统盘大小只支持扩容不支持缩容;重装只支持修改系统盘的大小,不能修改系统盘的类型。 + SystemDisk *SystemDisk `json:"SystemDisk" name:"SystemDisk"` + // 实例登录设置。通过该参数可以设置实例的登录方式密码、密钥或保持镜像的原始登录设置。默认情况下会随机生成密码,并以站内信方式知会到用户。 + LoginSettings *LoginSettings `json:"LoginSettings" name:"LoginSettings"` + // 增强服务。通过该参数可以指定是否开启云安全、云监控等服务。若不指定该参数,则默认开启云监控、云安全服务。 + EnhancedService *EnhancedService `json:"EnhancedService" name:"EnhancedService"` +} + +func (r *ResetInstanceRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ResetInstanceRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ResetInstanceResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ResetInstanceResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ResetInstanceResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ResetInstancesInternetMaxBandwidthRequest struct { + *tchttp.BaseRequest + // 一个或多个待操作的实例ID。可通过[`DescribeInstances`](https://cloud.tencent.com/document/api/213/9388)接口返回值中的 `InstanceId` 获取。 每次请求批量实例的上限为100。当调整 `BANDWIDTH_PREPAID` 和 `BANDWIDTH_POSTPAID_BY_HOUR` 计费方式的带宽时,只支持一个实例。 + InstanceIds []*string `json:"InstanceIds" name:"InstanceIds" list` + // 公网出带宽配置。不同机型带宽上限范围不一致,具体限制详见带宽限制对账表。暂时只支持 `InternetMaxBandwidthOut` 参数。 + InternetAccessible *InternetAccessible `json:"InternetAccessible" name:"InternetAccessible"` + // 带宽生效的起始时间。格式:`YYYY-MM-DD`,例如:`2016-10-30`。起始时间不能早于当前时间。如果起始时间是今天则新设置的带宽立即生效。该参数只对包年包月带宽有效,其他模式带宽不支持该参数,否则接口会以相应错误码返回。 + StartTime *string `json:"StartTime" name:"StartTime"` + // 带宽生效的终止时间。格式: `YYYY-MM-DD` ,例如:`2016-10-30` 。新设置的带宽的有效期包含终止时间此日期。终止时间不能晚于包年包月实例的到期时间。实例的到期时间可通过 [`DescribeInstances`](https://cloud.tencent.com/document/api/213/9388)接口返回值中的`ExpiredTime`获取。该参数只对包年包月带宽有效,其他模式带宽不支持该参数,否则接口会以相应错误码返回。 + EndTime *string `json:"EndTime" name:"EndTime"` +} + +func (r *ResetInstancesInternetMaxBandwidthRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ResetInstancesInternetMaxBandwidthRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ResetInstancesInternetMaxBandwidthResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ResetInstancesInternetMaxBandwidthResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ResetInstancesInternetMaxBandwidthResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ResetInstancesPasswordRequest struct { + *tchttp.BaseRequest + // 一个或多个待操作的实例ID。可通过[`DescribeInstances`](https://cloud.tencent.com/document/api/213/15728) API返回值中的`InstanceId`获取。每次请求允许操作的实例数量上限是100。 + InstanceIds []*string `json:"InstanceIds" name:"InstanceIds" list` + // 实例登录密码。不同操作系统类型密码复杂度限制不一样,具体如下:
  • `Linux`实例密码必须8到16位,至少包括两项`[a-z,A-Z]、[0-9]`和`[( ) ~ ~ ! @ # $ % ^ & * - + = _ | { } [ ] : ; ' < > , . ? /]`中的符号。密码不允许以`/`符号开头。
  • `Windows`实例密码必须12到16位,至少包括三项`[a-z],[A-Z],[0-9]`和`[( ) ~ ~ ! @ # $ % ^ & * - + = _ | { } [ ] : ; ' < > , . ? /]`中的符号。密码不允许以`/`符号开头。
  • 如果实例即包含`Linux`实例又包含`Windows`实例,则密码复杂度限制按照`Windows`实例的限制。 + Password *string `json:"Password" name:"Password"` + // 待重置密码的实例操作系统用户名。不得超过64个字符。 + UserName *string `json:"UserName" name:"UserName"` + // 是否对运行中的实例选择强制关机。建议对运行中的实例先手动关机,然后再重置用户密码。取值范围:
  • TRUE:表示在正常关机失败后进行强制关机
  • FALSE:表示在正常关机失败后不进行强制关机

    默认取值:FALSE。

    强制关机的效果等同于关闭物理计算机的电源开关。强制关机可能会导致数据丢失或文件系统损坏,请仅在服务器不能正常关机时使用。 + ForceStop *bool `json:"ForceStop" name:"ForceStop"` +} + +func (r *ResetInstancesPasswordRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ResetInstancesPasswordRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ResetInstancesPasswordResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ResetInstancesPasswordResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ResetInstancesPasswordResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ResetInstancesTypeRequest struct { + *tchttp.BaseRequest + // 一个或多个待操作的实例ID。可通过[`DescribeInstances`](https://cloud.tencent.com/document/api/213/15728)接口返回值中的`InstanceId`获取。每次请求批量实例的上限为1。 + InstanceIds []*string `json:"InstanceIds" name:"InstanceIds" list` + // 实例机型。不同实例机型指定了不同的资源规格,具体取值可通过调用接口[`DescribeInstanceTypeConfigs`](https://cloud.tencent.com/document/api/213/15749)来获得最新的规格表或参见[实例类型](https://cloud.tencent.com/document/product/213/11518)描述。 + InstanceType *string `json:"InstanceType" name:"InstanceType"` + // 是否对运行中的实例选择强制关机。建议对运行中的实例先手动关机,然后再重置用户密码。取值范围:
  • TRUE:表示在正常关机失败后进行强制关机
  • FALSE:表示在正常关机失败后不进行强制关机

    默认取值:FALSE。

    强制关机的效果等同于关闭物理计算机的电源开关。强制关机可能会导致数据丢失或文件系统损坏,请仅在服务器不能正常关机时使用。 + ForceStop *bool `json:"ForceStop" name:"ForceStop"` +} + +func (r *ResetInstancesTypeRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ResetInstancesTypeRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ResetInstancesTypeResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ResetInstancesTypeResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ResetInstancesTypeResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ResizeInstanceDisksRequest struct { + *tchttp.BaseRequest + // 待操作的实例ID。可通过[`DescribeInstances`](https://cloud.tencent.com/document/api/213/15728)接口返回值中的`InstanceId`获取。 + InstanceId *string `json:"InstanceId" name:"InstanceId"` + // 待扩容的数据盘配置信息。只支持扩容随实例购买的数据盘,且[数据盘类型](/document/api/213/9452#block_device)为:`CLOUD_BASIC`、`CLOUD_PREMIUM`、`CLOUD_SSD`。数据盘容量单位:GB。最小扩容步长:10G。关于数据盘类型的选择请参考硬盘产品简介。可选数据盘类型受到实例类型`InstanceType`限制。另外允许扩容的最大容量也因数据盘类型的不同而有所差异。 + DataDisks []*DataDisk `json:"DataDisks" name:"DataDisks" list` + // 是否对运行中的实例选择强制关机。建议对运行中的实例先手动关机,然后再重置用户密码。取值范围:
  • TRUE:表示在正常关机失败后进行强制关机
  • FALSE:表示在正常关机失败后不进行强制关机

    默认取值:FALSE。

    强制关机的效果等同于关闭物理计算机的电源开关。强制关机可能会导致数据丢失或文件系统损坏,请仅在服务器不能正常关机时使用。 + ForceStop *bool `json:"ForceStop" name:"ForceStop"` +} + +func (r *ResizeInstanceDisksRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ResizeInstanceDisksRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ResizeInstanceDisksResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ResizeInstanceDisksResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ResizeInstanceDisksResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type RunInstancesRequest struct { + *tchttp.BaseRequest + // 实例所在的位置。通过该参数可以指定实例所属可用区,所属项目,专用宿主机(对于独享母机付费模式的实例创建)等属性。 + Placement *Placement `json:"Placement" name:"Placement"` + // 指定有效的[镜像](https://cloud.tencent.com/document/product/213/4940)ID,格式形如`img-xxx`。镜像类型分为四种:
  • 公共镜像
  • 自定义镜像
  • 共享镜像
  • 服务市场镜像

  • 可通过以下方式获取可用的镜像ID:
  • `公共镜像`、`自定义镜像`、`共享镜像`的镜像ID可通过登录[控制台](https://console.cloud.tencent.com/cvm/image?rid=1&imageType=PUBLIC_IMAGE)查询;`服务镜像市场`的镜像ID可通过[云市场](https://market.cloud.tencent.com/list)查询。
  • 通过调用接口 [DescribeImages](https://cloud.tencent.com/document/api/213/15715) ,取返回信息中的`ImageId`字段。
  • + ImageId *string `json:"ImageId" name:"ImageId"` + // 实例[计费类型](https://cloud.tencent.com/document/product/213/2180)。
  • PREPAID:预付费,即包年包月
  • POSTPAID_BY_HOUR:按小时后付费
  • CDHPAID:独享母机付费(基于专用宿主机创建,宿主机部分的资源不收费)
  • SPOTPAID:竞价付费
    默认值:POSTPAID_BY_HOUR。 + InstanceChargeType *string `json:"InstanceChargeType" name:"InstanceChargeType"` + // 预付费模式,即包年包月相关参数设置。通过该参数可以指定包年包月实例的购买时长、是否设置自动续费等属性。若指定实例的付费模式为预付费则该参数必传。 + InstanceChargePrepaid *InstanceChargePrepaid `json:"InstanceChargePrepaid" name:"InstanceChargePrepaid"` + // 实例机型。不同实例机型指定了不同的资源规格。 + //
  • 对于付费模式为PREPAID或POSTPAID\_BY\_HOUR的实例创建,具体取值可通过调用接口[DescribeInstanceTypeConfigs](https://cloud.tencent.com/document/api/213/15749)来获得最新的规格表或参见[实例类型](https://cloud.tencent.com/document/product/213/11518)描述。若不指定该参数,则默认机型为S1.SMALL1。
  • 对于付费模式为CDHPAID的实例创建,该参数以"CDH_"为前缀,根据cpu和内存配置生成,具体形式为:CDH_XCXG,例如对于创建cpu为1核,内存为1G大小的专用宿主机的实例,该参数应该为CDH_1C1G。 + InstanceType *string `json:"InstanceType" name:"InstanceType"` + // 实例系统盘配置信息。若不指定该参数,则按照系统默认值进行分配。 + SystemDisk *SystemDisk `json:"SystemDisk" name:"SystemDisk"` + // 实例数据盘配置信息。若不指定该参数,则默认不购买数据盘。支持购买的时候指定11块数据盘,其中最多包含1块LOCAL_BASIC数据盘或者LOCAL_SSD数据盘,最多包含10块CLOUD_BASIC数据盘、CLOUD_PREMIUM数据盘或者CLOUD_SSD数据盘。 + DataDisks []*DataDisk `json:"DataDisks" name:"DataDisks" list` + // 私有网络相关信息配置。通过该参数可以指定私有网络的ID,子网ID等信息。若不指定该参数,则默认使用基础网络。若在此参数中指定了私有网络ip,表示每个实例的主网卡ip,而且InstanceCount参数必须与私有网络ip的个数一致。 + VirtualPrivateCloud *VirtualPrivateCloud `json:"VirtualPrivateCloud" name:"VirtualPrivateCloud"` + // 公网带宽相关信息设置。若不指定该参数,则默认公网带宽为0Mbps。 + InternetAccessible *InternetAccessible `json:"InternetAccessible" name:"InternetAccessible"` + // 购买实例数量。取值范围:[1,100]。默认取值:1。指定购买实例的数量不能超过用户所能购买的剩余配额数量,具体配额相关限制详见[CVM实例购买限制](https://cloud.tencent.com/document/product/213/2664)。 + InstanceCount *int64 `json:"InstanceCount" name:"InstanceCount"` + // 实例显示名称。
  • 不指定实例显示名称则默认显示‘未命名’。
  • 购买多台实例,如果指定模式串`{R:x}`,表示生成数字`[x, x+n-1]`,其中`n`表示购买实例的数量,例如`server_{R:3}`,购买1台时,实例显示名称为`server_3`;购买2台时,实例显示名称分别为`server_3`,`server_4`。支持指定多个模式串`{R:x}`。
  • 购买多台实例,如果不指定模式串,则在实例显示名称添加后缀`1、2...n`,其中`n`表示购买实例的数量,例如`server_`,购买2台时,实例显示名称分别为`server_1`,`server_2`。 + InstanceName *string `json:"InstanceName" name:"InstanceName"` + // 实例登录设置。通过该参数可以设置实例的登录方式密码、密钥或保持镜像的原始登录设置。默认情况下会随机生成密码,并以站内信方式知会到用户。 + LoginSettings *LoginSettings `json:"LoginSettings" name:"LoginSettings"` + // 实例所属安全组。该参数可以通过调用 [DescribeSecurityGroups](https://cloud.tencent.com/document/api/215/15808) 的返回值中的sgId字段来获取。若不指定该参数,则默认不绑定安全组。 + SecurityGroupIds []*string `json:"SecurityGroupIds" name:"SecurityGroupIds" list` + // 增强服务。通过该参数可以指定是否开启云安全、云监控等服务。若不指定该参数,则默认开启云监控、云安全服务。 + EnhancedService *EnhancedService `json:"EnhancedService" name:"EnhancedService"` + // 用于保证请求幂等性的字符串。该字符串由客户生成,需保证不同请求之间唯一,最大值不超过64个ASCII字符。若不指定该参数,则无法保证请求的幂等性。
    更多详细信息请参阅:如何保证幂等性。 + ClientToken *string `json:"ClientToken" name:"ClientToken"` + // 云服务器的主机名。
  • 点号(.)和短横线(-)不能作为 HostName 的首尾字符,不能连续使用。
  • Windows 实例:名字符长度为[2, 15],允许字母(不限制大小写)、数字和短横线(-)组成,不支持点号(.),不能全是数字。
  • 其他类型(Linux 等)实例:字符长度为[2, 60],允许支持多个点号,点之间为一段,每段允许字母(不限制大小写)、数字和短横线(-)组成。 + HostName *string `json:"HostName" name:"HostName"` + // 定时任务。通过该参数可以为实例指定定时任务,目前仅支持定时销毁。 + ActionTimer *ActionTimer `json:"ActionTimer" name:"ActionTimer"` + // 容灾组id,仅支持指定一个。 + DisasterRecoverGroupIds []*string `json:"DisasterRecoverGroupIds" name:"DisasterRecoverGroupIds" list` + // 标签描述列表。通过指定该参数可以同时绑定标签到相应的资源实例,当前仅支持绑定标签到云主机实例。 + TagSpecification []*TagSpecification `json:"TagSpecification" name:"TagSpecification" list` + // 实例的市场相关选项,如竞价实例相关参数,若指定实例的付费模式为竞价付费则该参数必传。 + InstanceMarketOptions *InstanceMarketOptionsRequest `json:"InstanceMarketOptions" name:"InstanceMarketOptions"` + // 提供给实例使用的用户数据,需要以 base64 方式编码,支持的最大数据大小为 16KB。关于获取此参数的详细介绍,请参阅[Windows](https://cloud.tencent.com/document/product/213/17526)和[Linux](https://cloud.tencent.com/document/product/213/17525)启动时运行命令。 + UserData *string `json:"UserData" name:"UserData"` +} + +func (r *RunInstancesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *RunInstancesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type RunInstancesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 当通过本接口来创建实例时会返回该参数,表示一个或多个实例`ID`。返回实例`ID`列表并不代表实例创建成功,可根据 [DescribeInstances](https://cloud.tencent.com/document/api/213/15728) 接口查询返回的InstancesSet中对应实例的`ID`的状态来判断创建是否完成;如果实例状态由“准备中”变为“正在运行”,则为创建成功。 + InstanceIdSet []*string `json:"InstanceIdSet" name:"InstanceIdSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *RunInstancesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *RunInstancesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type RunMonitorServiceEnabled struct { + // 是否开启[云监控](/document/product/248)服务。取值范围:
  • TRUE:表示开启云监控服务
  • FALSE:表示不开启云监控服务

    默认取值:TRUE。 + Enabled *bool `json:"Enabled" name:"Enabled"` +} + +type RunSecurityServiceEnabled struct { + // 是否开启[云安全](/document/product/296)服务。取值范围:
  • TRUE:表示开启云安全服务
  • FALSE:表示不开启云安全服务

    默认取值:TRUE。 + Enabled *bool `json:"Enabled" name:"Enabled"` +} + +type SharePermission struct { + // 镜像分享时间 + CreatedTime *string `json:"CreatedTime" name:"CreatedTime"` + // 镜像分享的账户ID + AccountId *string `json:"AccountId" name:"AccountId"` +} + +type SpotMarketOptions struct { + // 竞价出价 + MaxPrice *string `json:"MaxPrice" name:"MaxPrice"` + // 竞价请求类型,当前仅支持类型:one-time + SpotInstanceType *string `json:"SpotInstanceType" name:"SpotInstanceType"` +} + +type StartInstancesRequest struct { + *tchttp.BaseRequest + // 一个或多个待操作的实例ID。可通过[`DescribeInstances`](https://cloud.tencent.com/document/api/213/15728)接口返回值中的`InstanceId`获取。每次请求批量实例的上限为100。 + InstanceIds []*string `json:"InstanceIds" name:"InstanceIds" list` +} + +func (r *StartInstancesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *StartInstancesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type StartInstancesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *StartInstancesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *StartInstancesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type StopInstancesRequest struct { + *tchttp.BaseRequest + // 一个或多个待操作的实例ID。可通过[`DescribeInstances`](https://cloud.tencent.com/document/api/213/15728)接口返回值中的`InstanceId`获取。每次请求批量实例的上限为100。 + InstanceIds []*string `json:"InstanceIds" name:"InstanceIds" list` + // 是否在正常关闭失败后选择强制关闭实例。取值范围:
  • TRUE:表示在正常关闭失败后进行强制关闭
  • FALSE:表示在正常关闭失败后不进行强制关闭

    默认取值:FALSE。 + ForceStop *bool `json:"ForceStop" name:"ForceStop"` + // 实例的关闭模式。取值范围:
  • SOFT_FIRST:表示在正常关闭失败后进行强制关闭
  • HARD:直接强制关闭
  • SOFT:仅软关机
    默认取值:SOFT。 + StopType *string `json:"StopType" name:"StopType"` +} + +func (r *StopInstancesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *StopInstancesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type StopInstancesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *StopInstancesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *StopInstancesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type StorageBlock struct { + // HDD本地存储类型,值为:LOCAL_PRO. + Type *string `json:"Type" name:"Type"` + // HDD本地存储的最小容量 + MinSize *int64 `json:"MinSize" name:"MinSize"` + // HDD本地存储的最大容量 + MaxSize *int64 `json:"MaxSize" name:"MaxSize"` +} + +type SyncImagesRequest struct { + *tchttp.BaseRequest + // 镜像ID列表 ,镜像ID可以通过如下方式获取:
  • 通过[DescribeImages](https://cloud.tencent.com/document/api/213/15715)接口返回的`ImageId`获取。
  • 通过[镜像控制台](https://console.cloud.tencent.com/cvm/image)获取。
    镜像ID必须满足限制:
  • 镜像ID对应的镜像状态必须为`NORMAL`。
  • 镜像大小小于50GB。
    镜像状态请参考[镜像数据表](/document/api/213/9452#image_state)。 + ImageIds []*string `json:"ImageIds" name:"ImageIds" list` + // 目的同步地域列表;必须满足限制:
  • 不能为源地域,
  • 必须是一个合法的Region。
  • 暂不支持部分地域同步。
    具体地域参数请参考[Region](https://cloud.tencent.com/document/product/213/6091)。 + DestinationRegions []*string `json:"DestinationRegions" name:"DestinationRegions" list` +} + +func (r *SyncImagesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *SyncImagesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type SyncImagesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *SyncImagesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *SyncImagesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type SystemDisk struct { + // 系统盘类型。系统盘类型限制详见[CVM实例配置](/document/product/213/2177)。取值范围:
  • LOCAL_BASIC:本地硬盘
  • LOCAL_SSD:本地SSD硬盘
  • CLOUD_BASIC:普通云硬盘
  • CLOUD_SSD:SSD云硬盘
  • CLOUD_PREMIUM:高性能云硬盘

    默认取值:CLOUD_BASIC。 + DiskType *string `json:"DiskType" name:"DiskType"` + // 系统盘ID。LOCAL_BASIC 和 LOCAL_SSD 类型没有ID。暂时不支持该参数。 + DiskId *string `json:"DiskId" name:"DiskId"` + // 系统盘大小,单位:GB。默认值为 50 + DiskSize *int64 `json:"DiskSize" name:"DiskSize"` +} + +type Tag struct { + // 标签键 + Key *string `json:"Key" name:"Key"` + // 标签值 + Value *string `json:"Value" name:"Value"` +} + +type TagSpecification struct { + // 标签绑定的资源类型,当前仅支持类型:"instance" + ResourceType *string `json:"ResourceType" name:"ResourceType"` + // 标签对列表 + Tags []*Tag `json:"Tags" name:"Tags" list` +} + +type TerminateInstancesRequest struct { + *tchttp.BaseRequest + // 一个或多个待操作的实例ID。可通过[`DescribeInstances`](https://cloud.tencent.com/document/api/213/15728)接口返回值中的`InstanceId`获取。每次请求批量实例的上限为100。 + InstanceIds []*string `json:"InstanceIds" name:"InstanceIds" list` +} + +func (r *TerminateInstancesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *TerminateInstancesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type TerminateInstancesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *TerminateInstancesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *TerminateInstancesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type VirtualPrivateCloud struct { + // 私有网络ID,形如`vpc-xxx`。有效的VpcId可通过登录[控制台](https://console.cloud.tencent.com/vpc/vpc?rid=1)查询;也可以调用接口 [DescribeVpcEx](/document/api/215/1372) ,从接口返回中的`unVpcId`字段获取。 + VpcId *string `json:"VpcId" name:"VpcId"` + // 私有网络子网ID,形如`subnet-xxx`。有效的私有网络子网ID可通过登录[控制台](https://console.cloud.tencent.com/vpc/subnet?rid=1)查询;也可以调用接口 [DescribeSubnets](/document/api/215/15784) ,从接口返回中的`unSubnetId`字段获取。 + SubnetId *string `json:"SubnetId" name:"SubnetId"` + // 是否用作公网网关。公网网关只有在实例拥有公网IP以及处于私有网络下时才能正常使用。取值范围:
  • TRUE:表示用作公网网关
  • FALSE:表示不用作公网网关

    默认取值:FALSE。 + AsVpcGateway *bool `json:"AsVpcGateway" name:"AsVpcGateway"` + // 私有网络子网 IP 数组,在创建实例、修改实例vpc属性操作中可使用此参数。当前仅批量创建多台实例时支持传入相同子网的多个 IP。 + PrivateIpAddresses []*string `json:"PrivateIpAddresses" name:"PrivateIpAddresses" list` +} + +type ZoneInfo struct { + // 可用区名称,例如,ap-guangzhou-3 + Zone *string `json:"Zone" name:"Zone"` + // 可用区描述,例如,广州三区 + ZoneName *string `json:"ZoneName" name:"ZoneName"` + // 可用区ID + ZoneId *string `json:"ZoneId" name:"ZoneId"` + // 可用区状态 + ZoneState *string `json:"ZoneState" name:"ZoneState"` +} diff --git a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312/client.go b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312/client.go new file mode 100644 index 000000000..ae8b6cb13 --- /dev/null +++ b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312/client.go @@ -0,0 +1,3079 @@ +// Copyright (c) 2017-2018 THL A29 Limited, a Tencent company. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v20170312 + +import ( + "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" + tchttp "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http" + "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" +) + +const APIVersion = "2017-03-12" + +type Client struct { + common.Client +} + +func NewClientWithSecretId(secretId, secretKey, region string) (client *Client, err error) { + cpf := profile.NewClientProfile() + client = &Client{} + client.Init(region).WithSecretId(secretId, secretKey).WithProfile(cpf) + return +} + +func NewClient(credential *common.Credential, region string, clientProfile *profile.ClientProfile) (client *Client, err error) { + client = &Client{} + client.Init(region). + WithSecretId(credential.SecretId, credential.SecretKey). + WithProfile(clientProfile) + return +} + + +func NewAcceptAttachCcnInstancesRequest() (request *AcceptAttachCcnInstancesRequest) { + request = &AcceptAttachCcnInstancesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "AcceptAttachCcnInstances") + return +} + +func NewAcceptAttachCcnInstancesResponse() (response *AcceptAttachCcnInstancesResponse) { + response = &AcceptAttachCcnInstancesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(AcceptAttachCcnInstances)用于跨账号关联实例时,云联网所有者接受并同意关联操作。 +func (c *Client) AcceptAttachCcnInstances(request *AcceptAttachCcnInstancesRequest) (response *AcceptAttachCcnInstancesResponse, err error) { + if request == nil { + request = NewAcceptAttachCcnInstancesRequest() + } + response = NewAcceptAttachCcnInstancesResponse() + err = c.Send(request, response) + return +} + +func NewAddBandwidthPackageResourcesRequest() (request *AddBandwidthPackageResourcesRequest) { + request = &AddBandwidthPackageResourcesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "AddBandwidthPackageResources") + return +} + +func NewAddBandwidthPackageResourcesResponse() (response *AddBandwidthPackageResourcesResponse) { + response = &AddBandwidthPackageResourcesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 接口用于添加带宽包资源,包括[弹性公网IP](https://cloud.tencent.com/document/product/213/1941)和[负载均衡](https://cloud.tencent.com/document/product/214/517)等 +func (c *Client) AddBandwidthPackageResources(request *AddBandwidthPackageResourcesRequest) (response *AddBandwidthPackageResourcesResponse, err error) { + if request == nil { + request = NewAddBandwidthPackageResourcesRequest() + } + response = NewAddBandwidthPackageResourcesResponse() + err = c.Send(request, response) + return +} + +func NewAllocateAddressesRequest() (request *AllocateAddressesRequest) { + request = &AllocateAddressesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "AllocateAddresses") + return +} + +func NewAllocateAddressesResponse() (response *AllocateAddressesResponse) { + response = &AllocateAddressesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (AllocateAddresses) 用于申请一个或多个[弹性公网IP](https://cloud.tencent.com/document/product/213/1941)(简称 EIP)。 +// * EIP 是专为动态云计算设计的静态 IP 地址。借助 EIP,您可以快速将 EIP 重新映射到您的另一个实例上,从而屏蔽实例故障。 +// * 您的 EIP 与腾讯云账户相关联,而不是与某个实例相关联。在您选择显式释放该地址,或欠费超过七天之前,它会一直与您的腾讯云账户保持关联。 +// * 平台对用户每地域能申请的 EIP 最大配额有所限制,可参见 [EIP 产品简介](https://cloud.tencent.com/document/product/213/5733),上述配额可通过 DescribeAddressQuota 接口获取。 +func (c *Client) AllocateAddresses(request *AllocateAddressesRequest) (response *AllocateAddressesResponse, err error) { + if request == nil { + request = NewAllocateAddressesRequest() + } + response = NewAllocateAddressesResponse() + err = c.Send(request, response) + return +} + +func NewAssignPrivateIpAddressesRequest() (request *AssignPrivateIpAddressesRequest) { + request = &AssignPrivateIpAddressesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "AssignPrivateIpAddresses") + return +} + +func NewAssignPrivateIpAddressesResponse() (response *AssignPrivateIpAddressesResponse) { + response = &AssignPrivateIpAddressesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(AssignPrivateIpAddresses)用于弹性网卡申请内网 IP。 +// * 一个弹性网卡支持绑定的IP地址是有限制的,更多资源限制信息详见弹性网卡使用限制。 +// * 可以指定内网IP地址申请,内网IP地址类型不能为主IP,主IP已存在,不能修改,内网IP必须要弹性网卡所在子网内,而且不能被占用。 +// * 在弹性网卡上申请一个到多个辅助内网IP,接口会在弹性网卡所在子网网段内返回指定数量的辅助内网IP。 +func (c *Client) AssignPrivateIpAddresses(request *AssignPrivateIpAddressesRequest) (response *AssignPrivateIpAddressesResponse, err error) { + if request == nil { + request = NewAssignPrivateIpAddressesRequest() + } + response = NewAssignPrivateIpAddressesResponse() + err = c.Send(request, response) + return +} + +func NewAssociateAddressRequest() (request *AssociateAddressRequest) { + request = &AssociateAddressRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "AssociateAddress") + return +} + +func NewAssociateAddressResponse() (response *AssociateAddressResponse) { + response = &AssociateAddressResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (AssociateAddress) 用于将[弹性公网IP](https://cloud.tencent.com/document/product/213/1941)(简称 EIP)绑定到实例或弹性网卡的指定内网 IP 上。 +// * 将 EIP 绑定到实例上,其本质是将 EIP 绑定到实例上主网卡的主内网 IP 上。 +// * 将 EIP 绑定到主网卡的主内网IP上,绑定过程会把其上绑定的普通公网 IP 自动解绑并释放。 +// * 如果指定网卡的内网 IP 已经绑定了 EIP,则必须先解绑该 EIP,才能再绑定新的。 +// * EIP 如果欠费或被封堵,则不能被绑定。 +// * 只有状态为 UNBIND 的 EIP 才能够被绑定。 +func (c *Client) AssociateAddress(request *AssociateAddressRequest) (response *AssociateAddressResponse, err error) { + if request == nil { + request = NewAssociateAddressRequest() + } + response = NewAssociateAddressResponse() + err = c.Send(request, response) + return +} + +func NewAttachCcnInstancesRequest() (request *AttachCcnInstancesRequest) { + request = &AttachCcnInstancesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "AttachCcnInstances") + return +} + +func NewAttachCcnInstancesResponse() (response *AttachCcnInstancesResponse) { + response = &AttachCcnInstancesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(AttachCcnInstances)用于将网络实例加载到云联网实例中,网络实例包括VPC和专线网关。
    +// 每个云联网能够关联的网络实例个数是有限的,详请参考产品文档。如果需要扩充请联系在线客服。 +func (c *Client) AttachCcnInstances(request *AttachCcnInstancesRequest) (response *AttachCcnInstancesResponse, err error) { + if request == nil { + request = NewAttachCcnInstancesRequest() + } + response = NewAttachCcnInstancesResponse() + err = c.Send(request, response) + return +} + +func NewAttachClassicLinkVpcRequest() (request *AttachClassicLinkVpcRequest) { + request = &AttachClassicLinkVpcRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "AttachClassicLinkVpc") + return +} + +func NewAttachClassicLinkVpcResponse() (response *AttachClassicLinkVpcResponse) { + response = &AttachClassicLinkVpcResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(AttachClassicLinkVpc)用于创建私有网络和基础网络设备互通。 +// * 私有网络和基础网络设备必须在同一个地域。 +// * 私有网络和基础网络的区别详见vpc产品文档-私有网络与基础网络。 +func (c *Client) AttachClassicLinkVpc(request *AttachClassicLinkVpcRequest) (response *AttachClassicLinkVpcResponse, err error) { + if request == nil { + request = NewAttachClassicLinkVpcRequest() + } + response = NewAttachClassicLinkVpcResponse() + err = c.Send(request, response) + return +} + +func NewAttachNetworkInterfaceRequest() (request *AttachNetworkInterfaceRequest) { + request = &AttachNetworkInterfaceRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "AttachNetworkInterface") + return +} + +func NewAttachNetworkInterfaceResponse() (response *AttachNetworkInterfaceResponse) { + response = &AttachNetworkInterfaceResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(AttachNetworkInterface)用于弹性网卡绑定云主机。 +// * 一个云主机可以绑定多个弹性网卡,但只能绑定一个主网卡。更多限制信息详见弹性网卡使用限制。 +// * 一个弹性网卡只能同时绑定一个云主机。 +// * 只有运行中或者已关机状态的云主机才能绑定弹性网卡,查看云主机状态详见腾讯云主机信息。 +// * 弹性网卡绑定的云主机必须是私有网络的,而且云主机所在可用区必须和弹性网卡子网的可用区相同。 +func (c *Client) AttachNetworkInterface(request *AttachNetworkInterfaceRequest) (response *AttachNetworkInterfaceResponse, err error) { + if request == nil { + request = NewAttachNetworkInterfaceRequest() + } + response = NewAttachNetworkInterfaceResponse() + err = c.Send(request, response) + return +} + +func NewCreateAddressTemplateRequest() (request *CreateAddressTemplateRequest) { + request = &CreateAddressTemplateRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "CreateAddressTemplate") + return +} + +func NewCreateAddressTemplateResponse() (response *CreateAddressTemplateResponse) { + response = &CreateAddressTemplateResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 创建IP地址模版 +func (c *Client) CreateAddressTemplate(request *CreateAddressTemplateRequest) (response *CreateAddressTemplateResponse, err error) { + if request == nil { + request = NewCreateAddressTemplateRequest() + } + response = NewCreateAddressTemplateResponse() + err = c.Send(request, response) + return +} + +func NewCreateAddressTemplateGroupRequest() (request *CreateAddressTemplateGroupRequest) { + request = &CreateAddressTemplateGroupRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "CreateAddressTemplateGroup") + return +} + +func NewCreateAddressTemplateGroupResponse() (response *CreateAddressTemplateGroupResponse) { + response = &CreateAddressTemplateGroupResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 创建IP地址模版集合 +func (c *Client) CreateAddressTemplateGroup(request *CreateAddressTemplateGroupRequest) (response *CreateAddressTemplateGroupResponse, err error) { + if request == nil { + request = NewCreateAddressTemplateGroupRequest() + } + response = NewCreateAddressTemplateGroupResponse() + err = c.Send(request, response) + return +} + +func NewCreateBandwidthPackageRequest() (request *CreateBandwidthPackageRequest) { + request = &CreateBandwidthPackageRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "CreateBandwidthPackage") + return +} + +func NewCreateBandwidthPackageResponse() (response *CreateBandwidthPackageResponse) { + response = &CreateBandwidthPackageResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 接口支持创建[设备带宽包](https://cloud.tencent.com/document/product/684/15246#.E8.AE.BE.E5.A4.87.E5.B8.A6.E5.AE.BD.E5.8C.85)和[ip带宽包](https://cloud.tencent.com/document/product/684/15246#ip-.E5.B8.A6.E5.AE.BD.E5.8C.85) +func (c *Client) CreateBandwidthPackage(request *CreateBandwidthPackageRequest) (response *CreateBandwidthPackageResponse, err error) { + if request == nil { + request = NewCreateBandwidthPackageRequest() + } + response = NewCreateBandwidthPackageResponse() + err = c.Send(request, response) + return +} + +func NewCreateCcnRequest() (request *CreateCcnRequest) { + request = &CreateCcnRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "CreateCcn") + return +} + +func NewCreateCcnResponse() (response *CreateCcnResponse) { + response = &CreateCcnResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(CreateCcn)用于创建云联网(CCN)。
    +// 每个账号能创建的云联网实例个数是有限的,详请参考产品文档。如果需要扩充请联系在线客服。 +func (c *Client) CreateCcn(request *CreateCcnRequest) (response *CreateCcnResponse, err error) { + if request == nil { + request = NewCreateCcnRequest() + } + response = NewCreateCcnResponse() + err = c.Send(request, response) + return +} + +func NewCreateCustomerGatewayRequest() (request *CreateCustomerGatewayRequest) { + request = &CreateCustomerGatewayRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "CreateCustomerGateway") + return +} + +func NewCreateCustomerGatewayResponse() (response *CreateCustomerGatewayResponse) { + response = &CreateCustomerGatewayResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(CreateCustomerGateway)用于创建对端网关。 +func (c *Client) CreateCustomerGateway(request *CreateCustomerGatewayRequest) (response *CreateCustomerGatewayResponse, err error) { + if request == nil { + request = NewCreateCustomerGatewayRequest() + } + response = NewCreateCustomerGatewayResponse() + err = c.Send(request, response) + return +} + +func NewCreateDefaultVpcRequest() (request *CreateDefaultVpcRequest) { + request = &CreateDefaultVpcRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "CreateDefaultVpc") + return +} + +func NewCreateDefaultVpcResponse() (response *CreateDefaultVpcResponse) { + response = &CreateDefaultVpcResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(CreateDefaultVpc)用于创建默认私有网络(VPC)。 +// +// 默认VPC适用于快速入门和启动公共实例,您可以像使用任何其他VPC一样使用默认VPC。如果你想创建标准VPC,即指定VPC名称、VPC网段、子网网段、子网可用区,请使用常规创建VPC接口(CreateVpc) +// +// 正常情况,本接口并不一定生产默认VPC,而是根据用户账号的网络属性(DescribeAccountAttributes)来决定的 +// * 支持基础网络、VPC,返回VpcId为0 +// * 只支持VPC,返回默认VPC信息 +// +// 你也可以通过 Force 参数,强制返回默认VPC +func (c *Client) CreateDefaultVpc(request *CreateDefaultVpcRequest) (response *CreateDefaultVpcResponse, err error) { + if request == nil { + request = NewCreateDefaultVpcRequest() + } + response = NewCreateDefaultVpcResponse() + err = c.Send(request, response) + return +} + +func NewCreateDirectConnectGatewayRequest() (request *CreateDirectConnectGatewayRequest) { + request = &CreateDirectConnectGatewayRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "CreateDirectConnectGateway") + return +} + +func NewCreateDirectConnectGatewayResponse() (response *CreateDirectConnectGatewayResponse) { + response = &CreateDirectConnectGatewayResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(CreateDirectConnectGateway)用于创建专线网关。 +func (c *Client) CreateDirectConnectGateway(request *CreateDirectConnectGatewayRequest) (response *CreateDirectConnectGatewayResponse, err error) { + if request == nil { + request = NewCreateDirectConnectGatewayRequest() + } + response = NewCreateDirectConnectGatewayResponse() + err = c.Send(request, response) + return +} + +func NewCreateDirectConnectGatewayCcnRoutesRequest() (request *CreateDirectConnectGatewayCcnRoutesRequest) { + request = &CreateDirectConnectGatewayCcnRoutesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "CreateDirectConnectGatewayCcnRoutes") + return +} + +func NewCreateDirectConnectGatewayCcnRoutesResponse() (response *CreateDirectConnectGatewayCcnRoutesResponse) { + response = &CreateDirectConnectGatewayCcnRoutesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(CreateDirectConnectGatewayCcnRoutes)用于创建专线网关的云联网路由(IDC网段) +func (c *Client) CreateDirectConnectGatewayCcnRoutes(request *CreateDirectConnectGatewayCcnRoutesRequest) (response *CreateDirectConnectGatewayCcnRoutesResponse, err error) { + if request == nil { + request = NewCreateDirectConnectGatewayCcnRoutesRequest() + } + response = NewCreateDirectConnectGatewayCcnRoutesResponse() + err = c.Send(request, response) + return +} + +func NewCreateNetworkInterfaceRequest() (request *CreateNetworkInterfaceRequest) { + request = &CreateNetworkInterfaceRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "CreateNetworkInterface") + return +} + +func NewCreateNetworkInterfaceResponse() (response *CreateNetworkInterfaceResponse) { + response = &CreateNetworkInterfaceResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(CreateNetworkInterface)用于创建弹性网卡。 +// * 创建弹性网卡时可以指定内网IP,并且可以指定一个主IP,指定的内网IP必须在弹性网卡所在子网内,而且不能被占用。 +// * 创建弹性网卡时可以指定需要申请的内网IP数量,系统会随机生成内网IP地址。 +// * 创建弹性网卡同时可以绑定已有安全组。 +func (c *Client) CreateNetworkInterface(request *CreateNetworkInterfaceRequest) (response *CreateNetworkInterfaceResponse, err error) { + if request == nil { + request = NewCreateNetworkInterfaceRequest() + } + response = NewCreateNetworkInterfaceResponse() + err = c.Send(request, response) + return +} + +func NewCreateRouteTableRequest() (request *CreateRouteTableRequest) { + request = &CreateRouteTableRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "CreateRouteTable") + return +} + +func NewCreateRouteTableResponse() (response *CreateRouteTableResponse) { + response = &CreateRouteTableResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(CreateRouteTable)用于创建路由表。 +// * 创建了VPC后,系统会创建一个默认路由表,所有新建的子网都会关联到默认路由表。默认情况下您可以直接使用默认路由表来管理您的路由策略。当您的路由策略较多时,您可以调用创建路由表接口创建更多路由表管理您的路由策略。 +func (c *Client) CreateRouteTable(request *CreateRouteTableRequest) (response *CreateRouteTableResponse, err error) { + if request == nil { + request = NewCreateRouteTableRequest() + } + response = NewCreateRouteTableResponse() + err = c.Send(request, response) + return +} + +func NewCreateRoutesRequest() (request *CreateRoutesRequest) { + request = &CreateRoutesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "CreateRoutes") + return +} + +func NewCreateRoutesResponse() (response *CreateRoutesResponse) { + response = &CreateRoutesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(CreateRoutes)用于创建路由策略。 +// * 向指定路由表批量新增路由策略。 +func (c *Client) CreateRoutes(request *CreateRoutesRequest) (response *CreateRoutesResponse, err error) { + if request == nil { + request = NewCreateRoutesRequest() + } + response = NewCreateRoutesResponse() + err = c.Send(request, response) + return +} + +func NewCreateSecurityGroupRequest() (request *CreateSecurityGroupRequest) { + request = &CreateSecurityGroupRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "CreateSecurityGroup") + return +} + +func NewCreateSecurityGroupResponse() (response *CreateSecurityGroupResponse) { + response = &CreateSecurityGroupResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(CreateSecurityGroup)用于创建新的安全组(SecurityGroup)。 +// * 每个账户下每个地域的每个项目的安全组数量限制。 +// * 新建的安全组的入站和出站规则默认都是全部拒绝,在创建后通常您需要再调用CreateSecurityGroupPolicies将安全组的规则设置为需要的规则。 +func (c *Client) CreateSecurityGroup(request *CreateSecurityGroupRequest) (response *CreateSecurityGroupResponse, err error) { + if request == nil { + request = NewCreateSecurityGroupRequest() + } + response = NewCreateSecurityGroupResponse() + err = c.Send(request, response) + return +} + +func NewCreateSecurityGroupPoliciesRequest() (request *CreateSecurityGroupPoliciesRequest) { + request = &CreateSecurityGroupPoliciesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "CreateSecurityGroupPolicies") + return +} + +func NewCreateSecurityGroupPoliciesResponse() (response *CreateSecurityGroupPoliciesResponse) { + response = &CreateSecurityGroupPoliciesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(CreateSecurityGroupPolicies)用于创建安全组规则(SecurityGroupPolicy)。 +// +// * Version安全组规则版本号,用户每次更新安全规则版本会自动加1,防止你更新的路由规则已过期,不填不考虑冲突。 +// * Protocol字段支持输入TCP, UDP, ICMP, GRE, ALL。 +// * CidrBlock字段允许输入符合cidr格式标准的任意字符串。(展开)在基础网络中,如果CidrBlock包含您的账户内的云服务器之外的设备在腾讯云的内网IP,并不代表此规则允许您访问这些设备,租户之间网络隔离规则优先于安全组中的内网规则。 +// * SecurityGroupId字段允许输入与待修改的安全组位于相同项目中的安全组ID,包括这个安全组ID本身,代表安全组下所有云服务器的内网IP。使用这个字段时,这条规则用来匹配网络报文的过程中会随着被使用的这个ID所关联的云服务器变化而变化,不需要重新修改。 +// * Port字段允许输入一个单独端口号,或者用减号分隔的两个端口号代表端口范围,例如80或8000-8010。只有当Protocol字段是TCP或UDP时,Port字段才被接受。 +// * Action字段只允许输入ACCEPT或DROP。 +// * CidrBlock, SecurityGroupId, AddressTemplate三者是排他关系,不允许同时输入,Protocol + Port和ServiceTemplate二者是排他关系,不允许同时输入。 +// * 一次请求中只能创建单个方向的规则, 如果需要指定索引(PolicyIndex)参数, 多条规则的索引必须一致。 +func (c *Client) CreateSecurityGroupPolicies(request *CreateSecurityGroupPoliciesRequest) (response *CreateSecurityGroupPoliciesResponse, err error) { + if request == nil { + request = NewCreateSecurityGroupPoliciesRequest() + } + response = NewCreateSecurityGroupPoliciesResponse() + err = c.Send(request, response) + return +} + +func NewCreateServiceTemplateRequest() (request *CreateServiceTemplateRequest) { + request = &CreateServiceTemplateRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "CreateServiceTemplate") + return +} + +func NewCreateServiceTemplateResponse() (response *CreateServiceTemplateResponse) { + response = &CreateServiceTemplateResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 创建协议端口模板 +func (c *Client) CreateServiceTemplate(request *CreateServiceTemplateRequest) (response *CreateServiceTemplateResponse, err error) { + if request == nil { + request = NewCreateServiceTemplateRequest() + } + response = NewCreateServiceTemplateResponse() + err = c.Send(request, response) + return +} + +func NewCreateServiceTemplateGroupRequest() (request *CreateServiceTemplateGroupRequest) { + request = &CreateServiceTemplateGroupRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "CreateServiceTemplateGroup") + return +} + +func NewCreateServiceTemplateGroupResponse() (response *CreateServiceTemplateGroupResponse) { + response = &CreateServiceTemplateGroupResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 创建协议端口模板集合 +func (c *Client) CreateServiceTemplateGroup(request *CreateServiceTemplateGroupRequest) (response *CreateServiceTemplateGroupResponse, err error) { + if request == nil { + request = NewCreateServiceTemplateGroupRequest() + } + response = NewCreateServiceTemplateGroupResponse() + err = c.Send(request, response) + return +} + +func NewCreateSubnetRequest() (request *CreateSubnetRequest) { + request = &CreateSubnetRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "CreateSubnet") + return +} + +func NewCreateSubnetResponse() (response *CreateSubnetResponse) { + response = &CreateSubnetResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(CreateSubnet)用于创建子网。 +// * 创建子网前必须创建好 VPC。 +// * 子网创建成功后,子网网段不能修改。子网网段必须在VPC网段内,可以和VPC网段相同(VPC有且只有一个子网时),建议子网网段在VPC网段内,预留网段给其他子网使用。 +// * 你可以创建的最小网段子网掩码为28(有16个IP地址),最大网段子网掩码为16(65,536个IP地址)。 +// * 同一个VPC内,多个子网的网段不能重叠。 +// * 子网创建后会自动关联到默认路由表。 +func (c *Client) CreateSubnet(request *CreateSubnetRequest) (response *CreateSubnetResponse, err error) { + if request == nil { + request = NewCreateSubnetRequest() + } + response = NewCreateSubnetResponse() + err = c.Send(request, response) + return +} + +func NewCreateVpcRequest() (request *CreateVpcRequest) { + request = &CreateVpcRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "CreateVpc") + return +} + +func NewCreateVpcResponse() (response *CreateVpcResponse) { + response = &CreateVpcResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(CreateVpc)用于创建私有网络(VPC)。 +// * 用户可以创建的最小网段子网掩码为28(有16个IP地址),最大网段子网掩码为16(65,536个IP地址),如果规划VPC网段请参见VPC网段规划说明。 +// * 同一个地域能创建的VPC资源个数也是有限制的,详见 VPC使用限制,如果需要扩充请联系在线客服。 +func (c *Client) CreateVpc(request *CreateVpcRequest) (response *CreateVpcResponse, err error) { + if request == nil { + request = NewCreateVpcRequest() + } + response = NewCreateVpcResponse() + err = c.Send(request, response) + return +} + +func NewCreateVpnConnectionRequest() (request *CreateVpnConnectionRequest) { + request = &CreateVpnConnectionRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "CreateVpnConnection") + return +} + +func NewCreateVpnConnectionResponse() (response *CreateVpnConnectionResponse) { + response = &CreateVpnConnectionResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(CreateVpnConnection)用于创建VPN通道。 +func (c *Client) CreateVpnConnection(request *CreateVpnConnectionRequest) (response *CreateVpnConnectionResponse, err error) { + if request == nil { + request = NewCreateVpnConnectionRequest() + } + response = NewCreateVpnConnectionResponse() + err = c.Send(request, response) + return +} + +func NewCreateVpnGatewayRequest() (request *CreateVpnGatewayRequest) { + request = &CreateVpnGatewayRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "CreateVpnGateway") + return +} + +func NewCreateVpnGatewayResponse() (response *CreateVpnGatewayResponse) { + response = &CreateVpnGatewayResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(CreateVpnGateways)用于创建VPN网关。 +func (c *Client) CreateVpnGateway(request *CreateVpnGatewayRequest) (response *CreateVpnGatewayResponse, err error) { + if request == nil { + request = NewCreateVpnGatewayRequest() + } + response = NewCreateVpnGatewayResponse() + err = c.Send(request, response) + return +} + +func NewDeleteAddressTemplateRequest() (request *DeleteAddressTemplateRequest) { + request = &DeleteAddressTemplateRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DeleteAddressTemplate") + return +} + +func NewDeleteAddressTemplateResponse() (response *DeleteAddressTemplateResponse) { + response = &DeleteAddressTemplateResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 删除IP地址模板 +func (c *Client) DeleteAddressTemplate(request *DeleteAddressTemplateRequest) (response *DeleteAddressTemplateResponse, err error) { + if request == nil { + request = NewDeleteAddressTemplateRequest() + } + response = NewDeleteAddressTemplateResponse() + err = c.Send(request, response) + return +} + +func NewDeleteAddressTemplateGroupRequest() (request *DeleteAddressTemplateGroupRequest) { + request = &DeleteAddressTemplateGroupRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DeleteAddressTemplateGroup") + return +} + +func NewDeleteAddressTemplateGroupResponse() (response *DeleteAddressTemplateGroupResponse) { + response = &DeleteAddressTemplateGroupResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 删除IP地址模板集合 +func (c *Client) DeleteAddressTemplateGroup(request *DeleteAddressTemplateGroupRequest) (response *DeleteAddressTemplateGroupResponse, err error) { + if request == nil { + request = NewDeleteAddressTemplateGroupRequest() + } + response = NewDeleteAddressTemplateGroupResponse() + err = c.Send(request, response) + return +} + +func NewDeleteBandwidthPackageRequest() (request *DeleteBandwidthPackageRequest) { + request = &DeleteBandwidthPackageRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DeleteBandwidthPackage") + return +} + +func NewDeleteBandwidthPackageResponse() (response *DeleteBandwidthPackageResponse) { + response = &DeleteBandwidthPackageResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 接口支持删除共享带宽包,包括[设备带宽包](https://cloud.tencent.com/document/product/684/15246#.E8.AE.BE.E5.A4.87.E5.B8.A6.E5.AE.BD.E5.8C.85)和[ip带宽包](https://cloud.tencent.com/document/product/684/15246#ip-.E5.B8.A6.E5.AE.BD.E5.8C.85) +func (c *Client) DeleteBandwidthPackage(request *DeleteBandwidthPackageRequest) (response *DeleteBandwidthPackageResponse, err error) { + if request == nil { + request = NewDeleteBandwidthPackageRequest() + } + response = NewDeleteBandwidthPackageResponse() + err = c.Send(request, response) + return +} + +func NewDeleteCcnRequest() (request *DeleteCcnRequest) { + request = &DeleteCcnRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DeleteCcn") + return +} + +func NewDeleteCcnResponse() (response *DeleteCcnResponse) { + response = &DeleteCcnResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DeleteCcn)用于删除云联网。 +// * 删除后,云联网关联的所有实例间路由将被删除,网络将会中断,请务必确认 +// * 删除云联网是不可逆的操作,请谨慎处理。 +func (c *Client) DeleteCcn(request *DeleteCcnRequest) (response *DeleteCcnResponse, err error) { + if request == nil { + request = NewDeleteCcnRequest() + } + response = NewDeleteCcnResponse() + err = c.Send(request, response) + return +} + +func NewDeleteCustomerGatewayRequest() (request *DeleteCustomerGatewayRequest) { + request = &DeleteCustomerGatewayRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DeleteCustomerGateway") + return +} + +func NewDeleteCustomerGatewayResponse() (response *DeleteCustomerGatewayResponse) { + response = &DeleteCustomerGatewayResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DeleteCustomerGateway)用于删除对端网关。 +func (c *Client) DeleteCustomerGateway(request *DeleteCustomerGatewayRequest) (response *DeleteCustomerGatewayResponse, err error) { + if request == nil { + request = NewDeleteCustomerGatewayRequest() + } + response = NewDeleteCustomerGatewayResponse() + err = c.Send(request, response) + return +} + +func NewDeleteDirectConnectGatewayCcnRoutesRequest() (request *DeleteDirectConnectGatewayCcnRoutesRequest) { + request = &DeleteDirectConnectGatewayCcnRoutesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DeleteDirectConnectGatewayCcnRoutes") + return +} + +func NewDeleteDirectConnectGatewayCcnRoutesResponse() (response *DeleteDirectConnectGatewayCcnRoutesResponse) { + response = &DeleteDirectConnectGatewayCcnRoutesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DeleteDirectConnectGatewayCcnRoutes)用于删除专线网关的云联网路由(IDC网段) +func (c *Client) DeleteDirectConnectGatewayCcnRoutes(request *DeleteDirectConnectGatewayCcnRoutesRequest) (response *DeleteDirectConnectGatewayCcnRoutesResponse, err error) { + if request == nil { + request = NewDeleteDirectConnectGatewayCcnRoutesRequest() + } + response = NewDeleteDirectConnectGatewayCcnRoutesResponse() + err = c.Send(request, response) + return +} + +func NewDeleteNetworkInterfaceRequest() (request *DeleteNetworkInterfaceRequest) { + request = &DeleteNetworkInterfaceRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DeleteNetworkInterface") + return +} + +func NewDeleteNetworkInterfaceResponse() (response *DeleteNetworkInterfaceResponse) { + response = &DeleteNetworkInterfaceResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DeleteNetworkInterface)用于创建弹性网卡。 +// * 弹性网卡上绑定了云主机时,不能被删除。 +// * 删除指定弹性网卡,弹性网卡必须先和子机解绑才能删除。删除之后弹性网卡上所有内网IP都将被退还。 +func (c *Client) DeleteNetworkInterface(request *DeleteNetworkInterfaceRequest) (response *DeleteNetworkInterfaceResponse, err error) { + if request == nil { + request = NewDeleteNetworkInterfaceRequest() + } + response = NewDeleteNetworkInterfaceResponse() + err = c.Send(request, response) + return +} + +func NewDeleteRouteTableRequest() (request *DeleteRouteTableRequest) { + request = &DeleteRouteTableRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DeleteRouteTable") + return +} + +func NewDeleteRouteTableResponse() (response *DeleteRouteTableResponse) { + response = &DeleteRouteTableResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 删除路由表 +func (c *Client) DeleteRouteTable(request *DeleteRouteTableRequest) (response *DeleteRouteTableResponse, err error) { + if request == nil { + request = NewDeleteRouteTableRequest() + } + response = NewDeleteRouteTableResponse() + err = c.Send(request, response) + return +} + +func NewDeleteRoutesRequest() (request *DeleteRoutesRequest) { + request = &DeleteRoutesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DeleteRoutes") + return +} + +func NewDeleteRoutesResponse() (response *DeleteRoutesResponse) { + response = &DeleteRoutesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DeleteRoutes)用于对某个路由表批量删除路由策略(Route)。 +func (c *Client) DeleteRoutes(request *DeleteRoutesRequest) (response *DeleteRoutesResponse, err error) { + if request == nil { + request = NewDeleteRoutesRequest() + } + response = NewDeleteRoutesResponse() + err = c.Send(request, response) + return +} + +func NewDeleteSecurityGroupRequest() (request *DeleteSecurityGroupRequest) { + request = &DeleteSecurityGroupRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DeleteSecurityGroup") + return +} + +func NewDeleteSecurityGroupResponse() (response *DeleteSecurityGroupResponse) { + response = &DeleteSecurityGroupResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DeleteSecurityGroup)用于删除安全组(SecurityGroup)。 +// * 只有当前账号下的安全组允许被删除。 +// * 安全组实例ID如果在其他安全组的规则中被引用,则无法直接删除。这种情况下,需要先进行规则修改,再删除安全组。 +// * 删除的安全组无法再找回,请谨慎调用。 +func (c *Client) DeleteSecurityGroup(request *DeleteSecurityGroupRequest) (response *DeleteSecurityGroupResponse, err error) { + if request == nil { + request = NewDeleteSecurityGroupRequest() + } + response = NewDeleteSecurityGroupResponse() + err = c.Send(request, response) + return +} + +func NewDeleteSecurityGroupPoliciesRequest() (request *DeleteSecurityGroupPoliciesRequest) { + request = &DeleteSecurityGroupPoliciesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DeleteSecurityGroupPolicies") + return +} + +func NewDeleteSecurityGroupPoliciesResponse() (response *DeleteSecurityGroupPoliciesResponse) { + response = &DeleteSecurityGroupPoliciesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DeleteSecurityGroupPolicies)用于用于删除安全组规则(SecurityGroupPolicy)。 +// * SecurityGroupPolicySet.Version 用于指定要操作的安全组的版本。传入 Version 版本号若不等于当前安全组的最新版本,将返回失败;若不传 Version 则直接删除指定PolicyIndex的规则。 +func (c *Client) DeleteSecurityGroupPolicies(request *DeleteSecurityGroupPoliciesRequest) (response *DeleteSecurityGroupPoliciesResponse, err error) { + if request == nil { + request = NewDeleteSecurityGroupPoliciesRequest() + } + response = NewDeleteSecurityGroupPoliciesResponse() + err = c.Send(request, response) + return +} + +func NewDeleteServiceTemplateRequest() (request *DeleteServiceTemplateRequest) { + request = &DeleteServiceTemplateRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DeleteServiceTemplate") + return +} + +func NewDeleteServiceTemplateResponse() (response *DeleteServiceTemplateResponse) { + response = &DeleteServiceTemplateResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 删除协议端口模板 +func (c *Client) DeleteServiceTemplate(request *DeleteServiceTemplateRequest) (response *DeleteServiceTemplateResponse, err error) { + if request == nil { + request = NewDeleteServiceTemplateRequest() + } + response = NewDeleteServiceTemplateResponse() + err = c.Send(request, response) + return +} + +func NewDeleteServiceTemplateGroupRequest() (request *DeleteServiceTemplateGroupRequest) { + request = &DeleteServiceTemplateGroupRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DeleteServiceTemplateGroup") + return +} + +func NewDeleteServiceTemplateGroupResponse() (response *DeleteServiceTemplateGroupResponse) { + response = &DeleteServiceTemplateGroupResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 删除协议端口模板集合 +func (c *Client) DeleteServiceTemplateGroup(request *DeleteServiceTemplateGroupRequest) (response *DeleteServiceTemplateGroupResponse, err error) { + if request == nil { + request = NewDeleteServiceTemplateGroupRequest() + } + response = NewDeleteServiceTemplateGroupResponse() + err = c.Send(request, response) + return +} + +func NewDeleteSubnetRequest() (request *DeleteSubnetRequest) { + request = &DeleteSubnetRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DeleteSubnet") + return +} + +func NewDeleteSubnetResponse() (response *DeleteSubnetResponse) { + response = &DeleteSubnetResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DeleteSubnet)用于用于删除子网(Subnet)。 +// * 删除子网前,请清理该子网下所有资源,包括云主机、负载均衡、云数据、noSql、弹性网卡等资源。 +func (c *Client) DeleteSubnet(request *DeleteSubnetRequest) (response *DeleteSubnetResponse, err error) { + if request == nil { + request = NewDeleteSubnetRequest() + } + response = NewDeleteSubnetResponse() + err = c.Send(request, response) + return +} + +func NewDeleteVpcRequest() (request *DeleteVpcRequest) { + request = &DeleteVpcRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DeleteVpc") + return +} + +func NewDeleteVpcResponse() (response *DeleteVpcResponse) { + response = &DeleteVpcResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DeleteVpc)用于删除私有网络。 +// * 删除前请确保 VPC 内已经没有相关资源,例如云主机、云数据库、NoSQL、VPN网关、专线网关、负载均衡、对等连接、与之互通的基础网络设备等。 +// * 删除私有网络是不可逆的操作,请谨慎处理。 +func (c *Client) DeleteVpc(request *DeleteVpcRequest) (response *DeleteVpcResponse, err error) { + if request == nil { + request = NewDeleteVpcRequest() + } + response = NewDeleteVpcResponse() + err = c.Send(request, response) + return +} + +func NewDeleteVpnConnectionRequest() (request *DeleteVpnConnectionRequest) { + request = &DeleteVpnConnectionRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DeleteVpnConnection") + return +} + +func NewDeleteVpnConnectionResponse() (response *DeleteVpnConnectionResponse) { + response = &DeleteVpnConnectionResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DeleteVpnConnection)用于删除VPN通道。 +func (c *Client) DeleteVpnConnection(request *DeleteVpnConnectionRequest) (response *DeleteVpnConnectionResponse, err error) { + if request == nil { + request = NewDeleteVpnConnectionRequest() + } + response = NewDeleteVpnConnectionResponse() + err = c.Send(request, response) + return +} + +func NewDeleteVpnGatewayRequest() (request *DeleteVpnGatewayRequest) { + request = &DeleteVpnGatewayRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DeleteVpnGateway") + return +} + +func NewDeleteVpnGatewayResponse() (response *DeleteVpnGatewayResponse) { + response = &DeleteVpnGatewayResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DeleteVpnGateway)用于删除VPN网关。目前只支持删除运行中的按量计费的IPSEC网关实例。 +func (c *Client) DeleteVpnGateway(request *DeleteVpnGatewayRequest) (response *DeleteVpnGatewayResponse, err error) { + if request == nil { + request = NewDeleteVpnGatewayRequest() + } + response = NewDeleteVpnGatewayResponse() + err = c.Send(request, response) + return +} + +func NewDescribeAccountAttributesRequest() (request *DescribeAccountAttributesRequest) { + request = &DescribeAccountAttributesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DescribeAccountAttributes") + return +} + +func NewDescribeAccountAttributesResponse() (response *DescribeAccountAttributesResponse) { + response = &DescribeAccountAttributesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeAccountAttributes)用于查询用户账号私有属性。 +func (c *Client) DescribeAccountAttributes(request *DescribeAccountAttributesRequest) (response *DescribeAccountAttributesResponse, err error) { + if request == nil { + request = NewDescribeAccountAttributesRequest() + } + response = NewDescribeAccountAttributesResponse() + err = c.Send(request, response) + return +} + +func NewDescribeAddressQuotaRequest() (request *DescribeAddressQuotaRequest) { + request = &DescribeAddressQuotaRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DescribeAddressQuota") + return +} + +func NewDescribeAddressQuotaResponse() (response *DescribeAddressQuotaResponse) { + response = &DescribeAddressQuotaResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (DescribeAddressQuota) 用于查询您账户的[弹性公网IP](https://cloud.tencent.com/document/product/213/1941)(简称 EIP)在当前地域的配额信息。配额详情可参见 [EIP 产品简介](https://cloud.tencent.com/document/product/213/5733)。 +func (c *Client) DescribeAddressQuota(request *DescribeAddressQuotaRequest) (response *DescribeAddressQuotaResponse, err error) { + if request == nil { + request = NewDescribeAddressQuotaRequest() + } + response = NewDescribeAddressQuotaResponse() + err = c.Send(request, response) + return +} + +func NewDescribeAddressTemplateGroupsRequest() (request *DescribeAddressTemplateGroupsRequest) { + request = &DescribeAddressTemplateGroupsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DescribeAddressTemplateGroups") + return +} + +func NewDescribeAddressTemplateGroupsResponse() (response *DescribeAddressTemplateGroupsResponse) { + response = &DescribeAddressTemplateGroupsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 查询IP地址模板集合 +func (c *Client) DescribeAddressTemplateGroups(request *DescribeAddressTemplateGroupsRequest) (response *DescribeAddressTemplateGroupsResponse, err error) { + if request == nil { + request = NewDescribeAddressTemplateGroupsRequest() + } + response = NewDescribeAddressTemplateGroupsResponse() + err = c.Send(request, response) + return +} + +func NewDescribeAddressTemplatesRequest() (request *DescribeAddressTemplatesRequest) { + request = &DescribeAddressTemplatesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DescribeAddressTemplates") + return +} + +func NewDescribeAddressTemplatesResponse() (response *DescribeAddressTemplatesResponse) { + response = &DescribeAddressTemplatesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 查询IP地址模板 +func (c *Client) DescribeAddressTemplates(request *DescribeAddressTemplatesRequest) (response *DescribeAddressTemplatesResponse, err error) { + if request == nil { + request = NewDescribeAddressTemplatesRequest() + } + response = NewDescribeAddressTemplatesResponse() + err = c.Send(request, response) + return +} + +func NewDescribeAddressesRequest() (request *DescribeAddressesRequest) { + request = &DescribeAddressesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DescribeAddresses") + return +} + +func NewDescribeAddressesResponse() (response *DescribeAddressesResponse) { + response = &DescribeAddressesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (DescribeAddresses) 用于查询一个或多个[弹性公网IP](https://cloud.tencent.com/document/product/213/1941)(简称 EIP)的详细信息。 +// * 如果参数为空,返回当前用户一定数量(Limit所指定的数量,默认为20)的 EIP。 +func (c *Client) DescribeAddresses(request *DescribeAddressesRequest) (response *DescribeAddressesResponse, err error) { + if request == nil { + request = NewDescribeAddressesRequest() + } + response = NewDescribeAddressesResponse() + err = c.Send(request, response) + return +} + +func NewDescribeBandwidthPackageQuotaRequest() (request *DescribeBandwidthPackageQuotaRequest) { + request = &DescribeBandwidthPackageQuotaRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DescribeBandwidthPackageQuota") + return +} + +func NewDescribeBandwidthPackageQuotaResponse() (response *DescribeBandwidthPackageQuotaResponse) { + response = &DescribeBandwidthPackageQuotaResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 接口用于查询账户在当前地域的带宽包上限数量以及使用数量 +func (c *Client) DescribeBandwidthPackageQuota(request *DescribeBandwidthPackageQuotaRequest) (response *DescribeBandwidthPackageQuotaResponse, err error) { + if request == nil { + request = NewDescribeBandwidthPackageQuotaRequest() + } + response = NewDescribeBandwidthPackageQuotaResponse() + err = c.Send(request, response) + return +} + +func NewDescribeBandwidthPackagesRequest() (request *DescribeBandwidthPackagesRequest) { + request = &DescribeBandwidthPackagesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DescribeBandwidthPackages") + return +} + +func NewDescribeBandwidthPackagesResponse() (response *DescribeBandwidthPackagesResponse) { + response = &DescribeBandwidthPackagesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 接口用于查询带宽包详细信息,包括带宽包唯一标识ID,类型,计费模式,名称,资源信息等 +func (c *Client) DescribeBandwidthPackages(request *DescribeBandwidthPackagesRequest) (response *DescribeBandwidthPackagesResponse, err error) { + if request == nil { + request = NewDescribeBandwidthPackagesRequest() + } + response = NewDescribeBandwidthPackagesResponse() + err = c.Send(request, response) + return +} + +func NewDescribeCcnAttachedInstancesRequest() (request *DescribeCcnAttachedInstancesRequest) { + request = &DescribeCcnAttachedInstancesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DescribeCcnAttachedInstances") + return +} + +func NewDescribeCcnAttachedInstancesResponse() (response *DescribeCcnAttachedInstancesResponse) { + response = &DescribeCcnAttachedInstancesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeCcnAttachedInstances)用于查询云联网实例下已关联的网络实例。 +func (c *Client) DescribeCcnAttachedInstances(request *DescribeCcnAttachedInstancesRequest) (response *DescribeCcnAttachedInstancesResponse, err error) { + if request == nil { + request = NewDescribeCcnAttachedInstancesRequest() + } + response = NewDescribeCcnAttachedInstancesResponse() + err = c.Send(request, response) + return +} + +func NewDescribeCcnRegionBandwidthLimitsRequest() (request *DescribeCcnRegionBandwidthLimitsRequest) { + request = &DescribeCcnRegionBandwidthLimitsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DescribeCcnRegionBandwidthLimits") + return +} + +func NewDescribeCcnRegionBandwidthLimitsResponse() (response *DescribeCcnRegionBandwidthLimitsResponse) { + response = &DescribeCcnRegionBandwidthLimitsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeCcnRegionBandwidthLimits)用于查询云联网各地域出带宽上限,该接口只返回已关联网络实例包含的地域 +func (c *Client) DescribeCcnRegionBandwidthLimits(request *DescribeCcnRegionBandwidthLimitsRequest) (response *DescribeCcnRegionBandwidthLimitsResponse, err error) { + if request == nil { + request = NewDescribeCcnRegionBandwidthLimitsRequest() + } + response = NewDescribeCcnRegionBandwidthLimitsResponse() + err = c.Send(request, response) + return +} + +func NewDescribeCcnRoutesRequest() (request *DescribeCcnRoutesRequest) { + request = &DescribeCcnRoutesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DescribeCcnRoutes") + return +} + +func NewDescribeCcnRoutesResponse() (response *DescribeCcnRoutesResponse) { + response = &DescribeCcnRoutesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeCcnRoutes)用于查询已加入云联网(CCN)的路由 +func (c *Client) DescribeCcnRoutes(request *DescribeCcnRoutesRequest) (response *DescribeCcnRoutesResponse, err error) { + if request == nil { + request = NewDescribeCcnRoutesRequest() + } + response = NewDescribeCcnRoutesResponse() + err = c.Send(request, response) + return +} + +func NewDescribeCcnsRequest() (request *DescribeCcnsRequest) { + request = &DescribeCcnsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DescribeCcns") + return +} + +func NewDescribeCcnsResponse() (response *DescribeCcnsResponse) { + response = &DescribeCcnsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeCcns)用于查询云联网(CCN)列表。 +func (c *Client) DescribeCcns(request *DescribeCcnsRequest) (response *DescribeCcnsResponse, err error) { + if request == nil { + request = NewDescribeCcnsRequest() + } + response = NewDescribeCcnsResponse() + err = c.Send(request, response) + return +} + +func NewDescribeClassicLinkInstancesRequest() (request *DescribeClassicLinkInstancesRequest) { + request = &DescribeClassicLinkInstancesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DescribeClassicLinkInstances") + return +} + +func NewDescribeClassicLinkInstancesResponse() (response *DescribeClassicLinkInstancesResponse) { + response = &DescribeClassicLinkInstancesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeClassicLinkInstances)用于查询私有网络和基础网络设备互通列表。 +func (c *Client) DescribeClassicLinkInstances(request *DescribeClassicLinkInstancesRequest) (response *DescribeClassicLinkInstancesResponse, err error) { + if request == nil { + request = NewDescribeClassicLinkInstancesRequest() + } + response = NewDescribeClassicLinkInstancesResponse() + err = c.Send(request, response) + return +} + +func NewDescribeCustomerGatewayVendorsRequest() (request *DescribeCustomerGatewayVendorsRequest) { + request = &DescribeCustomerGatewayVendorsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DescribeCustomerGatewayVendors") + return +} + +func NewDescribeCustomerGatewayVendorsResponse() (response *DescribeCustomerGatewayVendorsResponse) { + response = &DescribeCustomerGatewayVendorsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeCustomerGatewayVendors)用于查询可支持的对端网关厂商信息。 +func (c *Client) DescribeCustomerGatewayVendors(request *DescribeCustomerGatewayVendorsRequest) (response *DescribeCustomerGatewayVendorsResponse, err error) { + if request == nil { + request = NewDescribeCustomerGatewayVendorsRequest() + } + response = NewDescribeCustomerGatewayVendorsResponse() + err = c.Send(request, response) + return +} + +func NewDescribeCustomerGatewaysRequest() (request *DescribeCustomerGatewaysRequest) { + request = &DescribeCustomerGatewaysRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DescribeCustomerGateways") + return +} + +func NewDescribeCustomerGatewaysResponse() (response *DescribeCustomerGatewaysResponse) { + response = &DescribeCustomerGatewaysResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeCustomerGateways)用于查询对端网关列表。 +func (c *Client) DescribeCustomerGateways(request *DescribeCustomerGatewaysRequest) (response *DescribeCustomerGatewaysResponse, err error) { + if request == nil { + request = NewDescribeCustomerGatewaysRequest() + } + response = NewDescribeCustomerGatewaysResponse() + err = c.Send(request, response) + return +} + +func NewDescribeDirectConnectGatewayCcnRoutesRequest() (request *DescribeDirectConnectGatewayCcnRoutesRequest) { + request = &DescribeDirectConnectGatewayCcnRoutesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DescribeDirectConnectGatewayCcnRoutes") + return +} + +func NewDescribeDirectConnectGatewayCcnRoutesResponse() (response *DescribeDirectConnectGatewayCcnRoutesResponse) { + response = &DescribeDirectConnectGatewayCcnRoutesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeDirectConnectGatewayCcnRoutes)用于查询专线网关的云联网路由(IDC网段) +func (c *Client) DescribeDirectConnectGatewayCcnRoutes(request *DescribeDirectConnectGatewayCcnRoutesRequest) (response *DescribeDirectConnectGatewayCcnRoutesResponse, err error) { + if request == nil { + request = NewDescribeDirectConnectGatewayCcnRoutesRequest() + } + response = NewDescribeDirectConnectGatewayCcnRoutesResponse() + err = c.Send(request, response) + return +} + +func NewDescribeNetworkInterfacesRequest() (request *DescribeNetworkInterfacesRequest) { + request = &DescribeNetworkInterfacesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DescribeNetworkInterfaces") + return +} + +func NewDescribeNetworkInterfacesResponse() (response *DescribeNetworkInterfacesResponse) { + response = &DescribeNetworkInterfacesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeNetworkInterfaces)用于查询弹性网卡列表。 +func (c *Client) DescribeNetworkInterfaces(request *DescribeNetworkInterfacesRequest) (response *DescribeNetworkInterfacesResponse, err error) { + if request == nil { + request = NewDescribeNetworkInterfacesRequest() + } + response = NewDescribeNetworkInterfacesResponse() + err = c.Send(request, response) + return +} + +func NewDescribeRouteConflictsRequest() (request *DescribeRouteConflictsRequest) { + request = &DescribeRouteConflictsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DescribeRouteConflicts") + return +} + +func NewDescribeRouteConflictsResponse() (response *DescribeRouteConflictsResponse) { + response = &DescribeRouteConflictsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeRouteConflicts)用于查询自定义路由策略与云联网路由策略冲突列表 +func (c *Client) DescribeRouteConflicts(request *DescribeRouteConflictsRequest) (response *DescribeRouteConflictsResponse, err error) { + if request == nil { + request = NewDescribeRouteConflictsRequest() + } + response = NewDescribeRouteConflictsResponse() + err = c.Send(request, response) + return +} + +func NewDescribeRouteTablesRequest() (request *DescribeRouteTablesRequest) { + request = &DescribeRouteTablesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DescribeRouteTables") + return +} + +func NewDescribeRouteTablesResponse() (response *DescribeRouteTablesResponse) { + response = &DescribeRouteTablesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeRouteTables)用于查询路由表。 +func (c *Client) DescribeRouteTables(request *DescribeRouteTablesRequest) (response *DescribeRouteTablesResponse, err error) { + if request == nil { + request = NewDescribeRouteTablesRequest() + } + response = NewDescribeRouteTablesResponse() + err = c.Send(request, response) + return +} + +func NewDescribeSecurityGroupAssociationStatisticsRequest() (request *DescribeSecurityGroupAssociationStatisticsRequest) { + request = &DescribeSecurityGroupAssociationStatisticsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DescribeSecurityGroupAssociationStatistics") + return +} + +func NewDescribeSecurityGroupAssociationStatisticsResponse() (response *DescribeSecurityGroupAssociationStatisticsResponse) { + response = &DescribeSecurityGroupAssociationStatisticsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeSecurityGroupAssociationStatistics)用于查询安全组关联的实例统计。 +func (c *Client) DescribeSecurityGroupAssociationStatistics(request *DescribeSecurityGroupAssociationStatisticsRequest) (response *DescribeSecurityGroupAssociationStatisticsResponse, err error) { + if request == nil { + request = NewDescribeSecurityGroupAssociationStatisticsRequest() + } + response = NewDescribeSecurityGroupAssociationStatisticsResponse() + err = c.Send(request, response) + return +} + +func NewDescribeSecurityGroupPoliciesRequest() (request *DescribeSecurityGroupPoliciesRequest) { + request = &DescribeSecurityGroupPoliciesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DescribeSecurityGroupPolicies") + return +} + +func NewDescribeSecurityGroupPoliciesResponse() (response *DescribeSecurityGroupPoliciesResponse) { + response = &DescribeSecurityGroupPoliciesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeSecurityGroupPolicies)用于查询安全组规则。 +func (c *Client) DescribeSecurityGroupPolicies(request *DescribeSecurityGroupPoliciesRequest) (response *DescribeSecurityGroupPoliciesResponse, err error) { + if request == nil { + request = NewDescribeSecurityGroupPoliciesRequest() + } + response = NewDescribeSecurityGroupPoliciesResponse() + err = c.Send(request, response) + return +} + +func NewDescribeSecurityGroupsRequest() (request *DescribeSecurityGroupsRequest) { + request = &DescribeSecurityGroupsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DescribeSecurityGroups") + return +} + +func NewDescribeSecurityGroupsResponse() (response *DescribeSecurityGroupsResponse) { + response = &DescribeSecurityGroupsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeSecurityGroups)用于查询安全组。 +func (c *Client) DescribeSecurityGroups(request *DescribeSecurityGroupsRequest) (response *DescribeSecurityGroupsResponse, err error) { + if request == nil { + request = NewDescribeSecurityGroupsRequest() + } + response = NewDescribeSecurityGroupsResponse() + err = c.Send(request, response) + return +} + +func NewDescribeServiceTemplateGroupsRequest() (request *DescribeServiceTemplateGroupsRequest) { + request = &DescribeServiceTemplateGroupsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DescribeServiceTemplateGroups") + return +} + +func NewDescribeServiceTemplateGroupsResponse() (response *DescribeServiceTemplateGroupsResponse) { + response = &DescribeServiceTemplateGroupsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 查询协议端口模板集合 +func (c *Client) DescribeServiceTemplateGroups(request *DescribeServiceTemplateGroupsRequest) (response *DescribeServiceTemplateGroupsResponse, err error) { + if request == nil { + request = NewDescribeServiceTemplateGroupsRequest() + } + response = NewDescribeServiceTemplateGroupsResponse() + err = c.Send(request, response) + return +} + +func NewDescribeServiceTemplatesRequest() (request *DescribeServiceTemplatesRequest) { + request = &DescribeServiceTemplatesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DescribeServiceTemplates") + return +} + +func NewDescribeServiceTemplatesResponse() (response *DescribeServiceTemplatesResponse) { + response = &DescribeServiceTemplatesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 查询协议端口模板 +func (c *Client) DescribeServiceTemplates(request *DescribeServiceTemplatesRequest) (response *DescribeServiceTemplatesResponse, err error) { + if request == nil { + request = NewDescribeServiceTemplatesRequest() + } + response = NewDescribeServiceTemplatesResponse() + err = c.Send(request, response) + return +} + +func NewDescribeSubnetsRequest() (request *DescribeSubnetsRequest) { + request = &DescribeSubnetsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DescribeSubnets") + return +} + +func NewDescribeSubnetsResponse() (response *DescribeSubnetsResponse) { + response = &DescribeSubnetsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeSubnets)用于查询子网列表。 +func (c *Client) DescribeSubnets(request *DescribeSubnetsRequest) (response *DescribeSubnetsResponse, err error) { + if request == nil { + request = NewDescribeSubnetsRequest() + } + response = NewDescribeSubnetsResponse() + err = c.Send(request, response) + return +} + +func NewDescribeVpcsRequest() (request *DescribeVpcsRequest) { + request = &DescribeVpcsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DescribeVpcs") + return +} + +func NewDescribeVpcsResponse() (response *DescribeVpcsResponse) { + response = &DescribeVpcsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeVpcs)用于查询私有网络列表。 +func (c *Client) DescribeVpcs(request *DescribeVpcsRequest) (response *DescribeVpcsResponse, err error) { + if request == nil { + request = NewDescribeVpcsRequest() + } + response = NewDescribeVpcsResponse() + err = c.Send(request, response) + return +} + +func NewDescribeVpnConnectionsRequest() (request *DescribeVpnConnectionsRequest) { + request = &DescribeVpnConnectionsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DescribeVpnConnections") + return +} + +func NewDescribeVpnConnectionsResponse() (response *DescribeVpnConnectionsResponse) { + response = &DescribeVpnConnectionsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeVpnConnections)查询VPN通道列表。 +func (c *Client) DescribeVpnConnections(request *DescribeVpnConnectionsRequest) (response *DescribeVpnConnectionsResponse, err error) { + if request == nil { + request = NewDescribeVpnConnectionsRequest() + } + response = NewDescribeVpnConnectionsResponse() + err = c.Send(request, response) + return +} + +func NewDescribeVpnGatewaysRequest() (request *DescribeVpnGatewaysRequest) { + request = &DescribeVpnGatewaysRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DescribeVpnGateways") + return +} + +func NewDescribeVpnGatewaysResponse() (response *DescribeVpnGatewaysResponse) { + response = &DescribeVpnGatewaysResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeVpnGateways)用于查询VPN网关列表。 +func (c *Client) DescribeVpnGateways(request *DescribeVpnGatewaysRequest) (response *DescribeVpnGatewaysResponse, err error) { + if request == nil { + request = NewDescribeVpnGatewaysRequest() + } + response = NewDescribeVpnGatewaysResponse() + err = c.Send(request, response) + return +} + +func NewDetachCcnInstancesRequest() (request *DetachCcnInstancesRequest) { + request = &DetachCcnInstancesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DetachCcnInstances") + return +} + +func NewDetachCcnInstancesResponse() (response *DetachCcnInstancesResponse) { + response = &DetachCcnInstancesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DetachCcnInstances)用于从云联网实例中解关联指定的网络实例。
    +// 解关联网络实例后,相应的路由策略会一并删除。 +func (c *Client) DetachCcnInstances(request *DetachCcnInstancesRequest) (response *DetachCcnInstancesResponse, err error) { + if request == nil { + request = NewDetachCcnInstancesRequest() + } + response = NewDetachCcnInstancesResponse() + err = c.Send(request, response) + return +} + +func NewDetachClassicLinkVpcRequest() (request *DetachClassicLinkVpcRequest) { + request = &DetachClassicLinkVpcRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DetachClassicLinkVpc") + return +} + +func NewDetachClassicLinkVpcResponse() (response *DetachClassicLinkVpcResponse) { + response = &DetachClassicLinkVpcResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DetachClassicLinkVpc)用于删除私有网络和基础网络设备互通。 +func (c *Client) DetachClassicLinkVpc(request *DetachClassicLinkVpcRequest) (response *DetachClassicLinkVpcResponse, err error) { + if request == nil { + request = NewDetachClassicLinkVpcRequest() + } + response = NewDetachClassicLinkVpcResponse() + err = c.Send(request, response) + return +} + +func NewDetachNetworkInterfaceRequest() (request *DetachNetworkInterfaceRequest) { + request = &DetachNetworkInterfaceRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DetachNetworkInterface") + return +} + +func NewDetachNetworkInterfaceResponse() (response *DetachNetworkInterfaceResponse) { + response = &DetachNetworkInterfaceResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DetachNetworkInterface)用于弹性网卡解绑云主机。 +func (c *Client) DetachNetworkInterface(request *DetachNetworkInterfaceRequest) (response *DetachNetworkInterfaceResponse, err error) { + if request == nil { + request = NewDetachNetworkInterfaceRequest() + } + response = NewDetachNetworkInterfaceResponse() + err = c.Send(request, response) + return +} + +func NewDisableCcnRoutesRequest() (request *DisableCcnRoutesRequest) { + request = &DisableCcnRoutesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DisableCcnRoutes") + return +} + +func NewDisableCcnRoutesResponse() (response *DisableCcnRoutesResponse) { + response = &DisableCcnRoutesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DisableCcnRoutes)用于禁用已经启用的云联网(CCN)路由 +func (c *Client) DisableCcnRoutes(request *DisableCcnRoutesRequest) (response *DisableCcnRoutesResponse, err error) { + if request == nil { + request = NewDisableCcnRoutesRequest() + } + response = NewDisableCcnRoutesResponse() + err = c.Send(request, response) + return +} + +func NewDisableRoutesRequest() (request *DisableRoutesRequest) { + request = &DisableRoutesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DisableRoutes") + return +} + +func NewDisableRoutesResponse() (response *DisableRoutesResponse) { + response = &DisableRoutesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DisableRoutes)用于禁用已启用的子网路由 +func (c *Client) DisableRoutes(request *DisableRoutesRequest) (response *DisableRoutesResponse, err error) { + if request == nil { + request = NewDisableRoutesRequest() + } + response = NewDisableRoutesResponse() + err = c.Send(request, response) + return +} + +func NewDisassociateAddressRequest() (request *DisassociateAddressRequest) { + request = &DisassociateAddressRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DisassociateAddress") + return +} + +func NewDisassociateAddressResponse() (response *DisassociateAddressResponse) { + response = &DisassociateAddressResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (DisassociateAddress) 用于解绑[弹性公网IP](https://cloud.tencent.com/document/product/213/1941)(简称 EIP)。 +// * 只有状态为 BIND 和 BIND_ENI 的 EIP 才能进行解绑定操作。 +// * EIP 如果被封堵,则不能进行解绑定操作。 +func (c *Client) DisassociateAddress(request *DisassociateAddressRequest) (response *DisassociateAddressResponse, err error) { + if request == nil { + request = NewDisassociateAddressRequest() + } + response = NewDisassociateAddressResponse() + err = c.Send(request, response) + return +} + +func NewDownloadCustomerGatewayConfigurationRequest() (request *DownloadCustomerGatewayConfigurationRequest) { + request = &DownloadCustomerGatewayConfigurationRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "DownloadCustomerGatewayConfiguration") + return +} + +func NewDownloadCustomerGatewayConfigurationResponse() (response *DownloadCustomerGatewayConfigurationResponse) { + response = &DownloadCustomerGatewayConfigurationResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DownloadCustomerGatewayConfiguration)用于下载VPN通道配置。 +func (c *Client) DownloadCustomerGatewayConfiguration(request *DownloadCustomerGatewayConfigurationRequest) (response *DownloadCustomerGatewayConfigurationResponse, err error) { + if request == nil { + request = NewDownloadCustomerGatewayConfigurationRequest() + } + response = NewDownloadCustomerGatewayConfigurationResponse() + err = c.Send(request, response) + return +} + +func NewEnableCcnRoutesRequest() (request *EnableCcnRoutesRequest) { + request = &EnableCcnRoutesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "EnableCcnRoutes") + return +} + +func NewEnableCcnRoutesResponse() (response *EnableCcnRoutesResponse) { + response = &EnableCcnRoutesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(EnableCcnRoutes)用于启用已经加入云联网(CCN)的路由。
    +// 本接口会校验启用后,是否与已有路由冲突,如果冲突,则无法启用,失败处理。路由冲突时,需要先禁用与之冲突的路由,才能启用该路由。 +func (c *Client) EnableCcnRoutes(request *EnableCcnRoutesRequest) (response *EnableCcnRoutesResponse, err error) { + if request == nil { + request = NewEnableCcnRoutesRequest() + } + response = NewEnableCcnRoutesResponse() + err = c.Send(request, response) + return +} + +func NewEnableRoutesRequest() (request *EnableRoutesRequest) { + request = &EnableRoutesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "EnableRoutes") + return +} + +func NewEnableRoutesResponse() (response *EnableRoutesResponse) { + response = &EnableRoutesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(EnableRoutes)用于启用已禁用的子网路由。
    +// 本接口会校验启用后,是否与已有路由冲突,如果冲突,则无法启用,失败处理。路由冲突时,需要先禁用与之冲突的路由,才能启用该路由。 +func (c *Client) EnableRoutes(request *EnableRoutesRequest) (response *EnableRoutesResponse, err error) { + if request == nil { + request = NewEnableRoutesRequest() + } + response = NewEnableRoutesResponse() + err = c.Send(request, response) + return +} + +func NewInquiryPriceCreateVpnGatewayRequest() (request *InquiryPriceCreateVpnGatewayRequest) { + request = &InquiryPriceCreateVpnGatewayRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "InquiryPriceCreateVpnGateway") + return +} + +func NewInquiryPriceCreateVpnGatewayResponse() (response *InquiryPriceCreateVpnGatewayResponse) { + response = &InquiryPriceCreateVpnGatewayResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(InquiryPriceCreateVpnGateway)用于创建VPN网关询价。 +func (c *Client) InquiryPriceCreateVpnGateway(request *InquiryPriceCreateVpnGatewayRequest) (response *InquiryPriceCreateVpnGatewayResponse, err error) { + if request == nil { + request = NewInquiryPriceCreateVpnGatewayRequest() + } + response = NewInquiryPriceCreateVpnGatewayResponse() + err = c.Send(request, response) + return +} + +func NewInquiryPriceRenewVpnGatewayRequest() (request *InquiryPriceRenewVpnGatewayRequest) { + request = &InquiryPriceRenewVpnGatewayRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "InquiryPriceRenewVpnGateway") + return +} + +func NewInquiryPriceRenewVpnGatewayResponse() (response *InquiryPriceRenewVpnGatewayResponse) { + response = &InquiryPriceRenewVpnGatewayResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(InquiryPriceRenewVpnGateway)用于续费VPN网关询价。目前仅支持IPSEC类型网关的询价。 +func (c *Client) InquiryPriceRenewVpnGateway(request *InquiryPriceRenewVpnGatewayRequest) (response *InquiryPriceRenewVpnGatewayResponse, err error) { + if request == nil { + request = NewInquiryPriceRenewVpnGatewayRequest() + } + response = NewInquiryPriceRenewVpnGatewayResponse() + err = c.Send(request, response) + return +} + +func NewInquiryPriceResetVpnGatewayInternetMaxBandwidthRequest() (request *InquiryPriceResetVpnGatewayInternetMaxBandwidthRequest) { + request = &InquiryPriceResetVpnGatewayInternetMaxBandwidthRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "InquiryPriceResetVpnGatewayInternetMaxBandwidth") + return +} + +func NewInquiryPriceResetVpnGatewayInternetMaxBandwidthResponse() (response *InquiryPriceResetVpnGatewayInternetMaxBandwidthResponse) { + response = &InquiryPriceResetVpnGatewayInternetMaxBandwidthResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(InquiryPriceResetVpnGatewayInternetMaxBandwidth)调整VPN网关带宽上限询价。 +func (c *Client) InquiryPriceResetVpnGatewayInternetMaxBandwidth(request *InquiryPriceResetVpnGatewayInternetMaxBandwidthRequest) (response *InquiryPriceResetVpnGatewayInternetMaxBandwidthResponse, err error) { + if request == nil { + request = NewInquiryPriceResetVpnGatewayInternetMaxBandwidthRequest() + } + response = NewInquiryPriceResetVpnGatewayInternetMaxBandwidthResponse() + err = c.Send(request, response) + return +} + +func NewMigrateNetworkInterfaceRequest() (request *MigrateNetworkInterfaceRequest) { + request = &MigrateNetworkInterfaceRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "MigrateNetworkInterface") + return +} + +func NewMigrateNetworkInterfaceResponse() (response *MigrateNetworkInterfaceResponse) { + response = &MigrateNetworkInterfaceResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(MigrateNetworkInterface)用于弹性网卡迁移。 +func (c *Client) MigrateNetworkInterface(request *MigrateNetworkInterfaceRequest) (response *MigrateNetworkInterfaceResponse, err error) { + if request == nil { + request = NewMigrateNetworkInterfaceRequest() + } + response = NewMigrateNetworkInterfaceResponse() + err = c.Send(request, response) + return +} + +func NewMigratePrivateIpAddressRequest() (request *MigratePrivateIpAddressRequest) { + request = &MigratePrivateIpAddressRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "MigratePrivateIpAddress") + return +} + +func NewMigratePrivateIpAddressResponse() (response *MigratePrivateIpAddressResponse) { + response = &MigratePrivateIpAddressResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(MigratePrivateIpAddress)用于弹性网卡内网IP迁移。 +// +// * 该接口用于将一个内网IP从一个弹性网卡上迁移到另外一个弹性网卡,主IP地址不支持迁移。 +// * 迁移前后的弹性网卡必须在同一个子网内。 +func (c *Client) MigratePrivateIpAddress(request *MigratePrivateIpAddressRequest) (response *MigratePrivateIpAddressResponse, err error) { + if request == nil { + request = NewMigratePrivateIpAddressRequest() + } + response = NewMigratePrivateIpAddressResponse() + err = c.Send(request, response) + return +} + +func NewModifyAddressAttributeRequest() (request *ModifyAddressAttributeRequest) { + request = &ModifyAddressAttributeRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "ModifyAddressAttribute") + return +} + +func NewModifyAddressAttributeResponse() (response *ModifyAddressAttributeResponse) { + response = &ModifyAddressAttributeResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (ModifyAddressAttribute) 用于修改[弹性公网IP](https://cloud.tencent.com/document/product/213/1941)(简称 EIP)的名称。 +func (c *Client) ModifyAddressAttribute(request *ModifyAddressAttributeRequest) (response *ModifyAddressAttributeResponse, err error) { + if request == nil { + request = NewModifyAddressAttributeRequest() + } + response = NewModifyAddressAttributeResponse() + err = c.Send(request, response) + return +} + +func NewModifyAddressTemplateAttributeRequest() (request *ModifyAddressTemplateAttributeRequest) { + request = &ModifyAddressTemplateAttributeRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "ModifyAddressTemplateAttribute") + return +} + +func NewModifyAddressTemplateAttributeResponse() (response *ModifyAddressTemplateAttributeResponse) { + response = &ModifyAddressTemplateAttributeResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 修改IP地址模板 +func (c *Client) ModifyAddressTemplateAttribute(request *ModifyAddressTemplateAttributeRequest) (response *ModifyAddressTemplateAttributeResponse, err error) { + if request == nil { + request = NewModifyAddressTemplateAttributeRequest() + } + response = NewModifyAddressTemplateAttributeResponse() + err = c.Send(request, response) + return +} + +func NewModifyAddressTemplateGroupAttributeRequest() (request *ModifyAddressTemplateGroupAttributeRequest) { + request = &ModifyAddressTemplateGroupAttributeRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "ModifyAddressTemplateGroupAttribute") + return +} + +func NewModifyAddressTemplateGroupAttributeResponse() (response *ModifyAddressTemplateGroupAttributeResponse) { + response = &ModifyAddressTemplateGroupAttributeResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 修改IP地址模板集合 +func (c *Client) ModifyAddressTemplateGroupAttribute(request *ModifyAddressTemplateGroupAttributeRequest) (response *ModifyAddressTemplateGroupAttributeResponse, err error) { + if request == nil { + request = NewModifyAddressTemplateGroupAttributeRequest() + } + response = NewModifyAddressTemplateGroupAttributeResponse() + err = c.Send(request, response) + return +} + +func NewModifyAddressesBandwidthRequest() (request *ModifyAddressesBandwidthRequest) { + request = &ModifyAddressesBandwidthRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "ModifyAddressesBandwidth") + return +} + +func NewModifyAddressesBandwidthResponse() (response *ModifyAddressesBandwidthResponse) { + response = &ModifyAddressesBandwidthResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 接口用于调整[弹性公网IP](https://cloud.tencent.com/document/product/213/1941)(简称EIP)带宽,包括后付费EIP, 预付费EIP和带宽包EIP +func (c *Client) ModifyAddressesBandwidth(request *ModifyAddressesBandwidthRequest) (response *ModifyAddressesBandwidthResponse, err error) { + if request == nil { + request = NewModifyAddressesBandwidthRequest() + } + response = NewModifyAddressesBandwidthResponse() + err = c.Send(request, response) + return +} + +func NewModifyBandwidthPackageAttributeRequest() (request *ModifyBandwidthPackageAttributeRequest) { + request = &ModifyBandwidthPackageAttributeRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "ModifyBandwidthPackageAttribute") + return +} + +func NewModifyBandwidthPackageAttributeResponse() (response *ModifyBandwidthPackageAttributeResponse) { + response = &ModifyBandwidthPackageAttributeResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 接口用于修改带宽包属性,包括带宽包名字等 +func (c *Client) ModifyBandwidthPackageAttribute(request *ModifyBandwidthPackageAttributeRequest) (response *ModifyBandwidthPackageAttributeResponse, err error) { + if request == nil { + request = NewModifyBandwidthPackageAttributeRequest() + } + response = NewModifyBandwidthPackageAttributeResponse() + err = c.Send(request, response) + return +} + +func NewModifyCcnAttributeRequest() (request *ModifyCcnAttributeRequest) { + request = &ModifyCcnAttributeRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "ModifyCcnAttribute") + return +} + +func NewModifyCcnAttributeResponse() (response *ModifyCcnAttributeResponse) { + response = &ModifyCcnAttributeResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ModifyCcnAttribute)用于修改云联网(CCN)的相关属性。 +func (c *Client) ModifyCcnAttribute(request *ModifyCcnAttributeRequest) (response *ModifyCcnAttributeResponse, err error) { + if request == nil { + request = NewModifyCcnAttributeRequest() + } + response = NewModifyCcnAttributeResponse() + err = c.Send(request, response) + return +} + +func NewModifyCustomerGatewayAttributeRequest() (request *ModifyCustomerGatewayAttributeRequest) { + request = &ModifyCustomerGatewayAttributeRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "ModifyCustomerGatewayAttribute") + return +} + +func NewModifyCustomerGatewayAttributeResponse() (response *ModifyCustomerGatewayAttributeResponse) { + response = &ModifyCustomerGatewayAttributeResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ModifyCustomerGatewayAttribute)用于修改对端网关信息。 +func (c *Client) ModifyCustomerGatewayAttribute(request *ModifyCustomerGatewayAttributeRequest) (response *ModifyCustomerGatewayAttributeResponse, err error) { + if request == nil { + request = NewModifyCustomerGatewayAttributeRequest() + } + response = NewModifyCustomerGatewayAttributeResponse() + err = c.Send(request, response) + return +} + +func NewModifyNetworkInterfaceAttributeRequest() (request *ModifyNetworkInterfaceAttributeRequest) { + request = &ModifyNetworkInterfaceAttributeRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "ModifyNetworkInterfaceAttribute") + return +} + +func NewModifyNetworkInterfaceAttributeResponse() (response *ModifyNetworkInterfaceAttributeResponse) { + response = &ModifyNetworkInterfaceAttributeResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ModifyNetworkInterfaceAttribute)用于修改弹性网卡属性。 +func (c *Client) ModifyNetworkInterfaceAttribute(request *ModifyNetworkInterfaceAttributeRequest) (response *ModifyNetworkInterfaceAttributeResponse, err error) { + if request == nil { + request = NewModifyNetworkInterfaceAttributeRequest() + } + response = NewModifyNetworkInterfaceAttributeResponse() + err = c.Send(request, response) + return +} + +func NewModifyPrivateIpAddressesAttributeRequest() (request *ModifyPrivateIpAddressesAttributeRequest) { + request = &ModifyPrivateIpAddressesAttributeRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "ModifyPrivateIpAddressesAttribute") + return +} + +func NewModifyPrivateIpAddressesAttributeResponse() (response *ModifyPrivateIpAddressesAttributeResponse) { + response = &ModifyPrivateIpAddressesAttributeResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ModifyPrivateIpAddressesAttribute)用于修改弹性网卡内网IP属性。 +func (c *Client) ModifyPrivateIpAddressesAttribute(request *ModifyPrivateIpAddressesAttributeRequest) (response *ModifyPrivateIpAddressesAttributeResponse, err error) { + if request == nil { + request = NewModifyPrivateIpAddressesAttributeRequest() + } + response = NewModifyPrivateIpAddressesAttributeResponse() + err = c.Send(request, response) + return +} + +func NewModifyRouteTableAttributeRequest() (request *ModifyRouteTableAttributeRequest) { + request = &ModifyRouteTableAttributeRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "ModifyRouteTableAttribute") + return +} + +func NewModifyRouteTableAttributeResponse() (response *ModifyRouteTableAttributeResponse) { + response = &ModifyRouteTableAttributeResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ModifyRouteTableAttribute)用于修改路由表(RouteTable)属性。 +func (c *Client) ModifyRouteTableAttribute(request *ModifyRouteTableAttributeRequest) (response *ModifyRouteTableAttributeResponse, err error) { + if request == nil { + request = NewModifyRouteTableAttributeRequest() + } + response = NewModifyRouteTableAttributeResponse() + err = c.Send(request, response) + return +} + +func NewModifySecurityGroupAttributeRequest() (request *ModifySecurityGroupAttributeRequest) { + request = &ModifySecurityGroupAttributeRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "ModifySecurityGroupAttribute") + return +} + +func NewModifySecurityGroupAttributeResponse() (response *ModifySecurityGroupAttributeResponse) { + response = &ModifySecurityGroupAttributeResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ModifySecurityGroupAttribute)用于修改安全组(SecurityGroupPolicy)属性。 +func (c *Client) ModifySecurityGroupAttribute(request *ModifySecurityGroupAttributeRequest) (response *ModifySecurityGroupAttributeResponse, err error) { + if request == nil { + request = NewModifySecurityGroupAttributeRequest() + } + response = NewModifySecurityGroupAttributeResponse() + err = c.Send(request, response) + return +} + +func NewModifySecurityGroupPoliciesRequest() (request *ModifySecurityGroupPoliciesRequest) { + request = &ModifySecurityGroupPoliciesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "ModifySecurityGroupPolicies") + return +} + +func NewModifySecurityGroupPoliciesResponse() (response *ModifySecurityGroupPoliciesResponse) { + response = &ModifySecurityGroupPoliciesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ModifySecurityGroupPolicies)用于重置安全组出站和入站规则(SecurityGroupPolicy)。 +// +// * 接口是先删除当前所有的出入站规则,然后再添加 Egress 和 Ingress 规则,不支持自定义索引 PolicyIndex 。 +// * 如果指定 SecurityGroupPolicySet.Version 为0, 表示清空所有规则,并忽略Egress和Ingress。 +// * Protocol字段支持输入TCP, UDP, ICMP, GRE, ALL。 +// * CidrBlock字段允许输入符合cidr格式标准的任意字符串。(展开)在基础网络中,如果CidrBlock包含您的账户内的云服务器之外的设备在腾讯云的内网IP,并不代表此规则允许您访问这些设备,租户之间网络隔离规则优先于安全组中的内网规则。 +// * SecurityGroupId字段允许输入与待修改的安全组位于相同项目中的安全组ID,包括这个安全组ID本身,代表安全组下所有云服务器的内网IP。使用这个字段时,这条规则用来匹配网络报文的过程中会随着被使用的这个ID所关联的云服务器变化而变化,不需要重新修改。 +// * Port字段允许输入一个单独端口号,或者用减号分隔的两个端口号代表端口范围,例如80或8000-8010。只有当Protocol字段是TCP或UDP时,Port字段才被接受。 +// * Action字段只允许输入ACCEPT或DROP。 +// * CidrBlock, SecurityGroupId, AddressTemplate三者是排他关系,不允许同时输入,Protocol + Port和ServiceTemplate二者是排他关系,不允许同时输入。 +func (c *Client) ModifySecurityGroupPolicies(request *ModifySecurityGroupPoliciesRequest) (response *ModifySecurityGroupPoliciesResponse, err error) { + if request == nil { + request = NewModifySecurityGroupPoliciesRequest() + } + response = NewModifySecurityGroupPoliciesResponse() + err = c.Send(request, response) + return +} + +func NewModifyServiceTemplateAttributeRequest() (request *ModifyServiceTemplateAttributeRequest) { + request = &ModifyServiceTemplateAttributeRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "ModifyServiceTemplateAttribute") + return +} + +func NewModifyServiceTemplateAttributeResponse() (response *ModifyServiceTemplateAttributeResponse) { + response = &ModifyServiceTemplateAttributeResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 修改协议端口模板 +func (c *Client) ModifyServiceTemplateAttribute(request *ModifyServiceTemplateAttributeRequest) (response *ModifyServiceTemplateAttributeResponse, err error) { + if request == nil { + request = NewModifyServiceTemplateAttributeRequest() + } + response = NewModifyServiceTemplateAttributeResponse() + err = c.Send(request, response) + return +} + +func NewModifyServiceTemplateGroupAttributeRequest() (request *ModifyServiceTemplateGroupAttributeRequest) { + request = &ModifyServiceTemplateGroupAttributeRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "ModifyServiceTemplateGroupAttribute") + return +} + +func NewModifyServiceTemplateGroupAttributeResponse() (response *ModifyServiceTemplateGroupAttributeResponse) { + response = &ModifyServiceTemplateGroupAttributeResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ModifyServiceTemplateGroupAttribute)用于修改协议端口模板集合。 +func (c *Client) ModifyServiceTemplateGroupAttribute(request *ModifyServiceTemplateGroupAttributeRequest) (response *ModifyServiceTemplateGroupAttributeResponse, err error) { + if request == nil { + request = NewModifyServiceTemplateGroupAttributeRequest() + } + response = NewModifyServiceTemplateGroupAttributeResponse() + err = c.Send(request, response) + return +} + +func NewModifySubnetAttributeRequest() (request *ModifySubnetAttributeRequest) { + request = &ModifySubnetAttributeRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "ModifySubnetAttribute") + return +} + +func NewModifySubnetAttributeResponse() (response *ModifySubnetAttributeResponse) { + response = &ModifySubnetAttributeResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ModifySubnetAttribute)用于修改子网属性。 +func (c *Client) ModifySubnetAttribute(request *ModifySubnetAttributeRequest) (response *ModifySubnetAttributeResponse, err error) { + if request == nil { + request = NewModifySubnetAttributeRequest() + } + response = NewModifySubnetAttributeResponse() + err = c.Send(request, response) + return +} + +func NewModifyVpcAttributeRequest() (request *ModifyVpcAttributeRequest) { + request = &ModifyVpcAttributeRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "ModifyVpcAttribute") + return +} + +func NewModifyVpcAttributeResponse() (response *ModifyVpcAttributeResponse) { + response = &ModifyVpcAttributeResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ModifyVpcAttribute)用于修改私有网络(VPC)的相关属性。 +func (c *Client) ModifyVpcAttribute(request *ModifyVpcAttributeRequest) (response *ModifyVpcAttributeResponse, err error) { + if request == nil { + request = NewModifyVpcAttributeRequest() + } + response = NewModifyVpcAttributeResponse() + err = c.Send(request, response) + return +} + +func NewModifyVpnConnectionAttributeRequest() (request *ModifyVpnConnectionAttributeRequest) { + request = &ModifyVpnConnectionAttributeRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "ModifyVpnConnectionAttribute") + return +} + +func NewModifyVpnConnectionAttributeResponse() (response *ModifyVpnConnectionAttributeResponse) { + response = &ModifyVpnConnectionAttributeResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ModifyVpnConnectionAttribute)用于修改VPN通道。 +func (c *Client) ModifyVpnConnectionAttribute(request *ModifyVpnConnectionAttributeRequest) (response *ModifyVpnConnectionAttributeResponse, err error) { + if request == nil { + request = NewModifyVpnConnectionAttributeRequest() + } + response = NewModifyVpnConnectionAttributeResponse() + err = c.Send(request, response) + return +} + +func NewModifyVpnGatewayAttributeRequest() (request *ModifyVpnGatewayAttributeRequest) { + request = &ModifyVpnGatewayAttributeRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "ModifyVpnGatewayAttribute") + return +} + +func NewModifyVpnGatewayAttributeResponse() (response *ModifyVpnGatewayAttributeResponse) { + response = &ModifyVpnGatewayAttributeResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ModifyVpnGatewayAttribute)用于修改VPN网关属性。 +func (c *Client) ModifyVpnGatewayAttribute(request *ModifyVpnGatewayAttributeRequest) (response *ModifyVpnGatewayAttributeResponse, err error) { + if request == nil { + request = NewModifyVpnGatewayAttributeRequest() + } + response = NewModifyVpnGatewayAttributeResponse() + err = c.Send(request, response) + return +} + +func NewRejectAttachCcnInstancesRequest() (request *RejectAttachCcnInstancesRequest) { + request = &RejectAttachCcnInstancesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "RejectAttachCcnInstances") + return +} + +func NewRejectAttachCcnInstancesResponse() (response *RejectAttachCcnInstancesResponse) { + response = &RejectAttachCcnInstancesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(RejectAttachCcnInstances)用于跨账号关联实例时,云联网所有者拒绝关联操作。 +func (c *Client) RejectAttachCcnInstances(request *RejectAttachCcnInstancesRequest) (response *RejectAttachCcnInstancesResponse, err error) { + if request == nil { + request = NewRejectAttachCcnInstancesRequest() + } + response = NewRejectAttachCcnInstancesResponse() + err = c.Send(request, response) + return +} + +func NewReleaseAddressesRequest() (request *ReleaseAddressesRequest) { + request = &ReleaseAddressesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "ReleaseAddresses") + return +} + +func NewReleaseAddressesResponse() (response *ReleaseAddressesResponse) { + response = &ReleaseAddressesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (ReleaseAddresses) 用于释放一个或多个[弹性公网IP](https://cloud.tencent.com/document/product/213/1941)(简称 EIP)。 +// * 该操作不可逆,释放后 EIP 关联的 IP 地址将不再属于您的名下。 +// * 只有状态为 UNBIND 的 EIP 才能进行释放操作。 +func (c *Client) ReleaseAddresses(request *ReleaseAddressesRequest) (response *ReleaseAddressesResponse, err error) { + if request == nil { + request = NewReleaseAddressesRequest() + } + response = NewReleaseAddressesResponse() + err = c.Send(request, response) + return +} + +func NewRemoveBandwidthPackageResourcesRequest() (request *RemoveBandwidthPackageResourcesRequest) { + request = &RemoveBandwidthPackageResourcesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "RemoveBandwidthPackageResources") + return +} + +func NewRemoveBandwidthPackageResourcesResponse() (response *RemoveBandwidthPackageResourcesResponse) { + response = &RemoveBandwidthPackageResourcesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 接口用于删除带宽包资源,包括[弹性公网IP](https://cloud.tencent.com/document/product/213/1941)和[负载均衡](https://cloud.tencent.com/document/product/214/517)等 +func (c *Client) RemoveBandwidthPackageResources(request *RemoveBandwidthPackageResourcesRequest) (response *RemoveBandwidthPackageResourcesResponse, err error) { + if request == nil { + request = NewRemoveBandwidthPackageResourcesRequest() + } + response = NewRemoveBandwidthPackageResourcesResponse() + err = c.Send(request, response) + return +} + +func NewRenewVpnGatewayRequest() (request *RenewVpnGatewayRequest) { + request = &RenewVpnGatewayRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "RenewVpnGateway") + return +} + +func NewRenewVpnGatewayResponse() (response *RenewVpnGatewayResponse) { + response = &RenewVpnGatewayResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(RenewVpnGateway)用于预付费(包年包月)VPN网关续费。目前只支持IPSEC网关。 +func (c *Client) RenewVpnGateway(request *RenewVpnGatewayRequest) (response *RenewVpnGatewayResponse, err error) { + if request == nil { + request = NewRenewVpnGatewayRequest() + } + response = NewRenewVpnGatewayResponse() + err = c.Send(request, response) + return +} + +func NewReplaceDirectConnectGatewayCcnRoutesRequest() (request *ReplaceDirectConnectGatewayCcnRoutesRequest) { + request = &ReplaceDirectConnectGatewayCcnRoutesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "ReplaceDirectConnectGatewayCcnRoutes") + return +} + +func NewReplaceDirectConnectGatewayCcnRoutesResponse() (response *ReplaceDirectConnectGatewayCcnRoutesResponse) { + response = &ReplaceDirectConnectGatewayCcnRoutesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ReplaceDirectConnectGatewayCcnRoutes)根据路由ID(RouteId)修改指定的路由(Route),支持批量修改。 +func (c *Client) ReplaceDirectConnectGatewayCcnRoutes(request *ReplaceDirectConnectGatewayCcnRoutesRequest) (response *ReplaceDirectConnectGatewayCcnRoutesResponse, err error) { + if request == nil { + request = NewReplaceDirectConnectGatewayCcnRoutesRequest() + } + response = NewReplaceDirectConnectGatewayCcnRoutesResponse() + err = c.Send(request, response) + return +} + +func NewReplaceRouteTableAssociationRequest() (request *ReplaceRouteTableAssociationRequest) { + request = &ReplaceRouteTableAssociationRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "ReplaceRouteTableAssociation") + return +} + +func NewReplaceRouteTableAssociationResponse() (response *ReplaceRouteTableAssociationResponse) { + response = &ReplaceRouteTableAssociationResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ReplaceRouteTableAssociation)用于修改子网(Subnet)关联的路由表(RouteTable)。 +// * 一个子网只能关联一个路由表。 +func (c *Client) ReplaceRouteTableAssociation(request *ReplaceRouteTableAssociationRequest) (response *ReplaceRouteTableAssociationResponse, err error) { + if request == nil { + request = NewReplaceRouteTableAssociationRequest() + } + response = NewReplaceRouteTableAssociationResponse() + err = c.Send(request, response) + return +} + +func NewReplaceRoutesRequest() (request *ReplaceRoutesRequest) { + request = &ReplaceRoutesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "ReplaceRoutes") + return +} + +func NewReplaceRoutesResponse() (response *ReplaceRoutesResponse) { + response = &ReplaceRoutesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ReplaceRoutes)根据路由策略ID(RouteId)修改指定的路由策略(Route),支持批量修改。 +func (c *Client) ReplaceRoutes(request *ReplaceRoutesRequest) (response *ReplaceRoutesResponse, err error) { + if request == nil { + request = NewReplaceRoutesRequest() + } + response = NewReplaceRoutesResponse() + err = c.Send(request, response) + return +} + +func NewReplaceSecurityGroupPolicyRequest() (request *ReplaceSecurityGroupPolicyRequest) { + request = &ReplaceSecurityGroupPolicyRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "ReplaceSecurityGroupPolicy") + return +} + +func NewReplaceSecurityGroupPolicyResponse() (response *ReplaceSecurityGroupPolicyResponse) { + response = &ReplaceSecurityGroupPolicyResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ReplaceSecurityGroupPolicy)用于替换单条安全组规则(SecurityGroupPolicy)。 +// 单个请求中只能替换单个方向的一条规则, 必须要指定索引(PolicyIndex)。 +func (c *Client) ReplaceSecurityGroupPolicy(request *ReplaceSecurityGroupPolicyRequest) (response *ReplaceSecurityGroupPolicyResponse, err error) { + if request == nil { + request = NewReplaceSecurityGroupPolicyRequest() + } + response = NewReplaceSecurityGroupPolicyResponse() + err = c.Send(request, response) + return +} + +func NewResetAttachCcnInstancesRequest() (request *ResetAttachCcnInstancesRequest) { + request = &ResetAttachCcnInstancesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "ResetAttachCcnInstances") + return +} + +func NewResetAttachCcnInstancesResponse() (response *ResetAttachCcnInstancesResponse) { + response = &ResetAttachCcnInstancesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ResetAttachCcnInstances)用于跨账号关联实例申请过期时,重新申请关联操作。 +func (c *Client) ResetAttachCcnInstances(request *ResetAttachCcnInstancesRequest) (response *ResetAttachCcnInstancesResponse, err error) { + if request == nil { + request = NewResetAttachCcnInstancesRequest() + } + response = NewResetAttachCcnInstancesResponse() + err = c.Send(request, response) + return +} + +func NewResetRoutesRequest() (request *ResetRoutesRequest) { + request = &ResetRoutesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "ResetRoutes") + return +} + +func NewResetRoutesResponse() (response *ResetRoutesResponse) { + response = &ResetRoutesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ResetRoutes)用于对某个路由表名称和所有路由策略(Route)进行重新设置。
    +// 注意: 调用本接口是先删除当前路由表中所有路由策略, 再保存新提交的路由策略内容, 会引起网络中断。 +func (c *Client) ResetRoutes(request *ResetRoutesRequest) (response *ResetRoutesResponse, err error) { + if request == nil { + request = NewResetRoutesRequest() + } + response = NewResetRoutesResponse() + err = c.Send(request, response) + return +} + +func NewResetVpnConnectionRequest() (request *ResetVpnConnectionRequest) { + request = &ResetVpnConnectionRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "ResetVpnConnection") + return +} + +func NewResetVpnConnectionResponse() (response *ResetVpnConnectionResponse) { + response = &ResetVpnConnectionResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ResetVpnConnection)用于重置VPN通道。 +func (c *Client) ResetVpnConnection(request *ResetVpnConnectionRequest) (response *ResetVpnConnectionResponse, err error) { + if request == nil { + request = NewResetVpnConnectionRequest() + } + response = NewResetVpnConnectionResponse() + err = c.Send(request, response) + return +} + +func NewResetVpnGatewayInternetMaxBandwidthRequest() (request *ResetVpnGatewayInternetMaxBandwidthRequest) { + request = &ResetVpnGatewayInternetMaxBandwidthRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "ResetVpnGatewayInternetMaxBandwidth") + return +} + +func NewResetVpnGatewayInternetMaxBandwidthResponse() (response *ResetVpnGatewayInternetMaxBandwidthResponse) { + response = &ResetVpnGatewayInternetMaxBandwidthResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ResetVpnGatewayInternetMaxBandwidth)调整VPN网关带宽上限。目前支持升级配置,如果是包年包月VPN网关需要在有效期内。 +func (c *Client) ResetVpnGatewayInternetMaxBandwidth(request *ResetVpnGatewayInternetMaxBandwidthRequest) (response *ResetVpnGatewayInternetMaxBandwidthResponse, err error) { + if request == nil { + request = NewResetVpnGatewayInternetMaxBandwidthRequest() + } + response = NewResetVpnGatewayInternetMaxBandwidthResponse() + err = c.Send(request, response) + return +} + +func NewSetCcnRegionBandwidthLimitsRequest() (request *SetCcnRegionBandwidthLimitsRequest) { + request = &SetCcnRegionBandwidthLimitsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "SetCcnRegionBandwidthLimits") + return +} + +func NewSetCcnRegionBandwidthLimitsResponse() (response *SetCcnRegionBandwidthLimitsResponse) { + response = &SetCcnRegionBandwidthLimitsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(SetCcnRegionBandwidthLimits)用于设置云联网(CCN)各地域出带宽上限,该接口只能设置已关联网络实例包含的地域的出带宽上限 +func (c *Client) SetCcnRegionBandwidthLimits(request *SetCcnRegionBandwidthLimitsRequest) (response *SetCcnRegionBandwidthLimitsResponse, err error) { + if request == nil { + request = NewSetCcnRegionBandwidthLimitsRequest() + } + response = NewSetCcnRegionBandwidthLimitsResponse() + err = c.Send(request, response) + return +} + +func NewTransformAddressRequest() (request *TransformAddressRequest) { + request = &TransformAddressRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "TransformAddress") + return +} + +func NewTransformAddressResponse() (response *TransformAddressResponse) { + response = &TransformAddressResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口 (TransformAddress) 用于将实例的普通公网 IP 转换为[弹性公网IP](https://cloud.tencent.com/document/product/213/1941)(简称 EIP)。 +// * 平台对用户每地域每日解绑 EIP 重新分配普通公网 IP 次数有所限制(可参见 [EIP 产品简介](/document/product/213/1941))。上述配额可通过 [DescribeAddressQuota](https://cloud.tencent.com/document/api/213/1378) 接口获取。 +func (c *Client) TransformAddress(request *TransformAddressRequest) (response *TransformAddressResponse, err error) { + if request == nil { + request = NewTransformAddressRequest() + } + response = NewTransformAddressResponse() + err = c.Send(request, response) + return +} + +func NewUnassignPrivateIpAddressesRequest() (request *UnassignPrivateIpAddressesRequest) { + request = &UnassignPrivateIpAddressesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("vpc", APIVersion, "UnassignPrivateIpAddresses") + return +} + +func NewUnassignPrivateIpAddressesResponse() (response *UnassignPrivateIpAddressesResponse) { + response = &UnassignPrivateIpAddressesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(UnassignPrivateIpAddresses)用于弹性网卡退还内网 IP。 +// * 退还弹性网卡上的辅助内网IP,接口自动解关联弹性公网 IP。不能退还弹性网卡的主内网IP。 +func (c *Client) UnassignPrivateIpAddresses(request *UnassignPrivateIpAddressesRequest) (response *UnassignPrivateIpAddressesResponse, err error) { + if request == nil { + request = NewUnassignPrivateIpAddressesRequest() + } + response = NewUnassignPrivateIpAddressesResponse() + err = c.Send(request, response) + return +} diff --git a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312/models.go b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312/models.go new file mode 100644 index 000000000..8ee915479 --- /dev/null +++ b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312/models.go @@ -0,0 +1,5024 @@ +// Copyright (c) 2017-2018 THL A29 Limited, a Tencent company. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v20170312 + +import ( + "encoding/json" + + tchttp "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http" +) + +type AcceptAttachCcnInstancesRequest struct { + *tchttp.BaseRequest + // CCN实例ID。形如:ccn-f49l6u0z。 + CcnId *string `json:"CcnId" name:"CcnId"` + // 接受关联实例列表。 + Instances []*CcnInstance `json:"Instances" name:"Instances" list` +} + +func (r *AcceptAttachCcnInstancesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AcceptAttachCcnInstancesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type AcceptAttachCcnInstancesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *AcceptAttachCcnInstancesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AcceptAttachCcnInstancesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type AccountAttribute struct { + // 属性名 + AttributeName *string `json:"AttributeName" name:"AttributeName"` + // 属性值 + AttributeValues []*string `json:"AttributeValues" name:"AttributeValues" list` +} + +type AddBandwidthPackageResourcesRequest struct { + *tchttp.BaseRequest + // 资源Id,形如'eip-xxxx', 'lb-xxxx' + ResourceIds []*string `json:"ResourceIds" name:"ResourceIds" list` + // 带宽包唯一标识ID,形如'bwp-xxxx' + BandwidthPackageId *string `json:"BandwidthPackageId" name:"BandwidthPackageId"` + // 带宽包类型,包括'BGP', 'SINGLEISP', 'ANYCAST' + NetworkType *string `json:"NetworkType" name:"NetworkType"` + // 资源类型,包括'Address', 'LoadBalance' + ResourceType *string `json:"ResourceType" name:"ResourceType"` +} + +func (r *AddBandwidthPackageResourcesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AddBandwidthPackageResourcesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type AddBandwidthPackageResourcesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *AddBandwidthPackageResourcesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AddBandwidthPackageResourcesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type Address struct { + // `EIP`的`ID`,是`EIP`的唯一标识。 + AddressId *string `json:"AddressId" name:"AddressId"` + // `EIP`名称。 + AddressName *string `json:"AddressName" name:"AddressName"` + // `EIP`状态。 + AddressStatus *string `json:"AddressStatus" name:"AddressStatus"` + // 外网IP地址 + AddressIp *string `json:"AddressIp" name:"AddressIp"` + // 绑定的资源实例`ID`。可能是一个`CVM`,`NAT`。 + InstanceId *string `json:"InstanceId" name:"InstanceId"` + // 创建时间。按照`ISO8601`标准表示,并且使用`UTC`时间。格式为:`YYYY-MM-DDThh:mm:ssZ`。 + CreatedTime *string `json:"CreatedTime" name:"CreatedTime"` + // 绑定的弹性网卡ID + NetworkInterfaceId *string `json:"NetworkInterfaceId" name:"NetworkInterfaceId"` + // 绑定的资源内网ip + PrivateAddressIp *string `json:"PrivateAddressIp" name:"PrivateAddressIp"` + // 资源隔离状态。true表示eip处于隔离状态,false表示资源处于未隔离装填 + IsArrears *bool `json:"IsArrears" name:"IsArrears"` + // 资源封堵状态。true表示eip处于封堵状态,false表示eip处于未封堵状态 + IsBlocked *bool `json:"IsBlocked" name:"IsBlocked"` + // eip是否支持直通模式。true表示eip支持直通模式,false表示资源不支持直通模式 + IsEipDirectConnection *bool `json:"IsEipDirectConnection" name:"IsEipDirectConnection"` + // eip资源类型,包括"CalcIP","WanIP","EIP","AnycastEIP"。其中"CalcIP"表示设备ip,“WanIP”表示普通公网ip,“EIP”表示弹性公网ip,“AnycastEip”表示加速EIP + AddressType *string `json:"AddressType" name:"AddressType"` + // eip是否在解绑后自动释放。true表示eip将会在解绑后自动释放,false表示eip在解绑后不会自动释放 + CascadeRelease *bool `json:"CascadeRelease" name:"CascadeRelease"` +} + +type AddressTemplate struct { + // IP地址模板名称。 + AddressTemplateName *string `json:"AddressTemplateName" name:"AddressTemplateName"` + // IP地址模板实例唯一ID。 + AddressTemplateId *string `json:"AddressTemplateId" name:"AddressTemplateId"` + // IP地址信息。 + AddressSet []*string `json:"AddressSet" name:"AddressSet" list` + // 创建时间。 + CreatedTime *string `json:"CreatedTime" name:"CreatedTime"` +} + +type AddressTemplateGroup struct { + // IP地址模板集合名称。 + AddressTemplateGroupName *string `json:"AddressTemplateGroupName" name:"AddressTemplateGroupName"` + // IP地址模板集合实例ID,例如:ipmg-dih8xdbq。 + AddressTemplateGroupId *string `json:"AddressTemplateGroupId" name:"AddressTemplateGroupId"` + // IP地址模板ID。 + AddressTemplateIdSet []*string `json:"AddressTemplateIdSet" name:"AddressTemplateIdSet" list` + // 创建时间。 + CreatedTime *string `json:"CreatedTime" name:"CreatedTime"` +} + +type AddressTemplateSpecification struct { + // IP地址ID,例如:ipm-2uw6ujo6。 + AddressId *string `json:"AddressId" name:"AddressId"` + // IP地址组ID,例如:ipmg-2uw6ujo6。 + AddressGroupId *string `json:"AddressGroupId" name:"AddressGroupId"` +} + +type AllocateAddressesRequest struct { + *tchttp.BaseRequest + // 申请 EIP 数量,默认值为1。 + AddressCount *int64 `json:"AddressCount" name:"AddressCount"` +} + +func (r *AllocateAddressesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AllocateAddressesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type AllocateAddressesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 申请到的 EIP 的唯一 ID 列表。 + AddressSet []*string `json:"AddressSet" name:"AddressSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *AllocateAddressesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AllocateAddressesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type AssignPrivateIpAddressesRequest struct { + *tchttp.BaseRequest + // 弹性网卡实例ID,例如:eni-m6dyj72l。 + NetworkInterfaceId *string `json:"NetworkInterfaceId" name:"NetworkInterfaceId"` + // 指定的内网IP信息。 + PrivateIpAddresses []*PrivateIpAddressSpecification `json:"PrivateIpAddresses" name:"PrivateIpAddresses" list` + // 新申请的内网IP地址个数。 + SecondaryPrivateIpAddressCount *uint64 `json:"SecondaryPrivateIpAddressCount" name:"SecondaryPrivateIpAddressCount"` +} + +func (r *AssignPrivateIpAddressesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AssignPrivateIpAddressesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type AssignPrivateIpAddressesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 内网IP详细信息。 + PrivateIpAddressSet []*PrivateIpAddressSpecification `json:"PrivateIpAddressSet" name:"PrivateIpAddressSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *AssignPrivateIpAddressesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AssignPrivateIpAddressesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type AssociateAddressRequest struct { + *tchttp.BaseRequest + // 标识 EIP 的唯一 ID。EIP 唯一 ID 形如:`eip-11112222`。 + AddressId *string `json:"AddressId" name:"AddressId"` + // 要绑定的实例 ID。实例 ID 形如:`ins-11112222`。可通过登录[控制台](https://console.cloud.tencent.com/cvm)查询,也可通过 [DescribeInstances](https://cloud.tencent.com/document/api/213/9389) 接口返回值中的`InstanceId`获取。 + InstanceId *string `json:"InstanceId" name:"InstanceId"` + // 要绑定的弹性网卡 ID。 弹性网卡 ID 形如:`eni-11112222`。`NetworkInterfaceId` 与 `InstanceId` 不可同时指定。弹性网卡 ID 可通过登录[控制台](https://console.cloud.tencent.com/vpc/eni)查询,也可通过[DescribeNetworkInterfaces](https://cloud.tencent.com/document/api/215/4814)接口返回值中的`networkInterfaceId`获取。 + NetworkInterfaceId *string `json:"NetworkInterfaceId" name:"NetworkInterfaceId"` + // 要绑定的内网 IP。如果指定了 `NetworkInterfaceId` 则也必须指定 `PrivateIpAddress` ,表示将 EIP 绑定到指定弹性网卡的指定内网 IP 上。同时要确保指定的 `PrivateIpAddress` 是指定的 `NetworkInterfaceId` 上的一个内网 IP。指定弹性网卡的内网 IP 可通过登录[控制台](https://console.cloud.tencent.com/vpc/eni)查询,也可通过[DescribeNetworkInterfaces](https://cloud.tencent.com/document/api/215/4814)接口返回值中的`privateIpAddress`获取。 + PrivateIpAddress *string `json:"PrivateIpAddress" name:"PrivateIpAddress"` +} + +func (r *AssociateAddressRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AssociateAddressRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type AssociateAddressResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *AssociateAddressResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AssociateAddressResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type AttachCcnInstancesRequest struct { + *tchttp.BaseRequest + // CCN实例ID。形如:ccn-f49l6u0z。 + CcnId *string `json:"CcnId" name:"CcnId"` + // 关联网络实例列表 + Instances []*CcnInstance `json:"Instances" name:"Instances" list` + // CCN所属UIN(根账号),默认当前账号所属UIN + CcnUin *string `json:"CcnUin" name:"CcnUin"` +} + +func (r *AttachCcnInstancesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AttachCcnInstancesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type AttachCcnInstancesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *AttachCcnInstancesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AttachCcnInstancesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type AttachClassicLinkVpcRequest struct { + *tchttp.BaseRequest + // VPC实例ID + VpcId *string `json:"VpcId" name:"VpcId"` + // CVM实例ID + InstanceIds []*string `json:"InstanceIds" name:"InstanceIds" list` +} + +func (r *AttachClassicLinkVpcRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AttachClassicLinkVpcRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type AttachClassicLinkVpcResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *AttachClassicLinkVpcResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AttachClassicLinkVpcResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type AttachNetworkInterfaceRequest struct { + *tchttp.BaseRequest + // 弹性网卡实例ID,例如:eni-m6dyj72l。 + NetworkInterfaceId *string `json:"NetworkInterfaceId" name:"NetworkInterfaceId"` + // CVM实例ID。形如:ins-r8hr2upy。 + InstanceId *string `json:"InstanceId" name:"InstanceId"` +} + +func (r *AttachNetworkInterfaceRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AttachNetworkInterfaceRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type AttachNetworkInterfaceResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *AttachNetworkInterfaceResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AttachNetworkInterfaceResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type BandwidthPackage struct { + // 带宽包唯一标识Id + BandwidthPackageId *string `json:"BandwidthPackageId" name:"BandwidthPackageId"` + // 带宽包类型,包括'BGP','SINGLEISP','ANYCAST' + NetworkType *string `json:"NetworkType" name:"NetworkType"` + // 带宽包计费类型,包括'TOP5_POSTPAID_BY_MONTH'和'PERCENT95_POSTPAID_BY_MONTH' + ChargeType *string `json:"ChargeType" name:"ChargeType"` + // 带宽包名称 + BandwidthPackageName *string `json:"BandwidthPackageName" name:"BandwidthPackageName"` + // 带宽包创建时间。按照`ISO8601`标准表示,并且使用`UTC`时间。格式为:`YYYY-MM-DDThh:mm:ssZ`。 + CreatedTime *string `json:"CreatedTime" name:"CreatedTime"` + // 带宽包状态,包括'CREATING','CREATED','DELETING','DELETED' + Status *string `json:"Status" name:"Status"` + // 带宽包资源信息 + ResourceSet []*Resource `json:"ResourceSet" name:"ResourceSet" list` +} + +type CCN struct { + // 云联网唯一ID + CcnId *string `json:"CcnId" name:"CcnId"` + // 云联网名称 + CcnName *string `json:"CcnName" name:"CcnName"` + // 云联网描述信息 + CcnDescription *string `json:"CcnDescription" name:"CcnDescription"` + // 关联实例数量 + InstanceCount *uint64 `json:"InstanceCount" name:"InstanceCount"` + // 创建时间 + CreateTime *string `json:"CreateTime" name:"CreateTime"` + // 实例状态, 'ISOLATED': 隔离中(欠费停服),'AVAILABLE':运行中。 + State *string `json:"State" name:"State"` +} + +type CcnAttachedInstance struct { + // 云联网实例ID + CcnId *string `json:"CcnId" name:"CcnId"` + // 关联实例类型,可选值:VPC、DIRECTCONNECT + InstanceType *string `json:"InstanceType" name:"InstanceType"` + // 关联实例ID + InstanceId *string `json:"InstanceId" name:"InstanceId"` + // 关联实例名称 + InstanceName *string `json:"InstanceName" name:"InstanceName"` + // 关联实例所属大区,例如:ap-guangzhou + InstanceRegion *string `json:"InstanceRegion" name:"InstanceRegion"` + // 关联实例所属UIN(根账号) + InstanceUin *string `json:"InstanceUin" name:"InstanceUin"` + // 关联实例CIDR + CidrBlock []*string `json:"CidrBlock" name:"CidrBlock" list` + // 关联实例状态: + // PENDING:申请中 + // ACTIVE:已连接 + // EXPIRED:已过期 + // REJECTED:已拒绝 + // DELETED:已删除 + State *string `json:"State" name:"State"` + // 关联时间 + AttachedTime *string `json:"AttachedTime" name:"AttachedTime"` + // 云联网所属UIN(根账号) + CcnUin *string `json:"CcnUin" name:"CcnUin"` +} + +type CcnInstance struct { + // 关联实例ID + InstanceId *string `json:"InstanceId" name:"InstanceId"` + // 关联实例ID所属大区,例如:ap-guangzhou + InstanceRegion *string `json:"InstanceRegion" name:"InstanceRegion"` + // 关联实例类型,可选值:VPC、DIRECTCONNECT + InstanceType *string `json:"InstanceType" name:"InstanceType"` +} + +type CcnRegionBandwidthLimit struct { + // 地域,例如:ap-guangzhou + Region *string `json:"Region" name:"Region"` + // 出带宽上限,单位:Mbps + BandwidthLimit *uint64 `json:"BandwidthLimit" name:"BandwidthLimit"` +} + +type CcnRoute struct { + // 路由策略ID + RouteId *string `json:"RouteId" name:"RouteId"` + // 目的端 + DestinationCidrBlock *string `json:"DestinationCidrBlock" name:"DestinationCidrBlock"` + // 下一跳类型(关联实例类型),所有类型:VPC、DIRECTCONNECT + InstanceType *string `json:"InstanceType" name:"InstanceType"` + // 下一跳(关联实例) + InstanceId *string `json:"InstanceId" name:"InstanceId"` + // 下一跳名称(关联实例名称) + InstanceName *string `json:"InstanceName" name:"InstanceName"` + // 下一跳所属地域(关联实例所属地域) + InstanceRegion *string `json:"InstanceRegion" name:"InstanceRegion"` + // 更新时间 + UpdateTime *string `json:"UpdateTime" name:"UpdateTime"` + // 路由是否启用 + Enabled *bool `json:"Enabled" name:"Enabled"` + // 关联实例所属UIN(根账号) + InstanceUin *string `json:"InstanceUin" name:"InstanceUin"` +} + +type ClassicLinkInstance struct { + // VPC实例ID + VpcId *string `json:"VpcId" name:"VpcId"` + // 云服务器实例唯一ID + InstanceId *string `json:"InstanceId" name:"InstanceId"` +} + +type CreateAddressTemplateGroupRequest struct { + *tchttp.BaseRequest + // IP地址模版集合名称。 + AddressTemplateGroupName *string `json:"AddressTemplateGroupName" name:"AddressTemplateGroupName"` + // IP地址模版实例ID,例如:ipm-mdunqeb6。 + AddressTemplateIds []*string `json:"AddressTemplateIds" name:"AddressTemplateIds" list` +} + +func (r *CreateAddressTemplateGroupRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateAddressTemplateGroupRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateAddressTemplateGroupResponse struct { + *tchttp.BaseResponse + Response *struct { + // IP地址模板集合对象。 + AddressTemplateGroup *AddressTemplateGroup `json:"AddressTemplateGroup" name:"AddressTemplateGroup"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *CreateAddressTemplateGroupResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateAddressTemplateGroupResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateAddressTemplateRequest struct { + *tchttp.BaseRequest + // IP地址模版名称 + AddressTemplateName *string `json:"AddressTemplateName" name:"AddressTemplateName"` + // 地址信息,支持 IP、CIDR、IP 范围。 + Addresses []*string `json:"Addresses" name:"Addresses" list` +} + +func (r *CreateAddressTemplateRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateAddressTemplateRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateAddressTemplateResponse struct { + *tchttp.BaseResponse + Response *struct { + // IP地址模板对象。 + AddressTemplate *AddressTemplate `json:"AddressTemplate" name:"AddressTemplate"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *CreateAddressTemplateResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateAddressTemplateResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateBandwidthPackageRequest struct { + *tchttp.BaseRequest + // 带宽包类型,包括'BGP','SINGLEISP','ANYCAST' + NetworkType *string `json:"NetworkType" name:"NetworkType"` + // 带宽包计费类型,包括‘TOP5_POSTPAID_BY_MONTH’,‘PERCENT95_POSTPAID_BY_MONTH’ + ChargeType *string `json:"ChargeType" name:"ChargeType"` + // 带宽包名字 + BandwidthPackageName *string `json:"BandwidthPackageName" name:"BandwidthPackageName"` + // 带宽包数量(非上移账户只能填1) + BandwidthPackageCount *uint64 `json:"BandwidthPackageCount" name:"BandwidthPackageCount"` +} + +func (r *CreateBandwidthPackageRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateBandwidthPackageRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateBandwidthPackageResponse struct { + *tchttp.BaseResponse + Response *struct { + // 带宽包Id + BandwidthPackageId *string `json:"BandwidthPackageId" name:"BandwidthPackageId"` + // 带宽包Ids(申请数量大于1时有效) + BandwidthPackageIds []*string `json:"BandwidthPackageIds" name:"BandwidthPackageIds" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *CreateBandwidthPackageResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateBandwidthPackageResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateCcnRequest struct { + *tchttp.BaseRequest + // CCN名称,最大长度不能超过60个字节。 + CcnName *string `json:"CcnName" name:"CcnName"` + // CCN描述信息,最大长度不能超过100个字节。 + CcnDescription *string `json:"CcnDescription" name:"CcnDescription"` +} + +func (r *CreateCcnRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateCcnRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateCcnResponse struct { + *tchttp.BaseResponse + Response *struct { + // 云联网(CCN)对象。 + Ccn *CCN `json:"Ccn" name:"Ccn"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *CreateCcnResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateCcnResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateCustomerGatewayRequest struct { + *tchttp.BaseRequest + // 对端网关名称,可任意命名,但不得超过60个字符。 + CustomerGatewayName *string `json:"CustomerGatewayName" name:"CustomerGatewayName"` + // 对端网关公网IP。 + IpAddress *string `json:"IpAddress" name:"IpAddress"` +} + +func (r *CreateCustomerGatewayRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateCustomerGatewayRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateCustomerGatewayResponse struct { + *tchttp.BaseResponse + Response *struct { + // 对端网关对象 + CustomerGateway *CustomerGateway `json:"CustomerGateway" name:"CustomerGateway"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *CreateCustomerGatewayResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateCustomerGatewayResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateDefaultVpcRequest struct { + *tchttp.BaseRequest + // 子网所在的可用区ID,不指定将随机选择可用区 + Zone *string `json:"Zone" name:"Zone"` + // 是否强制返回默认VPC + Force *bool `json:"Force" name:"Force"` +} + +func (r *CreateDefaultVpcRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateDefaultVpcRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateDefaultVpcResponse struct { + *tchttp.BaseResponse + Response *struct { + // 默认VPC和子网ID + Vpc *DefaultVpcSubnet `json:"Vpc" name:"Vpc"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *CreateDefaultVpcResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateDefaultVpcResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateDirectConnectGatewayCcnRoutesRequest struct { + *tchttp.BaseRequest + // 专线网关ID,形如:dcg-prpqlmg1 + DirectConnectGatewayId *string `json:"DirectConnectGatewayId" name:"DirectConnectGatewayId"` + // 需要连通的IDC网段列表 + Routes []*DirectConnectGatewayCcnRoute `json:"Routes" name:"Routes" list` +} + +func (r *CreateDirectConnectGatewayCcnRoutesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateDirectConnectGatewayCcnRoutesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateDirectConnectGatewayCcnRoutesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *CreateDirectConnectGatewayCcnRoutesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateDirectConnectGatewayCcnRoutesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateDirectConnectGatewayRequest struct { + *tchttp.BaseRequest + // 专线网关名称 + DirectConnectGatewayName *string `json:"DirectConnectGatewayName" name:"DirectConnectGatewayName"` + // 关联网络类型,可选值: + //
  • VPC - 私有网络
  • + //
  • CCN - 云联网
  • + NetworkType *string `json:"NetworkType" name:"NetworkType"` + //
  • NetworkType 为 VPC 时,这里传值为私有网络实例ID
  • + //
  • NetworkType 为 NAT 时,这里传值为云联网实例ID
  • + NetworkInstanceId *string `json:"NetworkInstanceId" name:"NetworkInstanceId"` + // 网关类型,可选值: + //
  • NORMAL - (默认)标准型,注:云联网只支持标准型
  • + //
  • NAT - NAT型
  • NAT类型支持网络地址转换配置,类型确定后不能修改;一个私有网络可以创建一个NAT类型的专线网关和一个非NAT类型的专线网关 + GatewayType *string `json:"GatewayType" name:"GatewayType"` +} + +func (r *CreateDirectConnectGatewayRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateDirectConnectGatewayRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateDirectConnectGatewayResponse struct { + *tchttp.BaseResponse + Response *struct { + // 专线网关对象。 + DirectConnectGateway *DirectConnectGateway `json:"DirectConnectGateway" name:"DirectConnectGateway"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *CreateDirectConnectGatewayResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateDirectConnectGatewayResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateNetworkInterfaceRequest struct { + *tchttp.BaseRequest + // VPC实例ID。可通过DescribeVpcs接口返回值中的VpcId获取。 + VpcId *string `json:"VpcId" name:"VpcId"` + // 弹性网卡名称,最大长度不能超过60个字节。 + NetworkInterfaceName *string `json:"NetworkInterfaceName" name:"NetworkInterfaceName"` + // 弹性网卡所在的子网实例ID,例如:subnet-0ap8nwca。 + SubnetId *string `json:"SubnetId" name:"SubnetId"` + // 弹性网卡描述,可任意命名,但不得超过60个字符。 + NetworkInterfaceDescription *string `json:"NetworkInterfaceDescription" name:"NetworkInterfaceDescription"` + // 新申请的内网IP地址个数。 + SecondaryPrivateIpAddressCount *uint64 `json:"SecondaryPrivateIpAddressCount" name:"SecondaryPrivateIpAddressCount"` + // 指定绑定的安全组,例如:['sg-1dd51d']。 + SecurityGroupIds []*string `json:"SecurityGroupIds" name:"SecurityGroupIds" list` + // 指定内网IP信息。 + PrivateIpAddresses []*PrivateIpAddressSpecification `json:"PrivateIpAddresses" name:"PrivateIpAddresses" list` +} + +func (r *CreateNetworkInterfaceRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateNetworkInterfaceRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateNetworkInterfaceResponse struct { + *tchttp.BaseResponse + Response *struct { + // 弹性网卡实例。 + NetworkInterface *NetworkInterface `json:"NetworkInterface" name:"NetworkInterface"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *CreateNetworkInterfaceResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateNetworkInterfaceResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateRouteTableRequest struct { + *tchttp.BaseRequest + // 待操作的VPC实例ID。可通过DescribeVpcs接口返回值中的VpcId获取。 + VpcId *string `json:"VpcId" name:"VpcId"` + // 路由表名称,最大长度不能超过60个字节。 + RouteTableName *string `json:"RouteTableName" name:"RouteTableName"` +} + +func (r *CreateRouteTableRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateRouteTableRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateRouteTableResponse struct { + *tchttp.BaseResponse + Response *struct { + // 路由表对象。 + RouteTable *RouteTable `json:"RouteTable" name:"RouteTable"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *CreateRouteTableResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateRouteTableResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateRoutesRequest struct { + *tchttp.BaseRequest + // 路由表实例ID。 + RouteTableId *string `json:"RouteTableId" name:"RouteTableId"` + // 路由策略对象。 + Routes []*Route `json:"Routes" name:"Routes" list` +} + +func (r *CreateRoutesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateRoutesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateRoutesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *CreateRoutesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateRoutesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateSecurityGroupPoliciesRequest struct { + *tchttp.BaseRequest + // 安全组实例ID,例如sg-33ocnj9n,可通过DescribeSecurityGroups获取。 + SecurityGroupId *string `json:"SecurityGroupId" name:"SecurityGroupId"` + // 安全组规则集合。 + SecurityGroupPolicySet *SecurityGroupPolicySet `json:"SecurityGroupPolicySet" name:"SecurityGroupPolicySet"` +} + +func (r *CreateSecurityGroupPoliciesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateSecurityGroupPoliciesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateSecurityGroupPoliciesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *CreateSecurityGroupPoliciesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateSecurityGroupPoliciesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateSecurityGroupRequest struct { + *tchttp.BaseRequest + // 安全组名称,可任意命名,但不得超过60个字符。 + GroupName *string `json:"GroupName" name:"GroupName"` + // 安全组备注,最多100个字符。 + GroupDescription *string `json:"GroupDescription" name:"GroupDescription"` + // 项目id,默认0。可在qcloud控制台项目管理页面查询到。 + ProjectId *string `json:"ProjectId" name:"ProjectId"` +} + +func (r *CreateSecurityGroupRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateSecurityGroupRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateSecurityGroupResponse struct { + *tchttp.BaseResponse + Response *struct { + // 安全组对象。 + SecurityGroup *SecurityGroup `json:"SecurityGroup" name:"SecurityGroup"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *CreateSecurityGroupResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateSecurityGroupResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateServiceTemplateGroupRequest struct { + *tchttp.BaseRequest + // 协议端口模板集合名称 + ServiceTemplateGroupName *string `json:"ServiceTemplateGroupName" name:"ServiceTemplateGroupName"` + // 协议端口模板实例ID,例如:ppm-4dw6agho。 + ServiceTemplateIds []*string `json:"ServiceTemplateIds" name:"ServiceTemplateIds" list` +} + +func (r *CreateServiceTemplateGroupRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateServiceTemplateGroupRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateServiceTemplateGroupResponse struct { + *tchttp.BaseResponse + Response *struct { + // 协议端口模板集合对象。 + ServiceTemplateGroup *ServiceTemplateGroup `json:"ServiceTemplateGroup" name:"ServiceTemplateGroup"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *CreateServiceTemplateGroupResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateServiceTemplateGroupResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateServiceTemplateRequest struct { + *tchttp.BaseRequest + // 协议端口模板名称 + ServiceTemplateName *string `json:"ServiceTemplateName" name:"ServiceTemplateName"` + // 支持单个端口、多个端口、连续端口及所有端口,协议支持:TCP、UDP、ICMP、GRE 协议。 + Services []*string `json:"Services" name:"Services" list` +} + +func (r *CreateServiceTemplateRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateServiceTemplateRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateServiceTemplateResponse struct { + *tchttp.BaseResponse + Response *struct { + // 协议端口模板对象。 + ServiceTemplate *ServiceTemplate `json:"ServiceTemplate" name:"ServiceTemplate"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *CreateServiceTemplateResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateServiceTemplateResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateSubnetRequest struct { + *tchttp.BaseRequest + // 待操作的VPC实例ID。可通过DescribeVpcs接口返回值中的VpcId获取。 + VpcId *string `json:"VpcId" name:"VpcId"` + // 子网名称,最大长度不能超过60个字节。 + SubnetName *string `json:"SubnetName" name:"SubnetName"` + // 子网网段,子网网段必须在VPC网段内,相同VPC内子网网段不能重叠。 + CidrBlock *string `json:"CidrBlock" name:"CidrBlock"` + // 子网所在的可用区ID,不同子网选择不同可用区可以做跨可用区灾备。 + Zone *string `json:"Zone" name:"Zone"` +} + +func (r *CreateSubnetRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateSubnetRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateSubnetResponse struct { + *tchttp.BaseResponse + Response *struct { + // 子网对象。 + Subnet *Subnet `json:"Subnet" name:"Subnet"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *CreateSubnetResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateSubnetResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateVpcRequest struct { + *tchttp.BaseRequest + // vpc名称,最大长度不能超过60个字节。 + VpcName *string `json:"VpcName" name:"VpcName"` + // vpc的cidr,只能为10.0.0.0/16,172.16.0.0/12,192.168.0.0/16这三个内网网段内。 + CidrBlock *string `json:"CidrBlock" name:"CidrBlock"` + // 是否开启组播。true: 开启, false: 不开启。 + EnableMulticast *string `json:"EnableMulticast" name:"EnableMulticast"` + // DNS地址,最多支持4个 + DnsServers []*string `json:"DnsServers" name:"DnsServers" list` + // 域名 + DomainName *string `json:"DomainName" name:"DomainName"` +} + +func (r *CreateVpcRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateVpcRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateVpcResponse struct { + *tchttp.BaseResponse + Response *struct { + // Vpc对象。 + Vpc *Vpc `json:"Vpc" name:"Vpc"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *CreateVpcResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateVpcResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateVpnConnectionRequest struct { + *tchttp.BaseRequest + // VPC实例ID。可通过DescribeVpcs接口返回值中的VpcId获取。 + VpcId *string `json:"VpcId" name:"VpcId"` + // VPN网关实例ID。 + VpnGatewayId *string `json:"VpnGatewayId" name:"VpnGatewayId"` + // 对端网关ID,例如:cgw-2wqq41m9,可通过DescribeCustomerGateways接口查询对端网关。 + CustomerGatewayId *string `json:"CustomerGatewayId" name:"CustomerGatewayId"` + // 通道名称,可任意命名,但不得超过60个字符。 + VpnConnectionName *string `json:"VpnConnectionName" name:"VpnConnectionName"` + // 预共享密钥。 + PreShareKey *string `json:"PreShareKey" name:"PreShareKey"` + // SPD策略组,例如:{"10.0.0.5/24":["172.123.10.5/16"]},10.0.0.5/24是vpc内网段172.123.10.5/16是IDC网段。用户指定VPC内哪些网段可以和您IDC中哪些网段通信。 + SecurityPolicyDatabases []*SecurityPolicyDatabase `json:"SecurityPolicyDatabases" name:"SecurityPolicyDatabases" list` + // IKE配置(Internet Key Exchange,因特网密钥交换),IKE具有一套自保护机制,用户配置网络安全协议 + IKEOptionsSpecification *IKEOptionsSpecification `json:"IKEOptionsSpecification" name:"IKEOptionsSpecification"` + // IPSec配置,腾讯云提供IPSec安全会话设置 + IPSECOptionsSpecification *IPSECOptionsSpecification `json:"IPSECOptionsSpecification" name:"IPSECOptionsSpecification"` +} + +func (r *CreateVpnConnectionRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateVpnConnectionRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateVpnConnectionResponse struct { + *tchttp.BaseResponse + Response *struct { + // 通道实例对象。 + VpnConnection *VpnConnection `json:"VpnConnection" name:"VpnConnection"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *CreateVpnConnectionResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateVpnConnectionResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateVpnGatewayRequest struct { + *tchttp.BaseRequest + // VPC实例ID。可通过DescribeVpcs接口返回值中的VpcId获取。 + VpcId *string `json:"VpcId" name:"VpcId"` + // VPN网关名称,最大长度不能超过60个字节。 + VpnGatewayName *string `json:"VpnGatewayName" name:"VpnGatewayName"` + // 公网带宽设置。可选带宽规格:5, 10, 20, 50, 100;单位:Mbps + InternetMaxBandwidthOut *uint64 `json:"InternetMaxBandwidthOut" name:"InternetMaxBandwidthOut"` + // VPN网关计费模式,PREPAID:表示预付费,即包年包月,POSTPAID_BY_HOUR:表示后付费,即按量计费。默认:POSTPAID_BY_HOUR,如果指定预付费模式,参数InstanceChargePrepaid必填。 + InstanceChargeType *string `json:"InstanceChargeType" name:"InstanceChargeType"` + // 预付费模式,即包年包月相关参数设置。通过该参数可以指定包年包月实例的购买时长、是否设置自动续费等属性。若指定实例的付费模式为预付费则该参数必传。 + InstanceChargePrepaid *InstanceChargePrepaid `json:"InstanceChargePrepaid" name:"InstanceChargePrepaid"` + // 可用区,如:ap-guangzhou-2。 + Zone *string `json:"Zone" name:"Zone"` +} + +func (r *CreateVpnGatewayRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateVpnGatewayRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateVpnGatewayResponse struct { + *tchttp.BaseResponse + Response *struct { + // VPN网关对象 + VpnGateway *VpnGateway `json:"VpnGateway" name:"VpnGateway"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *CreateVpnGatewayResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateVpnGatewayResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CustomerGateway struct { + // 用户网关唯一ID + CustomerGatewayId *string `json:"CustomerGatewayId" name:"CustomerGatewayId"` + // 网关名称 + CustomerGatewayName *string `json:"CustomerGatewayName" name:"CustomerGatewayName"` + // 公网地址 + IpAddress *string `json:"IpAddress" name:"IpAddress"` + // 创建时间 + CreatedTime *string `json:"CreatedTime" name:"CreatedTime"` +} + +type CustomerGatewayVendor struct { + // 平台。 + Platform *string `json:"Platform" name:"Platform"` + // 软件版本。 + SoftwareVersion *string `json:"SoftwareVersion" name:"SoftwareVersion"` + // 供应商名称。 + VendorName *string `json:"VendorName" name:"VendorName"` +} + +type DefaultVpcSubnet struct { + // 默认VpcId + VpcId *string `json:"VpcId" name:"VpcId"` + // 默认SubnetId + SubnetId *string `json:"SubnetId" name:"SubnetId"` +} + +type DeleteAddressTemplateGroupRequest struct { + *tchttp.BaseRequest + // IP地址模板集合实例ID,例如:ipmg-90cex8mq。 + AddressTemplateGroupId *string `json:"AddressTemplateGroupId" name:"AddressTemplateGroupId"` +} + +func (r *DeleteAddressTemplateGroupRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteAddressTemplateGroupRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteAddressTemplateGroupResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DeleteAddressTemplateGroupResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteAddressTemplateGroupResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteAddressTemplateRequest struct { + *tchttp.BaseRequest + // IP地址模板实例ID,例如:ipm-09o5m8kc。 + AddressTemplateId *string `json:"AddressTemplateId" name:"AddressTemplateId"` +} + +func (r *DeleteAddressTemplateRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteAddressTemplateRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteAddressTemplateResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DeleteAddressTemplateResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteAddressTemplateResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteBandwidthPackageRequest struct { + *tchttp.BaseRequest + // 待删除带宽包bwpId + BandwidthPackageId *string `json:"BandwidthPackageId" name:"BandwidthPackageId"` +} + +func (r *DeleteBandwidthPackageRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteBandwidthPackageRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteBandwidthPackageResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DeleteBandwidthPackageResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteBandwidthPackageResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteCcnRequest struct { + *tchttp.BaseRequest + // CCN实例ID。形如:ccn-f49l6u0z。 + CcnId *string `json:"CcnId" name:"CcnId"` +} + +func (r *DeleteCcnRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteCcnRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteCcnResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DeleteCcnResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteCcnResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteCustomerGatewayRequest struct { + *tchttp.BaseRequest + // 对端网关ID,例如:cgw-2wqq41m9,可通过DescribeCustomerGateways接口查询对端网关。 + CustomerGatewayId *string `json:"CustomerGatewayId" name:"CustomerGatewayId"` +} + +func (r *DeleteCustomerGatewayRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteCustomerGatewayRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteCustomerGatewayResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DeleteCustomerGatewayResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteCustomerGatewayResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteDirectConnectGatewayCcnRoutesRequest struct { + *tchttp.BaseRequest + // 专线网关ID,形如:dcg-prpqlmg1 + DirectConnectGatewayId *string `json:"DirectConnectGatewayId" name:"DirectConnectGatewayId"` + // 路由ID。形如:ccnr-f49l6u0z。 + RouteIds []*string `json:"RouteIds" name:"RouteIds" list` +} + +func (r *DeleteDirectConnectGatewayCcnRoutesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteDirectConnectGatewayCcnRoutesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteDirectConnectGatewayCcnRoutesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DeleteDirectConnectGatewayCcnRoutesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteDirectConnectGatewayCcnRoutesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteNetworkInterfaceRequest struct { + *tchttp.BaseRequest + // 弹性网卡实例ID,例如:eni-m6dyj72l。 + NetworkInterfaceId *string `json:"NetworkInterfaceId" name:"NetworkInterfaceId"` +} + +func (r *DeleteNetworkInterfaceRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteNetworkInterfaceRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteNetworkInterfaceResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DeleteNetworkInterfaceResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteNetworkInterfaceResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteRouteTableRequest struct { + *tchttp.BaseRequest + // 路由表实例ID,例如:rtb-azd4dt1c。 + RouteTableId *string `json:"RouteTableId" name:"RouteTableId"` +} + +func (r *DeleteRouteTableRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteRouteTableRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteRouteTableResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DeleteRouteTableResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteRouteTableResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteRoutesRequest struct { + *tchttp.BaseRequest + // 路由表实例ID。 + RouteTableId *string `json:"RouteTableId" name:"RouteTableId"` + // 路由策略对象。 + Routes []*Route `json:"Routes" name:"Routes" list` +} + +func (r *DeleteRoutesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteRoutesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteRoutesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DeleteRoutesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteRoutesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteSecurityGroupPoliciesRequest struct { + *tchttp.BaseRequest + // 安全组实例ID,例如sg-33ocnj9n,可通过DescribeSecurityGroups获取。 + SecurityGroupId *string `json:"SecurityGroupId" name:"SecurityGroupId"` + // 安全组规则集合。一个请求中只能删除单个方向的一条或多条规则。支持指定索引(PolicyIndex) 匹配删除和安全组规则匹配删除两种方式,一个请求中只能使用一种匹配方式。 + SecurityGroupPolicySet *SecurityGroupPolicySet `json:"SecurityGroupPolicySet" name:"SecurityGroupPolicySet"` +} + +func (r *DeleteSecurityGroupPoliciesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteSecurityGroupPoliciesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteSecurityGroupPoliciesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DeleteSecurityGroupPoliciesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteSecurityGroupPoliciesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteSecurityGroupRequest struct { + *tchttp.BaseRequest + // 安全组实例ID,例如sg-33ocnj9n,可通过DescribeSecurityGroups获取。 + SecurityGroupId *string `json:"SecurityGroupId" name:"SecurityGroupId"` +} + +func (r *DeleteSecurityGroupRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteSecurityGroupRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteSecurityGroupResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DeleteSecurityGroupResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteSecurityGroupResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteServiceTemplateGroupRequest struct { + *tchttp.BaseRequest + // 协议端口模板集合实例ID,例如:ppmg-n17uxvve。 + ServiceTemplateGroupId *string `json:"ServiceTemplateGroupId" name:"ServiceTemplateGroupId"` +} + +func (r *DeleteServiceTemplateGroupRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteServiceTemplateGroupRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteServiceTemplateGroupResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DeleteServiceTemplateGroupResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteServiceTemplateGroupResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteServiceTemplateRequest struct { + *tchttp.BaseRequest + // 协议端口模板实例ID,例如:ppm-e6dy460g。 + ServiceTemplateId *string `json:"ServiceTemplateId" name:"ServiceTemplateId"` +} + +func (r *DeleteServiceTemplateRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteServiceTemplateRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteServiceTemplateResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DeleteServiceTemplateResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteServiceTemplateResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteSubnetRequest struct { + *tchttp.BaseRequest + // 子网实例ID。可通过DescribeSubnets接口返回值中的SubnetId获取。 + SubnetId *string `json:"SubnetId" name:"SubnetId"` +} + +func (r *DeleteSubnetRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteSubnetRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteSubnetResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DeleteSubnetResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteSubnetResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteVpcRequest struct { + *tchttp.BaseRequest + // VPC实例ID。可通过DescribeVpcs接口返回值中的VpcId获取。 + VpcId *string `json:"VpcId" name:"VpcId"` +} + +func (r *DeleteVpcRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteVpcRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteVpcResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DeleteVpcResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteVpcResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteVpnConnectionRequest struct { + *tchttp.BaseRequest + // VPN网关实例ID。 + VpnGatewayId *string `json:"VpnGatewayId" name:"VpnGatewayId"` + // VPN通道实例ID。形如:vpnx-f49l6u0z。 + VpnConnectionId *string `json:"VpnConnectionId" name:"VpnConnectionId"` +} + +func (r *DeleteVpnConnectionRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteVpnConnectionRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteVpnConnectionResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DeleteVpnConnectionResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteVpnConnectionResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteVpnGatewayRequest struct { + *tchttp.BaseRequest + // VPN网关实例ID。 + VpnGatewayId *string `json:"VpnGatewayId" name:"VpnGatewayId"` +} + +func (r *DeleteVpnGatewayRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteVpnGatewayRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteVpnGatewayResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DeleteVpnGatewayResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteVpnGatewayResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeAccountAttributesRequest struct { + *tchttp.BaseRequest +} + +func (r *DescribeAccountAttributesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeAccountAttributesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeAccountAttributesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 用户账号属性对象 + AccountAttributeSet []*AccountAttribute `json:"AccountAttributeSet" name:"AccountAttributeSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeAccountAttributesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeAccountAttributesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeAddressQuotaRequest struct { + *tchttp.BaseRequest +} + +func (r *DescribeAddressQuotaRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeAddressQuotaRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeAddressQuotaResponse struct { + *tchttp.BaseResponse + Response *struct { + // 账户 EIP 配额信息。 + QuotaSet []*Quota `json:"QuotaSet" name:"QuotaSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeAddressQuotaResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeAddressQuotaResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeAddressTemplateGroupsRequest struct { + *tchttp.BaseRequest + // 过滤条件。 + //
  • address-template-group-name - String - (过滤条件)IP地址模板集合名称。
  • + //
  • address-template-group-id - String - (过滤条件)IP地址模板实集合例ID,例如:ipmg-mdunqeb6。
  • + Filters []*Filter `json:"Filters" name:"Filters" list` + // 偏移量,默认为0。 + Offset *string `json:"Offset" name:"Offset"` + // 返回数量,默认为20,最大值为100。 + Limit *string `json:"Limit" name:"Limit"` +} + +func (r *DescribeAddressTemplateGroupsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeAddressTemplateGroupsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeAddressTemplateGroupsResponse struct { + *tchttp.BaseResponse + Response *struct { + // 符合条件的实例数量。 + TotalCount *uint64 `json:"TotalCount" name:"TotalCount"` + // IP地址模板。 + AddressTemplateGroupSet []*AddressTemplateGroup `json:"AddressTemplateGroupSet" name:"AddressTemplateGroupSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeAddressTemplateGroupsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeAddressTemplateGroupsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeAddressTemplatesRequest struct { + *tchttp.BaseRequest + // 过滤条件。 + //
  • address-template-name - String - (过滤条件)IP地址模板名称。
  • + //
  • address-template-id - String - (过滤条件)IP地址模板实例ID,例如:ipm-mdunqeb6。
  • + Filters []*Filter `json:"Filters" name:"Filters" list` + // 偏移量,默认为0。 + Offset *string `json:"Offset" name:"Offset"` + // 返回数量,默认为20,最大值为100。 + Limit *string `json:"Limit" name:"Limit"` +} + +func (r *DescribeAddressTemplatesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeAddressTemplatesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeAddressTemplatesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 符合条件的实例数量。 + TotalCount *uint64 `json:"TotalCount" name:"TotalCount"` + // IP地址模版。 + AddressTemplateSet []*AddressTemplate `json:"AddressTemplateSet" name:"AddressTemplateSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeAddressTemplatesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeAddressTemplatesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeAddressesRequest struct { + *tchttp.BaseRequest + // 标识 EIP 的唯一 ID 列表。EIP 唯一 ID 形如:`eip-11112222`。参数不支持同时指定`AddressIds`和`Filters`。 + AddressIds []*string `json:"AddressIds" name:"AddressIds" list` + // 每次请求的`Filters`的上限为10,`Filter.Values`的上限为5。参数不支持同时指定`AddressIds`和`Filters`。详细的过滤条件如下: + //
  • address-id - String - 是否必填:否 - (过滤条件)按照 EIP 的唯一 ID 过滤。EIP 唯一 ID 形如:eip-11112222。
  • + //
  • address-name - String - 是否必填:否 - (过滤条件)按照 EIP 名称过滤。不支持模糊过滤。
  • + //
  • address-ip - String - 是否必填:否 - (过滤条件)按照 EIP 的 IP 地址过滤。
  • + //
  • address-status - String - 是否必填:否 - (过滤条件)按照 EIP 的状态过滤。取值范围:[详见EIP状态列表](https://cloud.tencent.com/document/api/213/9452#eip_state)。
  • + //
  • instance-id - String - 是否必填:否 - (过滤条件)按照 EIP 绑定的实例 ID 过滤。实例 ID 形如:ins-11112222。
  • + //
  • private-ip-address - String - 是否必填:否 - (过滤条件)按照 EIP 绑定的内网 IP 过滤。
  • + //
  • network-interface-id - String - 是否必填:否 - (过滤条件)按照 EIP 绑定的弹性网卡 ID 过滤。弹性网卡 ID 形如:eni-11112222。
  • + //
  • is-arrears - String - 是否必填:否 - (过滤条件)按照 EIP 是否欠费进行过滤。(TRUE:EIP 处于欠费状态|FALSE:EIP 费用状态正常)
  • + Filters []*Filter `json:"Filters" name:"Filters" list` + // 偏移量,默认为0。关于`Offset`的更进一步介绍请参考 API [简介](https://cloud.tencent.com/document/api/213/11646)中的相关小节。 + Offset *int64 `json:"Offset" name:"Offset"` + // 返回数量,默认为20,最大值为100。关于`Limit`的更进一步介绍请参考 API [简介](https://cloud.tencent.com/document/api/213/11646)中的相关小节。 + Limit *int64 `json:"Limit" name:"Limit"` +} + +func (r *DescribeAddressesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeAddressesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeAddressesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 符合条件的 EIP 数量。 + TotalCount *int64 `json:"TotalCount" name:"TotalCount"` + // EIP 详细信息列表。 + AddressSet []*Address `json:"AddressSet" name:"AddressSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeAddressesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeAddressesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeBandwidthPackageQuotaRequest struct { + *tchttp.BaseRequest +} + +func (r *DescribeBandwidthPackageQuotaRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeBandwidthPackageQuotaRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeBandwidthPackageQuotaResponse struct { + *tchttp.BaseResponse + Response *struct { + // 带宽包配额数据结构 + QuotaSet []*Quota `json:"QuotaSet" name:"QuotaSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeBandwidthPackageQuotaResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeBandwidthPackageQuotaResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeBandwidthPackagesRequest struct { + *tchttp.BaseRequest + // 带宽包Id,支持批量 + BandwidthPackageIds []*string `json:"BandwidthPackageIds" name:"BandwidthPackageIds" list` + // 每次请求的`Filters`的上限为10。参数不支持同时指定`BandwidthPackageIds`和`Filters`。详细的过滤条件如下: + //
  • bandwidth-package_id - String - 是否必填:否 - (过滤条件)按照带宽包的唯一标识ID过滤。
  • + //
  • bandwidth-package-name - String - 是否必填:否 - (过滤条件)按照 带宽包名称过滤。不支持模糊过滤。
  • + //
  • network-type - String - 是否必填:否 - (过滤条件)按照带宽包的类型过滤。类型包括'BGP','SINGLEISP'和'ANYCAST'。
  • + //
  • charge-type - String - 是否必填:否 - (过滤条件)按照带宽包的计费类型过滤。计费类型包括'TOP5_POSTPAID_BY_MONTH'和'PERCENT95_POSTPAID_BY_MONTH'
  • + //
  • resource.resource-type - String - 是否必填:否 - (过滤条件)按照带宽包资源类型过滤。资源类型包括'Address'和'LoadBalance'
  • + //
  • resource.resource-id - String - 是否必填:否 - (过滤条件)按照带宽包资源Id过滤。资源Id形如'eip-xxxx','lb-xxxx'
  • + //
  • resource.address-ip - String - 是否必填:否 - (过滤条件)按照带宽包资源Ip过滤。
  • + Filters []*Filter `json:"Filters" name:"Filters" list` + // 查询带宽包偏移量 + Offset *uint64 `json:"Offset" name:"Offset"` + // 查询带宽包数量限制 + Limit *uint64 `json:"Limit" name:"Limit"` +} + +func (r *DescribeBandwidthPackagesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeBandwidthPackagesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeBandwidthPackagesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 符合条件的带宽包数量 + TotalCount *uint64 `json:"TotalCount" name:"TotalCount"` + // 描述带宽包详细信息 + BandwidthPackageSet []*BandwidthPackage `json:"BandwidthPackageSet" name:"BandwidthPackageSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeBandwidthPackagesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeBandwidthPackagesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeCcnAttachedInstancesRequest struct { + *tchttp.BaseRequest + // 偏移量 + Offset *uint64 `json:"Offset" name:"Offset"` + // 返回数量 + Limit *uint64 `json:"Limit" name:"Limit"` + // 过滤条件: + //
  • ccn-id - String -(过滤条件)CCN实例ID。
  • + //
  • instance-type - String -(过滤条件)关联实例类型。
  • + //
  • instance-region - String -(过滤条件)关联实例所属地域。
  • + //
  • instance-id - String -(过滤条件)关联实例实例ID。
  • + Filters []*Filter `json:"Filters" name:"Filters" list` + // 云联网实例ID + CcnId *string `json:"CcnId" name:"CcnId"` +} + +func (r *DescribeCcnAttachedInstancesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeCcnAttachedInstancesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeCcnAttachedInstancesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 符合条件的对象数。 + TotalCount *uint64 `json:"TotalCount" name:"TotalCount"` + // 关联实例列表。 + InstanceSet []*CcnAttachedInstance `json:"InstanceSet" name:"InstanceSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeCcnAttachedInstancesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeCcnAttachedInstancesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeCcnRegionBandwidthLimitsRequest struct { + *tchttp.BaseRequest + // CCN实例ID。形如:ccn-f49l6u0z。 + CcnId *string `json:"CcnId" name:"CcnId"` +} + +func (r *DescribeCcnRegionBandwidthLimitsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeCcnRegionBandwidthLimitsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeCcnRegionBandwidthLimitsResponse struct { + *tchttp.BaseResponse + Response *struct { + // 云联网(CCN)各地域出带宽上限 + CcnRegionBandwidthLimitSet []*CcnRegionBandwidthLimit `json:"CcnRegionBandwidthLimitSet" name:"CcnRegionBandwidthLimitSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeCcnRegionBandwidthLimitsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeCcnRegionBandwidthLimitsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeCcnRoutesRequest struct { + *tchttp.BaseRequest + // CCN实例ID,形如:ccn-gree226l。 + CcnId *string `json:"CcnId" name:"CcnId"` + // CCN路由策略唯一ID。形如:ccnr-f49l6u0z。 + RouteIds []*string `json:"RouteIds" name:"RouteIds" list` + // 过滤条件,参数不支持同时指定RouteIds和Filters。 + //
  • ccn-id - String -(过滤条件)CCN实例ID。
  • + //
  • route-id - String -(过滤条件)路由策略ID。
  • + //
  • cidr-block - String -(过滤条件)目的端。
  • + //
  • instance-type - String -(过滤条件)下一跳类型。
  • + //
  • instance-region - String -(过滤条件)下一跳所属地域。
  • + //
  • instance-id - String -(过滤条件)下一跳实例ID。
  • + Filters []*Filter `json:"Filters" name:"Filters" list` + // 偏移量 + Offset *uint64 `json:"Offset" name:"Offset"` + // 返回数量 + Limit *uint64 `json:"Limit" name:"Limit"` +} + +func (r *DescribeCcnRoutesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeCcnRoutesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeCcnRoutesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 符合条件的对象数。 + TotalCount *uint64 `json:"TotalCount" name:"TotalCount"` + // CCN路由策略对象。 + RouteSet []*CcnRoute `json:"RouteSet" name:"RouteSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeCcnRoutesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeCcnRoutesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeCcnsRequest struct { + *tchttp.BaseRequest + // CCN实例ID。形如:ccn-f49l6u0z。每次请求的实例的上限为100。参数不支持同时指定CcnIds和Filters。 + CcnIds []*string `json:"CcnIds" name:"CcnIds" list` + // 过滤条件,参数不支持同时指定CcnIds和Filters。 + //
  • ccn-id - String - (过滤条件)CCN唯一ID,形如:vpc-f49l6u0z。
  • + //
  • ccn-name - String - (过滤条件)CCN名称。
  • + //
  • ccn-description - String - (过滤条件)CCN描述。
  • + //
  • state - String - (过滤条件)实例状态, 'ISOLATED': 隔离中(欠费停服),'AVAILABLE':运行中。
  • + Filters []*Filter `json:"Filters" name:"Filters" list` + // 偏移量 + Offset *uint64 `json:"Offset" name:"Offset"` + // 返回数量 + Limit *uint64 `json:"Limit" name:"Limit"` +} + +func (r *DescribeCcnsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeCcnsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeCcnsResponse struct { + *tchttp.BaseResponse + Response *struct { + // 符合条件的对象数。 + TotalCount *uint64 `json:"TotalCount" name:"TotalCount"` + // CCN对象。 + CcnSet []*CCN `json:"CcnSet" name:"CcnSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeCcnsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeCcnsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeClassicLinkInstancesRequest struct { + *tchttp.BaseRequest + // 过滤条件。 + //
  • vpc-id - String - (过滤条件)VPC实例ID。
  • + //
  • vm-ip - String - (过滤条件)基础网络云主机IP。
  • + Filters []*FilterObject `json:"Filters" name:"Filters" list` + // 偏移量 + Offset *string `json:"Offset" name:"Offset"` + // 返回数量 + Limit *string `json:"Limit" name:"Limit"` +} + +func (r *DescribeClassicLinkInstancesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeClassicLinkInstancesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeClassicLinkInstancesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 符合条件的实例数量。 + TotalCount *uint64 `json:"TotalCount" name:"TotalCount"` + // 私有网络和基础网络互通设备。 + ClassicLinkInstanceSet []*ClassicLinkInstance `json:"ClassicLinkInstanceSet" name:"ClassicLinkInstanceSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeClassicLinkInstancesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeClassicLinkInstancesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeCustomerGatewayVendorsRequest struct { + *tchttp.BaseRequest +} + +func (r *DescribeCustomerGatewayVendorsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeCustomerGatewayVendorsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeCustomerGatewayVendorsResponse struct { + *tchttp.BaseResponse + Response *struct { + // 对端网关厂商信息对象。 + CustomerGatewayVendorSet []*CustomerGatewayVendor `json:"CustomerGatewayVendorSet" name:"CustomerGatewayVendorSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeCustomerGatewayVendorsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeCustomerGatewayVendorsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeCustomerGatewaysRequest struct { + *tchttp.BaseRequest + // 对端网关ID,例如:cgw-2wqq41m9。每次请求的实例的上限为100。参数不支持同时指定CustomerGatewayIds和Filters。 + CustomerGatewayIds []*string `json:"CustomerGatewayIds" name:"CustomerGatewayIds" list` + // 过滤条件,详见下表:实例过滤条件表。每次请求的Filters的上限为10,Filter.Values的上限为5。参数不支持同时指定CustomerGatewayIds和Filters。 + Filters []*Filter `json:"Filters" name:"Filters" list` + // 偏移量,默认为0。关于Offset的更进一步介绍请参考 API 简介中的相关小节。 + Offset *uint64 `json:"Offset" name:"Offset"` + // 返回数量,默认为20,最大值为100。 + Limit *uint64 `json:"Limit" name:"Limit"` +} + +func (r *DescribeCustomerGatewaysRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeCustomerGatewaysRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeCustomerGatewaysResponse struct { + *tchttp.BaseResponse + Response *struct { + // 对端网关对象列表 + CustomerGatewaySet []*CustomerGateway `json:"CustomerGatewaySet" name:"CustomerGatewaySet" list` + // 符合条件的实例数量。 + TotalCount *uint64 `json:"TotalCount" name:"TotalCount"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeCustomerGatewaysResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeCustomerGatewaysResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeDirectConnectGatewayCcnRoutesRequest struct { + *tchttp.BaseRequest + // 专线网关ID,形如:dcg-prpqlmg1 + DirectConnectGatewayId *string `json:"DirectConnectGatewayId" name:"DirectConnectGatewayId"` +} + +func (r *DescribeDirectConnectGatewayCcnRoutesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeDirectConnectGatewayCcnRoutesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeDirectConnectGatewayCcnRoutesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 符合条件的对象数。 + TotalCount *uint64 `json:"TotalCount" name:"TotalCount"` + // 云联网路由(IDC网段)列表。 + RouteSet []*DirectConnectGatewayCcnRoute `json:"RouteSet" name:"RouteSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeDirectConnectGatewayCcnRoutesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeDirectConnectGatewayCcnRoutesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeNetworkInterfacesRequest struct { + *tchttp.BaseRequest + // 弹性网卡实例ID查询。形如:eni-pxir56ns。每次请求的实例的上限为100。参数不支持同时指定NetworkInterfaceIds和Filters。 + NetworkInterfaceIds []*string `json:"NetworkInterfaceIds" name:"NetworkInterfaceIds" list` + // 过滤条件,参数不支持同时指定NetworkInterfaceIds和Filters。 + //
  • vpc-id - String - (过滤条件)VPC实例ID,形如:vpc-f49l6u0z。
  • + //
  • subnet-id - String - (过滤条件)所属子网实例ID,形如:subnet-f49l6u0z。
  • + //
  • network-interface-id - String - (过滤条件)弹性网卡实例ID,形如:eni-5k56k7k7。
  • + //
  • attachment.instance-id - String - (过滤条件)绑定的云服务器实例ID,形如:ins-3nqpdn3i。
  • + //
  • groups.security-group-id - String - (过滤条件)绑定的安全组实例ID,例如:sg-f9ekbxeq。
  • + //
  • network-interface-name - String - (过滤条件)网卡实例名称。
  • + //
  • network-interface-description - String - (过滤条件)网卡实例描述。
  • + Filters []*Filter `json:"Filters" name:"Filters" list` + // 偏移量,默认为0。 + Offset *uint64 `json:"Offset" name:"Offset"` + // 返回数量,默认为20,最大值为100。 + Limit *uint64 `json:"Limit" name:"Limit"` +} + +func (r *DescribeNetworkInterfacesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeNetworkInterfacesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeNetworkInterfacesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 实例详细信息列表。 + NetworkInterfaceSet []*NetworkInterface `json:"NetworkInterfaceSet" name:"NetworkInterfaceSet" list` + // 符合条件的实例数量。 + TotalCount *uint64 `json:"TotalCount" name:"TotalCount"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeNetworkInterfacesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeNetworkInterfacesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeRouteConflictsRequest struct { + *tchttp.BaseRequest + // 路由表实例ID,例如:rtb-azd4dt1c。 + RouteTableId *string `json:"RouteTableId" name:"RouteTableId"` + // 要检查的与之冲突的目的端列表 + DestinationCidrBlocks []*string `json:"DestinationCidrBlocks" name:"DestinationCidrBlocks" list` +} + +func (r *DescribeRouteConflictsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeRouteConflictsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeRouteConflictsResponse struct { + *tchttp.BaseResponse + Response *struct { + // 路由策略冲突列表 + RouteConflictSet []*RouteConflict `json:"RouteConflictSet" name:"RouteConflictSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeRouteConflictsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeRouteConflictsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeRouteTablesRequest struct { + *tchttp.BaseRequest + // 路由表实例ID,例如:rtb-azd4dt1c。 + RouteTableIds []*string `json:"RouteTableIds" name:"RouteTableIds" list` + // 过滤条件,参数不支持同时指定RouteTableIds和Filters。 + //
  • route-table-id - String - (过滤条件)路由表实例ID。
  • + //
  • route-table-name - String - (过滤条件)路由表名称。
  • + //
  • vpc-id - String - (过滤条件)VPC实例ID,形如:vpc-f49l6u0z。
  • + //
  • association.main - String - (过滤条件)是否主路由表。
  • + Filters []*Filter `json:"Filters" name:"Filters" list` + // 偏移量。 + Offset *string `json:"Offset" name:"Offset"` + // 请求对象个数。 + Limit *string `json:"Limit" name:"Limit"` +} + +func (r *DescribeRouteTablesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeRouteTablesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeRouteTablesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 符合条件的实例数量。 + TotalCount *uint64 `json:"TotalCount" name:"TotalCount"` + // 路由表对象。 + RouteTableSet []*RouteTable `json:"RouteTableSet" name:"RouteTableSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeRouteTablesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeRouteTablesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeSecurityGroupAssociationStatisticsRequest struct { + *tchttp.BaseRequest + // 安全实例ID,例如sg-33ocnj9n,可通过DescribeSecurityGroups获取。 + SecurityGroupIds []*string `json:"SecurityGroupIds" name:"SecurityGroupIds" list` +} + +func (r *DescribeSecurityGroupAssociationStatisticsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeSecurityGroupAssociationStatisticsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeSecurityGroupAssociationStatisticsResponse struct { + *tchttp.BaseResponse + Response *struct { + // 安全组关联实例统计。 + SecurityGroupAssociationStatisticsSet []*SecurityGroupAssociationStatistics `json:"SecurityGroupAssociationStatisticsSet" name:"SecurityGroupAssociationStatisticsSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeSecurityGroupAssociationStatisticsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeSecurityGroupAssociationStatisticsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeSecurityGroupPoliciesRequest struct { + *tchttp.BaseRequest + // 安全组实例ID,例如:sg-33ocnj9n,可通过DescribeSecurityGroups获取。 + SecurityGroupId *string `json:"SecurityGroupId" name:"SecurityGroupId"` +} + +func (r *DescribeSecurityGroupPoliciesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeSecurityGroupPoliciesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeSecurityGroupPoliciesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 安全组规则集合。 + SecurityGroupPolicySet *SecurityGroupPolicySet `json:"SecurityGroupPolicySet" name:"SecurityGroupPolicySet"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeSecurityGroupPoliciesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeSecurityGroupPoliciesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeSecurityGroupsRequest struct { + *tchttp.BaseRequest + // 安全组实例ID,例如:sg-33ocnj9n,可通过DescribeSecurityGroups获取。每次请求的实例的上限为100。参数不支持同时指定SecurityGroupIds和Filters。 + SecurityGroupIds []*string `json:"SecurityGroupIds" name:"SecurityGroupIds" list` + // 过滤条件,参数不支持同时指定SecurityGroupIds和Filters。 + //
  • project-id - Integer - (过滤条件)项目id。
  • + //
  • security-group-name - String - (过滤条件)安全组名称。
  • + Filters []*Filter `json:"Filters" name:"Filters" list` + // 偏移量。 + Offset *string `json:"Offset" name:"Offset"` + // 返回数量。 + Limit *string `json:"Limit" name:"Limit"` +} + +func (r *DescribeSecurityGroupsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeSecurityGroupsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeSecurityGroupsResponse struct { + *tchttp.BaseResponse + Response *struct { + // 安全组对象。 + SecurityGroupSet []*SecurityGroup `json:"SecurityGroupSet" name:"SecurityGroupSet" list` + // 符合条件的实例数量。 + TotalCount *uint64 `json:"TotalCount" name:"TotalCount"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeSecurityGroupsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeSecurityGroupsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeServiceTemplateGroupsRequest struct { + *tchttp.BaseRequest + // 过滤条件。 + //
  • service-template-group-name - String - (过滤条件)协议端口模板集合名称。
  • + //
  • service-template-group-id - String - (过滤条件)协议端口模板集合实例ID,例如:ppmg-e6dy460g。
  • + Filters []*Filter `json:"Filters" name:"Filters" list` + // 偏移量,默认为0。 + Offset *string `json:"Offset" name:"Offset"` + // 返回数量,默认为20,最大值为100。 + Limit *string `json:"Limit" name:"Limit"` +} + +func (r *DescribeServiceTemplateGroupsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeServiceTemplateGroupsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeServiceTemplateGroupsResponse struct { + *tchttp.BaseResponse + Response *struct { + // 符合条件的实例数量。 + TotalCount *uint64 `json:"TotalCount" name:"TotalCount"` + // 协议端口模板集合。 + ServiceTemplateGroupSet []*ServiceTemplateGroup `json:"ServiceTemplateGroupSet" name:"ServiceTemplateGroupSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeServiceTemplateGroupsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeServiceTemplateGroupsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeServiceTemplatesRequest struct { + *tchttp.BaseRequest + // 过滤条件。 + //
  • service-template-name - String - (过滤条件)协议端口模板名称。
  • + //
  • service-template-id - String - (过滤条件)协议端口模板实例ID,例如:ppm-e6dy460g。
  • + Filters []*Filter `json:"Filters" name:"Filters" list` + // 偏移量,默认为0。 + Offset *string `json:"Offset" name:"Offset"` + // 返回数量,默认为20,最大值为100。 + Limit *string `json:"Limit" name:"Limit"` +} + +func (r *DescribeServiceTemplatesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeServiceTemplatesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeServiceTemplatesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 符合条件的实例数量。 + TotalCount *uint64 `json:"TotalCount" name:"TotalCount"` + // 协议端口模板对象。 + ServiceTemplateSet []*ServiceTemplate `json:"ServiceTemplateSet" name:"ServiceTemplateSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeServiceTemplatesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeServiceTemplatesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeSubnetsRequest struct { + *tchttp.BaseRequest + // 子网实例ID查询。形如:subnet-pxir56ns。每次请求的实例的上限为100。参数不支持同时指定SubnetIds和Filters。 + SubnetIds []*string `json:"SubnetIds" name:"SubnetIds" list` + // 过滤条件,参数不支持同时指定SubnetIds和Filters。 + //
  • subnet-id - String - (过滤条件)Subnet实例名称。
  • + //
  • vpc-id - String - (过滤条件)VPC实例ID,形如:vpc-f49l6u0z。
  • + //
  • cidr-block - String - (过滤条件)vpc的cidr。
  • + //
  • is-default - Boolean - (过滤条件)是否是默认子网。
  • + //
  • subnet-name - String - (过滤条件)子网名称。
  • + //
  • zone - String - (过滤条件)可用区。
  • + Filters []*Filter `json:"Filters" name:"Filters" list` + // 偏移量 + Offset *string `json:"Offset" name:"Offset"` + // 返回数量 + Limit *string `json:"Limit" name:"Limit"` +} + +func (r *DescribeSubnetsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeSubnetsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeSubnetsResponse struct { + *tchttp.BaseResponse + Response *struct { + // 符合条件的实例数量。 + TotalCount *uint64 `json:"TotalCount" name:"TotalCount"` + // 子网对象。 + SubnetSet []*Subnet `json:"SubnetSet" name:"SubnetSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeSubnetsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeSubnetsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeVpcsRequest struct { + *tchttp.BaseRequest + // VPC实例ID。形如:vpc-f49l6u0z。每次请求的实例的上限为100。参数不支持同时指定VpcIds和Filters。 + VpcIds []*string `json:"VpcIds" name:"VpcIds" list` + // 过滤条件,参数不支持同时指定VpcIds和Filters。 + //
  • vpc-name - String - (过滤条件)VPC实例名称。
  • + //
  • is-default - String - (过滤条件)是否默认VPC。
  • + //
  • vpc-id - String - (过滤条件)VPC实例ID形如:vpc-f49l6u0z。
  • + //
  • cidr-block - String - (过滤条件)vpc的cidr。
  • + Filters []*Filter `json:"Filters" name:"Filters" list` + // 偏移量 + Offset *string `json:"Offset" name:"Offset"` + // 返回数量 + Limit *string `json:"Limit" name:"Limit"` +} + +func (r *DescribeVpcsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeVpcsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeVpcsResponse struct { + *tchttp.BaseResponse + Response *struct { + // 符合条件的对象数。 + TotalCount *uint64 `json:"TotalCount" name:"TotalCount"` + // VPC对象。 + VpcSet []*Vpc `json:"VpcSet" name:"VpcSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeVpcsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeVpcsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeVpnConnectionsRequest struct { + *tchttp.BaseRequest + // VPN通道实例ID。形如:vpnx-f49l6u0z。每次请求的实例的上限为100。参数不支持同时指定VpnConnectionIds和Filters。 + VpnConnectionIds []*string `json:"VpnConnectionIds" name:"VpnConnectionIds" list` + // 过滤条件,详见下表:实例过滤条件表。每次请求的Filters的上限为10,Filter.Values的上限为5。参数不支持同时指定VpnConnectionIds和Filters。 + Filters []*Filter `json:"Filters" name:"Filters" list` + // 偏移量,默认为0。关于Offset的更进一步介绍请参考 API 简介中的相关小节。 + Offset *uint64 `json:"Offset" name:"Offset"` + // 返回数量,默认为20,最大值为100。 + Limit *uint64 `json:"Limit" name:"Limit"` +} + +func (r *DescribeVpnConnectionsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeVpnConnectionsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeVpnConnectionsResponse struct { + *tchttp.BaseResponse + Response *struct { + // 符合条件的实例数量。 + TotalCount *uint64 `json:"TotalCount" name:"TotalCount"` + // VPN通道实例。 + VpnConnectionSet []*VpnConnection `json:"VpnConnectionSet" name:"VpnConnectionSet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeVpnConnectionsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeVpnConnectionsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeVpnGatewaysRequest struct { + *tchttp.BaseRequest + // VPN网关实例ID。形如:vpngw-f49l6u0z。每次请求的实例的上限为100。参数不支持同时指定VpnGatewayIds和Filters。 + VpnGatewayIds []*string `json:"VpnGatewayIds" name:"VpnGatewayIds" list` + // 过滤条件,参数不支持同时指定VpnGatewayIds和Filters。 + //
  • vpc-id - String - (过滤条件)VPC实例ID形如:vpc-f49l6u0z。
  • + //
  • vpn-gateway-id - String - (过滤条件)VPN实例ID形如:vpngw-5aluhh9t。
  • + //
  • vpn-gateway-name - String - (过滤条件)VPN实例名称。
  • + //
  • type - String - (过滤条件)VPN网关类型:'IPSEC', 'SSL'。
  • + //
  • public-ip-address- String - (过滤条件)公网IP。
  • + //
  • renew-flag - String - (过滤条件)网关续费类型,手动续费:'NOTIFY_AND_MANUAL_RENEW'、自动续费:'NOTIFY_AND_AUTO_RENEW'。
  • + //
  • zone - String - (过滤条件)VPN所在可用区,形如:ap-guangzhou-2。
  • + Filters []*FilterObject `json:"Filters" name:"Filters" list` + // 偏移量 + Offset *uint64 `json:"Offset" name:"Offset"` + // 请求对象个数 + Limit *uint64 `json:"Limit" name:"Limit"` +} + +func (r *DescribeVpnGatewaysRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeVpnGatewaysRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeVpnGatewaysResponse struct { + *tchttp.BaseResponse + Response *struct { + // 符合条件的实例数量。 + TotalCount *uint64 `json:"TotalCount" name:"TotalCount"` + // VPN网关实例详细信息列表。 + VpnGatewaySet []*VpnGateway `json:"VpnGatewaySet" name:"VpnGatewaySet" list` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeVpnGatewaysResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeVpnGatewaysResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DetachCcnInstancesRequest struct { + *tchttp.BaseRequest + // CCN实例ID。形如:ccn-f49l6u0z。 + CcnId *string `json:"CcnId" name:"CcnId"` + // 要解关联网络实例列表 + Instances []*CcnInstance `json:"Instances" name:"Instances" list` +} + +func (r *DetachCcnInstancesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DetachCcnInstancesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DetachCcnInstancesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DetachCcnInstancesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DetachCcnInstancesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DetachClassicLinkVpcRequest struct { + *tchttp.BaseRequest + // VPC实例ID。可通过DescribeVpcs接口返回值中的VpcId获取。 + VpcId *string `json:"VpcId" name:"VpcId"` + // CVM实例ID查询。形如:ins-r8hr2upy。 + InstanceIds []*string `json:"InstanceIds" name:"InstanceIds" list` +} + +func (r *DetachClassicLinkVpcRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DetachClassicLinkVpcRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DetachClassicLinkVpcResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DetachClassicLinkVpcResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DetachClassicLinkVpcResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DetachNetworkInterfaceRequest struct { + *tchttp.BaseRequest + // 弹性网卡实例ID,例如:eni-m6dyj72l。 + NetworkInterfaceId *string `json:"NetworkInterfaceId" name:"NetworkInterfaceId"` + // CVM实例ID。形如:ins-r8hr2upy。 + InstanceId *string `json:"InstanceId" name:"InstanceId"` +} + +func (r *DetachNetworkInterfaceRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DetachNetworkInterfaceRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DetachNetworkInterfaceResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DetachNetworkInterfaceResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DetachNetworkInterfaceResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DirectConnectGateway struct { + // 专线网关ID + DirectConnectGatewayId *string `json:"DirectConnectGatewayId" name:"DirectConnectGatewayId"` + // 专线网关名称 + DirectConnectGatewayName *string `json:"DirectConnectGatewayName" name:"DirectConnectGatewayName"` + // VPC实例ID + VpcId *string `json:"VpcId" name:"VpcId"` + // 关联网络类型,可选值: + //
  • VPC - 私有网络
  • + //
  • CCN - 云联网
  • + NetworkType *string `json:"NetworkType" name:"NetworkType"` + //
  • NetworkType 为 VPC 时,这里传值为私有网络实例ID
  • + //
  • NetworkType 为 NAT 时,这里传值为云联网实例ID
  • + NetworkInstanceId *string `json:"NetworkInstanceId" name:"NetworkInstanceId"` + // 网关类型,可选值: + //
  • NORMAL - (默认)标准型,注:云联网只支持标准型
  • + //
  • NAT - NAT型
  • NAT类型支持网络地址转换配置,类型确定后不能修改;一个私有网络可以创建一个NAT类型的专线网关和一个非NAT类型的专线网关 + GatewayType *string `json:"GatewayType" name:"GatewayType"` + // 专线通道数 + DirectConnectTunnelCount *uint64 `json:"DirectConnectTunnelCount" name:"DirectConnectTunnelCount"` + // 创建时间 + CreateTime *string `json:"CreateTime" name:"CreateTime"` +} + +type DirectConnectGatewayCcnRoute struct { + // 路由ID + RouteId *string `json:"RouteId" name:"RouteId"` + // IDC网段 + DestinationCidrBlock *string `json:"DestinationCidrBlock" name:"DestinationCidrBlock"` +} + +type DisableCcnRoutesRequest struct { + *tchttp.BaseRequest + // CCN实例ID。形如:ccn-f49l6u0z。 + CcnId *string `json:"CcnId" name:"CcnId"` + // CCN路由策略唯一ID。形如:ccnr-f49l6u0z。 + RouteIds []*string `json:"RouteIds" name:"RouteIds" list` +} + +func (r *DisableCcnRoutesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DisableCcnRoutesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DisableCcnRoutesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DisableCcnRoutesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DisableCcnRoutesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DisableRoutesRequest struct { + *tchttp.BaseRequest + // 路由表唯一ID。 + RouteTableId *string `json:"RouteTableId" name:"RouteTableId"` + // 路由策略唯一ID。 + RouteIds []*uint64 `json:"RouteIds" name:"RouteIds" list` +} + +func (r *DisableRoutesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DisableRoutesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DisableRoutesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DisableRoutesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DisableRoutesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DisassociateAddressRequest struct { + *tchttp.BaseRequest + // 标识 EIP 的唯一 ID。EIP 唯一 ID 形如:`eip-11112222`。 + AddressId *string `json:"AddressId" name:"AddressId"` + // 表示解绑 EIP 之后是否分配普通公网 IP。取值范围:
  • TRUE:表示解绑 EIP 之后分配普通公网 IP。
  • FALSE:表示解绑 EIP 之后不分配普通公网 IP。
    默认取值:FALSE。

    只有满足以下条件时才能指定该参数:
  • 只有在解绑主网卡的主内网 IP 上的 EIP 时才能指定该参数。
  • 解绑 EIP 后重新分配普通公网 IP 操作一个账号每天最多操作 10 次;详情可通过 [DescribeAddressQuota](https://cloud.tencent.com/document/api/213/1378) 接口获取。 + ReallocateNormalPublicIp *bool `json:"ReallocateNormalPublicIp" name:"ReallocateNormalPublicIp"` +} + +func (r *DisassociateAddressRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DisassociateAddressRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DisassociateAddressResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DisassociateAddressResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DisassociateAddressResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DownloadCustomerGatewayConfigurationRequest struct { + *tchttp.BaseRequest + // VPN网关实例ID。 + VpnGatewayId *string `json:"VpnGatewayId" name:"VpnGatewayId"` + // VPN通道实例ID。形如:vpnx-f49l6u0z。 + VpnConnectionId *string `json:"VpnConnectionId" name:"VpnConnectionId"` + // 对端网关厂商信息对象,可通过DescribeCustomerGatewayVendors获取。 + CustomerGatewayVendor *CustomerGatewayVendor `json:"CustomerGatewayVendor" name:"CustomerGatewayVendor"` + // 通道接入设备物理接口名称。 + InterfaceName *string `json:"InterfaceName" name:"InterfaceName"` +} + +func (r *DownloadCustomerGatewayConfigurationRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DownloadCustomerGatewayConfigurationRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DownloadCustomerGatewayConfigurationResponse struct { + *tchttp.BaseResponse + Response *struct { + // XML格式配置信息。 + CustomerGatewayConfiguration *string `json:"CustomerGatewayConfiguration" name:"CustomerGatewayConfiguration"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *DownloadCustomerGatewayConfigurationResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DownloadCustomerGatewayConfigurationResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type EnableCcnRoutesRequest struct { + *tchttp.BaseRequest + // CCN实例ID。形如:ccn-f49l6u0z。 + CcnId *string `json:"CcnId" name:"CcnId"` + // CCN路由策略唯一ID。形如:ccnr-f49l6u0z。 + RouteIds []*string `json:"RouteIds" name:"RouteIds" list` +} + +func (r *EnableCcnRoutesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *EnableCcnRoutesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type EnableCcnRoutesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *EnableCcnRoutesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *EnableCcnRoutesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type EnableRoutesRequest struct { + *tchttp.BaseRequest + // 路由表唯一ID。 + RouteTableId *string `json:"RouteTableId" name:"RouteTableId"` + // 路由策略唯一ID。 + RouteIds []*uint64 `json:"RouteIds" name:"RouteIds" list` +} + +func (r *EnableRoutesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *EnableRoutesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type EnableRoutesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *EnableRoutesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *EnableRoutesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type Filter struct { + // 属性名称, 若存在多个Filter时,Filter间的关系为逻辑与(AND)关系。 + Name *string `json:"Name" name:"Name"` + // 属性值, 若同一个Filter存在多个Values,同一Filter下Values间的关系为逻辑或(OR)关系。 + Values []*string `json:"Values" name:"Values" list` +} + +type FilterObject struct { + // 属性名称, 若存在多个Filter时,Filter间的关系为逻辑与(AND)关系。 + Name *string `json:"Name" name:"Name"` + // 属性值, 若同一个Filter存在多个Values,同一Filter下Values间的关系为逻辑或(OR)关系。 + Values []*string `json:"Values" name:"Values" list` +} + +type IKEOptionsSpecification struct { + // 加密算法,可选值:'3DES-CBC', 'AES-CBC-128', 'AES-CBS-192', 'AES-CBC-256', 'DES-CBC',默认为3DES-CBC + PropoEncryAlgorithm *string `json:"PropoEncryAlgorithm" name:"PropoEncryAlgorithm"` + // 认证算法:可选值:'MD5', 'SHA1',默认为MD5 + PropoAuthenAlgorithm *string `json:"PropoAuthenAlgorithm" name:"PropoAuthenAlgorithm"` + // 协商模式:可选值:'AGGRESSIVE', 'MAIN',默认为MAIN + ExchangeMode *string `json:"ExchangeMode" name:"ExchangeMode"` + // 本端标识类型:可选值:'ADDRESS', 'FQDN',默认为ADDRESS + LocalIdentity *string `json:"LocalIdentity" name:"LocalIdentity"` + // 对端标识类型:可选值:'ADDRESS', 'FQDN',默认为ADDRESS + RemoteIdentity *string `json:"RemoteIdentity" name:"RemoteIdentity"` + // 本端标识,当LocalIdentity选为ADDRESS时,LocalAddress必填。localAddress默认为vpn网关公网IP + LocalAddress *string `json:"LocalAddress" name:"LocalAddress"` + // 对端标识,当RemoteIdentity选为ADDRESS时,RemoteAddress必填 + RemoteAddress *string `json:"RemoteAddress" name:"RemoteAddress"` + // 本端标识,当LocalIdentity选为FQDN时,LocalFqdnName必填 + LocalFqdnName *string `json:"LocalFqdnName" name:"LocalFqdnName"` + // 对端标识,当remoteIdentity选为FQDN时,RemoteFqdnName必填 + RemoteFqdnName *string `json:"RemoteFqdnName" name:"RemoteFqdnName"` + // DH group,指定IKE交换密钥时使用的DH组,可选值:'GROUP1', 'GROUP2', 'GROUP5', 'GROUP14', 'GROUP24', + DhGroupName *string `json:"DhGroupName" name:"DhGroupName"` + // IKE SA Lifetime,单位:秒,设置IKE SA的生存周期,取值范围:60-604800 + IKESaLifetimeSeconds *uint64 `json:"IKESaLifetimeSeconds" name:"IKESaLifetimeSeconds"` + // IKE版本 + IKEVersion *string `json:"IKEVersion" name:"IKEVersion"` +} + +type IPSECOptionsSpecification struct { + // 加密算法,可选值:'3DES-CBC', 'AES-CBC-128', 'AES-CBC-192', 'AES-CBC-256', 'DES-CBC', 'NULL', 默认为AES-CBC-128 + EncryptAlgorithm *string `json:"EncryptAlgorithm" name:"EncryptAlgorithm"` + // 认证算法:可选值:'MD5', 'SHA1',默认为 + IntegrityAlgorith *string `json:"IntegrityAlgorith" name:"IntegrityAlgorith"` + // IPsec SA lifetime(s):单位秒,取值范围:180-604800 + IPSECSaLifetimeSeconds *uint64 `json:"IPSECSaLifetimeSeconds" name:"IPSECSaLifetimeSeconds"` + // PFS:可选值:'NULL', 'DH-GROUP1', 'DH-GROUP2', 'DH-GROUP5', 'DH-GROUP14', 'DH-GROUP24',默认为NULL + PfsDhGroup *string `json:"PfsDhGroup" name:"PfsDhGroup"` + // IPsec SA lifetime(KB):单位KB,取值范围:2560-604800 + IPSECSaLifetimeTraffic *uint64 `json:"IPSECSaLifetimeTraffic" name:"IPSECSaLifetimeTraffic"` +} + +type InquiryPriceCreateVpnGatewayRequest struct { + *tchttp.BaseRequest + // 公网带宽设置。可选带宽规格:5, 10, 20, 50, 100;单位:Mbps。 + InternetMaxBandwidthOut *uint64 `json:"InternetMaxBandwidthOut" name:"InternetMaxBandwidthOut"` + // VPN网关计费模式,PREPAID:表示预付费,即包年包月,POSTPAID_BY_HOUR:表示后付费,即按量计费。默认:POSTPAID_BY_HOUR,如果指定预付费模式,参数InstanceChargePrepaid必填。 + InstanceChargeType *string `json:"InstanceChargeType" name:"InstanceChargeType"` + // 预付费模式,即包年包月相关参数设置。通过该参数可以指定包年包月实例的购买时长、是否设置自动续费等属性。若指定实例的付费模式为预付费则该参数必传。 + InstanceChargePrepaid *InstanceChargePrepaid `json:"InstanceChargePrepaid" name:"InstanceChargePrepaid"` +} + +func (r *InquiryPriceCreateVpnGatewayRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *InquiryPriceCreateVpnGatewayRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type InquiryPriceCreateVpnGatewayResponse struct { + *tchttp.BaseResponse + Response *struct { + // 商品价格。 + Price *Price `json:"Price" name:"Price"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *InquiryPriceCreateVpnGatewayResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *InquiryPriceCreateVpnGatewayResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type InquiryPriceRenewVpnGatewayRequest struct { + *tchttp.BaseRequest + // VPN网关实例ID。 + VpnGatewayId *string `json:"VpnGatewayId" name:"VpnGatewayId"` + // 预付费模式,即包年包月相关参数设置。通过该参数可以指定包年包月实例的购买时长、是否设置自动续费等属性。若指定实例的付费模式为预付费则该参数必传。 + InstanceChargePrepaid *InstanceChargePrepaid `json:"InstanceChargePrepaid" name:"InstanceChargePrepaid"` +} + +func (r *InquiryPriceRenewVpnGatewayRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *InquiryPriceRenewVpnGatewayRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type InquiryPriceRenewVpnGatewayResponse struct { + *tchttp.BaseResponse + Response *struct { + // 商品价格。 + Price *Price `json:"Price" name:"Price"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *InquiryPriceRenewVpnGatewayResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *InquiryPriceRenewVpnGatewayResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type InquiryPriceResetVpnGatewayInternetMaxBandwidthRequest struct { + *tchttp.BaseRequest + // VPN网关实例ID。 + VpnGatewayId *string `json:"VpnGatewayId" name:"VpnGatewayId"` + // 公网带宽设置。可选带宽规格:5, 10, 20, 50, 100;单位:Mbps。 + InternetMaxBandwidthOut *uint64 `json:"InternetMaxBandwidthOut" name:"InternetMaxBandwidthOut"` +} + +func (r *InquiryPriceResetVpnGatewayInternetMaxBandwidthRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *InquiryPriceResetVpnGatewayInternetMaxBandwidthRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type InquiryPriceResetVpnGatewayInternetMaxBandwidthResponse struct { + *tchttp.BaseResponse + Response *struct { + // 商品价格。 + Price *Price `json:"Price" name:"Price"` + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *InquiryPriceResetVpnGatewayInternetMaxBandwidthResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *InquiryPriceResetVpnGatewayInternetMaxBandwidthResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type InstanceChargePrepaid struct { + // 购买实例的时长,单位:月。取值范围:1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 24, 36。 + Period *uint64 `json:"Period" name:"Period"` + // 自动续费标识。取值范围: NOTIFY_AND_AUTO_RENEW:通知过期且自动续费, NOTIFY_AND_MANUAL_RENEW:通知过期不自动续费。默认:NOTIFY_AND_MANUAL_RENEW + RenewFlag *string `json:"RenewFlag" name:"RenewFlag"` +} + +type ItemPrice struct { + // 按量计费后付费单价,单位:元。 + UnitPrice *float64 `json:"UnitPrice" name:"UnitPrice"` + // 按量计费后付费计价单元,可取值范围: HOUR:表示计价单元是按每小时来计算。当前涉及该计价单元的场景有:实例按小时后付费(POSTPAID_BY_HOUR)、带宽按小时后付费(BANDWIDTH_POSTPAID_BY_HOUR): GB:表示计价单元是按每GB来计算。当前涉及该计价单元的场景有:流量按小时后付费(TRAFFIC_POSTPAID_BY_HOUR)。 + ChargeUnit *string `json:"ChargeUnit" name:"ChargeUnit"` + // 预付费商品的原价,单位:元。 + OriginalPrice *float64 `json:"OriginalPrice" name:"OriginalPrice"` + // 预付费商品的折扣价,单位:元。 + DiscountPrice *float64 `json:"DiscountPrice" name:"DiscountPrice"` +} + +type MigrateNetworkInterfaceRequest struct { + *tchttp.BaseRequest + // 弹性网卡实例ID,例如:eni-m6dyj72l。 + NetworkInterfaceId *string `json:"NetworkInterfaceId" name:"NetworkInterfaceId"` + // 弹性网卡当前绑定的CVM实例ID。形如:ins-r8hr2upy。 + SourceInstanceId *string `json:"SourceInstanceId" name:"SourceInstanceId"` + // 待迁移的目的CVM实例ID。 + DestinationInstanceId *string `json:"DestinationInstanceId" name:"DestinationInstanceId"` +} + +func (r *MigrateNetworkInterfaceRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *MigrateNetworkInterfaceRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type MigrateNetworkInterfaceResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *MigrateNetworkInterfaceResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *MigrateNetworkInterfaceResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type MigratePrivateIpAddressRequest struct { + *tchttp.BaseRequest + // 当内网IP绑定的弹性网卡实例ID,例如:eni-m6dyj72l。 + SourceNetworkInterfaceId *string `json:"SourceNetworkInterfaceId" name:"SourceNetworkInterfaceId"` + // 待迁移的目的弹性网卡实例ID。 + DestinationNetworkInterfaceId *string `json:"DestinationNetworkInterfaceId" name:"DestinationNetworkInterfaceId"` + // 迁移的内网IP地址,例如:10.0.0.6。 + PrivateIpAddress *string `json:"PrivateIpAddress" name:"PrivateIpAddress"` +} + +func (r *MigratePrivateIpAddressRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *MigratePrivateIpAddressRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type MigratePrivateIpAddressResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *MigratePrivateIpAddressResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *MigratePrivateIpAddressResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyAddressAttributeRequest struct { + *tchttp.BaseRequest + // 标识 EIP 的唯一 ID。EIP 唯一 ID 形如:`eip-11112222`。 + AddressId *string `json:"AddressId" name:"AddressId"` + // 修改后的 EIP 名称。长度上限为20个字符。 + AddressName *string `json:"AddressName" name:"AddressName"` +} + +func (r *ModifyAddressAttributeRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyAddressAttributeRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyAddressAttributeResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifyAddressAttributeResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyAddressAttributeResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyAddressTemplateAttributeRequest struct { + *tchttp.BaseRequest + // IP地址模板实例ID,例如:ipm-mdunqeb6。 + AddressTemplateId *string `json:"AddressTemplateId" name:"AddressTemplateId"` + // IP地址模板名称。 + AddressTemplateName *string `json:"AddressTemplateName" name:"AddressTemplateName"` + // 地址信息,支持 IP、CIDR、IP 范围。 + Addresses []*string `json:"Addresses" name:"Addresses" list` +} + +func (r *ModifyAddressTemplateAttributeRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyAddressTemplateAttributeRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyAddressTemplateAttributeResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifyAddressTemplateAttributeResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyAddressTemplateAttributeResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyAddressTemplateGroupAttributeRequest struct { + *tchttp.BaseRequest + // IP地址模板集合实例ID,例如:ipmg-2uw6ujo6。 + AddressTemplateGroupId *string `json:"AddressTemplateGroupId" name:"AddressTemplateGroupId"` + // IP地址模板集合名称。 + AddressTemplateGroupName *string `json:"AddressTemplateGroupName" name:"AddressTemplateGroupName"` + // IP地址模板实例ID, 例如:ipm-mdunqeb6。 + AddressTemplateIds []*string `json:"AddressTemplateIds" name:"AddressTemplateIds" list` +} + +func (r *ModifyAddressTemplateGroupAttributeRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyAddressTemplateGroupAttributeRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyAddressTemplateGroupAttributeResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifyAddressTemplateGroupAttributeResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyAddressTemplateGroupAttributeResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyAddressesBandwidthRequest struct { + *tchttp.BaseRequest + // EIP唯一标识id,形如'eip-xxxx' + AddressIds []*string `json:"AddressIds" name:"AddressIds" list` + // 调整带宽目标值 + InternetMaxBandwidthOut *int64 `json:"InternetMaxBandwidthOut" name:"InternetMaxBandwidthOut"` + // 包月带宽起始时间 + StartTime *string `json:"StartTime" name:"StartTime"` + // 包月带宽结束时间 + EndTime *string `json:"EndTime" name:"EndTime"` +} + +func (r *ModifyAddressesBandwidthRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyAddressesBandwidthRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyAddressesBandwidthResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifyAddressesBandwidthResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyAddressesBandwidthResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyBandwidthPackageAttributeRequest struct { + *tchttp.BaseRequest + // 带宽包唯一标识ID + BandwidthPackageId *string `json:"BandwidthPackageId" name:"BandwidthPackageId"` + // 带宽包名称 + BandwidthPackageName *string `json:"BandwidthPackageName" name:"BandwidthPackageName"` +} + +func (r *ModifyBandwidthPackageAttributeRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyBandwidthPackageAttributeRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyBandwidthPackageAttributeResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifyBandwidthPackageAttributeResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyBandwidthPackageAttributeResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyCcnAttributeRequest struct { + *tchttp.BaseRequest + // CCN实例ID。形如:ccn-f49l6u0z。 + CcnId *string `json:"CcnId" name:"CcnId"` + // CCN名称,最大长度不能超过60个字节。 + CcnName *string `json:"CcnName" name:"CcnName"` + // CCN描述信息,最大长度不能超过100个字节。 + CcnDescription *string `json:"CcnDescription" name:"CcnDescription"` +} + +func (r *ModifyCcnAttributeRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyCcnAttributeRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyCcnAttributeResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifyCcnAttributeResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyCcnAttributeResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyCustomerGatewayAttributeRequest struct { + *tchttp.BaseRequest + // 对端网关ID,例如:cgw-2wqq41m9,可通过DescribeCustomerGateways接口查询对端网关。 + CustomerGatewayId *string `json:"CustomerGatewayId" name:"CustomerGatewayId"` + // 对端网关名称,可任意命名,但不得超过60个字符。 + CustomerGatewayName *string `json:"CustomerGatewayName" name:"CustomerGatewayName"` +} + +func (r *ModifyCustomerGatewayAttributeRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyCustomerGatewayAttributeRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyCustomerGatewayAttributeResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifyCustomerGatewayAttributeResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyCustomerGatewayAttributeResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyNetworkInterfaceAttributeRequest struct { + *tchttp.BaseRequest + // 弹性网卡实例ID,例如:eni-pxir56ns。 + NetworkInterfaceId *string `json:"NetworkInterfaceId" name:"NetworkInterfaceId"` + // 弹性网卡名称,最大长度不能超过60个字节。 + NetworkInterfaceName *string `json:"NetworkInterfaceName" name:"NetworkInterfaceName"` + // 弹性网卡描述,可任意命名,但不得超过60个字符。 + NetworkInterfaceDescription *string `json:"NetworkInterfaceDescription" name:"NetworkInterfaceDescription"` + // 指定绑定的安全组,例如:['sg-1dd51d']。 + SecurityGroupIds []*string `json:"SecurityGroupIds" name:"SecurityGroupIds" list` +} + +func (r *ModifyNetworkInterfaceAttributeRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyNetworkInterfaceAttributeRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyNetworkInterfaceAttributeResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifyNetworkInterfaceAttributeResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyNetworkInterfaceAttributeResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyPrivateIpAddressesAttributeRequest struct { + *tchttp.BaseRequest + // 弹性网卡实例ID,例如:eni-m6dyj72l。 + NetworkInterfaceId *string `json:"NetworkInterfaceId" name:"NetworkInterfaceId"` + // 指定的内网IP信息。 + PrivateIpAddresses []*PrivateIpAddressSpecification `json:"PrivateIpAddresses" name:"PrivateIpAddresses" list` +} + +func (r *ModifyPrivateIpAddressesAttributeRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyPrivateIpAddressesAttributeRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyPrivateIpAddressesAttributeResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifyPrivateIpAddressesAttributeResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyPrivateIpAddressesAttributeResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyRouteTableAttributeRequest struct { + *tchttp.BaseRequest + // 路由表实例ID,例如:rtb-azd4dt1c。 + RouteTableId *string `json:"RouteTableId" name:"RouteTableId"` + // 路由表名称。 + RouteTableName *string `json:"RouteTableName" name:"RouteTableName"` +} + +func (r *ModifyRouteTableAttributeRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyRouteTableAttributeRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyRouteTableAttributeResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifyRouteTableAttributeResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyRouteTableAttributeResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifySecurityGroupAttributeRequest struct { + *tchttp.BaseRequest + // 安全组实例ID,例如sg-33ocnj9n,可通过DescribeSecurityGroups获取。 + SecurityGroupId *string `json:"SecurityGroupId" name:"SecurityGroupId"` + // 安全组名称,可任意命名,但不得超过60个字符。 + GroupName *string `json:"GroupName" name:"GroupName"` + // 安全组备注,最多100个字符。 + GroupDescription *string `json:"GroupDescription" name:"GroupDescription"` +} + +func (r *ModifySecurityGroupAttributeRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifySecurityGroupAttributeRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifySecurityGroupAttributeResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifySecurityGroupAttributeResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifySecurityGroupAttributeResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifySecurityGroupPoliciesRequest struct { + *tchttp.BaseRequest + // 安全组实例ID,例如sg-33ocnj9n,可通过DescribeSecurityGroups获取。 + SecurityGroupId *string `json:"SecurityGroupId" name:"SecurityGroupId"` + // 安全组规则集合。 SecurityGroupPolicySet对象必须同时指定新的出(Egress)入(Ingress)站规则。 SecurityGroupPolicy对象不支持自定义索引(PolicyIndex)。 + SecurityGroupPolicySet *SecurityGroupPolicySet `json:"SecurityGroupPolicySet" name:"SecurityGroupPolicySet"` +} + +func (r *ModifySecurityGroupPoliciesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifySecurityGroupPoliciesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifySecurityGroupPoliciesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifySecurityGroupPoliciesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifySecurityGroupPoliciesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyServiceTemplateAttributeRequest struct { + *tchttp.BaseRequest + // 协议端口模板实例ID,例如:ppm-529nwwj8。 + ServiceTemplateId *string `json:"ServiceTemplateId" name:"ServiceTemplateId"` + // 协议端口模板名称。 + ServiceTemplateName *string `json:"ServiceTemplateName" name:"ServiceTemplateName"` + // 支持单个端口、多个端口、连续端口及所有端口,协议支持:TCP、UDP、ICMP、GRE 协议。 + Services []*string `json:"Services" name:"Services" list` +} + +func (r *ModifyServiceTemplateAttributeRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyServiceTemplateAttributeRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyServiceTemplateAttributeResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifyServiceTemplateAttributeResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyServiceTemplateAttributeResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyServiceTemplateGroupAttributeRequest struct { + *tchttp.BaseRequest + // 协议端口模板集合实例ID,例如:ppmg-ei8hfd9a。 + ServiceTemplateGroupId *string `json:"ServiceTemplateGroupId" name:"ServiceTemplateGroupId"` + // 协议端口模板集合名称。 + ServiceTemplateGroupName *string `json:"ServiceTemplateGroupName" name:"ServiceTemplateGroupName"` + // 协议端口模板实例ID,例如:ppm-4dw6agho。 + ServiceTemplateIds []*string `json:"ServiceTemplateIds" name:"ServiceTemplateIds" list` +} + +func (r *ModifyServiceTemplateGroupAttributeRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyServiceTemplateGroupAttributeRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyServiceTemplateGroupAttributeResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifyServiceTemplateGroupAttributeResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyServiceTemplateGroupAttributeResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifySubnetAttributeRequest struct { + *tchttp.BaseRequest + // 子网实例ID。形如:subnet-pxir56ns。 + SubnetId *string `json:"SubnetId" name:"SubnetId"` + // 子网名称,最大长度不能超过60个字节。 + SubnetName *string `json:"SubnetName" name:"SubnetName"` + // 子网是否开启广播。 + EnableBroadcast *string `json:"EnableBroadcast" name:"EnableBroadcast"` +} + +func (r *ModifySubnetAttributeRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifySubnetAttributeRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifySubnetAttributeResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifySubnetAttributeResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifySubnetAttributeResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyVpcAttributeRequest struct { + *tchttp.BaseRequest + // VPC实例ID。形如:vpc-f49l6u0z。每次请求的实例的上限为100。参数不支持同时指定VpcIds和Filters。 + VpcId *string `json:"VpcId" name:"VpcId"` + // 私有网络名称,可任意命名,但不得超过60个字符。 + VpcName *string `json:"VpcName" name:"VpcName"` + // 是否开启组播。true: 开启, false: 关闭。 + EnableMulticast *string `json:"EnableMulticast" name:"EnableMulticast"` + // DNS地址,最多支持4个,第1个默认为主,其余为备 + DnsServers []*string `json:"DnsServers" name:"DnsServers" list` + // 域名 + DomainName *string `json:"DomainName" name:"DomainName"` +} + +func (r *ModifyVpcAttributeRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyVpcAttributeRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyVpcAttributeResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifyVpcAttributeResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyVpcAttributeResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyVpnConnectionAttributeRequest struct { + *tchttp.BaseRequest + // VPN通道实例ID。形如:vpnx-f49l6u0z。 + VpnConnectionId *string `json:"VpnConnectionId" name:"VpnConnectionId"` + // VPN通道名称,可任意命名,但不得超过60个字符。 + VpnConnectionName *string `json:"VpnConnectionName" name:"VpnConnectionName"` + // 预共享密钥。 + PreShareKey *string `json:"PreShareKey" name:"PreShareKey"` + // SPD策略组,例如:{"10.0.0.5/24":["172.123.10.5/16"]},10.0.0.5/24是vpc内网段172.123.10.5/16是IDC网段。用户指定VPC内哪些网段可以和您IDC中哪些网段通信。 + SecurityPolicyDatabases []*SecurityPolicyDatabase `json:"SecurityPolicyDatabases" name:"SecurityPolicyDatabases" list` + // IKE配置(Internet Key Exchange,因特网密钥交换),IKE具有一套自保护机制,用户配置网络安全协议。 + IKEOptionsSpecification *IKEOptionsSpecification `json:"IKEOptionsSpecification" name:"IKEOptionsSpecification"` + // IPSec配置,腾讯云提供IPSec安全会话设置。 + IPSECOptionsSpecification *IPSECOptionsSpecification `json:"IPSECOptionsSpecification" name:"IPSECOptionsSpecification"` +} + +func (r *ModifyVpnConnectionAttributeRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyVpnConnectionAttributeRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyVpnConnectionAttributeResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifyVpnConnectionAttributeResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyVpnConnectionAttributeResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyVpnGatewayAttributeRequest struct { + *tchttp.BaseRequest + // VPN网关实例ID。 + VpnGatewayId *string `json:"VpnGatewayId" name:"VpnGatewayId"` + // VPN网关名称,最大长度不能超过60个字节。 + VpnGatewayName *string `json:"VpnGatewayName" name:"VpnGatewayName"` + // VPN网关计费模式,目前只支持预付费(即包年包月)到后付费(即按量计费)的转换。即参数只支持:POSTPAID_BY_HOUR。 + InstanceChargeType *string `json:"InstanceChargeType" name:"InstanceChargeType"` +} + +func (r *ModifyVpnGatewayAttributeRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyVpnGatewayAttributeRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyVpnGatewayAttributeResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ModifyVpnGatewayAttributeResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ModifyVpnGatewayAttributeResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type NetworkInterface struct { + // 弹性网卡实例ID,例如:eni-f1xjkw1b。 + NetworkInterfaceId *string `json:"NetworkInterfaceId" name:"NetworkInterfaceId"` + // 弹性网卡名称。 + NetworkInterfaceName *string `json:"NetworkInterfaceName" name:"NetworkInterfaceName"` + // 弹性网卡描述。 + NetworkInterfaceDescription *string `json:"NetworkInterfaceDescription" name:"NetworkInterfaceDescription"` + // 子网实例ID。 + SubnetId *string `json:"SubnetId" name:"SubnetId"` + // VPC实例ID。 + VpcId *string `json:"VpcId" name:"VpcId"` + // 绑定的安全组。 + GroupSet []*string `json:"GroupSet" name:"GroupSet" list` + // 是否是主网卡。 + Primary *bool `json:"Primary" name:"Primary"` + // MAC地址。 + MacAddress *string `json:"MacAddress" name:"MacAddress"` + // 取值范围:PENDING|AVAILABLE|ATTACHING|DETACHING|DELETING。 + State *string `json:"State" name:"State"` + // 内网IP信息。 + PrivateIpAddressSet []*PrivateIpAddressSpecification `json:"PrivateIpAddressSet" name:"PrivateIpAddressSet" list` + // 绑定的云服务器对象。 + Attachment *NetworkInterfaceAttachment `json:"Attachment" name:"Attachment"` + // 可用区。 + Zone *string `json:"Zone" name:"Zone"` + // 创建时间。 + CreatedTime *string `json:"CreatedTime" name:"CreatedTime"` +} + +type NetworkInterfaceAttachment struct { + // 云主机实例ID。 + InstanceId *string `json:"InstanceId" name:"InstanceId"` + // 网卡在云主机实例内的序号。 + DeviceIndex *uint64 `json:"DeviceIndex" name:"DeviceIndex"` + // 云主机所有者账户信息。 + InstanceAccountId *string `json:"InstanceAccountId" name:"InstanceAccountId"` + // 绑定时间。 + AttachTime *string `json:"AttachTime" name:"AttachTime"` +} + +type Price struct { + // 实例价格。 + InstancePrice *ItemPrice `json:"InstancePrice" name:"InstancePrice"` + // 网络价格。 + BandwidthPrice *ItemPrice `json:"BandwidthPrice" name:"BandwidthPrice"` +} + +type PrivateIpAddressSpecification struct { + // 内网IP地址。 + PrivateIpAddress *string `json:"PrivateIpAddress" name:"PrivateIpAddress"` + // 是否是主IP。 + Primary *bool `json:"Primary" name:"Primary"` + // 公网IP地址。 + PublicIpAddress *string `json:"PublicIpAddress" name:"PublicIpAddress"` + // EIP实例ID,例如:eip-11112222。 + AddressId *string `json:"AddressId" name:"AddressId"` + // 内网IP描述信息。 + Description *string `json:"Description" name:"Description"` + // 公网IP是否被封堵。 + IsWanIpBlocked *bool `json:"IsWanIpBlocked" name:"IsWanIpBlocked"` + // IP状态: + // PENDING:生产中 + // MIGRATING:迁移中 + // DELETING:删除中 + // AVAILABLE:可用的 + State *string `json:"State" name:"State"` +} + +type Quota struct { + // 配额名称,取值范围:
  • `TOTAL_EIP_QUOTA`:用户当前地域下EIP的配额数;
  • `DAILY_EIP_APPLY`:用户当前地域下今日申购次数;
  • `DAILY_PUBLIC_IP_ASSIGN`:用户当前地域下,重新分配公网 IP次数。 + QuotaId *string `json:"QuotaId" name:"QuotaId"` + // 当前数量 + QuotaCurrent *int64 `json:"QuotaCurrent" name:"QuotaCurrent"` + // 配额数量 + QuotaLimit *int64 `json:"QuotaLimit" name:"QuotaLimit"` +} + +type RejectAttachCcnInstancesRequest struct { + *tchttp.BaseRequest + // CCN实例ID。形如:ccn-f49l6u0z。 + CcnId *string `json:"CcnId" name:"CcnId"` + // 拒绝关联实例列表。 + Instances []*CcnInstance `json:"Instances" name:"Instances" list` +} + +func (r *RejectAttachCcnInstancesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *RejectAttachCcnInstancesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type RejectAttachCcnInstancesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *RejectAttachCcnInstancesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *RejectAttachCcnInstancesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ReleaseAddressesRequest struct { + *tchttp.BaseRequest + // 标识 EIP 的唯一 ID 列表。EIP 唯一 ID 形如:`eip-11112222`。 + AddressIds []*string `json:"AddressIds" name:"AddressIds" list` +} + +func (r *ReleaseAddressesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ReleaseAddressesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ReleaseAddressesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ReleaseAddressesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ReleaseAddressesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type RemoveBandwidthPackageResourcesRequest struct { + *tchttp.BaseRequest + // 带宽包唯一标识ID,形如'bwp-xxxx' + BandwidthPackageId *string `json:"BandwidthPackageId" name:"BandwidthPackageId"` + // 资源类型,包括‘Address’, ‘LoadBalance’ + ResourceType *string `json:"ResourceType" name:"ResourceType"` + // 资源Id,形如'eip-xxxx', 'lb-xxxx' + ResourceIds []*string `json:"ResourceIds" name:"ResourceIds" list` +} + +func (r *RemoveBandwidthPackageResourcesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *RemoveBandwidthPackageResourcesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type RemoveBandwidthPackageResourcesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *RemoveBandwidthPackageResourcesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *RemoveBandwidthPackageResourcesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type RenewVpnGatewayRequest struct { + *tchttp.BaseRequest + // VPN网关实例ID。 + VpnGatewayId *string `json:"VpnGatewayId" name:"VpnGatewayId"` + // 预付费计费模式。 + InstanceChargePrepaid *InstanceChargePrepaid `json:"InstanceChargePrepaid" name:"InstanceChargePrepaid"` +} + +func (r *RenewVpnGatewayRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *RenewVpnGatewayRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type RenewVpnGatewayResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *RenewVpnGatewayResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *RenewVpnGatewayResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ReplaceDirectConnectGatewayCcnRoutesRequest struct { + *tchttp.BaseRequest + // 专线网关ID,形如:dcg-prpqlmg1 + DirectConnectGatewayId *string `json:"DirectConnectGatewayId" name:"DirectConnectGatewayId"` + // 需要连通的IDC网段列表 + Routes []*DirectConnectGatewayCcnRoute `json:"Routes" name:"Routes" list` +} + +func (r *ReplaceDirectConnectGatewayCcnRoutesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ReplaceDirectConnectGatewayCcnRoutesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ReplaceDirectConnectGatewayCcnRoutesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ReplaceDirectConnectGatewayCcnRoutesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ReplaceDirectConnectGatewayCcnRoutesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ReplaceRouteTableAssociationRequest struct { + *tchttp.BaseRequest + // 子网实例ID,例如:subnet-3x5lf5q0。可通过DescribeSubnets接口查询。 + SubnetId *string `json:"SubnetId" name:"SubnetId"` + // 路由表实例ID,例如:rtb-azd4dt1c。 + RouteTableId *string `json:"RouteTableId" name:"RouteTableId"` +} + +func (r *ReplaceRouteTableAssociationRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ReplaceRouteTableAssociationRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ReplaceRouteTableAssociationResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ReplaceRouteTableAssociationResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ReplaceRouteTableAssociationResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ReplaceRoutesRequest struct { + *tchttp.BaseRequest + // 路由表实例ID,例如:rtb-azd4dt1c。 + RouteTableId *string `json:"RouteTableId" name:"RouteTableId"` + // 路由策略对象。只需要指定路由策略ID(RouteId)。 + Routes []*Route `json:"Routes" name:"Routes" list` +} + +func (r *ReplaceRoutesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ReplaceRoutesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ReplaceRoutesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ReplaceRoutesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ReplaceRoutesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ReplaceSecurityGroupPolicyRequest struct { + *tchttp.BaseRequest + // 安全组实例ID,例如sg-33ocnj9n,可通过DescribeSecurityGroups获取。 + SecurityGroupId *string `json:"SecurityGroupId" name:"SecurityGroupId"` + // 安全组规则集合对象。 + SecurityGroupPolicySet *SecurityGroupPolicySet `json:"SecurityGroupPolicySet" name:"SecurityGroupPolicySet"` +} + +func (r *ReplaceSecurityGroupPolicyRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ReplaceSecurityGroupPolicyRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ReplaceSecurityGroupPolicyResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ReplaceSecurityGroupPolicyResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ReplaceSecurityGroupPolicyResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ResetAttachCcnInstancesRequest struct { + *tchttp.BaseRequest + // CCN实例ID。形如:ccn-f49l6u0z。 + CcnId *string `json:"CcnId" name:"CcnId"` + // CCN所属UIN(根账号)。 + CcnUin *string `json:"CcnUin" name:"CcnUin"` + // 重新申请关联网络实例列表。 + Instances []*CcnInstance `json:"Instances" name:"Instances" list` +} + +func (r *ResetAttachCcnInstancesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ResetAttachCcnInstancesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ResetAttachCcnInstancesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ResetAttachCcnInstancesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ResetAttachCcnInstancesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ResetRoutesRequest struct { + *tchttp.BaseRequest + // 路由表实例ID,例如:rtb-azd4dt1c。 + RouteTableId *string `json:"RouteTableId" name:"RouteTableId"` + // 路由表名称,最大长度不能超过60个字节。 + RouteTableName *string `json:"RouteTableName" name:"RouteTableName"` + // 路由策略。 + Routes []*Route `json:"Routes" name:"Routes" list` +} + +func (r *ResetRoutesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ResetRoutesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ResetRoutesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ResetRoutesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ResetRoutesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ResetVpnConnectionRequest struct { + *tchttp.BaseRequest + // VPN网关实例ID。 + VpnGatewayId *string `json:"VpnGatewayId" name:"VpnGatewayId"` + // VPN通道实例ID。形如:vpnx-f49l6u0z。 + VpnConnectionId *string `json:"VpnConnectionId" name:"VpnConnectionId"` +} + +func (r *ResetVpnConnectionRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ResetVpnConnectionRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ResetVpnConnectionResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ResetVpnConnectionResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ResetVpnConnectionResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ResetVpnGatewayInternetMaxBandwidthRequest struct { + *tchttp.BaseRequest + // VPN网关实例ID。 + VpnGatewayId *string `json:"VpnGatewayId" name:"VpnGatewayId"` + // 公网带宽设置。可选带宽规格:5, 10, 20, 50, 100;单位:Mbps。 + InternetMaxBandwidthOut *uint64 `json:"InternetMaxBandwidthOut" name:"InternetMaxBandwidthOut"` +} + +func (r *ResetVpnGatewayInternetMaxBandwidthRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ResetVpnGatewayInternetMaxBandwidthRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ResetVpnGatewayInternetMaxBandwidthResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *ResetVpnGatewayInternetMaxBandwidthResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ResetVpnGatewayInternetMaxBandwidthResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type Resource struct { + // 带宽包资源类型,包括'Address'和'LoadBalance' + ResourceType *string `json:"ResourceType" name:"ResourceType"` + // 带宽包资源Id,形如'eip-xxxx', 'lb-xxxx' + ResourceId *string `json:"ResourceId" name:"ResourceId"` + // 带宽包资源Ip + AddressIp *string `json:"AddressIp" name:"AddressIp"` +} + +type Route struct { + // 目的网段,取值不能在私有网络网段内,例如:112.20.51.0/24。 + DestinationCidrBlock *string `json:"DestinationCidrBlock" name:"DestinationCidrBlock"` + // 下一跳类型,目前我们支持的类型有: + // CVM:公网网关类型的云主机; + // VPN:VPN网关; + // DIRECTCONNECT:专线网关; + // PEERCONNECTION:对等连接; + // SSLVPN:sslvpn网关; + // NAT:NAT网关; + // NORMAL_CVM:普通云主机; + // EIP:云主机的公网IP; + // CCN:云联网。 + GatewayType *string `json:"GatewayType" name:"GatewayType"` + // 下一跳地址,这里只需要指定不同下一跳类型的网关ID,系统会自动匹配到下一跳地址。 + // 特别注意:当 GatewayType 为 EIP 时,GatewayId 固定值 '0' + GatewayId *string `json:"GatewayId" name:"GatewayId"` + // 路由策略ID。 + RouteId *uint64 `json:"RouteId" name:"RouteId"` + // 路由策略描述。 + RouteDescription *string `json:"RouteDescription" name:"RouteDescription"` + // 是否启用 + Enabled *bool `json:"Enabled" name:"Enabled"` + // 路由类型,目前我们支持的类型有: + // USER:用户路由; + // NETD:网络探测路由,创建网络探测实例时,系统默认下发,不可编辑与删除; + // CCN:云联网路由,系统默认下发,不可编辑与删除。 + // 用户只能添加和操作 USER 类型的路由。 + RouteType *string `json:"RouteType" name:"RouteType"` +} + +type RouteConflict struct { + // 路由表实例ID,例如:rtb-azd4dt1c。 + RouteTableId *string `json:"RouteTableId" name:"RouteTableId"` + // 要检查的与之冲突的目的端 + DestinationCidrBlock *string `json:"DestinationCidrBlock" name:"DestinationCidrBlock"` + // 冲突的路由策略列表 + ConflictSet []*Route `json:"ConflictSet" name:"ConflictSet" list` +} + +type RouteTable struct { + // VPC实例ID。 + VpcId *string `json:"VpcId" name:"VpcId"` + // 路由表实例ID,例如:rtb-azd4dt1c。 + RouteTableId *string `json:"RouteTableId" name:"RouteTableId"` + // 路由表名称。 + RouteTableName *string `json:"RouteTableName" name:"RouteTableName"` + // 路由表关联关系。 + AssociationSet []*RouteTableAssociation `json:"AssociationSet" name:"AssociationSet" list` + // 路由表策略集合。 + RouteSet []*Route `json:"RouteSet" name:"RouteSet" list` + // 是否默认路由表。 + Main *bool `json:"Main" name:"Main"` + // 创建时间。 + CreatedTime *string `json:"CreatedTime" name:"CreatedTime"` +} + +type RouteTableAssociation struct { + // 子网实例ID。 + SubnetId *string `json:"SubnetId" name:"SubnetId"` + // 路由表实例ID。 + RouteTableId *string `json:"RouteTableId" name:"RouteTableId"` +} + +type SecurityGroup struct { + // 安全组实例ID,例如:sg-ohuuioma。 + SecurityGroupId *string `json:"SecurityGroupId" name:"SecurityGroupId"` + // 安全组名称,可任意命名,但不得超过60个字符。 + SecurityGroupName *string `json:"SecurityGroupName" name:"SecurityGroupName"` + // 安全组备注,最多100个字符。 + SecurityGroupDesc *string `json:"SecurityGroupDesc" name:"SecurityGroupDesc"` + // 项目id,默认0。可在qcloud控制台项目管理页面查询到。 + ProjectId *string `json:"ProjectId" name:"ProjectId"` + // 是否是默认安全组,默认安全组不支持删除。 + IsDefault *bool `json:"IsDefault" name:"IsDefault"` + // 安全组创建时间。 + CreatedTime *string `json:"CreatedTime" name:"CreatedTime"` +} + +type SecurityGroupAssociationStatistics struct { + // 安全组实例ID。 + SecurityGroupId *string `json:"SecurityGroupId" name:"SecurityGroupId"` + // 云主机实例数。 + CVM *uint64 `json:"CVM" name:"CVM"` + // 数据库实例数。 + CDB *uint64 `json:"CDB" name:"CDB"` + // 弹性网卡实例数。 + ENI *uint64 `json:"ENI" name:"ENI"` + // 被安全组引用数。 + SG *uint64 `json:"SG" name:"SG"` + // 负载均衡实例数。 + CLB *uint64 `json:"CLB" name:"CLB"` +} + +type SecurityGroupPolicy struct { + // 安全组规则索引号。 + PolicyIndex *int64 `json:"PolicyIndex" name:"PolicyIndex"` + // 协议, 取值: TCP,UDP, ICMP。 + Protocol *string `json:"Protocol" name:"Protocol"` + // 端口(all, 离散port, range)。 + Port *string `json:"Port" name:"Port"` + // 协议端口ID或者协议端口组ID。ServiceTemplate和Protocol+Port互斥。 + ServiceTemplate *ServiceTemplateSpecification `json:"ServiceTemplate" name:"ServiceTemplate"` + // 网段或IP(互斥)。 + CidrBlock *string `json:"CidrBlock" name:"CidrBlock"` + // 已绑定安全组的网段或IP。 + SecurityGroupId *string `json:"SecurityGroupId" name:"SecurityGroupId"` + // IP地址ID或者ID地址组ID。 + AddressTemplate *AddressTemplateSpecification `json:"AddressTemplate" name:"AddressTemplate"` + // ACCEPT 或 DROP。 + Action *string `json:"Action" name:"Action"` + // 安全组规则描述。 + PolicyDescription *string `json:"PolicyDescription" name:"PolicyDescription"` +} + +type SecurityGroupPolicySet struct { + // 安全组规则当前版本。用户每次更新安全规则版本会自动加1,防止更新的路由规则已过期,不填不考虑冲突。 + Version *string `json:"Version" name:"Version"` + // 出站规则。 + Egress []*SecurityGroupPolicy `json:"Egress" name:"Egress" list` + // 入站规则。 + Ingress []*SecurityGroupPolicy `json:"Ingress" name:"Ingress" list` +} + +type SecurityPolicyDatabase struct { + // 本端网段 + LocalCidrBlock *string `json:"LocalCidrBlock" name:"LocalCidrBlock"` + // 对端网段 + RemoteCidrBlock []*string `json:"RemoteCidrBlock" name:"RemoteCidrBlock" list` +} + +type ServiceTemplate struct { + // 协议端口实例ID,例如:ppm-f5n1f8da。 + ServiceTemplateId *string `json:"ServiceTemplateId" name:"ServiceTemplateId"` + // 模板名称。 + ServiceTemplateName *string `json:"ServiceTemplateName" name:"ServiceTemplateName"` + // 协议端口信息。 + ServiceSet []*string `json:"ServiceSet" name:"ServiceSet" list` + // 创建时间。 + CreatedTime *string `json:"CreatedTime" name:"CreatedTime"` +} + +type ServiceTemplateGroup struct { + // 协议端口模板集合实例ID,例如:ppmg-2klmrefu。 + ServiceTemplateGroupId *string `json:"ServiceTemplateGroupId" name:"ServiceTemplateGroupId"` + // 协议端口模板集合名称。 + ServiceTemplateGroupName *string `json:"ServiceTemplateGroupName" name:"ServiceTemplateGroupName"` + // 协议端口模板实例ID。 + ServiceTemplateIdSet []*string `json:"ServiceTemplateIdSet" name:"ServiceTemplateIdSet" list` + // 创建时间。 + CreatedTime *string `json:"CreatedTime" name:"CreatedTime"` +} + +type ServiceTemplateSpecification struct { + // 协议端口ID,例如:ppm-f5n1f8da。 + ServiceId *string `json:"ServiceId" name:"ServiceId"` + // 协议端口组ID,例如:ppmg-f5n1f8da。 + ServiceGroupId *string `json:"ServiceGroupId" name:"ServiceGroupId"` +} + +type SetCcnRegionBandwidthLimitsRequest struct { + *tchttp.BaseRequest + // CCN实例ID。形如:ccn-f49l6u0z。 + CcnId *string `json:"CcnId" name:"CcnId"` + // 云联网(CCN)各地域出带宽上限。 + CcnRegionBandwidthLimits []*CcnRegionBandwidthLimit `json:"CcnRegionBandwidthLimits" name:"CcnRegionBandwidthLimits" list` +} + +func (r *SetCcnRegionBandwidthLimitsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *SetCcnRegionBandwidthLimitsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type SetCcnRegionBandwidthLimitsResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *SetCcnRegionBandwidthLimitsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *SetCcnRegionBandwidthLimitsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type Subnet struct { + // VPC实例ID。 + VpcId *string `json:"VpcId" name:"VpcId"` + // 子网实例ID,例如:subnet-bthucmmy。 + SubnetId *string `json:"SubnetId" name:"SubnetId"` + // 子网名称。 + SubnetName *string `json:"SubnetName" name:"SubnetName"` + // 子网的CIDR。 + CidrBlock *string `json:"CidrBlock" name:"CidrBlock"` + // 是否默认子网。 + IsDefault *bool `json:"IsDefault" name:"IsDefault"` + // 是否开启广播。 + EnableBroadcast *bool `json:"EnableBroadcast" name:"EnableBroadcast"` + // 可用区。 + Zone *string `json:"Zone" name:"Zone"` + // 路由表实例ID,例如:rtb-l2h8d7c2。 + RouteTableId *string `json:"RouteTableId" name:"RouteTableId"` + // 创建时间。 + CreatedTime *string `json:"CreatedTime" name:"CreatedTime"` + // 可用IP数。 + AvailableIpAddressCount *uint64 `json:"AvailableIpAddressCount" name:"AvailableIpAddressCount"` +} + +type TransformAddressRequest struct { + *tchttp.BaseRequest + // 待操作有普通公网 IP 的实例 ID。实例 ID 形如:`ins-11112222`。可通过登录[控制台](https://console.cloud.tencent.com/cvm)查询,也可通过 [DescribeInstances](https://cloud.tencent.com/document/api/213/9389) 接口返回值中的`InstanceId`获取。 + InstanceId *string `json:"InstanceId" name:"InstanceId"` +} + +func (r *TransformAddressRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *TransformAddressRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type TransformAddressResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *TransformAddressResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *TransformAddressResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type UnassignPrivateIpAddressesRequest struct { + *tchttp.BaseRequest + // 弹性网卡实例ID,例如:eni-m6dyj72l。 + NetworkInterfaceId *string `json:"NetworkInterfaceId" name:"NetworkInterfaceId"` + // 指定的内网IP信息。 + PrivateIpAddresses []*PrivateIpAddressSpecification `json:"PrivateIpAddresses" name:"PrivateIpAddresses" list` +} + +func (r *UnassignPrivateIpAddressesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *UnassignPrivateIpAddressesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type UnassignPrivateIpAddressesResponse struct { + *tchttp.BaseResponse + Response *struct { + // 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 + RequestId *string `json:"RequestId" name:"RequestId"` + } `json:"Response"` +} + +func (r *UnassignPrivateIpAddressesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *UnassignPrivateIpAddressesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type Vpc struct { + // Vpc名称。 + VpcName *string `json:"VpcName" name:"VpcName"` + // VPC实例ID,例如:vpc-azd4dt1c。 + VpcId *string `json:"VpcId" name:"VpcId"` + // VPC的cidr,只能为10.0.0.0/16,172.16.0.0/12,192.168.0.0/16这三个内网网段内。 + CidrBlock *string `json:"CidrBlock" name:"CidrBlock"` + // 是否默认VPC。 + IsDefault *bool `json:"IsDefault" name:"IsDefault"` + // 是否开启组播。 + EnableMulticast *bool `json:"EnableMulticast" name:"EnableMulticast"` + // 创建时间。 + CreatedTime *string `json:"CreatedTime" name:"CreatedTime"` + // DNS列表 + DnsServerSet []*string `json:"DnsServerSet" name:"DnsServerSet" list` + // DHCP域名选项值 + DomainName *string `json:"DomainName" name:"DomainName"` + // DHCP选项集ID + DhcpOptionsId *string `json:"DhcpOptionsId" name:"DhcpOptionsId"` +} + +type VpnConnection struct { + // 通道实例ID。 + VpnConnectionId *string `json:"VpnConnectionId" name:"VpnConnectionId"` + // 通道名称。 + VpnConnectionName *string `json:"VpnConnectionName" name:"VpnConnectionName"` + // VPC实例ID。 + VpcId *string `json:"VpcId" name:"VpcId"` + // VPN网关实例ID。 + VpnGatewayId *string `json:"VpnGatewayId" name:"VpnGatewayId"` + // 对端网关实例ID。 + CustomerGatewayId *string `json:"CustomerGatewayId" name:"CustomerGatewayId"` + // 预共享密钥。 + PreShareKey *string `json:"PreShareKey" name:"PreShareKey"` + // 通道传输协议。 + VpnProto *string `json:"VpnProto" name:"VpnProto"` + // 通道加密协议。 + EncryptProto *string `json:"EncryptProto" name:"EncryptProto"` + // 路由类型。 + RouteType *string `json:"RouteType" name:"RouteType"` + // 创建时间。 + CreatedTime *string `json:"CreatedTime" name:"CreatedTime"` + // 通道的生产状态,PENDING:生产中,AVAILABLE:运行中,DELETING:删除中。 + State *string `json:"State" name:"State"` + // 通道连接状态,AVAILABLE:已连接。 + NetStatus *string `json:"NetStatus" name:"NetStatus"` + // SPD。 + SecurityPolicyDatabaseSet []*SecurityPolicyDatabase `json:"SecurityPolicyDatabaseSet" name:"SecurityPolicyDatabaseSet" list` + // IKE选项。 + IKEOptionsSpecification *IKEOptionsSpecification `json:"IKEOptionsSpecification" name:"IKEOptionsSpecification"` + // IPSEC选择。 + IPSECOptionsSpecification *IPSECOptionsSpecification `json:"IPSECOptionsSpecification" name:"IPSECOptionsSpecification"` +} + +type VpnGateway struct { + // 网关实例ID。 + VpnGatewayId *string `json:"VpnGatewayId" name:"VpnGatewayId"` + // VPC实例ID。 + VpcId *string `json:"VpcId" name:"VpcId"` + // 网关实例名称。 + VpnGatewayName *string `json:"VpnGatewayName" name:"VpnGatewayName"` + // 网关实例类型:'IPSEC', 'SSL'。 + Type *string `json:"Type" name:"Type"` + // 网关实例状态, 'PENDING':生产中,'DELETING':删除中,'AVAILABLE':运行中。 + State *string `json:"State" name:"State"` + // 网关公网IP。 + PublicIpAddress *string `json:"PublicIpAddress" name:"PublicIpAddress"` + // 网关续费类型:'NOTIFY_AND_MANUAL_RENEW':手动续费,'NOTIFY_AND_AUTO_RENEW':自动续费 + RenewFlag *string `json:"RenewFlag" name:"RenewFlag"` + // 网关付费类型:POSTPAID_BY_HOUR:按小时后付费,PREPAID:包年包月预付费, + InstanceChargeType *string `json:"InstanceChargeType" name:"InstanceChargeType"` + // 网关出带宽。 + InternetMaxBandwidthOut *uint64 `json:"InternetMaxBandwidthOut" name:"InternetMaxBandwidthOut"` + // 创建时间。 + CreatedTime *string `json:"CreatedTime" name:"CreatedTime"` + // 预付费网关过期时间。 + ExpiredTime *string `json:"ExpiredTime" name:"ExpiredTime"` + // 公网IP是否被封堵。 + IsAddressBlocked *bool `json:"IsAddressBlocked" name:"IsAddressBlocked"` + // 计费模式变更,PREPAID_TO_POSTPAID:包年包月预付费到期转按小时后付费。 + NewPurchasePlan *string `json:"NewPurchasePlan" name:"NewPurchasePlan"` + // 网关计费装,PROTECTIVELY_ISOLATED:被安全隔离的实例,NORMAL:正常。 + RestrictState *string `json:"RestrictState" name:"RestrictState"` + // 可用区,如:ap-guangzhou-2 + Zone *string `json:"Zone" name:"Zone"` +} diff --git a/vendor/vendor.json b/vendor/vendor.json index 17d9bde1f..d12f143bb 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -1552,6 +1552,42 @@ "version": "v1.2.1", "versionExact": "v1.2.1" }, + { + "checksumSHA1": "Tq2BiJUqHH6rryU5xGdD/WQlxSk=", + "path": "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common", + "revision": "649583d76d09eff104d18aae17490d2cbf01b373", + "revisionTime": "2018-10-19T12:31:15Z" + }, + { + "checksumSHA1": "q+o6CYdmE6zUexIu50LJ8m5V9M8=", + "path": "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors", + "revision": "649583d76d09eff104d18aae17490d2cbf01b373", + "revisionTime": "2018-10-19T12:31:15Z" + }, + { + "checksumSHA1": "0ZnDtNVslrK0P9j01yquQ0qg4rs=", + "path": "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http", + "revision": "649583d76d09eff104d18aae17490d2cbf01b373", + "revisionTime": "2018-10-19T12:31:15Z" + }, + { + "checksumSHA1": "C2Ft9SlvvWAuKTymaJxyphqlTY0=", + "path": "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile", + "revision": "649583d76d09eff104d18aae17490d2cbf01b373", + "revisionTime": "2018-10-19T12:31:15Z" + }, + { + "checksumSHA1": "HtMaGZy24OmXN85TYpsLpfWFNr0=", + "path": "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312", + "revision": "649583d76d09eff104d18aae17490d2cbf01b373", + "revisionTime": "2018-10-19T12:31:15Z" + }, + { + "checksumSHA1": "Maw/I5DN4rRUO4WEenrg4hgPDJA=", + "path": "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312", + "revision": "649583d76d09eff104d18aae17490d2cbf01b373", + "revisionTime": "2018-10-19T12:31:15Z" + }, { "checksumSHA1": "GQ9bu6PuydK3Yor1JgtVKUfEJm8=", "path": "github.com/tent/http-link-go", diff --git a/website/source/docs/builders/tencentcloud-cvm.html.md b/website/source/docs/builders/tencentcloud-cvm.html.md new file mode 100644 index 000000000..45ae31ce3 --- /dev/null +++ b/website/source/docs/builders/tencentcloud-cvm.html.md @@ -0,0 +1,154 @@ +--- +description: | + The `tencentcloud-cvm` Packer builder plugin provide the capability to build + customized images based on an existing base images. +layout: docs +page_title: Tencentcloud Image Builder +sidebar_current: 'docs-builders-tencentcloud-ecs' +--- + +# Tencentcloud Image Builder + +Type: `tencentcloud-cvm` + +The `tencentcloud-cvm` Packer builder plugin provide the capability to build +customized images based on an existing base images. + +## Configuration Reference + +The following configuration options are available for building Tencentcloud images. +In addition to the options listed here, +a [communicator](/docs/templates/communicator.html) can be configured for this +builder. + +### Required: + +- `secret_id` (string) - Tencentcloud secret id. You should set it directly, + or set the `TENCENTCLOUD_ACCESS_KEY` environment variable. + +- `secret_key` (string) - Tencentcloud secret key. You should set it directly, + or set the `TENCENTCLOUD_SECRET_KEY` environment variable. + +- `region` (string) - The region where your cvm will be launch. You should + reference [Region and Zone](https://cloud.tencent.com/document/product/213/6091) + for parameter taking. + +- `zone` (string) - The zone where your cvm will be launch. You should + reference [Region and Zone](https://cloud.tencent.com/document/product/213/6091) + for parameter taking. + +- `instance_type` (string) - The instance type your cvm will be launched by. + You should reference [Instace Type](https://cloud.tencent.com/document/product/213/11518) + for parameter taking. + +- `source_image_id` (string) - The base image id of Image you want to create + your customized image from. + +- `image_name` (string) - The name you want to create your customize image, + it should be composed of no more than 20 characters, of letters, numbers + or minus sign. + +### Optional: + +- `force_poweroff` (boolean) - Whether to force power off cvm when create image. + Default value is `false`. + + Your cvm will try to shutdown normally; if shutdown failed and `force_poweroff` + set, your cvm will be powered off, otherwise task will fail. + +- `image_description` (string) - Image description. + +- `reboot` (boolean) - Whether shutdown cvm to create Image. Default value is + `false`. + + If `reboot` is not set and cvm is running, create image task will fail. + +- `sysprep` (boolean) - Whether enable Sysprep during creating windows image. + +- `image_copy_regions` (array of strings) - regions that will be copied to after + your image created. + +- `image_share_accounts` (array of strings) - accounts that will be shared to + after your image created. + +- `skip_region_validation` (boolean) - Do not check region and zone when validate. + +- `associate_public_ip_address` (boolean) - Whether allocate public ip to your cvm. + Default value is `false`. + + If not set, you could access your cvm from the same vpc. + +- `instance_name` (string) - Instance name. + +- `disk_type` (string) - Root disk type your cvm will be launched by. you could + reference [Disk Type](https://cloud.tencent.com/document/api/213/15753#SystemDisk) + for parameter taking. + +- `disk_size` (number) - Root disk size your cvm will be launched by. values range(in GB): + - LOCAL_BASIC: 50 + - Other: 50 ~ 1000 (need whitelist if > 50) + +- `vpc_id` - Specify vpc your cvm will be launched by. + +- `vpc_name` - Specify vpc name you will create. if `vpc_id` is not set, packer will + create a vpc for you named this parameter. + +- `cidr_block` (boolean) - Specify cider block of the vpc you will create if `vpc_id` not set + +- `subnet_id` - Specify subnet your cvm will be launched by. + +- 'subnet_name' - Specify subnet name you will create. if `subnet_id` is not set, packer will + create a subnet for you named this parameter. + +- `subnect_cidr_block` (boolean) - Specify cider block of the subnet you will create if + `subnet_id` not set + +- `internet_max_bandwidth_out` (number) - Max bandwidth out your cvm will be launched by(in MB). + values can be set between 1 ~ 100. + +- `security_group_id` - Specify security group your cvm will be launched by. + +- `security_group_name` - Specify security name you will create if `security_group_id` not set. + +- `user_data` - userdata. + +- `user_data_file` - userdata file. + +- `host_name` - host name. + +## Basic Example + +Here is a basic example for Tencentcloud. + +``` json +{ + "variables": { + "secret_id": "{{env `TENCENTCLOUD_ACCESS_KEY`}}", + "secret_key": "{{env `TENCENTCLOUD_SECRET_KEY`}}" + }, + "builders": [{ + "type": "tencentcloud-cvm", + "secret_id": "{{user `secret_id`}}", + "secret_key": "{{user `secret_key`}}", + "region": "ap-guangzhou", + "zone": "ap-guangzhou-3", + "instance_type": "S3.SMALL1", + "source_image_id": "img-oikl1tzv", + "ssh_username" : "root", + "image_name": "packerTest2", + "packer_debug": true, + "associate_public_ip_address": true + }], + "provisioners": [{ + "type": "shell", + "inline": [ + "sleep 30", + "yum install redis.x86_64 -y" + ] + }] +} +``` + +See the +[examples/tencentcloud](https://github.com/hashicorp/packer/tree/master/examples/tencentcloud) +folder in the packer project for more examples. From 427a35fc7ee1e327303a794e6c8e3f4f944f198e Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 20 Dec 2018 12:03:00 -0800 Subject: [PATCH 52/87] tests --- common/powershell/hyperv/hyperv.go | 128 ++++++++++++++--------------- 1 file changed, 64 insertions(+), 64 deletions(-) diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index 1c4201c96..f7f4e3d91 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -12,6 +12,21 @@ import ( "github.com/hashicorp/packer/common/powershell" ) +type scriptOptions struct { + Version string + VMName string + VHDX string + Path string + HardDrivePath string + MemoryStartupBytes int64 + NewVHDSizeBytes int64 + VHDBlockSizeBytes int64 + SwitchName string + Generation uint + DiffDisks bool + FixedVHD bool +} + func GetHostAdapterIpAddressForSwitch(switchName string) (string, error) { var script = ` param([string]$switchName, [int]$addressIndex) @@ -204,78 +219,60 @@ Hyper-V\Set-VMFloppyDiskDrive -VMName $vmName -Path $null return err } +// This was created as a proof of concept for moving logic out of the powershell +// scripting so that we can test the pathways activated by our variables. +// Rather than creating a powershell script with several conditionals, this will +// generate a conditional-free script which already sets all of the necessary +// variables inline. +// +// $vhdPath = Join-Path -Path C://mypath -ChildPath myvm.vhdx +// New-VHD -Path $vhdPath -ParentPath C://harddrivepath -Differencing -BlockSizeBytes 10 +// Hyper-V\New-VHD -Path $vhdPath -SizeBytes 8192 -BlockSizeBytes 10 +// Hyper-V\New-VM -Name myvm -Path C://mypath -MemoryStartupBytes 1024 -VHDPath $vhdPath -SwitchName hyperv-vmx-switch +// func getCreateVMScript(vmName string, path string, harddrivePath string, ram int64, diskSize int64, diskBlockSize int64, switchName string, generation uint, - diffDisks bool, fixedVHD bool, version string) string { - type scriptOptions struct { - VersionTag string - VMName string - Path string - HardDrivePath string - MemoryStartupBytes int64 - NewVHDSizeBytes int64 - VHDBlockSizeBytes int64 - SwitchName string - Generation uint - DiffDisks bool - FixedVHD bool + diffDisks bool, fixedVHD bool, version string) (string, error) { + + if fixedVHD && generation == 2 { + return "", fmt.Errorf("Generation 2 VMs don't support fixed disks.") } - versionTag := "" + vhdx := vmName + ".vhdx" + if fixedVHD { + vhdx = vmName + ".vhd" + } + + templateString := `$vhdPath = Join-Path -Path {{ .Path }} -ChildPath {{ .VHDX }}` + "\n" + if harddrivePath != "" { + if diffDisks { + templateString = templateString + `Hyper-V\New-VHD -Path $vhdPath -ParentPath {{ .HardDrivePath }} -Differencing -BlockSizeBytes {{ .VHDBlockSizeBytes }}` + "\n" + } else { + templateString = templateString + `Copy-Item -Path {{ .HardDrivePath }} -Destination $vhdPath` + "\n" + } + } else { + if fixedVHD { + // We only end up in here with generation 1 vms, because gen 2 doesn't support VHDs + templateString = templateString + `Hyper-V\New-VHD -Path $vhdPath -Fixed -SizeBytes {{ .NewVHDSizeBytes }}` + "\n" + } else { + templateString = templateString + `Hyper-V\New-VHD -Path $vhdPath -SizeBytes {{ .NewVHDSizeBytes }} -BlockSizeBytes {{ .VHDBlockSizeBytes }}` + "\n" + } + } + templateString = templateString + `Hyper-V\New-VM -Name {{ .VMName }} -Path {{ .Path }} -MemoryStartupBytes {{ .MemoryStartupBytes }} -VHDPath $vhdPath -SwitchName {{ .SwitchName }}` + if generation == 2 { + templateString = templateString + ` -Generation {{ .Generation }}` + } if version != "" { - versionTag = fmt.Sprintf("-Version %s", version) + templateString = templateString + ` -Version {{ .Version }}` } var scriptBuilder strings.Builder - scriptTemplate := template.Must(template.New("psScript").Parse(` -param([string]$fixedVHD) - -{{if .FixedVHD}} -$vhdx = {{ .VMName }} + '.vhd' -{{- else}} -$vhdx = {{ .VMName }} + '.vhdx' -{{- end}} - -$vhdPath = Join-Path -Path {{ .Path }} -ChildPath $vhdx -if ({{ .HardDrivePath }}){ - {{if .DiffDisks}} - New-VHD -Path $vhdPath -ParentPath {{ .HardDrivePath }} -Differencing -BlockSizeBytes {{ .VHDBlockSizeBytes }} - {{- else}} - Copy-Item -Path {{ .HardDrivePath }} -Destination $vhdPath - {{- end}} - Hyper-V\New-VM -Name {{ .VMName }} -Path {{ .Path }} -MemoryStartupBytes {{ .MemoryStartupBytes }} -VHDPath $vhdPath -SwitchName {{ .SwitchName }} {{ .VersionTag }} -} else { - {{if .FixedVHD}} - Hyper-V\New-VHD -Path $vhdPath -Fixed -SizeBytes {{ .NewVHDSizeBytes }} - {{- else}} - Hyper-V\New-VHD -Path $vhdPath -SizeBytes {{ .NewVHDSizeBytes }} -BlockSizeBytes {{ .VHDBlockSizeBytes }} - {{- end}} - Hyper-V\New-VM -Name {{ .VMName }} -Path {{ .Path }} -MemoryStartupBytes {{ .MemoryStartupBytes }} -VHDPath $vhdPath -SwitchName {{ .SwitchName }} {{ .VersionTag }} -} -`)) - if generation == 2 { - scriptTemplate = template.Must(template.New("psScript").Parse(` -$vhdx = {{ .VMName }} + '.vhdx' -$vhdPath = Join-Path -Path {{ .Path }} -ChildPath $vhdx -if ({{ .HardDrivePath }}){ - {{if .DiffDisks}} - New-VHD -Path $vhdPath -ParentPath {{ .HardDrivePath }} -Differencing -BlockSizeBytes {{ .VHDBlockSizeBytes }} - {{- else}} - Copy-Item -Path {{ .HardDrivePath }} -Destination $vhdPath - {{- end}} - Hyper-V\New-VM -Name {{ .VMName }} -Path {{ .Path }} -MemoryStartupBytes {{ .MemoryStartupBytes }} -VHDPath $vhdPath -SwitchName {{ .SwitchName }} -Generation {{ .Generation }} {{ .VersionTag }} -} -else { - Hyper-V\New-VHD -Path $vhdPath -SizeBytes {{ .NewVHDSizeBytes }} -BlockSizeBytes {{ .VHDBlockSizeBytes }} - Hyper-V\New-VM -Name {{ .VMName }} -Path {{ .Path }} -MemoryStartupBytes {{ .MemoryStartupBytes }} -VHDPath $vhdPath -SwitchName {{ .SwitchName }} -Generation {{ .Generation }} {{ .VersionTag }} -} -`)) - } - + scriptTemplate := template.Must(template.New("psScript").Parse(templateString)) scriptTemplate.Execute(&scriptBuilder, scriptOptions{ - VersionTag: versionTag, + Version: version, VMName: vmName, + VHDX: vhdx, Path: path, HardDrivePath: harddrivePath, MemoryStartupBytes: ram, @@ -287,19 +284,22 @@ else { FixedVHD: fixedVHD, }) - return scriptBuilder.String() + return scriptBuilder.String(), nil } func CreateVirtualMachine(vmName string, path string, harddrivePath string, ram int64, diskSize int64, diskBlockSize int64, switchName string, generation uint, diffDisks bool, fixedVHD bool, version string) error { - script := getCreateVMScript(vmName, path, harddrivePath, ram, + script, err := getCreateVMScript(vmName, path, harddrivePath, ram, diskSize, diskBlockSize, switchName, generation, diffDisks, fixedVHD, version) + if err != nil { + return err + } var ps powershell.PowerShellCmd - if err := ps.Run(script); err != nil { + if err = ps.Run(script); err != nil { return err } From 24d2cc34e561d3befdeb9dee9998979d92382cb4 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 20 Dec 2018 12:03:14 -0800 Subject: [PATCH 53/87] tests --- common/powershell/hyperv/hyperv_test.go | 147 ++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 common/powershell/hyperv/hyperv_test.go diff --git a/common/powershell/hyperv/hyperv_test.go b/common/powershell/hyperv/hyperv_test.go new file mode 100644 index 000000000..eadbd7538 --- /dev/null +++ b/common/powershell/hyperv/hyperv_test.go @@ -0,0 +1,147 @@ +package hyperv + +import ( + "strings" + "testing" +) + +func Test_getCreateVMScript(t *testing.T) { + vmName := "myvm" + path := "C://mypath" + harddrivepath := "C://harddrivepath" + ram := int64(1024) + disksize := int64(8192) + diskBlockSize := int64(10) + switchName := "hyperv-vmx-switch" + generation := uint(1) + diffdisks := true + fixedVHD := true + version := "5.0" + + // Check Fixed VHD conditional set + scriptString, err := getCreateVMScript(vmName, path, harddrivepath, ram, + disksize, diskBlockSize, switchName, generation, diffdisks, fixedVHD, + version) + if err != nil { + t.Fatalf("Error: %s", err.Error()) + } + + expected := `$vhdPath = Join-Path -Path C://mypath -ChildPath myvm.vhd +Hyper-V\New-VHD -Path $vhdPath -ParentPath C://harddrivepath -Differencing -BlockSizeBytes 10 +Hyper-V\New-VM -Name myvm -Path C://mypath -MemoryStartupBytes 1024 -VHDPath $vhdPath -SwitchName hyperv-vmx-switch -Version 5.0` + if ok := strings.Compare(scriptString, expected); ok != 0 { + t.Fatalf("EXPECTED: \n%s\n\n RECEIVED: \n%s\n\n", expected, scriptString) + } + + // We should never get here thanks to good template validation, but it's + // good to fail rather than trying to run the ps script and erroring. + generation = uint(2) + scriptString, err = getCreateVMScript(vmName, path, harddrivepath, ram, + disksize, diskBlockSize, switchName, generation, diffdisks, fixedVHD, + version) + if err == nil { + t.Fatalf("Should have Error: %s", err.Error()) + } + + // Check VHDX conditional set + fixedVHD = false + scriptString, err = getCreateVMScript(vmName, path, harddrivepath, ram, + disksize, diskBlockSize, switchName, generation, diffdisks, fixedVHD, + version) + if err != nil { + t.Fatalf("Error: %s", err.Error()) + } + + expected = `$vhdPath = Join-Path -Path C://mypath -ChildPath myvm.vhdx +Hyper-V\New-VHD -Path $vhdPath -ParentPath C://harddrivepath -Differencing -BlockSizeBytes 10 +Hyper-V\New-VM -Name myvm -Path C://mypath -MemoryStartupBytes 1024 -VHDPath $vhdPath -SwitchName hyperv-vmx-switch -Generation 2 -Version 5.0` + if ok := strings.Compare(scriptString, expected); ok != 0 { + t.Fatalf("EXPECTED: \n%s\n\n RECEIVED: \n%s\n\n", expected, scriptString) + } + + // Check generation 1 no fixed VHD + fixedVHD = false + generation = uint(1) + scriptString, err = getCreateVMScript(vmName, path, harddrivepath, ram, + disksize, diskBlockSize, switchName, generation, diffdisks, fixedVHD, + version) + if err != nil { + t.Fatalf("Error: %s", err.Error()) + } + + expected = `$vhdPath = Join-Path -Path C://mypath -ChildPath myvm.vhdx +Hyper-V\New-VHD -Path $vhdPath -ParentPath C://harddrivepath -Differencing -BlockSizeBytes 10 +Hyper-V\New-VM -Name myvm -Path C://mypath -MemoryStartupBytes 1024 -VHDPath $vhdPath -SwitchName hyperv-vmx-switch -Version 5.0` + if ok := strings.Compare(scriptString, expected); ok != 0 { + t.Fatalf("EXPECTED: \n%s\n\n RECEIVED: \n%s\n\n", expected, scriptString) + } + + // Check that we use generation one template even if generation is unset + generation = uint(0) + scriptString, err = getCreateVMScript(vmName, path, harddrivepath, ram, + disksize, diskBlockSize, switchName, generation, diffdisks, fixedVHD, + version) + if err != nil { + t.Fatalf("Error: %s", err.Error()) + } + // same "expected" as above + if ok := strings.Compare(scriptString, expected); ok != 0 { + t.Fatalf("EXPECTED: \n%s\n\n RECEIVED: \n%s\n\n", expected, scriptString) + } + + version = "" + scriptString, err = getCreateVMScript(vmName, path, harddrivepath, ram, + disksize, diskBlockSize, switchName, generation, diffdisks, fixedVHD, + version) + if err != nil { + t.Fatalf("Error: %s", err.Error()) + } + expected = `$vhdPath = Join-Path -Path C://mypath -ChildPath myvm.vhdx +Hyper-V\New-VHD -Path $vhdPath -ParentPath C://harddrivepath -Differencing -BlockSizeBytes 10 +Hyper-V\New-VM -Name myvm -Path C://mypath -MemoryStartupBytes 1024 -VHDPath $vhdPath -SwitchName hyperv-vmx-switch` + if ok := strings.Compare(scriptString, expected); ok != 0 { + t.Fatalf("EXPECTED: \n%s\n\n RECEIVED: \n%s\n\n", expected, scriptString) + } + + diffdisks = false + scriptString, err = getCreateVMScript(vmName, path, harddrivepath, ram, + disksize, diskBlockSize, switchName, generation, diffdisks, fixedVHD, + version) + if err != nil { + t.Fatalf("Error: %s", err.Error()) + } + expected = `$vhdPath = Join-Path -Path C://mypath -ChildPath myvm.vhdx +Copy-Item -Path C://harddrivepath -Destination $vhdPath +Hyper-V\New-VM -Name myvm -Path C://mypath -MemoryStartupBytes 1024 -VHDPath $vhdPath -SwitchName hyperv-vmx-switch` + if ok := strings.Compare(scriptString, expected); ok != 0 { + t.Fatalf("EXPECTED: \n%s\n\n RECEIVED: \n%s\n\n", expected, scriptString) + } + + harddrivepath = "" + scriptString, err = getCreateVMScript(vmName, path, harddrivepath, ram, + disksize, diskBlockSize, switchName, generation, diffdisks, fixedVHD, + version) + if err != nil { + t.Fatalf("Error: %s", err.Error()) + } + expected = `$vhdPath = Join-Path -Path C://mypath -ChildPath myvm.vhdx +Hyper-V\New-VHD -Path $vhdPath -SizeBytes 8192 -BlockSizeBytes 10 +Hyper-V\New-VM -Name myvm -Path C://mypath -MemoryStartupBytes 1024 -VHDPath $vhdPath -SwitchName hyperv-vmx-switch` + if ok := strings.Compare(scriptString, expected); ok != 0 { + t.Fatalf("EXPECTED: \n%s\n\n RECEIVED: \n%s\n\n", expected, scriptString) + } + + fixedVHD = true + scriptString, err = getCreateVMScript(vmName, path, harddrivepath, ram, + disksize, diskBlockSize, switchName, generation, diffdisks, fixedVHD, + version) + if err != nil { + t.Fatalf("Error: %s", err.Error()) + } + expected = `$vhdPath = Join-Path -Path C://mypath -ChildPath myvm.vhd +Hyper-V\New-VHD -Path $vhdPath -Fixed -SizeBytes 8192 +Hyper-V\New-VM -Name myvm -Path C://mypath -MemoryStartupBytes 1024 -VHDPath $vhdPath -SwitchName hyperv-vmx-switch` + if ok := strings.Compare(scriptString, expected); ok != 0 { + t.Fatalf("EXPECTED: \n%s\n\n RECEIVED: \n%s\n\n", expected, scriptString) + } +} From f26051a7daee713f2a8e002a786af847f43229d2 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 20 Dec 2018 13:09:32 -0800 Subject: [PATCH 54/87] code comments yo --- common/powershell/hyperv/hyperv.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index f7f4e3d91..15aa495b3 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -243,6 +243,7 @@ func getCreateVMScript(vmName string, path string, harddrivePath string, ram int vhdx = vmName + ".vhd" } + // Create VHD templateString := `$vhdPath = Join-Path -Path {{ .Path }} -ChildPath {{ .VHDX }}` + "\n" if harddrivePath != "" { if diffDisks { @@ -252,13 +253,15 @@ func getCreateVMScript(vmName string, path string, harddrivePath string, ram int } } else { if fixedVHD { - // We only end up in here with generation 1 vms, because gen 2 doesn't support VHDs templateString = templateString + `Hyper-V\New-VHD -Path $vhdPath -Fixed -SizeBytes {{ .NewVHDSizeBytes }}` + "\n" } else { templateString = templateString + `Hyper-V\New-VHD -Path $vhdPath -SizeBytes {{ .NewVHDSizeBytes }} -BlockSizeBytes {{ .VHDBlockSizeBytes }}` + "\n" } } + + // Create new VM using the VHD you just made templateString = templateString + `Hyper-V\New-VM -Name {{ .VMName }} -Path {{ .Path }} -MemoryStartupBytes {{ .MemoryStartupBytes }} -VHDPath $vhdPath -SwitchName {{ .SwitchName }}` + // Add optional tags to the end of the VM creation command if generation == 2 { templateString = templateString + ` -Generation {{ .Generation }}` } From 8b9926004039442dee32725520a78bd7573d3107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B2=E1=84=89=E1=85=A5=E1=86=BC=E1=84=83?= =?UTF-8?q?=E1=85=A5=E1=86=A8?= Date: Fri, 21 Dec 2018 17:40:10 +0900 Subject: [PATCH 55/87] Fix parameter name and update 'server_image_product_code' --- website/source/docs/builders/ncloud.html.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/website/source/docs/builders/ncloud.html.md b/website/source/docs/builders/ncloud.html.md index 276441d02..ff1f8f484 100644 --- a/website/source/docs/builders/ncloud.html.md +++ b/website/source/docs/builders/ncloud.html.md @@ -75,13 +75,15 @@ Platform](https://www.ncloud.com/). "access_key": "{{user `ncloud_access_key`}}", "secret_key": "{{user `ncloud_secret_key`}}", - "server_image_product_code": "SPSW0WINNT000016", - "server_product_code": "SPSVRSSD00000011", - "member_server_image_no": "4223", + "server_image_product_code": "SPSW0WINNTEN0016", + "server_product_code": "SPSVRSSD00000002", "server_image_name": "packer-test {{timestamp}}", - "server_description": "server description", + "server_image_description": "server description", "user_data": "CreateObject(\"WScript.Shell\").run(\"cmd.exe /c powershell Set-ExecutionPolicy RemoteSigned & winrm quickconfig -q & sc config WinRM start= auto & winrm set winrm/config/service/auth @{Basic=\"\"true\"\"} & winrm set winrm/config/service @{AllowUnencrypted=\"\"true\"\"} & winrm get winrm/config/service\")", - "region": "US-West" + "region": "US-West", + "communicator": "winrm", + "winrm_username": "Administrator", + "access_control_group_configuration_no" : 4964 } ] } From 38c4e21563fbf7eb7db8202835839b4aa1641d60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B2=E1=84=89=E1=85=A5=E1=86=BC=E1=84=83?= =?UTF-8?q?=E1=85=A5=E1=86=A8?= Date: Fri, 21 Dec 2018 17:53:52 +0900 Subject: [PATCH 56/87] Fix to get ssh password --- builder/ncloud/builder.go | 6 +++--- builder/ncloud/config.go | 2 +- builder/ncloud/step_get_rootpassword.go | 16 +++++++++++----- builder/ncloud/step_get_rootpassword_test.go | 2 ++ 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/builder/ncloud/builder.go b/builder/ncloud/builder.go index 9e53edcf8..9748a848a 100644 --- a/builder/ncloud/builder.go +++ b/builder/ncloud/builder.go @@ -44,7 +44,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe NewStepCreateLoginKey(conn, ui), NewStepCreateServerInstance(conn, ui, b.config), NewStepCreateBlockStorageInstance(conn, ui, b.config), - NewStepGetRootPassword(conn, ui), + NewStepGetRootPassword(conn, ui, b.config), NewStepCreatePublicIPInstance(conn, ui, b.config), &communicator.StepConnectSSH{ Config: &b.config.Comm, @@ -68,7 +68,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe NewStepCreateLoginKey(conn, ui), NewStepCreateServerInstance(conn, ui, b.config), NewStepCreateBlockStorageInstance(conn, ui, b.config), - NewStepGetRootPassword(conn, ui), + NewStepGetRootPassword(conn, ui, b.config), NewStepCreatePublicIPInstance(conn, ui, b.config), &communicator.StepConnectWinRM{ Config: &b.config.Comm, @@ -78,7 +78,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe WinRMConfig: func(state multistep.StateBag) (*communicator.WinRMConfig, error) { return &communicator.WinRMConfig{ Username: b.config.Comm.WinRMUser, - Password: state.Get("Password").(string), + Password: b.config.Comm.WinRMPassword, }, nil }, }, diff --git a/builder/ncloud/config.go b/builder/ncloud/config.go index c8c1374bb..e16f480c0 100644 --- a/builder/ncloud/config.go +++ b/builder/ncloud/config.go @@ -105,7 +105,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { errs = packer.MultiErrorAppend(errs, errors.New("If user_data field is set, length of UserData should be max 21847")) } - if c.Comm.Type == "wrinrm" && c.AccessControlGroupConfigurationNo == "" { + if c.Comm.Type == "winrm" && c.AccessControlGroupConfigurationNo == "" { errs = packer.MultiErrorAppend(errs, errors.New("If Communicator is winrm, access_control_group_configuration_no is required")) } diff --git a/builder/ncloud/step_get_rootpassword.go b/builder/ncloud/step_get_rootpassword.go index 051eb386b..a57058dc6 100644 --- a/builder/ncloud/step_get_rootpassword.go +++ b/builder/ncloud/step_get_rootpassword.go @@ -14,13 +14,15 @@ type StepGetRootPassword struct { GetRootPassword func(serverInstanceNo string, privateKey string) (string, error) Say func(message string) Error func(e error) + Config *Config } -func NewStepGetRootPassword(conn *ncloud.Conn, ui packer.Ui) *StepGetRootPassword { +func NewStepGetRootPassword(conn *ncloud.Conn, ui packer.Ui, config *Config) *StepGetRootPassword { var step = &StepGetRootPassword{ - Conn: conn, - Say: func(message string) { ui.Say(message) }, - Error: func(e error) { ui.Error(e.Error()) }, + Conn: conn, + Say: func(message string) { ui.Say(message) }, + Error: func(e error) { ui.Error(e.Error()) }, + Config: config, } step.GetRootPassword = step.getRootPassword @@ -51,7 +53,11 @@ func (s *StepGetRootPassword) Run(_ context.Context, state multistep.StateBag) m rootPassword, err := s.GetRootPassword(serverInstanceNo, loginKey.PrivateKey) - state.Put("Password", rootPassword) + if s.Config.Comm.Type == "ssh" { + s.Config.Comm.SSHPassword = rootPassword + } else if s.Config.Comm.Type == "winrm" { + s.Config.Comm.WinRMPassword = rootPassword + } return processStepResult(err, s.Error, state) } diff --git a/builder/ncloud/step_get_rootpassword_test.go b/builder/ncloud/step_get_rootpassword_test.go index 0c93229bd..c048a8144 100644 --- a/builder/ncloud/step_get_rootpassword_test.go +++ b/builder/ncloud/step_get_rootpassword_test.go @@ -13,6 +13,7 @@ func TestStepGetRootPasswordShouldFailIfOperationGetRootPasswordFails(t *testing GetRootPassword: func(string, string) (string, error) { return "", fmt.Errorf("!! Unit Test FAIL !!") }, Say: func(message string) {}, Error: func(e error) {}, + Config: &Config{}, } stateBag := DeleteTestStateBagStepGetRootPassword() @@ -33,6 +34,7 @@ func TestStepGetRootPasswordShouldPassIfOperationGetRootPasswordPasses(t *testin GetRootPassword: func(string, string) (string, error) { return "a", nil }, Say: func(message string) {}, Error: func(e error) {}, + Config: &Config{}, } stateBag := DeleteTestStateBagStepGetRootPassword() From fb62fa50df784af223275fd4425a18acfb74654d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B2=E1=84=89=E1=85=A5=E1=86=BC=E1=84=83?= =?UTF-8?q?=E1=85=A5=E1=86=A8?= Date: Fri, 21 Dec 2018 19:18:43 +0900 Subject: [PATCH 57/87] Add example file for linux server --- website/source/docs/builders/ncloud.html.md | 27 +++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/website/source/docs/builders/ncloud.html.md b/website/source/docs/builders/ncloud.html.md index ff1f8f484..1aacf633f 100644 --- a/website/source/docs/builders/ncloud.html.md +++ b/website/source/docs/builders/ncloud.html.md @@ -64,6 +64,8 @@ Platform](https://www.ncloud.com/). ## Sample code of template.json +Here is a basic example for windows server. + { "variables": { "ncloud_access_key": "FRxhOQRNjKVMqIz3sRLY", @@ -88,6 +90,31 @@ Platform](https://www.ncloud.com/). ] } + +Here is a basic example for linux server. + + { + "variables": { + "ncloud_access_key": "FRxhOQRNjKVMqIz3sRLY", + "ncloud_secret_key": "xd6kTO5iNcLookBx0D8TDKmpLj2ikxqEhc06MQD2" + }, + "builders": [ + { + "type": "ncloud", + "access_key": "{{user `ncloud_access_key`}}", + "secret_key": "{{user `ncloud_secret_key`}}", + + "server_image_product_code": "SPSW0LINUX000044", + "server_product_code": "SPSVRSSD00000002", + "server_image_name": "packertest2", + "server_image_description": "server image description", + "region": "US-West", + "communicator": "ssh", + "ssh_username": "root" + } + ] + } + ## Requirements for creating Windows images You should include the following code in the packer configuration file for From e6de727c25c1c53e30584255d75f36c155e82e37 Mon Sep 17 00:00:00 2001 From: Ladar Levison Date: Tue, 25 Dec 2018 16:54:26 -0600 Subject: [PATCH 58/87] Fix the Hyper-V gen 1 guest boot order. --- common/powershell/hyperv/hyperv.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index 23e5f505f..dd887f6f0 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -135,7 +135,7 @@ func SetBootDvdDrive(vmName string, controllerNumber uint, controllerLocation ui if generation < 2 { script := ` param([string]$vmName) -Hyper-V\Set-VMBios -VMName $vmName -StartupOrder @("CD", "IDE","LegacyNetworkAdapter","Floppy") +Hyper-V\Set-VMBios -VMName $vmName -StartupOrder @("IDE","CD","LegacyNetworkAdapter","Floppy") ` var ps powershell.PowerShellCmd err := ps.Run(script, vmName) From 89a5f545c47c1439210586abe3b334abe4a429fe Mon Sep 17 00:00:00 2001 From: Ladar Levison Date: Tue, 25 Dec 2018 23:14:12 -0600 Subject: [PATCH 59/87] Updated prlctl section with a non-cpu/mem example. --- .../docs/builders/parallels-iso.html.md.erb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/website/source/docs/builders/parallels-iso.html.md.erb b/website/source/docs/builders/parallels-iso.html.md.erb index 0a109efe3..51bdc0922 100644 --- a/website/source/docs/builders/parallels-iso.html.md.erb +++ b/website/source/docs/builders/parallels-iso.html.md.erb @@ -290,24 +290,24 @@ In order to perform extra customization of the virtual machine, a template can define extra calls to `prlctl` to perform. [prlctl](http://download.parallels.com/desktop/v9/ga/docs/en_US/Parallels%20Command%20Line%20Reference%20Guide.pdf) is the command-line interface to Parallels Desktop. It can be used to configure -the virtual machine, such as set RAM, CPUs, etc. +the advanced virtual machine options. -Extra `prlctl` commands are defined in the template in the `prlctl` section. An -example is shown below that sets the memory and number of CPUs within the -virtual machine: +Extra `prlctl` commands are defined in the template in the `prlctl` section. In the +example below `prlctl` is used to explicitly enable the adaptive hypervisor, and +disable 3d acceleration: ``` json { "prlctl": [ - ["set", "{{.Name}}", "--memsize", "1024"], - ["set", "{{.Name}}", "--cpus", "2"] + ["set", "{{.Name}}", "--3d-accelerate", "off"], + ["set", "{{.Name}}", "--adaptive-hypervisor", "on"] ] } ``` The value of `prlctl` is an array of commands to execute. These commands are -executed in the order defined. So in the above example, the memory will be set -followed by the CPUs. +executed in the order defined. So in the above example, 3d acceleration will be disabled +first, followed by the command which enables the adaptive hypervisor. Each command itself is an array of strings, where each string is an argument to `prlctl`. Each argument is treated as a [template engine](/docs/templates/engine.html). The only available From bf9c67cf483331b9fbfc9fde41e72f3bd315017e Mon Sep 17 00:00:00 2001 From: Mike Ripley Date: Wed, 26 Dec 2018 15:37:09 -0500 Subject: [PATCH 60/87] Update VirtualBox.org documentation references VirtualBox documentation chapter numbers have changed, try to link the correct place. --- .../source/docs/builders/virtualbox-iso.html.md.erb | 10 +++++----- .../source/docs/builders/virtualbox-ovf.html.md.erb | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/website/source/docs/builders/virtualbox-iso.html.md.erb b/website/source/docs/builders/virtualbox-iso.html.md.erb index 2de4cd132..dac021aa6 100644 --- a/website/source/docs/builders/virtualbox-iso.html.md.erb +++ b/website/source/docs/builders/virtualbox-iso.html.md.erb @@ -102,7 +102,7 @@ builder. - `export_opts` (array of strings) - Additional options to pass to the [VBoxManage - export](https://www.virtualbox.org/manual/ch08.html#vboxmanage-export). This + export](https://www.virtualbox.org/manual/ch09.html#vboxmanage-export). This can be useful for passing product information to include in the resulting appliance file. Packer JSON configuration file example: @@ -121,9 +121,9 @@ builder. ``` A VirtualBox [VM - description](https://www.virtualbox.org/manual/ch08.html#idm3756) may - contain arbitrary strings; the GUI interprets HTML formatting. However, the - JSON format does not allow arbitrary newlines within a value. Add a + description](https://www.virtualbox.org/manual/ch09.html#vboxmanage-modifyvm-general) + may contain arbitrary strings; the GUI interprets HTML formatting. However, + the JSON format does not allow arbitrary newlines within a value. Add a multi-line description by preparing the string in the shell before the packer call like this (shell `>` continuation character snipped for easier copy & paste): @@ -411,7 +411,7 @@ directory of the SSH user. In order to perform extra customization of the virtual machine, a template can define extra calls to `VBoxManage` to perform. -[VBoxManage](https://www.virtualbox.org/manual/ch08.html) is the command-line +[VBoxManage](https://www.virtualbox.org/manual/ch09.html) is the command-line interface to VirtualBox where you can completely control VirtualBox. It can be used to do things such as set RAM, CPUs, etc. diff --git a/website/source/docs/builders/virtualbox-ovf.html.md.erb b/website/source/docs/builders/virtualbox-ovf.html.md.erb index 5981ad8cf..e03d47bf8 100644 --- a/website/source/docs/builders/virtualbox-ovf.html.md.erb +++ b/website/source/docs/builders/virtualbox-ovf.html.md.erb @@ -93,7 +93,7 @@ builder. - `export_opts` (array of strings) - Additional options to pass to the [VBoxManage - export](https://www.virtualbox.org/manual/ch08.html#vboxmanage-export). This + export](https://www.virtualbox.org/manual/ch09.html#vboxmanage-export). This can be useful for passing product information to include in the resulting appliance file. Packer JSON configuration file example: @@ -112,9 +112,9 @@ builder. ``` A VirtualBox [VM - description](https://www.virtualbox.org/manual/ch08.html#idm3756) may - contain arbitrary strings; the GUI interprets HTML formatting. However, the - JSON format does not allow arbitrary newlines within a value. Add a + description](https://www.virtualbox.org/manual/ch09.html#vboxmanage-modifyvm-general) + may contain arbitrary strings; the GUI interprets HTML formatting. However, + the JSON format does not allow arbitrary newlines within a value. Add a multi-line description by preparing the string in the shell before the packer call like this (shell `>` continuation character snipped for easier copy & paste): @@ -356,7 +356,7 @@ directory of the SSH user. In order to perform extra customization of the virtual machine, a template can define extra calls to `VBoxManage` to perform. -[VBoxManage](https://www.virtualbox.org/manual/ch08.html) is the command-line +[VBoxManage](https://www.virtualbox.org/manual/ch09.html) is the command-line interface to VirtualBox where you can completely control VirtualBox. It can be used to do things such as set RAM, CPUs, etc. From 490b11ba15c0e9003c51e0a0163171f110a648c5 Mon Sep 17 00:00:00 2001 From: Ladar Levison Date: Wed, 26 Dec 2018 22:25:58 -0600 Subject: [PATCH 61/87] Removed duplicate Azure, moved Docker entry. The Docker entry was last, but should have been 4th, since it appears this list is supposed to be alpha ordered. --- website/source/docs/post-processors/vagrant.html.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/website/source/docs/post-processors/vagrant.html.md b/website/source/docs/post-processors/vagrant.html.md index c06c11fc2..c0ccf6241 100644 --- a/website/source/docs/post-processors/vagrant.html.md +++ b/website/source/docs/post-processors/vagrant.html.md @@ -33,14 +33,13 @@ providers. - AWS - Azure - DigitalOcean -- Azure +- Docker - Hyper-V - LXC - Parallels - 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, From cb0011d665e2d5e81293023d3193627ce33814f3 Mon Sep 17 00:00:00 2001 From: Ladar Levison Date: Thu, 27 Dec 2018 02:33:58 -0600 Subject: [PATCH 62/87] Fix ssh_host bug in hyper-v builders. --- builder/hyperv/common/ssh.go | 34 ++++++++++++++++++++++------------ builder/hyperv/iso/builder.go | 2 +- builder/hyperv/vmcx/builder.go | 2 +- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/builder/hyperv/common/ssh.go b/builder/hyperv/common/ssh.go index ab136f373..07141aab9 100644 --- a/builder/hyperv/common/ssh.go +++ b/builder/hyperv/common/ssh.go @@ -1,22 +1,32 @@ package common import ( + "log" + "github.com/hashicorp/packer/helper/multistep" ) -func CommHost(state multistep.StateBag) (string, error) { - vmName := state.Get("vmName").(string) - driver := state.Get("driver").(Driver) +func CommHost(host string) func(multistep.StateBag) (string, error) { + return func(state multistep.StateBag) (string, error) { - mac, err := driver.Mac(vmName) - if err != nil { - return "", err - } + if host != "" { + log.Println("Using ssh_host value: %s", ipAddress) + return host, nil + } - ip, err := driver.IpAddress(mac) - if err != nil { - return "", err - } + vmName := state.Get("vmName").(string) + driver := state.Get("driver").(Driver) - return ip, nil + mac, err := driver.Mac(vmName) + if err != nil { + return "", err + } + + ip, err := driver.IpAddress(mac) + if err != nil { + return "", err + } + + return ip, nil + } } diff --git a/builder/hyperv/iso/builder.go b/builder/hyperv/iso/builder.go index b21f2f385..27d32ffa7 100644 --- a/builder/hyperv/iso/builder.go +++ b/builder/hyperv/iso/builder.go @@ -459,7 +459,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe // configure the communicator ssh, winrm &communicator.StepConnect{ Config: &b.config.SSHConfig.Comm, - Host: hypervcommon.CommHost, + Host: hypervcommon.CommHost(b.config.SSHConfig.Comm.SSHHost), SSHConfig: b.config.SSHConfig.Comm.SSHConfigFunc(), }, diff --git a/builder/hyperv/vmcx/builder.go b/builder/hyperv/vmcx/builder.go index e207c548f..d9da950a1 100644 --- a/builder/hyperv/vmcx/builder.go +++ b/builder/hyperv/vmcx/builder.go @@ -482,7 +482,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe // configure the communicator ssh, winrm &communicator.StepConnect{ Config: &b.config.SSHConfig.Comm, - Host: hypervcommon.CommHost, + Host: hypervcommon.CommHost(b.config.SSHConfig.Comm.SSHHost), SSHConfig: b.config.SSHConfig.Comm.SSHConfigFunc(), }, From 35aaf44fa502b7aa71d93a53abad13fd08f1c106 Mon Sep 17 00:00:00 2001 From: Ladar Levison Date: Thu, 27 Dec 2018 02:55:14 -0600 Subject: [PATCH 63/87] A properly formatted hyperv ssh.go file. --- builder/hyperv/common/ssh.go | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/builder/hyperv/common/ssh.go b/builder/hyperv/common/ssh.go index 07141aab9..95d4eeaf8 100644 --- a/builder/hyperv/common/ssh.go +++ b/builder/hyperv/common/ssh.go @@ -1,32 +1,32 @@ package common import ( - "log" + "log" "github.com/hashicorp/packer/helper/multistep" ) func CommHost(host string) func(multistep.StateBag) (string, error) { - return func(state multistep.StateBag) (string, error) { + return func(state multistep.StateBag) (string, error) { - if host != "" { - log.Println("Using ssh_host value: %s", ipAddress) - return host, nil - } + if host != "" { + log.Println("Using ssh_host value: %s", ipAddress) + return host, nil + } - vmName := state.Get("vmName").(string) - driver := state.Get("driver").(Driver) + vmName := state.Get("vmName").(string) + driver := state.Get("driver").(Driver) - mac, err := driver.Mac(vmName) - if err != nil { - return "", err - } + mac, err := driver.Mac(vmName) + if err != nil { + return "", err + } - ip, err := driver.IpAddress(mac) - if err != nil { - return "", err - } + ip, err := driver.IpAddress(mac) + if err != nil { + return "", err + } - return ip, nil - } + return ip, nil + } } From 8a9962882ccd1dda3cdb9708d3db3205d40deb4a Mon Sep 17 00:00:00 2001 From: Ladar Levison Date: Thu, 27 Dec 2018 03:15:44 -0600 Subject: [PATCH 64/87] Use Printf not Println. D'oh. --- builder/hyperv/common/ssh.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/hyperv/common/ssh.go b/builder/hyperv/common/ssh.go index 95d4eeaf8..e02cf04a6 100644 --- a/builder/hyperv/common/ssh.go +++ b/builder/hyperv/common/ssh.go @@ -10,7 +10,7 @@ func CommHost(host string) func(multistep.StateBag) (string, error) { return func(state multistep.StateBag) (string, error) { if host != "" { - log.Println("Using ssh_host value: %s", ipAddress) + log.Printf("Using ssh_host value: %s", host) return host, nil } From 217028b9025746f532c22484e1f933eb1027159a Mon Sep 17 00:00:00 2001 From: Ladar Levison Date: Thu, 27 Dec 2018 03:34:08 -0600 Subject: [PATCH 65/87] Added comment regarding use of host param. --- builder/hyperv/common/ssh.go | 1 + 1 file changed, 1 insertion(+) diff --git a/builder/hyperv/common/ssh.go b/builder/hyperv/common/ssh.go index e02cf04a6..133f20a91 100644 --- a/builder/hyperv/common/ssh.go +++ b/builder/hyperv/common/ssh.go @@ -9,6 +9,7 @@ import ( func CommHost(host string) func(multistep.StateBag) (string, error) { return func(state multistep.StateBag) (string, error) { + // Skip IP auto detection if the configuration has an ssh host configured. if host != "" { log.Printf("Using ssh_host value: %s", host) return host, nil From 4d93956a8da047e7674a20678b61e460af56aef6 Mon Sep 17 00:00:00 2001 From: Mark Kwan Date: Thu, 3 Jan 2019 01:39:44 -0800 Subject: [PATCH 66/87] Fix typo in changelog for 1.3.3 bug fixes. (#7145) --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a7754798..f7e681579 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -69,7 +69,7 @@ ### BUG FIXES: * builder/amazon: Better error handling of region/credential guessing from metadata [GH-6931] -* builder.amazon: move region validation to run so that we don't break +* builder/amazon: move region validation to run so that we don't break validation when no credentials are set [GH-7032] * builder/hyperv: Remove -Copy:$false when calling Hyper-V\Compare-VM compatability report [GH-7030] From a99e1fc017002fe3b7f13d4678a7b434a0ed7125 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 3 Jan 2019 10:21:41 -0800 Subject: [PATCH 67/87] add note about ansible to chroot builder --- 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 6af73d0a5..29342374e 100644 --- a/website/source/docs/builders/amazon-chroot.html.md +++ b/website/source/docs/builders/amazon-chroot.html.md @@ -455,6 +455,11 @@ services: } ``` +### Ansible provisioner + +Running ansible against `amazon-chroot` requires changing the Ansible connection +to chroot. + ### Using Instances with NVMe block devices. In C5, C5d, M5, and i3.metal instances, EBS volumes are exposed as NVMe block From 82aadb3fe20cbf0400ea8e070f9bc978199bda51 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 3 Jan 2019 10:21:41 -0800 Subject: [PATCH 68/87] add note about ansible to chroot builder --- website/source/docs/builders/amazon-chroot.html.md | 5 +++++ website/source/docs/provisioners/ansible.html.md | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/website/source/docs/builders/amazon-chroot.html.md b/website/source/docs/builders/amazon-chroot.html.md index 6af73d0a5..24622e049 100644 --- a/website/source/docs/builders/amazon-chroot.html.md +++ b/website/source/docs/builders/amazon-chroot.html.md @@ -455,6 +455,11 @@ services: } ``` +### Ansible provisioner + +Running ansible against `amazon-chroot` requires changing the Ansible connection +to chroot and running Ansible as root/sudo. + ### Using Instances with NVMe block devices. In C5, C5d, M5, and i3.metal instances, EBS volumes are exposed as NVMe block diff --git a/website/source/docs/provisioners/ansible.html.md b/website/source/docs/provisioners/ansible.html.md index 04b7134f2..440215b8a 100644 --- a/website/source/docs/provisioners/ansible.html.md +++ b/website/source/docs/provisioners/ansible.html.md @@ -195,7 +195,7 @@ Redhat / CentOS builds have been known to fail with the following error due to ### chroot communicator Building within a chroot (e.g. `amazon-chroot`) requires changing the Ansible -connection to chroot. +connection to chroot and running Ansible as root/sudo. ``` json { From 6ff61b3cdf57f1280df0919939581a521b92fc0f Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 3 Jan 2019 11:22:27 -0800 Subject: [PATCH 69/87] update docs for iso_url --- website/source/docs/builders/virtualbox-iso.html.md.erb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/website/source/docs/builders/virtualbox-iso.html.md.erb b/website/source/docs/builders/virtualbox-iso.html.md.erb index 2de4cd132..9ba476c8d 100644 --- a/website/source/docs/builders/virtualbox-iso.html.md.erb +++ b/website/source/docs/builders/virtualbox-iso.html.md.erb @@ -75,9 +75,12 @@ builder. and `iso_checksum_url` must be defined. This will be ignored if `iso_checksum` is non empty. -- `iso_url` (string) - A URL to the ISO containing the installation image. - This URL can be either an HTTP URL or a file URL (or path to a file). If - this is an HTTP URL, Packer will download it and cache it between runs. +- `iso_url` (string) or `iso_urls` (array of strings) - `iso_url` is a URL to + the ISO containing the installation image. This URL can be either an HTTP + URL or a file URL (or path to a file). If this is an HTTP URL, Packer will + download it and cache it between runs. `iso_url` is required unless + `iso_urls` is set in its place (see below for documentation on the + `iso_urls` option) ### Optional: From 8391a93ecc39e015d10bf6a209af776f30ca04b0 Mon Sep 17 00:00:00 2001 From: Mike Ripley Date: Thu, 3 Jan 2019 16:13:54 -0500 Subject: [PATCH 70/87] Fix VirtualBox HREFs Per feedback on PR 7152 --- website/source/docs/builders/virtualbox-iso.html.md.erb | 2 +- website/source/docs/builders/virtualbox-ovf.html.md.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/website/source/docs/builders/virtualbox-iso.html.md.erb b/website/source/docs/builders/virtualbox-iso.html.md.erb index dac021aa6..0f2926e7b 100644 --- a/website/source/docs/builders/virtualbox-iso.html.md.erb +++ b/website/source/docs/builders/virtualbox-iso.html.md.erb @@ -121,7 +121,7 @@ builder. ``` A VirtualBox [VM - description](https://www.virtualbox.org/manual/ch09.html#vboxmanage-modifyvm-general) + description](https://www.virtualbox.org/manual/ch09.html#vboxmanage-export-ovf) may contain arbitrary strings; the GUI interprets HTML formatting. However, the JSON format does not allow arbitrary newlines within a value. Add a multi-line description by preparing the string in the shell before the diff --git a/website/source/docs/builders/virtualbox-ovf.html.md.erb b/website/source/docs/builders/virtualbox-ovf.html.md.erb index e03d47bf8..d3ca4d7ae 100644 --- a/website/source/docs/builders/virtualbox-ovf.html.md.erb +++ b/website/source/docs/builders/virtualbox-ovf.html.md.erb @@ -112,7 +112,7 @@ builder. ``` A VirtualBox [VM - description](https://www.virtualbox.org/manual/ch09.html#vboxmanage-modifyvm-general) + description](https://www.virtualbox.org/manual/ch09.html#vboxmanage-export-ovf) may contain arbitrary strings; the GUI interprets HTML formatting. However, the JSON format does not allow arbitrary newlines within a value. Add a multi-line description by preparing the string in the shell before the From b39f398fda427cbf41c586b4177840ff76701ae2 Mon Sep 17 00:00:00 2001 From: Nelson Chen Date: Tue, 25 Dec 2018 22:49:42 -0800 Subject: [PATCH 71/87] Add support for whpx accelerator to qemu builder Windows Hypervisor Platform (WHPX) is the Windows counterpart to HVF and KVM. It's an operating system provided component that provides virtualization acceleration support. This is kind of the missing counterpart to https://github.com/hashicorp/packer/pull/6193. QEMU 2.12 also added support for WHPX. There's no support for libvirt on Windows so nothing was added in those areas. The popular QEMU for Windows distribution does not have WHPX support built-in for legal reasons as the maintainer does not wish to use or obtain any part of Microsoft's SDK to compile the distribution. --- builder/qemu/builder.go | 3 ++- website/source/docs/builders/qemu.html.md.erb | 10 +++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/builder/qemu/builder.go b/builder/qemu/builder.go index 1535eda86..79885daef 100644 --- a/builder/qemu/builder.go +++ b/builder/qemu/builder.go @@ -28,6 +28,7 @@ var accels = map[string]struct{}{ "xen": {}, "hax": {}, "hvf": {}, + "whpx": {}, } var netDevice = map[string]bool{ @@ -274,7 +275,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { 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")) + errs, errors.New("invalid accelerator, only 'kvm', 'tcg', 'xen', 'hax', 'hvf', 'whpx', or 'none' are allowed")) } if _, ok := netDevice[b.config.NetDevice]; !ok { diff --git a/website/source/docs/builders/qemu.html.md.erb b/website/source/docs/builders/qemu.html.md.erb index 0099f657f..d21e212a6 100644 --- a/website/source/docs/builders/qemu.html.md.erb +++ b/website/source/docs/builders/qemu.html.md.erb @@ -107,7 +107,7 @@ Linux server and have not enabled X11 forwarding (`ssh -X`). ### Optional: - `accelerator` (string) - The accelerator type to use when running the VM. - This may be `none`, `kvm`, `tcg`, `hax`, `hvf`, or `xen`. The appropriate + This may be `none`, `kvm`, `tcg`, `hax`, `hvf`, `whpx`, or `xen`. The appropriate software must have already been installed on your build machine to use the accelerator you specified. When no accelerator is specified, Packer will try to use `kvm` if it is available but will default to `tcg` otherwise. @@ -116,12 +116,16 @@ Linux server and have not enabled X11 forwarding (`ssh -X`). upstream issue which can be tracked [here](https://github.com/intel/haxm/issues/20). - -> The `hvf` accelerator is new and experimental as of + -> The `hvf` and `whpx` accelerator are new and experimental as of [QEMU 2.12.0](https://wiki.qemu.org/ChangeLog/2.12#Host_support). - You may encounter issues unrelated to Packer when using it. You may need to + You may encounter issues unrelated to Packer when using these. You may need to add [ "-global", "virtio-pci.disable-modern=on" ] to `qemuargs` depending on the guest operating system. + -> For `whpx`, note that [Stefan Weil's QEMU for Windows distribution](https://qemu.weilnetz.de/w64/) + does not include WHPX support and users may need to compile or source a + build of QEMU for Windows themselves with WHPX support. + - `boot_command` (array of strings) - This is an array of commands to type when the virtual machine is first booted. The goal of these commands should be to type just enough to initialize the operating system installer. Special From 5c2da6b81688e24e7b78476bf97bbbd5d0558850 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 3 Jan 2019 16:03:42 -0800 Subject: [PATCH 72/87] fix destination pathing so that it doesnt break on windows --- provisioner/file/provisioner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provisioner/file/provisioner.go b/provisioner/file/provisioner.go index 6787a20cb..72a5018b9 100644 --- a/provisioner/file/provisioner.go +++ b/provisioner/file/provisioner.go @@ -172,7 +172,7 @@ func (p *Provisioner) ProvisionUpload(ui packer.Ui, comm packer.Communicator) er } if strings.HasSuffix(dst, "/") { - dst = filepath.Join(dst, filepath.Base(src)) + dst = dst + filepath.Base(src) } // Get a default progress bar From 7384b86e953a74cddd572f7dac1e9d4ea1b9ce06 Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Fri, 4 Jan 2019 14:10:30 +0100 Subject: [PATCH 73/87] windows plugin: prioritize AppData over default user directory ( UserProfile ) It was the default behaviour before. It is also standard for a binary to use files from the AppData directory. ex: https://github.com/golang/oauth2/blob/c453e0c757598fd055e170a3a359263c91e13153/google/default.go#L104 More on home: https://en.wikipedia.org/wiki/Home_directory --- packer/config_file.go | 7 ++++++- website/source/docs/extending/plugins.html.md | 9 ++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/packer/config_file.go b/packer/config_file.go index f95914230..27e671283 100644 --- a/packer/config_file.go +++ b/packer/config_file.go @@ -44,12 +44,17 @@ func ConfigTmpDir() (string, error) { func homeDir() (string, error) { - // First prefer the HOME environmental variable + // Prefer $HOME over user.Current due to glibc bug: golang.org/issue/13470 if home := os.Getenv("HOME"); home != "" { log.Printf("Detected home directory from env var: %s", home) return home, nil } + if home := os.Getenv("APPDATA"); home != "" { + log.Printf("Detected home directory from env var: %s", home) + return home, nil + } + // Fall back to the passwd database if not found which follows // the same semantics as bourne shell u, err := user.Current() diff --git a/website/source/docs/extending/plugins.html.md b/website/source/docs/extending/plugins.html.md index b9477914f..e1667ce92 100644 --- a/website/source/docs/extending/plugins.html.md +++ b/website/source/docs/extending/plugins.html.md @@ -52,10 +52,13 @@ later, it will take precedence over one found earlier. 1. The directory where `packer` is, or the executable directory. -2. `~/.packer.d/plugins` on Unix systems or `%APPDATA%/packer.d/plugins` on - Windows. +2. The `$HOME/packer.d/plugins` directory, if `$HOME` is defined (unix) -3. The current working directory. +3. The `%APPDATA%/packer.d/plugins` if `%APPDATA%` is defined (windows) + +4. The `%USERPROFILE%/packer.d/plugins` if `%USERPROFILE%` is defined (windows) + +4. The current working directory. The valid types for plugins are: From 2bc8cefb8117334defcf308d1ab7edbeb5e269bd Mon Sep 17 00:00:00 2001 From: DanHam Date: Sun, 6 Jan 2019 14:52:56 +0000 Subject: [PATCH 74/87] Fix links broken by fmt-docs (Pandoc) due to newline --- website/source/docs/builders/amazon-ebs.html.md | 12 ++++++------ .../docs/builders/amazon-ebssurrogate.html.md | 12 ++++++------ .../docs/builders/amazon-ebsvolume.html.md | 16 ++++++++-------- .../source/docs/builders/amazon-instance.html.md | 16 ++++++++-------- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/website/source/docs/builders/amazon-ebs.html.md b/website/source/docs/builders/amazon-ebs.html.md index c26d0a4f6..35e0112c9 100644 --- a/website/source/docs/builders/amazon-ebs.html.md +++ b/website/source/docs/builders/amazon-ebs.html.md @@ -197,12 +197,12 @@ builder. networking](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/enhanced-networking.html#enabling_enhanced_networking). - `enable_t2_unlimited` (boolean) - Enabling T2 Unlimited allows the source - instance to burst additional CPU beyond its available \[CPU Credits\] - (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/t2-credits-baseline-concepts.html) + instance to burst additional CPU beyond its available [CPU + Credits](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/t2-credits-baseline-concepts.html) for as long as the demand exists. This is in contrast to the standard configuration that only allows an instance to consume up to its available - CPU Credits. See the AWS documentation for \[T2 Unlimited\] - (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/t2-unlimited.html) + CPU Credits. See the AWS documentation for [T2 + Unlimited](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/t2-unlimited.html) and the **T2 Unlimited Pricing** section of the [Amazon EC2 On-Demand Pricing](https://aws.amazon.com/ec2/pricing/on-demand/) document for more information. By default this option is disabled and Packer will set up a @@ -210,9 +210,9 @@ builder. Standard](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/t2-std.html) instance instead. - To use T2 Unlimited you must use a T2 instance type e.g. `t2.micro`. + To use T2 Unlimited you must use a T2 instance type, e.g. `t2.micro`. Additionally, T2 Unlimited cannot be used in conjunction with Spot - Instances, e.g., when the `spot_price` option has been configured. + Instances, e.g. when the `spot_price` option has been configured. Attempting to do so will cause an error. !> **Warning!** Additional costs may be incurred by enabling T2 diff --git a/website/source/docs/builders/amazon-ebssurrogate.html.md b/website/source/docs/builders/amazon-ebssurrogate.html.md index e86abaa07..becffc4f4 100644 --- a/website/source/docs/builders/amazon-ebssurrogate.html.md +++ b/website/source/docs/builders/amazon-ebssurrogate.html.md @@ -190,12 +190,12 @@ builder. networking](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/enhanced-networking.html#enabling_enhanced_networking). - `enable_t2_unlimited` (boolean) - Enabling T2 Unlimited allows the source - instance to burst additional CPU beyond its available \[CPU Credits\] - (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/t2-credits-baseline-concepts.html) + instance to burst additional CPU beyond its available [CPU + Credits](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/t2-credits-baseline-concepts.html) for as long as the demand exists. This is in contrast to the standard configuration that only allows an instance to consume up to its available - CPU Credits. See the AWS documentation for \[T2 Unlimited\] - (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/t2-unlimited.html) + CPU Credits. See the AWS documentation for [T2 + Unlimited](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/t2-unlimited.html) and the **T2 Unlimited Pricing** section of the [Amazon EC2 On-Demand Pricing](https://aws.amazon.com/ec2/pricing/on-demand/) document for more information. By default this option is disabled and Packer will set up a @@ -203,9 +203,9 @@ builder. Standard](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/t2-std.html) instance instead. - To use T2 Unlimited you must use a T2 instance type, e.g., `t2.micro`. + To use T2 Unlimited you must use a T2 instance type, e.g. `t2.micro`. Additionally, T2 Unlimited cannot be used in conjunction with Spot - Instances, e.g., when the `spot_price` option has been configured. + Instances, e.g. when the `spot_price` option has been configured. Attempting to do so will cause an error. !> **Warning!** Additional costs may be incurred by enabling T2 diff --git a/website/source/docs/builders/amazon-ebsvolume.html.md b/website/source/docs/builders/amazon-ebsvolume.html.md index 9e85d5589..9cd438a8a 100644 --- a/website/source/docs/builders/amazon-ebsvolume.html.md +++ b/website/source/docs/builders/amazon-ebsvolume.html.md @@ -163,23 +163,23 @@ builder. networking](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/enhanced-networking.html#enabling_enhanced_networking). - `enable_t2_unlimited` (boolean) - Enabling T2 Unlimited allows the source - instance to burst additional CPU beyond its available \[CPU Credits\] - (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/t2-credits-baseline-concepts.html) + instance to burst additional CPU beyond its available [CPU + Credits](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/t2-credits-baseline-concepts.html) for as long as the demand exists. This is in contrast to the standard configuration that only allows an instance to consume up to its available - CPU Credits. See the AWS documentation for \[T2 Unlimited\] - (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/t2-unlimited.html) - and the 'T2 Unlimited Pricing' section of the [Amazon EC2 On-Demand + CPU Credits. See the AWS documentation for [T2 + Unlimited](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/t2-unlimited.html) + and the **T2 Unlimited Pricing** section of the [Amazon EC2 On-Demand Pricing](https://aws.amazon.com/ec2/pricing/on-demand/) document for more information. By default this option is disabled and Packer will set up a [T2 Standard](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/t2-std.html) instance instead. - To use T2 Unlimited you must use a T2 instance type e.g. t2.micro. + To use T2 Unlimited you must use a T2 instance type, e.g. `t2.micro`. Additionally, T2 Unlimited cannot be used in conjunction with Spot - Instances e.g. when the `spot_price` option has been configured. Attempting - to do so will cause an error. + Instances, e.g. when the `spot_price` option has been configured. + Attempting to do so will cause an error. !> **Warning!** Additional costs may be incurred by enabling T2 Unlimited - even for instances that would usually qualify for the [AWS Free diff --git a/website/source/docs/builders/amazon-instance.html.md b/website/source/docs/builders/amazon-instance.html.md index cfaa070c0..4ce4a0255 100644 --- a/website/source/docs/builders/amazon-instance.html.md +++ b/website/source/docs/builders/amazon-instance.html.md @@ -213,23 +213,23 @@ builder. networking](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/enhanced-networking.html#enabling_enhanced_networking). - `enable_t2_unlimited` (boolean) - Enabling T2 Unlimited allows the source - instance to burst additional CPU beyond its available \[CPU Credits\] - (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/t2-credits-baseline-concepts.html) + instance to burst additional CPU beyond its available [CPU + Credits](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/t2-credits-baseline-concepts.html) for as long as the demand exists. This is in contrast to the standard configuration that only allows an instance to consume up to its available - CPU Credits. See the AWS documentation for \[T2 Unlimited\] - (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/t2-unlimited.html) - and the 'T2 Unlimited Pricing' section of the [Amazon EC2 On-Demand + CPU Credits. See the AWS documentation for [T2 + Unlimited](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/t2-unlimited.html) + and the **T2 Unlimited Pricing** section of the [Amazon EC2 On-Demand Pricing](https://aws.amazon.com/ec2/pricing/on-demand/) document for more information. By default this option is disabled and Packer will set up a [T2 Standard](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/t2-std.html) instance instead. - To use T2 Unlimited you must use a T2 instance type e.g. t2.micro. + To use T2 Unlimited you must use a T2 instance type, e.g. `t2.micro`. Additionally, T2 Unlimited cannot be used in conjunction with Spot - Instances e.g. when the `spot_price` option has been configured. Attempting - to do so will cause an error. + Instances, e.g. when the `spot_price` option has been configured. + Attempting to do so will cause an error. !> **Warning!** Additional costs may be incurred by enabling T2 Unlimited - even for instances that would usually qualify for the [AWS Free From 1d8fd936bf99d5576fb395b4a075927dce943216 Mon Sep 17 00:00:00 2001 From: Rickard von Essen Date: Mon, 7 Jan 2019 08:51:26 +0100 Subject: [PATCH 75/87] Updated CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f7e681579..0f8aa56a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ * builder/amazon: don't Cleanup Temp Keys when there is no communicator to avoid a panic [GH-7100] [GH-7095] * builder/azure: allow to configure disk caching [GH-7061] +* builder/openstack: Don't require network v2 [GH-6933] * core/shell: Add env vars "PACKER_HTTP_IP" and "PACKER_HTTP_PORT" to shell provisioners [GH-7075] * core: Deprecate mitchellh/go-homedir package in favor of os/user [GH-7062] From e40c90423f5ea05edbed7806f2c3bc49820f8e92 Mon Sep 17 00:00:00 2001 From: Ed Maxwell-Lyte <2248005+edwardmlyte@users.noreply.github.com> Date: Tue, 8 Jan 2019 14:14:21 +0000 Subject: [PATCH 76/87] Reverse default port count virtualbox argument As we know the exact versions that used the old `sataportcount` option, it's safe to assume we want to use the newer `portcount` option for everything else. Reversed the option check and use the `portcount` option by default. Prevents needing to update this for future major versions of VirtualBox. --- builder/virtualbox/common/driver_4_2.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/builder/virtualbox/common/driver_4_2.go b/builder/virtualbox/common/driver_4_2.go index b5dc64c67..54ec4ddde 100644 --- a/builder/virtualbox/common/driver_4_2.go +++ b/builder/virtualbox/common/driver_4_2.go @@ -24,9 +24,9 @@ func (d *VBox42Driver) CreateSATAController(vmName string, name string, portcoun return err } - portCountArg := "--sataportcount" - if strings.HasPrefix(version, "4.3") || strings.HasPrefix(version, "5.") || strings.HasPrefix(version, "6.") { - portCountArg = "--portcount" + portCountArg = "--portcount" + if strings.HasPrefix(version, "1.") || strings.HasPrefix(version, "2.") || strings.HasPrefix(version, "3.") || strings.HasPrefix(version, "4.0") || strings.HasPrefix(version, "4.1") || strings.HasPrefix(version, "4.2") { + portCountArg := "--sataportcount" } command := []string{ From 7feb73dd5dd1f1d868b8aa2a4c1ace5357100406 Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Tue, 8 Jan 2019 16:33:15 +0100 Subject: [PATCH 77/87] set list number 5 correctly in plugins.html.md --- website/source/docs/extending/plugins.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/extending/plugins.html.md b/website/source/docs/extending/plugins.html.md index e1667ce92..1a027c4b4 100644 --- a/website/source/docs/extending/plugins.html.md +++ b/website/source/docs/extending/plugins.html.md @@ -58,7 +58,7 @@ later, it will take precedence over one found earlier. 4. The `%USERPROFILE%/packer.d/plugins` if `%USERPROFILE%` is defined (windows) -4. The current working directory. +5. The current working directory. The valid types for plugins are: From e5b1e0f4d93ee2f5ddb9f769369229c493c970ae Mon Sep 17 00:00:00 2001 From: Ed Maxwell-Lyte <2248005+edwardmlyte@users.noreply.github.com> Date: Tue, 8 Jan 2019 15:35:45 +0000 Subject: [PATCH 78/87] Add version 0.x to the rule --- builder/virtualbox/common/driver_4_2.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/builder/virtualbox/common/driver_4_2.go b/builder/virtualbox/common/driver_4_2.go index 54ec4ddde..c3c11554d 100644 --- a/builder/virtualbox/common/driver_4_2.go +++ b/builder/virtualbox/common/driver_4_2.go @@ -25,7 +25,9 @@ func (d *VBox42Driver) CreateSATAController(vmName string, name string, portcoun } portCountArg = "--portcount" - if strings.HasPrefix(version, "1.") || strings.HasPrefix(version, "2.") || strings.HasPrefix(version, "3.") || strings.HasPrefix(version, "4.0") || strings.HasPrefix(version, "4.1") || strings.HasPrefix(version, "4.2") { + if strings.HasPrefix(version, "0.") || strings.HasPrefix(version, "1.") || strings.HasPrefix(version, "2.") || + strings.HasPrefix(version, "3.") || strings.HasPrefix(version, "4.0") || strings.HasPrefix(version, "4.1") || + strings.HasPrefix(version, "4.2") { portCountArg := "--sataportcount" } From d7e0b3f34a2dabc37a528f727567551b33768772 Mon Sep 17 00:00:00 2001 From: Rickard von Essen Date: Tue, 8 Jan 2019 16:54:39 +0100 Subject: [PATCH 79/87] Updated CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f8aa56a8..7ea507302 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ avoid a panic [GH-7100] [GH-7095] * builder/azure: allow to configure disk caching [GH-7061] * builder/openstack: Don't require network v2 [GH-6933] +* builder/openstack: Support for tagging new images [GH-7037] * core/shell: Add env vars "PACKER_HTTP_IP" and "PACKER_HTTP_PORT" to shell provisioners [GH-7075] * core: Deprecate mitchellh/go-homedir package in favor of os/user [GH-7062] From a9eed311a653eaac735b9e9d74bf300320af6689 Mon Sep 17 00:00:00 2001 From: Ed Maxwell-Lyte <2248005+edwardmlyte@users.noreply.github.com> Date: Tue, 8 Jan 2019 15:58:05 +0000 Subject: [PATCH 80/87] Run gofmt on driver_4_2.go --- builder/virtualbox/common/driver_4_2.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/builder/virtualbox/common/driver_4_2.go b/builder/virtualbox/common/driver_4_2.go index c3c11554d..8af782947 100644 --- a/builder/virtualbox/common/driver_4_2.go +++ b/builder/virtualbox/common/driver_4_2.go @@ -25,9 +25,9 @@ func (d *VBox42Driver) CreateSATAController(vmName string, name string, portcoun } portCountArg = "--portcount" - if strings.HasPrefix(version, "0.") || strings.HasPrefix(version, "1.") || strings.HasPrefix(version, "2.") || - strings.HasPrefix(version, "3.") || strings.HasPrefix(version, "4.0") || strings.HasPrefix(version, "4.1") || - strings.HasPrefix(version, "4.2") { + if strings.HasPrefix(version, "0.") || strings.HasPrefix(version, "1.") || strings.HasPrefix(version, "2.") || + strings.HasPrefix(version, "3.") || strings.HasPrefix(version, "4.0") || strings.HasPrefix(version, "4.1") || + strings.HasPrefix(version, "4.2") { portCountArg := "--sataportcount" } From f91b6686179beac7fbf9ff695c1f4bf77d824675 Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Tue, 8 Jan 2019 16:15:24 +0000 Subject: [PATCH 81/87] Create portCountArg in the if statement You can't assign to something that doesn't exist Co-Authored-By: edwardmlyte --- builder/virtualbox/common/driver_4_2.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/virtualbox/common/driver_4_2.go b/builder/virtualbox/common/driver_4_2.go index 8af782947..9bfa3baf1 100644 --- a/builder/virtualbox/common/driver_4_2.go +++ b/builder/virtualbox/common/driver_4_2.go @@ -24,7 +24,7 @@ func (d *VBox42Driver) CreateSATAController(vmName string, name string, portcoun return err } - portCountArg = "--portcount" + portCountArg := "--portcount" if strings.HasPrefix(version, "0.") || strings.HasPrefix(version, "1.") || strings.HasPrefix(version, "2.") || strings.HasPrefix(version, "3.") || strings.HasPrefix(version, "4.0") || strings.HasPrefix(version, "4.1") || strings.HasPrefix(version, "4.2") { From 4fc02ea4061fc9398d58da91df7cac9fa5315af7 Mon Sep 17 00:00:00 2001 From: Ed Maxwell-Lyte <2248005+edwardmlyte@users.noreply.github.com> Date: Tue, 8 Jan 2019 16:19:11 +0000 Subject: [PATCH 82/87] Assign to existing var --- builder/virtualbox/common/driver_4_2.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/virtualbox/common/driver_4_2.go b/builder/virtualbox/common/driver_4_2.go index 9bfa3baf1..1a2c8541d 100644 --- a/builder/virtualbox/common/driver_4_2.go +++ b/builder/virtualbox/common/driver_4_2.go @@ -28,7 +28,7 @@ func (d *VBox42Driver) CreateSATAController(vmName string, name string, portcoun if strings.HasPrefix(version, "0.") || strings.HasPrefix(version, "1.") || strings.HasPrefix(version, "2.") || strings.HasPrefix(version, "3.") || strings.HasPrefix(version, "4.0") || strings.HasPrefix(version, "4.1") || strings.HasPrefix(version, "4.2") { - portCountArg := "--sataportcount" + portCountArg = "--sataportcount" } command := []string{ From 3dfbe45fcd7cf8c5b856267f6092479e99cca590 Mon Sep 17 00:00:00 2001 From: Christopher Boumenot Date: Tue, 8 Jan 2019 10:17:33 -0800 Subject: [PATCH 83/87] azure: sysprep after agent is ready --- examples/azure/windows.json | 13 +++++++++---- examples/azure/windows_custom_image.json | 13 +++++++++---- examples/azure/windows_quickstart.json | 13 +++++++++---- website/source/docs/builders/azure.html.md | 14 ++++++++++++++ 4 files changed, 41 insertions(+), 12 deletions(-) diff --git a/examples/azure/windows.json b/examples/azure/windows.json index e0b03b7ae..9e03043d7 100644 --- a/examples/azure/windows.json +++ b/examples/azure/windows.json @@ -30,10 +30,15 @@ }], "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 /quiet /quit", - "while($true) { $imageState = Get-ItemProperty HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State | Select ImageState; if($imageState.ImageState -ne 'IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE') { Write-Output $imageState.ImageState; Start-Sleep -s 10 } else { break } }" + "inline": [ + " # NOTE: the following *3* lines are only needed if the you have installed the Guest Agent.", + " while ((Get-Service RdAgent).Status -ne 'Running') { Start-Sleep -s 5 }", + " while ((Get-Service WindowsAzureTelemetryService).Status -ne 'Running') { Start-Sleep -s 5 }", + " while ((Get-Service WindowsAzureGuestAgent).Status -ne 'Running') { Start-Sleep -s 5 }", + + "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 /quiet /quit", + "while($true) { $imageState = Get-ItemProperty HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State | Select ImageState; if($imageState.ImageState -ne 'IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE') { Write-Output $imageState.ImageState; Start-Sleep -s 10 } else { break } }" ] }] } diff --git a/examples/azure/windows_custom_image.json b/examples/azure/windows_custom_image.json index 448340e19..7eeb7e377 100644 --- a/examples/azure/windows_custom_image.json +++ b/examples/azure/windows_custom_image.json @@ -35,10 +35,15 @@ ], "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 /quiet /quit", - "while($true) { $imageState = Get-ItemProperty HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State | Select ImageState; if($imageState.ImageState -ne 'IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE') { Write-Output $imageState.ImageState; Start-Sleep -s 10 } else { break } }" + "inline": [ + " # NOTE: the following *3* lines are only needed if the you have installed the Guest Agent.", + " while ((Get-Service RdAgent).Status -ne 'Running') { Start-Sleep -s 5 }", + " while ((Get-Service WindowsAzureTelemetryService).Status -ne 'Running') { Start-Sleep -s 5 }", + " while ((Get-Service WindowsAzureGuestAgent).Status -ne 'Running') { Start-Sleep -s 5 }", + + "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 /quiet /quit", + "while($true) { $imageState = Get-ItemProperty HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State | Select ImageState; if($imageState.ImageState -ne 'IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE') { Write-Output $imageState.ImageState; Start-Sleep -s 10 } else { break } }" ] }] } diff --git a/examples/azure/windows_quickstart.json b/examples/azure/windows_quickstart.json index 3f7a1e9bb..7cb6c9e8e 100644 --- a/examples/azure/windows_quickstart.json +++ b/examples/azure/windows_quickstart.json @@ -26,10 +26,15 @@ }], "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 /quiet /quit", - "while($true) { $imageState = Get-ItemProperty HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State | Select ImageState; if($imageState.ImageState -ne 'IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE') { Write-Output $imageState.ImageState; Start-Sleep -s 10 } else { break } }" + "inline": [ + " # NOTE: the following *3* lines are only needed if the you have installed the Guest Agent.", + " while ((Get-Service RdAgent).Status -ne 'Running') { Start-Sleep -s 5 }", + " while ((Get-Service WindowsAzureTelemetryService).Status -ne 'Running') { Start-Sleep -s 5 }", + " while ((Get-Service WindowsAzureGuestAgent).Status -ne 'Running') { Start-Sleep -s 5 }", + + "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 /quiet /quit", + "while($true) { $imageState = Get-ItemProperty HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State | Select ImageState; if($imageState.ImageState -ne 'IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE') { Write-Output $imageState.ImageState; Start-Sleep -s 10 } else { break } }" ] }] } diff --git a/website/source/docs/builders/azure.html.md b/website/source/docs/builders/azure.html.md index 556d0b968..3ed470369 100644 --- a/website/source/docs/builders/azure.html.md +++ b/website/source/docs/builders/azure.html.md @@ -374,6 +374,11 @@ here](https://technet.microsoft.com/en-us/library/hh824815.aspx) { "type": "powershell", "inline": [ + " # NOTE: the following *3* lines are only needed if the you have installed the Guest Agent.", + " while ((Get-Service RdAgent).Status -ne 'Running') { Start-Sleep -s 5 }", + " while ((Get-Service WindowsAzureTelemetryService).Status -ne 'Running') { Start-Sleep -s 5 }", + " while ((Get-Service WindowsAzureGuestAgent).Status -ne 'Running') { Start-Sleep -s 5 }", + "& $env:SystemRoot\\System32\\Sysprep\\Sysprep.exe /oobe /generalize /quiet /quit", "while($true) { $imageState = Get-ItemProperty HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State | Select ImageState; if($imageState.ImageState -ne 'IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE') { Write-Output $imageState.ImageState; Start-Sleep -s 10 } else { break } }" ] @@ -382,6 +387,15 @@ here](https://technet.microsoft.com/en-us/library/hh824815.aspx) } ``` +The Windows Guest Agent participates in the Sysprep process. The +agent must be fully installed before the VM can be sysprep'ed. To +ensure this is true all agent services must be running before +executing sysprep.exe. The above JSON snippet shows one way to do this +in the PowerShell provisioner. This snippet is **only** required if +the VM is configured to install the agent, which is the default. To +learn more about disabling the Windows Guest Agent please see [Install the VM Agent](https://docs.microsoft.com/en-us/azure/virtual-machines/extensions/agent-windows#install-the-vm-agent). + + ### Linux The following provisioner snippet shows how to deprovision a Linux VM. From a1b3b63cb93c4c72ab6b2897ae2536c98ee61b60 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Tue, 8 Jan 2019 11:17:19 -0800 Subject: [PATCH 84/87] use golang templating logic --- common/powershell/hyperv/hyperv.go | 74 +++++++++++++++++------------- 1 file changed, 42 insertions(+), 32 deletions(-) diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index 15aa495b3..bea951172 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -1,10 +1,12 @@ package hyperv import ( + "bytes" "context" "errors" "fmt" "os/exec" + "regexp" "strconv" "strings" "text/template" @@ -243,36 +245,7 @@ func getCreateVMScript(vmName string, path string, harddrivePath string, ram int vhdx = vmName + ".vhd" } - // Create VHD - templateString := `$vhdPath = Join-Path -Path {{ .Path }} -ChildPath {{ .VHDX }}` + "\n" - if harddrivePath != "" { - if diffDisks { - templateString = templateString + `Hyper-V\New-VHD -Path $vhdPath -ParentPath {{ .HardDrivePath }} -Differencing -BlockSizeBytes {{ .VHDBlockSizeBytes }}` + "\n" - } else { - templateString = templateString + `Copy-Item -Path {{ .HardDrivePath }} -Destination $vhdPath` + "\n" - } - } else { - if fixedVHD { - templateString = templateString + `Hyper-V\New-VHD -Path $vhdPath -Fixed -SizeBytes {{ .NewVHDSizeBytes }}` + "\n" - } else { - templateString = templateString + `Hyper-V\New-VHD -Path $vhdPath -SizeBytes {{ .NewVHDSizeBytes }} -BlockSizeBytes {{ .VHDBlockSizeBytes }}` + "\n" - } - } - - // Create new VM using the VHD you just made - templateString = templateString + `Hyper-V\New-VM -Name {{ .VMName }} -Path {{ .Path }} -MemoryStartupBytes {{ .MemoryStartupBytes }} -VHDPath $vhdPath -SwitchName {{ .SwitchName }}` - // Add optional tags to the end of the VM creation command - if generation == 2 { - templateString = templateString + ` -Generation {{ .Generation }}` - } - if version != "" { - templateString = templateString + ` -Version {{ .Version }}` - } - - var scriptBuilder strings.Builder - - scriptTemplate := template.Must(template.New("psScript").Parse(templateString)) - scriptTemplate.Execute(&scriptBuilder, scriptOptions{ + opts := scriptOptions{ Version: version, VMName: vmName, VHDX: vhdx, @@ -285,9 +258,46 @@ func getCreateVMScript(vmName string, path string, harddrivePath string, ram int Generation: generation, DiffDisks: diffDisks, FixedVHD: fixedVHD, - }) + } - return scriptBuilder.String(), nil + var tpl = template.Must(template.New("createVM").Parse(` +$vhdPath = Join-Path -Path {{ .Path }} -ChildPath {{ .VHDX }} + +{{ if ne .HardDrivePath "" -}} + {{- if .DiffDisks -}} + Hyper-V\New-VHD -Path $vhdPath -ParentPath {{ .HardDrivePath }} -Differencing -BlockSizeBytes {{ .VHDBlockSizeBytes }} + {{- else -}} + Copy-Item -Path {{ .HardDrivePath }} -Destination $vhdPath + {{- end -}} +{{- else -}} + {{- if .FixedVHD -}} + Hyper-V\New-VHD -Path $vhdPath -Fixed -SizeBytes {{ .NewVHDSizeBytes }} + {{- else -}} + Hyper-V\New-VHD -Path $vhdPath -SizeBytes {{ .NewVHDSizeBytes }} -BlockSizeBytes {{ .VHDBlockSizeBytes }} + {{- end -}} +{{- end }} + +Hyper-V\New-VM -Name {{ .VMName }} -Path {{ .Path }} -MemoryStartupBytes {{ .MemoryStartupBytes }} -VHDPath $vhdPath -SwitchName {{ .SwitchName }} +{{- if eq .Generation 2}} -Generation {{ .Generation }} {{- end -}} +{{- if ne .Version ""}} -Version {{ .Version }} {{- end -}} +`)) + + var b bytes.Buffer + err := tpl.Execute(&b, opts) + if err != nil { + return "", err + } + + // Tidy away the excess newlines left over by the template + regex, err := regexp.Compile("^\n") + if err != nil { + return "", err + } + final := regex.ReplaceAllString(b.String(), "") + regex, err = regexp.Compile("\n\n") + final = regex.ReplaceAllString(final, "\n") + + return final, nil } func CreateVirtualMachine(vmName string, path string, harddrivePath string, ram int64, From 9557f3eea75d3c97b4a41cf3807aa965d4544ca5 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Tue, 8 Jan 2019 11:29:38 -0800 Subject: [PATCH 85/87] use script options struct rather than passing all the variables around an extra time --- common/powershell/hyperv/hyperv.go | 45 +++++++------- common/powershell/hyperv/hyperv_test.go | 78 ++++++++++--------------- 2 files changed, 51 insertions(+), 72 deletions(-) diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index bea951172..05e60578d 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -232,32 +232,15 @@ Hyper-V\Set-VMFloppyDiskDrive -VMName $vmName -Path $null // Hyper-V\New-VHD -Path $vhdPath -SizeBytes 8192 -BlockSizeBytes 10 // Hyper-V\New-VM -Name myvm -Path C://mypath -MemoryStartupBytes 1024 -VHDPath $vhdPath -SwitchName hyperv-vmx-switch // -func getCreateVMScript(vmName string, path string, harddrivePath string, ram int64, - diskSize int64, diskBlockSize int64, switchName string, generation uint, - diffDisks bool, fixedVHD bool, version string) (string, error) { +func getCreateVMScript(opts *scriptOptions) (string, error) { - if fixedVHD && generation == 2 { + if opts.FixedVHD && opts.Generation == 2 { return "", fmt.Errorf("Generation 2 VMs don't support fixed disks.") } - vhdx := vmName + ".vhdx" - if fixedVHD { - vhdx = vmName + ".vhd" - } - - opts := scriptOptions{ - Version: version, - VMName: vmName, - VHDX: vhdx, - Path: path, - HardDrivePath: harddrivePath, - MemoryStartupBytes: ram, - NewVHDSizeBytes: diskSize, - VHDBlockSizeBytes: diskBlockSize, - SwitchName: switchName, - Generation: generation, - DiffDisks: diffDisks, - FixedVHD: fixedVHD, + opts.VHDX = opts.VMName + ".vhdx" + if opts.FixedVHD { + opts.VHDX = opts.VMName + ".vhd" } var tpl = template.Must(template.New("createVM").Parse(` @@ -304,9 +287,21 @@ func CreateVirtualMachine(vmName string, path string, harddrivePath string, ram diskSize int64, diskBlockSize int64, switchName string, generation uint, diffDisks bool, fixedVHD bool, version string) error { - script, err := getCreateVMScript(vmName, path, harddrivePath, ram, - diskSize, diskBlockSize, switchName, generation, - diffDisks, fixedVHD, version) + opts := scriptOptions{ + Version: version, + VMName: vmName, + Path: path, + HardDrivePath: harddrivePath, + MemoryStartupBytes: ram, + NewVHDSizeBytes: diskSize, + VHDBlockSizeBytes: diskBlockSize, + SwitchName: switchName, + Generation: generation, + DiffDisks: diffDisks, + FixedVHD: fixedVHD, + } + + script, err := getCreateVMScript(&opts) if err != nil { return err } diff --git a/common/powershell/hyperv/hyperv_test.go b/common/powershell/hyperv/hyperv_test.go index eadbd7538..b4cca857e 100644 --- a/common/powershell/hyperv/hyperv_test.go +++ b/common/powershell/hyperv/hyperv_test.go @@ -6,22 +6,22 @@ import ( ) func Test_getCreateVMScript(t *testing.T) { - vmName := "myvm" - path := "C://mypath" - harddrivepath := "C://harddrivepath" - ram := int64(1024) - disksize := int64(8192) - diskBlockSize := int64(10) - switchName := "hyperv-vmx-switch" - generation := uint(1) - diffdisks := true - fixedVHD := true - version := "5.0" + opts := scriptOptions{ + Version: "5.0", + VMName: "myvm", + Path: "C://mypath", + HardDrivePath: "C://harddrivepath", + MemoryStartupBytes: int64(1024), + NewVHDSizeBytes: int64(8192), + VHDBlockSizeBytes: int64(10), + SwitchName: "hyperv-vmx-switch", + Generation: uint(1), + DiffDisks: true, + FixedVHD: true, + } // Check Fixed VHD conditional set - scriptString, err := getCreateVMScript(vmName, path, harddrivepath, ram, - disksize, diskBlockSize, switchName, generation, diffdisks, fixedVHD, - version) + scriptString, err := getCreateVMScript(&opts) if err != nil { t.Fatalf("Error: %s", err.Error()) } @@ -35,19 +35,15 @@ Hyper-V\New-VM -Name myvm -Path C://mypath -MemoryStartupBytes 1024 -VHDPath $vh // We should never get here thanks to good template validation, but it's // good to fail rather than trying to run the ps script and erroring. - generation = uint(2) - scriptString, err = getCreateVMScript(vmName, path, harddrivepath, ram, - disksize, diskBlockSize, switchName, generation, diffdisks, fixedVHD, - version) + opts.Generation = uint(2) + scriptString, err = getCreateVMScript(&opts) if err == nil { t.Fatalf("Should have Error: %s", err.Error()) } // Check VHDX conditional set - fixedVHD = false - scriptString, err = getCreateVMScript(vmName, path, harddrivepath, ram, - disksize, diskBlockSize, switchName, generation, diffdisks, fixedVHD, - version) + opts.FixedVHD = false + scriptString, err = getCreateVMScript(&opts) if err != nil { t.Fatalf("Error: %s", err.Error()) } @@ -60,11 +56,9 @@ Hyper-V\New-VM -Name myvm -Path C://mypath -MemoryStartupBytes 1024 -VHDPath $vh } // Check generation 1 no fixed VHD - fixedVHD = false - generation = uint(1) - scriptString, err = getCreateVMScript(vmName, path, harddrivepath, ram, - disksize, diskBlockSize, switchName, generation, diffdisks, fixedVHD, - version) + opts.FixedVHD = false + opts.Generation = uint(1) + scriptString, err = getCreateVMScript(&opts) if err != nil { t.Fatalf("Error: %s", err.Error()) } @@ -77,10 +71,8 @@ Hyper-V\New-VM -Name myvm -Path C://mypath -MemoryStartupBytes 1024 -VHDPath $vh } // Check that we use generation one template even if generation is unset - generation = uint(0) - scriptString, err = getCreateVMScript(vmName, path, harddrivepath, ram, - disksize, diskBlockSize, switchName, generation, diffdisks, fixedVHD, - version) + opts.Generation = uint(0) + scriptString, err = getCreateVMScript(&opts) if err != nil { t.Fatalf("Error: %s", err.Error()) } @@ -89,10 +81,8 @@ Hyper-V\New-VM -Name myvm -Path C://mypath -MemoryStartupBytes 1024 -VHDPath $vh t.Fatalf("EXPECTED: \n%s\n\n RECEIVED: \n%s\n\n", expected, scriptString) } - version = "" - scriptString, err = getCreateVMScript(vmName, path, harddrivepath, ram, - disksize, diskBlockSize, switchName, generation, diffdisks, fixedVHD, - version) + opts.Version = "" + scriptString, err = getCreateVMScript(&opts) if err != nil { t.Fatalf("Error: %s", err.Error()) } @@ -103,10 +93,8 @@ Hyper-V\New-VM -Name myvm -Path C://mypath -MemoryStartupBytes 1024 -VHDPath $vh t.Fatalf("EXPECTED: \n%s\n\n RECEIVED: \n%s\n\n", expected, scriptString) } - diffdisks = false - scriptString, err = getCreateVMScript(vmName, path, harddrivepath, ram, - disksize, diskBlockSize, switchName, generation, diffdisks, fixedVHD, - version) + opts.DiffDisks = false + scriptString, err = getCreateVMScript(&opts) if err != nil { t.Fatalf("Error: %s", err.Error()) } @@ -117,10 +105,8 @@ Hyper-V\New-VM -Name myvm -Path C://mypath -MemoryStartupBytes 1024 -VHDPath $vh t.Fatalf("EXPECTED: \n%s\n\n RECEIVED: \n%s\n\n", expected, scriptString) } - harddrivepath = "" - scriptString, err = getCreateVMScript(vmName, path, harddrivepath, ram, - disksize, diskBlockSize, switchName, generation, diffdisks, fixedVHD, - version) + opts.HardDrivePath = "" + scriptString, err = getCreateVMScript(&opts) if err != nil { t.Fatalf("Error: %s", err.Error()) } @@ -131,10 +117,8 @@ Hyper-V\New-VM -Name myvm -Path C://mypath -MemoryStartupBytes 1024 -VHDPath $vh t.Fatalf("EXPECTED: \n%s\n\n RECEIVED: \n%s\n\n", expected, scriptString) } - fixedVHD = true - scriptString, err = getCreateVMScript(vmName, path, harddrivepath, ram, - disksize, diskBlockSize, switchName, generation, diffdisks, fixedVHD, - version) + opts.FixedVHD = true + scriptString, err = getCreateVMScript(&opts) if err != nil { t.Fatalf("Error: %s", err.Error()) } From 6c5688ca82a08839243252f9afb1fc74f40654e1 Mon Sep 17 00:00:00 2001 From: Gary Ewan Park Date: Tue, 8 Jan 2019 20:16:18 +0000 Subject: [PATCH 86/87] (doc) Minor correction is -> are --- website/source/intro/getting-started/install.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/intro/getting-started/install.html.md b/website/source/intro/getting-started/install.html.md index f3409431a..eab3b5675 100644 --- a/website/source/intro/getting-started/install.html.md +++ b/website/source/intro/getting-started/install.html.md @@ -95,7 +95,7 @@ Otherwise, Packer is installed and you're ready to go! ## Alternative Installation Methods -While the binary packages is the only official method of installation, there are +While the binary packages are the only official method of installation, there are alternatives available. ### Homebrew From 93053e04880eb55f7f9a2b7b4b05c2fd5aac8dd2 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Tue, 8 Jan 2019 15:15:00 -0800 Subject: [PATCH 87/87] update comments --- common/powershell/hyperv/hyperv.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index 05e60578d..14eef6b60 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -227,10 +227,8 @@ Hyper-V\Set-VMFloppyDiskDrive -VMName $vmName -Path $null // generate a conditional-free script which already sets all of the necessary // variables inline. // -// $vhdPath = Join-Path -Path C://mypath -ChildPath myvm.vhdx -// New-VHD -Path $vhdPath -ParentPath C://harddrivepath -Differencing -BlockSizeBytes 10 -// Hyper-V\New-VHD -Path $vhdPath -SizeBytes 8192 -BlockSizeBytes 10 -// Hyper-V\New-VM -Name myvm -Path C://mypath -MemoryStartupBytes 1024 -VHDPath $vhdPath -SwitchName hyperv-vmx-switch +// For examples of what this template will generate, you can look at the +// test cases in ./hyperv_test.go // func getCreateVMScript(opts *scriptOptions) (string, error) {