From 42f7cbc30bda24fdf62aa2039154486f22c0557e Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 11 Jul 2019 16:56:40 -0700 Subject: [PATCH 001/113] add code to deduplicate the region list, and to make sure that the original region's kms key id is in the map. --- builder/amazon/common/step_ami_region_copy.go | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/builder/amazon/common/step_ami_region_copy.go b/builder/amazon/common/step_ami_region_copy.go index 4a1f2d392..36ae711fe 100644 --- a/builder/amazon/common/step_ami_region_copy.go +++ b/builder/amazon/common/step_ami_region_copy.go @@ -26,6 +26,26 @@ type StepAMIRegionCopy struct { AMISkipBuildRegion bool } +func (s *StepAMIRegionCopy) DeduplicateRegions() { + // Deduplicates regions by looping over the list of regions and storing + // the regions as keys in a map. This saves users from accidentally copying + // regions twice if they've added a region to a map twice. + + RegionMap := map[string]bool{} + RegionSlice := []string{} + + for _, r := range s.Regions { + RegionMap[r] = true + } + + // Now print all those keys into the region slice again + for k, _ := range RegionMap { + RegionSlice = append(RegionSlice, k) + } + + s.Regions = RegionSlice +} + func (s *StepAMIRegionCopy) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) amis := state.Get("amis").(map[string]string) @@ -43,6 +63,10 @@ func (s *StepAMIRegionCopy) Run(ctx context.Context, state multistep.StateBag) m if !s.AMISkipBuildRegion { s.Regions = append(s.Regions, s.OriginalRegion) } + // Now that we've added OriginalRegion, best to make sure there aren't + // any duplicates hanging around; duplicates will waste time. + s.DeduplicateRegions() + if *s.EncryptBootVolume { // encrypt_boot is true, so we have to copy the temporary // AMI with required encryption setting. @@ -50,7 +74,11 @@ func (s *StepAMIRegionCopy) Run(ctx context.Context, state multistep.StateBag) m if s.RegionKeyIds == nil { s.RegionKeyIds = make(map[string]string) } - s.RegionKeyIds[s.OriginalRegion] = s.AMIKmsKeyId + + // Make sure the kms_key_id for the original region is in the map + if _, ok := s.RegionKeyIds[s.OriginalRegion]; !ok { + s.RegionKeyIds[s.OriginalRegion] = s.AMIKmsKeyId + } } } From f1d782e6f4b70c15a894e9e689b023485e1c8312 Mon Sep 17 00:00:00 2001 From: WilliamB Date: Wed, 17 Jul 2019 03:41:41 -0500 Subject: [PATCH 002/113] Correct HTTPIP == FALSE on HyperV builder --- 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 aa5ee1db3..d6539d328 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -35,7 +35,7 @@ param([string]$switchName, [int]$addressIndex) $HostVMAdapter = Hyper-V\Get-VMNetworkAdapter -ManagementOS -SwitchName $switchName if ($HostVMAdapter){ - $HostNetAdapter = Get-NetAdapter | ?{ $HostVMAdapter.DeviceId.Contains($_.DeviceID) } + $HostNetAdapter = Get-NetAdapter | ?{ $_.DeviceId -eq $HostVMAdapter.DeviceId } if ($HostNetAdapter){ $HostNetAdapterIfIndex = @() $HostNetAdapterIfIndex += $HostNetAdapter.ifIndex From e658a50880c1841ecb68405f0d5deff9c16a83d3 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Fri, 12 Jul 2019 14:59:11 -0700 Subject: [PATCH 003/113] refactored step_ami_region_copy to fix bugs and clarify assumptions; added more tests for that step. fix race condition caused by variable declaration outside of loop --- builder/amazon/common/block_device.go | 2 +- builder/amazon/common/step_ami_region_copy.go | 59 ++-- .../common/step_ami_region_copy_test.go | 255 +++++++++++++++--- builder/amazon/ebs/step_create_ami.go | 15 +- .../docs/builders/amazon-chroot.html.md.erb | 4 + .../docs/builders/amazon-ebs.html.md.erb | 4 + .../builders/amazon-ebssurrogate.html.md.erb | 4 + .../docs/builders/amazon-instance.html.md.erb | 4 + 8 files changed, 287 insertions(+), 60 deletions(-) diff --git a/builder/amazon/common/block_device.go b/builder/amazon/common/block_device.go index 06fda046b..88e066031 100644 --- a/builder/amazon/common/block_device.go +++ b/builder/amazon/common/block_device.go @@ -93,7 +93,7 @@ func (b *BlockDevice) Prepare(ctx *interpolate.Context) error { return fmt.Errorf("The `device_name` must be specified " + "for every device in the block device mapping.") } - // Warn that encrypted must be true when setting kms_key_id + // Warn that encrypted must be true or nil when setting kms_key_id if b.KmsKeyId != "" && b.Encrypted != nil && *b.Encrypted == false { return fmt.Errorf("The device %v, must also have `encrypted: "+ "true` when setting a kms_key_id.", b.DeviceName) diff --git a/builder/amazon/common/step_ami_region_copy.go b/builder/amazon/common/step_ami_region_copy.go index 36ae711fe..077459f5d 100644 --- a/builder/amazon/common/step_ami_region_copy.go +++ b/builder/amazon/common/step_ami_region_copy.go @@ -26,7 +26,7 @@ type StepAMIRegionCopy struct { AMISkipBuildRegion bool } -func (s *StepAMIRegionCopy) DeduplicateRegions() { +func (s *StepAMIRegionCopy) DeduplicateRegions(intermediary bool) { // Deduplicates regions by looping over the list of regions and storing // the regions as keys in a map. This saves users from accidentally copying // regions twice if they've added a region to a map twice. @@ -34,10 +34,24 @@ func (s *StepAMIRegionCopy) DeduplicateRegions() { RegionMap := map[string]bool{} RegionSlice := []string{} + // Original build region may or may not be present in the Regions list, so + // let's make absolutely sure it's in our map. + RegionMap[s.OriginalRegion] = true for _, r := range s.Regions { RegionMap[r] = true } + if !intermediary || s.AMISkipBuildRegion { + // We don't want to copy back into the original region if we aren't + // using an intermediary image, so remove the original region from our + // map. + + // We also don't want to copy back into the original region if the + // intermediary image is because we're skipping the build region. + delete(RegionMap, s.OriginalRegion) + + } + // Now print all those keys into the region slice again for k, _ := range RegionMap { RegionSlice = append(RegionSlice, k) @@ -50,35 +64,27 @@ func (s *StepAMIRegionCopy) Run(ctx context.Context, state multistep.StateBag) m ui := state.Get("ui").(packer.Ui) amis := state.Get("amis").(map[string]string) snapshots := state.Get("snapshots").(map[string][]string) + intermediary := state.Get("intermediary_image").(bool) + s.DeduplicateRegions(intermediary) ami := amis[s.OriginalRegion] - // Always copy back into original region to preserve the ami name - if s.EncryptBootVolume != nil || s.AMISkipBuildRegion { - // if we haven't specificed encryption and we aren't skipping the save - // to the build region, we don't have anything to delete + + // Make a note to delete the intermediary AMI if necessary. + if intermediary { s.toDelete = ami } - if s.EncryptBootVolume != nil { - if !s.AMISkipBuildRegion { - s.Regions = append(s.Regions, s.OriginalRegion) + if s.EncryptBootVolume != nil && *s.EncryptBootVolume { + // encrypt_boot is true, so we have to copy the temporary + // AMI with required encryption setting. + // temp image was created by stepCreateAMI. + if s.RegionKeyIds == nil { + s.RegionKeyIds = make(map[string]string) } - // Now that we've added OriginalRegion, best to make sure there aren't - // any duplicates hanging around; duplicates will waste time. - s.DeduplicateRegions() - if *s.EncryptBootVolume { - // encrypt_boot is true, so we have to copy the temporary - // AMI with required encryption setting. - // temp image was created by stepCreateAMI. - if s.RegionKeyIds == nil { - s.RegionKeyIds = make(map[string]string) - } - - // Make sure the kms_key_id for the original region is in the map - if _, ok := s.RegionKeyIds[s.OriginalRegion]; !ok { - s.RegionKeyIds[s.OriginalRegion] = s.AMIKmsKeyId - } + // Make sure the kms_key_id for the original region is in the map + if _, ok := s.RegionKeyIds[s.OriginalRegion]; !ok { + s.RegionKeyIds[s.OriginalRegion] = s.AMIKmsKeyId } } @@ -90,15 +96,18 @@ func (s *StepAMIRegionCopy) Run(ctx context.Context, state multistep.StateBag) m var lock sync.Mutex var wg sync.WaitGroup - var regKeyID string errs := new(packer.MultiError) - wg.Add(len(s.Regions)) for _, region := range s.Regions { + var regKeyID string ui.Message(fmt.Sprintf("Copying to: %s", region)) if s.EncryptBootVolume != nil && *s.EncryptBootVolume { + // Encrypt is true, explicitly regKeyID = s.RegionKeyIds[region] + } else { + // Encrypt is nil or false; Make sure region key is empty + regKeyID = "" } go func(region string) { diff --git a/builder/amazon/common/step_ami_region_copy_test.go b/builder/amazon/common/step_ami_region_copy_test.go index 03841b67d..d434b777f 100644 --- a/builder/amazon/common/step_ami_region_copy_test.go +++ b/builder/amazon/common/step_ami_region_copy_test.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "fmt" + "sync" "testing" "github.com/aws/aws-sdk-go/aws" @@ -25,10 +26,14 @@ type mockEC2Conn struct { deregisterImageCount int deleteSnapshotCount int waitCount int + + lock sync.Mutex } func (m *mockEC2Conn) CopyImage(copyInput *ec2.CopyImageInput) (*ec2.CopyImageOutput, error) { + m.lock.Lock() m.copyImageCount++ + m.lock.Unlock() copiedImage := fmt.Sprintf("%s-copied-%d", *copyInput.SourceImageId, m.copyImageCount) output := &ec2.CopyImageOutput{ ImageId: &copiedImage, @@ -38,7 +43,9 @@ func (m *mockEC2Conn) CopyImage(copyInput *ec2.CopyImageInput) (*ec2.CopyImageOu // functions we have to create mock responses for in order for test to run func (m *mockEC2Conn) DescribeImages(*ec2.DescribeImagesInput) (*ec2.DescribeImagesOutput, error) { + m.lock.Lock() m.describeImagesCount++ + m.lock.Unlock() output := &ec2.DescribeImagesOutput{ Images: []*ec2.Image{{}}, } @@ -46,19 +53,25 @@ func (m *mockEC2Conn) DescribeImages(*ec2.DescribeImagesInput) (*ec2.DescribeIma } func (m *mockEC2Conn) DeregisterImage(*ec2.DeregisterImageInput) (*ec2.DeregisterImageOutput, error) { + m.lock.Lock() m.deregisterImageCount++ + m.lock.Unlock() output := &ec2.DeregisterImageOutput{} return output, nil } func (m *mockEC2Conn) DeleteSnapshot(*ec2.DeleteSnapshotInput) (*ec2.DeleteSnapshotOutput, error) { + m.lock.Lock() m.deleteSnapshotCount++ + m.lock.Unlock() output := &ec2.DeleteSnapshotOutput{} return output, nil } func (m *mockEC2Conn) WaitUntilImageAvailableWithContext(aws.Context, *ec2.DescribeImagesInput, ...request.WaiterOption) error { + m.lock.Lock() m.waitCount++ + m.lock.Unlock() return nil } @@ -84,6 +97,128 @@ func tState() multistep.StateBag { return state } +func TestStepAMIRegionCopy_duplicates(t *testing.T) { + // ------------------------------------------------------------------------ + // Test that if the original region is added to both Regions and Region, + // the ami is only copied once (with encryption). + // ------------------------------------------------------------------------ + + stepAMIRegionCopy := StepAMIRegionCopy{ + AccessConfig: testAccessConfig(), + Regions: []string{"us-east-1"}, + AMIKmsKeyId: "12345", + // Original region key in regionkeyids is different than in amikmskeyid + RegionKeyIds: map[string]string{"us-east-1": "12345"}, + EncryptBootVolume: aws.Bool(true), + Name: "fake-ami-name", + OriginalRegion: "us-east-1", + } + // mock out the region connection code + stepAMIRegionCopy.getRegionConn = getMockConn + + state := tState() + state.Put("intermediary_image", true) + stepAMIRegionCopy.Run(context.Background(), state) + + if len(stepAMIRegionCopy.Regions) != 1 { + t.Fatalf("Should have added original ami to Regions one time only") + } + + // ------------------------------------------------------------------------ + // Both Region and Regions set, but no encryption - shouldn't copy anything + // ------------------------------------------------------------------------ + + // the ami is only copied once. + stepAMIRegionCopy = StepAMIRegionCopy{ + AccessConfig: testAccessConfig(), + Regions: []string{"us-east-1"}, + Name: "fake-ami-name", + OriginalRegion: "us-east-1", + } + // mock out the region connection code + state.Put("intermediary_image", false) + stepAMIRegionCopy.getRegionConn = getMockConn + stepAMIRegionCopy.Run(context.Background(), state) + + if len(stepAMIRegionCopy.Regions) != 0 { + t.Fatalf("Should not have added original ami to Regions; not encrypting") + } + + // ------------------------------------------------------------------------ + // Both Region and Regions set, but no encryption - shouldn't copy anything, + // this tests false as opposed to nil value above. + // ------------------------------------------------------------------------ + + // the ami is only copied once. + stepAMIRegionCopy = StepAMIRegionCopy{ + AccessConfig: testAccessConfig(), + Regions: []string{"us-east-1"}, + EncryptBootVolume: aws.Bool(false), + Name: "fake-ami-name", + OriginalRegion: "us-east-1", + } + // mock out the region connection code + state.Put("intermediary_image", false) + stepAMIRegionCopy.getRegionConn = getMockConn + stepAMIRegionCopy.Run(context.Background(), state) + + if len(stepAMIRegionCopy.Regions) != 0 { + t.Fatalf("Should not have added original ami to Regions once; not" + + "encrypting") + } + + // ------------------------------------------------------------------------ + // Multiple regions, many duplicates, and encryption (this shouldn't ever + // happen because of our template validation, but good to test it.) + // ------------------------------------------------------------------------ + + stepAMIRegionCopy = StepAMIRegionCopy{ + AccessConfig: testAccessConfig(), + // Many duplicates for only 3 actual values + Regions: []string{"us-east-1", "us-west-2", "us-west-2", "ap-east-1", "ap-east-1", "ap-east-1"}, + AMIKmsKeyId: "IlikePancakes", + // Original region key in regionkeyids is different than in amikmskeyid + RegionKeyIds: map[string]string{"us-east-1": "12345", "us-west-2": "abcde", "ap-east-1": "xyz"}, + EncryptBootVolume: aws.Bool(true), + Name: "fake-ami-name", + OriginalRegion: "us-east-1", + } + // mock out the region connection code + stepAMIRegionCopy.getRegionConn = getMockConn + state.Put("intermediary_image", true) + stepAMIRegionCopy.Run(context.Background(), state) + + if len(stepAMIRegionCopy.Regions) != 3 { + t.Fatalf("Each AMI should have been added to Regions one time only.") + } + + // Also verify that we respect RegionKeyIds over AMIKmsKeyIds: + if stepAMIRegionCopy.RegionKeyIds["us-east-1"] != "12345" { + t.Fatalf("RegionKeyIds should take precedence over AmiKmsKeyIds") + } + + // ------------------------------------------------------------------------ + // Multiple regions, many duplicates, NO encryption + // ------------------------------------------------------------------------ + + stepAMIRegionCopy = StepAMIRegionCopy{ + AccessConfig: testAccessConfig(), + // Many duplicates for only 3 actual values + Regions: []string{"us-east-1", "us-west-2", "us-west-2", "ap-east-1", "ap-east-1", "ap-east-1"}, + Name: "fake-ami-name", + OriginalRegion: "us-east-1", + } + // mock out the region connection code + stepAMIRegionCopy.getRegionConn = getMockConn + state.Put("intermediary_image", false) + stepAMIRegionCopy.Run(context.Background(), state) + + if len(stepAMIRegionCopy.Regions) != 2 { + t.Fatalf("Each AMI should have been added to Regions one time only, " + + "and original region shouldn't be added at all") + } +} + func TestStepAmiRegionCopy_nil_encryption(t *testing.T) { // create step stepAMIRegionCopy := StepAMIRegionCopy{ @@ -99,6 +234,7 @@ func TestStepAmiRegionCopy_nil_encryption(t *testing.T) { stepAMIRegionCopy.getRegionConn = getMockConn state := tState() + state.Put("intermediary_image", false) stepAMIRegionCopy.Run(context.Background(), state) if stepAMIRegionCopy.toDelete != "" { @@ -109,31 +245,6 @@ func TestStepAmiRegionCopy_nil_encryption(t *testing.T) { } } -func TestStepAmiRegionCopy_false_encryption(t *testing.T) { - // create step - stepAMIRegionCopy := StepAMIRegionCopy{ - AccessConfig: testAccessConfig(), - Regions: make([]string, 0), - AMIKmsKeyId: "", - RegionKeyIds: make(map[string]string), - EncryptBootVolume: aws.Bool(false), - Name: "fake-ami-name", - OriginalRegion: "us-east-1", - } - // mock out the region connection code - stepAMIRegionCopy.getRegionConn = getMockConn - - state := tState() - stepAMIRegionCopy.Run(context.Background(), state) - - if stepAMIRegionCopy.toDelete != "ami-12345" { - t.Fatalf("should be deleting the original intermediary ami") - } - if len(stepAMIRegionCopy.Regions) == 0 { - t.Fatalf("Should have added original ami to Regions") - } -} - func TestStepAmiRegionCopy_true_encryption(t *testing.T) { // create step stepAMIRegionCopy := StepAMIRegionCopy{ @@ -149,6 +260,7 @@ func TestStepAmiRegionCopy_true_encryption(t *testing.T) { stepAMIRegionCopy.getRegionConn = getMockConn state := tState() + state.Put("intermediary_image", true) stepAMIRegionCopy.Run(context.Background(), state) if stepAMIRegionCopy.toDelete == "" { @@ -159,13 +271,16 @@ func TestStepAmiRegionCopy_true_encryption(t *testing.T) { } } -func TestStepAmiRegionCopy_true_AMISkipBuildRegion(t *testing.T) { - // create step +func TestStepAmiRegionCopy_AMISkipBuildRegion(t *testing.T) { + // ------------------------------------------------------------------------ + // skip build region is true + // ------------------------------------------------------------------------ + stepAMIRegionCopy := StepAMIRegionCopy{ AccessConfig: testAccessConfig(), - Regions: make([]string, 0), + Regions: []string{"us-west-1"}, AMIKmsKeyId: "", - RegionKeyIds: make(map[string]string), + RegionKeyIds: map[string]string{"us-west-1": "abcde"}, Name: "fake-ami-name", OriginalRegion: "us-east-1", AMISkipBuildRegion: true, @@ -174,12 +289,90 @@ func TestStepAmiRegionCopy_true_AMISkipBuildRegion(t *testing.T) { stepAMIRegionCopy.getRegionConn = getMockConn state := tState() + state.Put("intermediary_image", true) stepAMIRegionCopy.Run(context.Background(), state) if stepAMIRegionCopy.toDelete == "" { t.Fatalf("Should delete original AMI if skip_save_build_region=true") } - if len(stepAMIRegionCopy.Regions) != 0 { - t.Fatalf("Should not have added original ami to Regions") + if len(stepAMIRegionCopy.Regions) != 1 { + t.Fatalf("Should not have added original ami to Regions; Regions: %#v", stepAMIRegionCopy.Regions) + } + + // ------------------------------------------------------------------------ + // skip build region is false. + // ------------------------------------------------------------------------ + stepAMIRegionCopy = StepAMIRegionCopy{ + AccessConfig: testAccessConfig(), + Regions: []string{"us-west-1"}, + AMIKmsKeyId: "", + RegionKeyIds: make(map[string]string), + Name: "fake-ami-name", + OriginalRegion: "us-east-1", + AMISkipBuildRegion: false, + } + // mock out the region connection code + stepAMIRegionCopy.getRegionConn = getMockConn + + state.Put("intermediary_image", false) // not encrypted + stepAMIRegionCopy.Run(context.Background(), state) + + if stepAMIRegionCopy.toDelete != "" { + t.Fatalf("Shouldn't have an intermediary AMI, so dont delete original ami") + } + if len(stepAMIRegionCopy.Regions) != 1 { + t.Fatalf("Should not have added original ami to Regions; Regions: %#v", stepAMIRegionCopy.Regions) + } + + // ------------------------------------------------------------------------ + // skip build region is false, but encrypt is true + // ------------------------------------------------------------------------ + stepAMIRegionCopy = StepAMIRegionCopy{ + AccessConfig: testAccessConfig(), + Regions: []string{"us-west-1"}, + AMIKmsKeyId: "", + RegionKeyIds: map[string]string{"us-west-1": "abcde"}, + Name: "fake-ami-name", + OriginalRegion: "us-east-1", + AMISkipBuildRegion: false, + EncryptBootVolume: aws.Bool(true), + } + // mock out the region connection code + stepAMIRegionCopy.getRegionConn = getMockConn + + state.Put("intermediary_image", true) //encrypted + stepAMIRegionCopy.Run(context.Background(), state) + + if stepAMIRegionCopy.toDelete == "" { + t.Fatalf("Have to delete intermediary AMI") + } + if len(stepAMIRegionCopy.Regions) != 2 { + t.Fatalf("Should have added original ami to Regions; Regions: %#v", stepAMIRegionCopy.Regions) + } + + // ------------------------------------------------------------------------ + // skip build region is true, and encrypt is true + // ------------------------------------------------------------------------ + stepAMIRegionCopy = StepAMIRegionCopy{ + AccessConfig: testAccessConfig(), + Regions: []string{"us-west-1"}, + AMIKmsKeyId: "", + RegionKeyIds: map[string]string{"us-west-1": "abcde"}, + Name: "fake-ami-name", + OriginalRegion: "us-east-1", + AMISkipBuildRegion: true, + EncryptBootVolume: aws.Bool(true), + } + // mock out the region connection code + stepAMIRegionCopy.getRegionConn = getMockConn + + state.Put("intermediary_image", true) //encrypted + stepAMIRegionCopy.Run(context.Background(), state) + + if stepAMIRegionCopy.toDelete == "" { + t.Fatalf("Have to delete intermediary AMI") + } + if len(stepAMIRegionCopy.Regions) != 1 { + t.Fatalf("Should not have added original ami to Regions; Regions: %#v", stepAMIRegionCopy.Regions) } } diff --git a/builder/amazon/ebs/step_create_ami.go b/builder/amazon/ebs/step_create_ami.go index c1d0da0b8..d4d35638f 100644 --- a/builder/amazon/ebs/step_create_ami.go +++ b/builder/amazon/ebs/step_create_ami.go @@ -26,9 +26,18 @@ func (s *stepCreateAMI) Run(ctx context.Context, state multistep.StateBag) multi // Create the image amiName := config.AMIName - if config.AMIEncryptBootVolume != nil || s.AMISkipBuildRegion { - // Create a temporary image and then create a copy of it with the - // correct encrypt_boot + state.Put("intermediary_image", false) + if config.AMIEncryptBootVolume != nil && *config.AMIEncryptBootVolume != false || s.AMISkipBuildRegion { + state.Put("intermediary_image", true) + + // From AWS SDK docs: You can encrypt a copy of an unencrypted snapshot, + // but you cannot use it to create an unencrypted copy of an encrypted + // snapshot. Your default CMK for EBS is used unless you specify a + // non-default key using KmsKeyId. + + // If encrypt_boot is nil or true, we need to create a temporary image + // so that in step_region_copy, we can copy it with the correct + // encryption amiName = random.AlphaNum(7) } diff --git a/website/source/docs/builders/amazon-chroot.html.md.erb b/website/source/docs/builders/amazon-chroot.html.md.erb index 14bc59195..635b3e505 100644 --- a/website/source/docs/builders/amazon-chroot.html.md.erb +++ b/website/source/docs/builders/amazon-chroot.html.md.erb @@ -198,6 +198,10 @@ each category, the available configuration keys are alphabetized. *KmsKeyId* in the [AWS API docs - CopyImage](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CopyImage.html). + This option supercedes the `kms_key_id` option -- if you set both, and they + are different, Packer will respect the value in `region_kms_key_ids` for + your build region and silently disregard the value provided in `kms_key_id`. + - `root_device_name` (string) - The root device name. For example, `xvda`. - `mfa_code` (string) - The MFA diff --git a/website/source/docs/builders/amazon-ebs.html.md.erb b/website/source/docs/builders/amazon-ebs.html.md.erb index 4825ccaca..3e7b6fe6d 100644 --- a/website/source/docs/builders/amazon-ebs.html.md.erb +++ b/website/source/docs/builders/amazon-ebs.html.md.erb @@ -244,6 +244,10 @@ builder. *KmsKeyId* in the [AWS API docs - CopyImage](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CopyImage.html). + This option supercedes the `kms_key_id` option -- if you set both, and they + are different, Packer will respect the value in `region_kms_key_ids` for + your build region and silently disregard the value provided in `kms_key_id`. + - `run_tags` (object of key/value strings) - Tags to apply to the instance that is *launched* to create the AMI. These tags are *not* applied to the resulting AMI unless they're duplicated in `tags`. This is a [template diff --git a/website/source/docs/builders/amazon-ebssurrogate.html.md.erb b/website/source/docs/builders/amazon-ebssurrogate.html.md.erb index cc1f7fcdb..e34e9ed1b 100644 --- a/website/source/docs/builders/amazon-ebssurrogate.html.md.erb +++ b/website/source/docs/builders/amazon-ebssurrogate.html.md.erb @@ -245,6 +245,10 @@ builder. *KmsKeyId* in the [AWS API docs - CopyImage](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CopyImage.html). + This option supercedes the `kms_key_id` option -- if you set both, and they + are different, Packer will respect the value in `region_kms_key_ids` for + your build region and silently disregard the value provided in `kms_key_id`. + - `run_tags` (object of key/value strings) - Tags to apply to the instance that is *launched* to create the AMI. These tags are *not* applied to the resulting AMI unless they're duplicated in `tags`. This is a [template diff --git a/website/source/docs/builders/amazon-instance.html.md.erb b/website/source/docs/builders/amazon-instance.html.md.erb index 7c8048a32..f0d61bdd0 100644 --- a/website/source/docs/builders/amazon-instance.html.md.erb +++ b/website/source/docs/builders/amazon-instance.html.md.erb @@ -247,6 +247,10 @@ builder. *KmsKeyId* in the [AWS API docs - CopyImage](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CopyImage.html). + This option supercedes the `kms_key_id` option -- if you set both, and they + are different, Packer will respect the value in `region_kms_key_ids` for + your build region and silently disregard the value provided in `kms_key_id`. + - `run_tags` (object of key/value strings) - Tags to apply to the instance that is *launched* to create the AMI. These tags are *not* applied to the resulting AMI unless they're duplicated in `tags`. This is a [template From c29816f4961920c94cddb068ed9d10ab7c81f45b Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Wed, 23 Jan 2019 15:53:41 -0600 Subject: [PATCH 004/113] chore: add bsusurrogate builder structure --- builder/osc/bsusurrogate/builder.go | 41 ++++++++++++++++++++++++ builder/osc/bsusurrogate/builder_test.go | 15 +++++++++ 2 files changed, 56 insertions(+) create mode 100644 builder/osc/bsusurrogate/builder.go create mode 100644 builder/osc/bsusurrogate/builder_test.go diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go new file mode 100644 index 000000000..a3b46d827 --- /dev/null +++ b/builder/osc/bsusurrogate/builder.go @@ -0,0 +1,41 @@ +// The bsusurrogate package contains a packer.Builder implementation that +// builds a new EBS-backed AMI using an ephemeral instance. +package bsusurrogate + +import ( + "log" + + "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/hashicorp/packer/template/interpolate" +) + +const BuilderId = "digitalonus.osc.bsusurrogate" + +type Config struct { + common.PackerConfig `mapstructure:",squash"` + ctx interpolate.Context +} + +type Builder struct { + config Config + runner multistep.Runner +} + +func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { + log.Println("Preparing Outscale Builder...") + return nil, nil +} + +func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { + log.Println("Running Outscale Builder...") + return nil, nil +} + +func (b *Builder) Cancel() { + if b.runner != nil { + log.Println("Cancelling the step runner...") + b.runner.Cancel() + } +} diff --git a/builder/osc/bsusurrogate/builder_test.go b/builder/osc/bsusurrogate/builder_test.go new file mode 100644 index 000000000..d91f46af8 --- /dev/null +++ b/builder/osc/bsusurrogate/builder_test.go @@ -0,0 +1,15 @@ +package bsusurrogate + +import ( + "testing" + + "github.com/hashicorp/packer/packer" +) + +func TestBuilder_ImplementsBuilder(t *testing.T) { + var raw interface{} + raw = &Builder{} + if _, ok := raw.(packer.Builder); !ok { + t.Fatal("Builder should be a builder") + } +} From c1fc2801ef961f17d585fcac3b376355d39dd9f3 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Mon, 28 Jan 2019 12:29:26 -0600 Subject: [PATCH 005/113] add access_config struct and test --- builder/osc/common/access_config.go | 84 ++++++++++++++++++++++++ builder/osc/common/access_config_test.go | 66 +++++++++++++++++++ builder/osc/common/regions.go | 56 ++++++++++++++++ 3 files changed, 206 insertions(+) create mode 100644 builder/osc/common/access_config.go create mode 100644 builder/osc/common/access_config_test.go create mode 100644 builder/osc/common/regions.go diff --git a/builder/osc/common/access_config.go b/builder/osc/common/access_config.go new file mode 100644 index 000000000..3b76ea7bb --- /dev/null +++ b/builder/osc/common/access_config.go @@ -0,0 +1,84 @@ +package common + +import ( + "crypto/tls" + "fmt" + "log" + "net/http" + + "github.com/hashicorp/packer/template/interpolate" + "github.com/outscale/osc-go/oapi" +) + +// AccessConfig is for common configuration related to AWS access +type AccessConfig struct { + AccessKey string `mapstructure:"access_key"` + CustomEndpoint string `mapstructure:"custom_endpoint"` + DecodeAuthZMessages bool `mapstructure:"decode_authorization_messages"` + InsecureSkipTLSVerify bool `mapstructure:"insecure_skip_tls_verify"` + MFACode string `mapstructure:"mfa_code"` + ProfileName string `mapstructure:"profile"` + RawRegion string `mapstructure:"region"` + SecretKey string `mapstructure:"secret_key"` + SkipValidation bool `mapstructure:"skip_region_validation"` + SkipMetadataApiCheck bool `mapstructure:"skip_metadata_api_check"` + Token string `mapstructure:"token"` + clientConfig *oapi.Config + + getOAPIConnection func() oapi.OAPIClient +} + +// Config returns a valid aws.Config object for access to AWS services, or +// an error if the authentication and region couldn't be resolved +func (c *AccessConfig) Config() (*oapi.Config, error) { + if c.clientConfig != nil { + return c.clientConfig, nil + } + + config := &oapi.Config{ + AccessKey: c.AccessKey, + SecretKey: c.SecretKey, + Region: c.RawRegion, + URL: c.CustomEndpoint, + Service: "api", + } + + return config, nil + +} + +func (c *AccessConfig) NewOAPIConnection() (oapi.OAPIClient, error) { + if c.getOAPIConnection != nil { + return c.getOAPIConnection(), nil + } + oapicfg, err := c.Config() + if err != nil { + return nil, err + } + + skipClient := &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }, + } + + oapiClient := oapi.NewClient(oapicfg, skipClient) + + return oapiClient, nil +} + +func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error { + var errs []error + + if c.SkipMetadataApiCheck { + log.Println("(WARN) skip_metadata_api_check ignored.") + } + // Either both access and secret key must be set or neither of them should + // be. + if (len(c.AccessKey) > 0) != (len(c.SecretKey) > 0) { + errs = append(errs, + fmt.Errorf("`access_key` and `secret_key` must both be either set or not set.")) + } + + return errs +} diff --git a/builder/osc/common/access_config_test.go b/builder/osc/common/access_config_test.go new file mode 100644 index 000000000..71de1c446 --- /dev/null +++ b/builder/osc/common/access_config_test.go @@ -0,0 +1,66 @@ +package common + +import ( + "testing" + + "github.com/outscale/osc-go/oapi" +) + +type mockOAPIClient struct { + oapi.OAPIClient +} + +func testAccessConfig() *AccessConfig { + return &AccessConfig{ + getOAPIConnection: func() oapi.OAPIClient { + return &mockOAPIClient{} + }, + } +} + +func (m *mockOAPIClient) POST_ReadRegions(oapi.ReadRegionsRequest) (*oapi.POST_ReadRegionsResponses, error) { + return &oapi.POST_ReadRegionsResponses{ + OK: &oapi.ReadRegionsResponse{ + Regions: []oapi.Region{ + {RegionEndpoint: "us-west1", RegionName: "us-west1"}, + {RegionEndpoint: "us-east-1", RegionName: "us-east-1"}, + }, + }, + }, nil +} + +func TestAccessConfigPrepare_Region(t *testing.T) { + c := testAccessConfig() + + c.RawRegion = "us-east-12" + err := c.ValidateRegion(c.RawRegion) + if err == nil { + t.Fatalf("should have region validation err: %s", c.RawRegion) + } + + c.RawRegion = "us-east-1" + err = c.ValidateRegion(c.RawRegion) + if err != nil { + t.Fatalf("shouldn't have region validation err: %s", c.RawRegion) + } + + c.RawRegion = "custom" + err = c.ValidateRegion(c.RawRegion) + if err == nil { + t.Fatalf("should have region validation err: %s", c.RawRegion) + } + + c.RawRegion = "custom" + c.SkipValidation = true + // testing whole prepare func here; this is checking that validation is + // skipped, so we don't need a mock connection + if err := c.Prepare(nil); err != nil { + t.Fatalf("shouldn't have err: %s", err) + } + + c.SkipValidation = false + c.RawRegion = "" + if err := c.Prepare(nil); err != nil { + t.Fatalf("shouldn't have err: %s", err) + } +} diff --git a/builder/osc/common/regions.go b/builder/osc/common/regions.go new file mode 100644 index 000000000..f52a53c3a --- /dev/null +++ b/builder/osc/common/regions.go @@ -0,0 +1,56 @@ +package common + +import ( + "fmt" + + "github.com/outscale/osc-go/oapi" +) + +func listOAPIRegions(oapiconn oapi.OAPIClient) ([]string, error) { + var regions []string + resp, err := oapiconn.POST_ReadRegions(oapi.ReadRegionsRequest{}) + if resp.OK == nil || err != nil { + return []string{}, err + } + + resultRegions := resp.OK + + for _, region := range resultRegions.Regions { + regions = append(regions, region.RegionName) + } + + return regions, nil +} + +// ValidateRegion returns true if the supplied region is a valid AWS +// region and false if it's not. +func (c *AccessConfig) ValidateRegion(regions ...string) error { + oapiconn, err := c.NewOAPIConnection() + if err != nil { + return err + } + + validRegions, err := listOAPIRegions(oapiconn) + if err != nil { + return err + } + + var invalidRegions []string + for _, region := range regions { + found := false + for _, validRegion := range validRegions { + if region == validRegion { + found = true + break + } + } + if !found { + invalidRegions = append(invalidRegions, region) + } + } + + if len(invalidRegions) > 0 { + return fmt.Errorf("Invalid region(s): %v", invalidRegions) + } + return nil +} From 1c3939fcd3a66cbf62e207043f2fc2ac8815fdc0 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Mon, 28 Jan 2019 12:33:28 -0600 Subject: [PATCH 006/113] add access config to bsusurrogate config struct --- builder/osc/bsusurrogate/builder.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index a3b46d827..62868b653 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -5,6 +5,7 @@ package bsusurrogate import ( "log" + osccommon "github.com/hashicorp/packer/builder/osc/common" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" @@ -14,8 +15,9 @@ import ( const BuilderId = "digitalonus.osc.bsusurrogate" type Config struct { - common.PackerConfig `mapstructure:",squash"` - ctx interpolate.Context + common.PackerConfig `mapstructure:",squash"` + osccommon.AccessConfig `mapstructure:",squash"` + ctx interpolate.Context } type Builder struct { From be36a2159e20bf2be72349b64be9c9b046640ced Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Mon, 28 Jan 2019 15:24:31 -0600 Subject: [PATCH 007/113] feature: add run config to bsusurrogate config struct --- builder/osc/bsusurrogate/builder.go | 1 + builder/osc/common/run_config.go | 218 ++++++++++++++++++++++++ builder/osc/common/run_config_test.go | 232 ++++++++++++++++++++++++++ 3 files changed, 451 insertions(+) create mode 100644 builder/osc/common/run_config.go create mode 100644 builder/osc/common/run_config_test.go diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index 62868b653..94de49b76 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -17,6 +17,7 @@ const BuilderId = "digitalonus.osc.bsusurrogate" type Config struct { common.PackerConfig `mapstructure:",squash"` osccommon.AccessConfig `mapstructure:",squash"` + osccommon.RunConfig `mapstructure:",squash"` ctx interpolate.Context } diff --git a/builder/osc/common/run_config.go b/builder/osc/common/run_config.go new file mode 100644 index 000000000..44b64b01e --- /dev/null +++ b/builder/osc/common/run_config.go @@ -0,0 +1,218 @@ +package common + +import ( + "fmt" + "net" + "os" + "regexp" + "strings" + "time" + + "github.com/hashicorp/packer/common/uuid" + "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/template/interpolate" +) + +var reShutdownBehavior = regexp.MustCompile("^(stop|terminate)$") + +type OmiFilterOptions struct { + Filters map[*string]*string + Owners []*string + MostRecent bool `mapstructure:"most_recent"` +} + +func (d *OmiFilterOptions) Empty() bool { + return len(d.Owners) == 0 && len(d.Filters) == 0 +} + +func (d *OmiFilterOptions) NoOwner() bool { + return len(d.Owners) == 0 +} + +type SubnetFilterOptions struct { + Filters map[*string]*string + MostFree bool `mapstructure:"most_free"` + Random bool `mapstructure:"random"` +} + +func (d *SubnetFilterOptions) Empty() bool { + return len(d.Filters) == 0 +} + +type NetFilterOptions struct { + Filters map[*string]*string +} + +func (d *NetFilterOptions) Empty() bool { + return len(d.Filters) == 0 +} + +type SecurityGroupFilterOptions struct { + Filters map[*string]*string +} + +func (d *SecurityGroupFilterOptions) Empty() bool { + return len(d.Filters) == 0 +} + +// RunConfig contains configuration for running an vm from a source +// AMI and details on how to access that launched image. +type RunConfig struct { + AssociatePublicIpAddress bool `mapstructure:"associate_public_ip_address"` + Subregion string `mapstructure:"availability_zone"` + BlockDurationMinutes int64 `mapstructure:"block_duration_minutes"` + DisableStopVm bool `mapstructure:"disable_stop_vm"` + BsuOptimized bool `mapstructure:"ebs_optimized"` + EnableT2Unlimited bool `mapstructure:"enable_t2_unlimited"` + IamVmProfile string `mapstructure:"iam_vm_profile"` + VmInitiatedShutdownBehavior string `mapstructure:"shutdown_behavior"` + VmType string `mapstructure:"vm_type"` + SecurityGroupFilter SecurityGroupFilterOptions `mapstructure:"security_group_filter"` + RunTags map[string]string `mapstructure:"run_tags"` + SecurityGroupId string `mapstructure:"security_group_id"` + SecurityGroupIds []string `mapstructure:"security_group_ids"` + SourceOmi string `mapstructure:"source_omi"` + SourceOmiFilter OmiFilterOptions `mapstructure:"source_omi_filter"` + SpotPrice string `mapstructure:"spot_price"` + SpotPriceAutoProduct string `mapstructure:"spot_price_auto_product"` + SpotTags map[string]string `mapstructure:"spot_tags"` + SubnetFilter SubnetFilterOptions `mapstructure:"subnet_filter"` + SubnetId string `mapstructure:"subnet_id"` + TemporaryKeyPairName string `mapstructure:"temporary_key_pair_name"` + TemporarySGSourceCidr string `mapstructure:"temporary_security_group_source_cidr"` + UserData string `mapstructure:"user_data"` + UserDataFile string `mapstructure:"user_data_file"` + NetFilter NetFilterOptions `mapstructure:"net_filter"` + NetId string `mapstructure:"net_id"` + WindowsPasswordTimeout time.Duration `mapstructure:"windows_password_timeout"` + + // Communicator settings + Comm communicator.Config `mapstructure:",squash"` +} + +func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { + // If we are not given an explicit ssh_keypair_name or + // ssh_private_key_file, then create a temporary one, but only if the + // temporary_key_pair_name has not been provided and we are not using + // ssh_password. + if c.Comm.SSHKeyPairName == "" && c.Comm.SSHTemporaryKeyPairName == "" && + c.Comm.SSHPrivateKeyFile == "" && c.Comm.SSHPassword == "" { + + c.Comm.SSHTemporaryKeyPairName = fmt.Sprintf("packer_%s", uuid.TimeOrderedUUID()) + } + + if c.WindowsPasswordTimeout == 0 { + c.WindowsPasswordTimeout = 20 * time.Minute + } + + if c.RunTags == nil { + c.RunTags = make(map[string]string) + } + + // Validation + errs := c.Comm.Prepare(ctx) + + // Validating ssh_interface + if c.Comm.SSHInterface != "public_ip" && + c.Comm.SSHInterface != "private_ip" && + c.Comm.SSHInterface != "public_dns" && + c.Comm.SSHInterface != "private_dns" && + c.Comm.SSHInterface != "" { + errs = append(errs, fmt.Errorf("Unknown interface type: %s", c.Comm.SSHInterface)) + } + + if c.Comm.SSHKeyPairName != "" { + if c.Comm.Type == "winrm" && c.Comm.WinRMPassword == "" && c.Comm.SSHPrivateKeyFile == "" { + errs = append(errs, fmt.Errorf("ssh_private_key_file must be provided to retrieve the winrm password when using ssh_keypair_name.")) + } else if c.Comm.SSHPrivateKeyFile == "" && !c.Comm.SSHAgentAuth { + errs = append(errs, fmt.Errorf("ssh_private_key_file must be provided or ssh_agent_auth enabled when ssh_keypair_name is specified.")) + } + } + + if c.SourceOmi == "" && c.SourceOmiFilter.Empty() { + errs = append(errs, fmt.Errorf("A source_omi or source_omi_filter must be specified")) + } + + if c.SourceOmi == "" && c.SourceOmiFilter.NoOwner() { + errs = append(errs, fmt.Errorf("For security reasons, your source AMI filter must declare an owner.")) + } + + if c.VmType == "" { + errs = append(errs, fmt.Errorf("An vm_type must be specified")) + } + + if c.BlockDurationMinutes%60 != 0 { + errs = append(errs, fmt.Errorf( + "block_duration_minutes must be multiple of 60")) + } + + if c.SpotPrice == "auto" { + if c.SpotPriceAutoProduct == "" { + errs = append(errs, fmt.Errorf( + "spot_price_auto_product must be specified when spot_price is auto")) + } + } + + if c.SpotPriceAutoProduct != "" { + if c.SpotPrice != "auto" { + errs = append(errs, fmt.Errorf( + "spot_price should be set to auto when spot_price_auto_product is specified")) + } + } + + if c.SpotTags != nil { + if c.SpotPrice == "" || c.SpotPrice == "0" { + errs = append(errs, fmt.Errorf( + "spot_tags should not be set when not requesting a spot vm")) + } + } + + if c.UserData != "" && c.UserDataFile != "" { + errs = append(errs, fmt.Errorf("Only one of user_data or user_data_file can be specified.")) + } else if c.UserDataFile != "" { + if _, err := os.Stat(c.UserDataFile); err != nil { + errs = append(errs, fmt.Errorf("user_data_file not found: %s", c.UserDataFile)) + } + } + + if c.SecurityGroupId != "" { + if len(c.SecurityGroupIds) > 0 { + errs = append(errs, fmt.Errorf("Only one of security_group_id or security_group_ids can be specified.")) + } else { + c.SecurityGroupIds = []string{c.SecurityGroupId} + c.SecurityGroupId = "" + } + } + + if c.TemporarySGSourceCidr == "" { + c.TemporarySGSourceCidr = "0.0.0.0/0" + } else { + if _, _, err := net.ParseCIDR(c.TemporarySGSourceCidr); err != nil { + errs = append(errs, fmt.Errorf("Error parsing temporary_security_group_source_cidr: %s", err.Error())) + } + } + + if c.VmInitiatedShutdownBehavior == "" { + c.VmInitiatedShutdownBehavior = "stop" + } else if !reShutdownBehavior.MatchString(c.VmInitiatedShutdownBehavior) { + errs = append(errs, fmt.Errorf("shutdown_behavior only accepts 'stop' or 'terminate' values.")) + } + + if c.EnableT2Unlimited { + if c.SpotPrice != "" { + errs = append(errs, fmt.Errorf("Error: T2 Unlimited cannot be used in conjuction with Spot Vms")) + } + firstDotIndex := strings.Index(c.VmType, ".") + if firstDotIndex == -1 { + errs = append(errs, fmt.Errorf("Error determining main Vm Type from: %s", c.VmType)) + } else if c.VmType[0:firstDotIndex] != "t2" { + errs = append(errs, fmt.Errorf("Error: T2 Unlimited enabled with a non-T2 Vm Type: %s", c.VmType)) + } + } + + return errs +} + +func (c *RunConfig) IsSpotVm() bool { + return c.SpotPrice != "" && c.SpotPrice != "0" +} diff --git a/builder/osc/common/run_config_test.go b/builder/osc/common/run_config_test.go new file mode 100644 index 000000000..5bdc977b7 --- /dev/null +++ b/builder/osc/common/run_config_test.go @@ -0,0 +1,232 @@ +package common + +import ( + "io/ioutil" + "os" + "regexp" + "testing" + + "github.com/hashicorp/packer/helper/communicator" +) + +func init() { + // Clear out the OUTSCALE access key env vars so they don't + // affect our tests. + os.Setenv("OUTSCALE_ACCESS_KEY_ID", "") + os.Setenv("OUTSCALE_ACCESS_KEY", "") + os.Setenv("OUTSCALE_SECRET_ACCESS_KEY", "") + os.Setenv("OUTSCALE_SECRET_KEY", "") +} + +func testConfig() *RunConfig { + return &RunConfig{ + SourceOmi: "abcd", + VmType: "m1.small", + + Comm: communicator.Config{ + SSHUsername: "foo", + }, + } +} + +func testConfigFilter() *RunConfig { + config := testConfig() + config.SourceOmi = "" + config.SourceOmiFilter = OmiFilterOptions{} + return config +} + +func TestRunConfigPrepare(t *testing.T) { + c := testConfig() + err := c.Prepare(nil) + if len(err) > 0 { + t.Fatalf("err: %s", err) + } +} + +func TestRunConfigPrepare_VmType(t *testing.T) { + c := testConfig() + c.VmType = "" + if err := c.Prepare(nil); len(err) != 1 { + t.Fatalf("Should error if an instance_type is not specified") + } +} + +func TestRunConfigPrepare_SourceOmi(t *testing.T) { + c := testConfig() + c.SourceOmi = "" + if err := c.Prepare(nil); len(err) != 2 { + t.Fatalf("Should error if a source_ami (or source_ami_filter) is not specified") + } +} + +func TestRunConfigPrepare_SourceOmiFilterBlank(t *testing.T) { + c := testConfigFilter() + if err := c.Prepare(nil); len(err) != 2 { + t.Fatalf("Should error if source_ami_filter is empty or not specified (and source_ami is not specified)") + } +} + +func TestRunConfigPrepare_SourceOmiFilterOwnersBlank(t *testing.T) { + c := testConfigFilter() + filter_key := "name" + filter_value := "foo" + c.SourceOmiFilter = OmiFilterOptions{Filters: map[*string]*string{&filter_key: &filter_value}} + if err := c.Prepare(nil); len(err) != 1 { + t.Fatalf("Should error if Owners is not specified)") + } +} + +func TestRunConfigPrepare_SourceOmiFilterGood(t *testing.T) { + c := testConfigFilter() + owner := "123" + filter_key := "name" + filter_value := "foo" + goodFilter := OmiFilterOptions{Owners: []*string{&owner}, Filters: map[*string]*string{&filter_key: &filter_value}} + c.SourceOmiFilter = goodFilter + if err := c.Prepare(nil); len(err) != 0 { + t.Fatalf("err: %s", err) + } +} + +func TestRunConfigPrepare_EnableT2UnlimitedGood(t *testing.T) { + c := testConfig() + // Must have a T2 instance type if T2 Unlimited is enabled + c.VmType = "t2.micro" + c.EnableT2Unlimited = true + err := c.Prepare(nil) + if len(err) > 0 { + t.Fatalf("err: %s", err) + } +} + +func TestRunConfigPrepare_EnableT2UnlimitedBadVmType(t *testing.T) { + c := testConfig() + // T2 Unlimited cannot be used with instance types other than T2 + c.VmType = "m5.large" + c.EnableT2Unlimited = true + err := c.Prepare(nil) + if len(err) != 1 { + t.Fatalf("Should error if T2 Unlimited is enabled with non-T2 instance_type") + } +} + +func TestRunConfigPrepare_EnableT2UnlimitedBadWithSpotInstanceRequest(t *testing.T) { + c := testConfig() + // T2 Unlimited cannot be used with Spot Instances + c.VmType = "t2.micro" + c.EnableT2Unlimited = true + c.SpotPrice = "auto" + c.SpotPriceAutoProduct = "Linux/UNIX" + err := c.Prepare(nil) + if len(err) != 1 { + t.Fatalf("Should error if T2 Unlimited has been used in conjuntion with a Spot Price request") + } +} + +func TestRunConfigPrepare_SpotAuto(t *testing.T) { + c := testConfig() + c.SpotPrice = "auto" + if err := c.Prepare(nil); len(err) != 1 { + t.Fatalf("Should error if spot_price_auto_product is not set and spot_price is set to auto") + } + + // Good - SpotPrice and SpotPriceAutoProduct are correctly set + c.SpotPriceAutoProduct = "foo" + if err := c.Prepare(nil); len(err) != 0 { + t.Fatalf("err: %s", err) + } + + c.SpotPrice = "" + if err := c.Prepare(nil); len(err) != 1 { + t.Fatalf("Should error if spot_price is not set to auto and spot_price_auto_product is set") + } +} + +func TestRunConfigPrepare_SSHPort(t *testing.T) { + c := testConfig() + c.Comm.SSHPort = 0 + if err := c.Prepare(nil); len(err) != 0 { + t.Fatalf("err: %s", err) + } + + if c.Comm.SSHPort != 22 { + t.Fatalf("invalid value: %d", c.Comm.SSHPort) + } + + c.Comm.SSHPort = 44 + if err := c.Prepare(nil); len(err) != 0 { + t.Fatalf("err: %s", err) + } + + if c.Comm.SSHPort != 44 { + t.Fatalf("invalid value: %d", c.Comm.SSHPort) + } +} + +func TestRunConfigPrepare_UserData(t *testing.T) { + c := testConfig() + tf, err := ioutil.TempFile("", "packer") + if err != nil { + t.Fatalf("err: %s", err) + } + defer os.Remove(tf.Name()) + defer tf.Close() + + c.UserData = "foo" + c.UserDataFile = tf.Name() + if err := c.Prepare(nil); len(err) != 1 { + t.Fatalf("Should error if user_data string and user_data_file have both been specified") + } +} + +func TestRunConfigPrepare_UserDataFile(t *testing.T) { + c := testConfig() + if err := c.Prepare(nil); len(err) != 0 { + t.Fatalf("err: %s", err) + } + + c.UserDataFile = "idontexistidontthink" + if err := c.Prepare(nil); len(err) != 1 { + t.Fatalf("Should error if the file specified by user_data_file does not exist") + } + + tf, err := ioutil.TempFile("", "packer") + if err != nil { + t.Fatalf("err: %s", err) + } + defer os.Remove(tf.Name()) + defer tf.Close() + + c.UserDataFile = tf.Name() + if err := c.Prepare(nil); len(err) != 0 { + t.Fatalf("err: %s", err) + } +} + +func TestRunConfigPrepare_TemporaryKeyPairName(t *testing.T) { + c := testConfig() + c.Comm.SSHTemporaryKeyPairName = "" + if err := c.Prepare(nil); len(err) != 0 { + t.Fatalf("err: %s", err) + } + + if c.Comm.SSHTemporaryKeyPairName == "" { + t.Fatal("keypair name is empty") + } + + // Match prefix and UUID, e.g. "packer_5790d491-a0b8-c84c-c9d2-2aea55086550". + r := regexp.MustCompile(`\Apacker_(?:(?i)[a-f\d]{8}(?:-[a-f\d]{4}){3}-[a-f\d]{12}?)\z`) + if !r.MatchString(c.Comm.SSHTemporaryKeyPairName) { + t.Fatal("keypair name is not valid") + } + + c.Comm.SSHTemporaryKeyPairName = "ssh-key-123" + if err := c.Prepare(nil); len(err) != 0 { + t.Fatalf("err: %s", err) + } + + if c.Comm.SSHTemporaryKeyPairName != "ssh-key-123" { + t.Fatal("keypair name does not match") + } +} From bb848366b6934a8b7a9583758a15d5d013285ae0 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Mon, 28 Jan 2019 17:11:57 -0600 Subject: [PATCH 008/113] feature: add block devices config to bsusurrogate config struct --- builder/osc/bsusurrogate/builder.go | 1 + builder/osc/common/block_device.go | 119 +++++++++++++++++ builder/osc/common/block_device_test.go | 163 ++++++++++++++++++++++++ 3 files changed, 283 insertions(+) create mode 100644 builder/osc/common/block_device.go create mode 100644 builder/osc/common/block_device_test.go diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index 94de49b76..415b82e3b 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -18,6 +18,7 @@ type Config struct { common.PackerConfig `mapstructure:",squash"` osccommon.AccessConfig `mapstructure:",squash"` osccommon.RunConfig `mapstructure:",squash"` + osccommon.BlockDevices `mapstructure:",squash"` ctx interpolate.Context } diff --git a/builder/osc/common/block_device.go b/builder/osc/common/block_device.go new file mode 100644 index 000000000..fa2a16f4e --- /dev/null +++ b/builder/osc/common/block_device.go @@ -0,0 +1,119 @@ +package common + +import ( + "fmt" + "strings" + + "github.com/hashicorp/packer/template/interpolate" + "github.com/outscale/osc-go/oapi" +) + +// BlockDevice +type BlockDevice struct { + DeleteOnVmDeletion bool `mapstructure:"delete_on_vm_deletion"` + DeviceName string `mapstructure:"device_name"` + IOPS int64 `mapstructure:"iops"` + NoDevice bool `mapstructure:"no_device"` + SnapshotId string `mapstructure:"snapshot_id"` + VirtualName string `mapstructure:"virtual_name"` + VolumeType string `mapstructure:"volume_type"` + VolumeSize int64 `mapstructure:"volume_size"` + // Encrypted bool `mapstructure:"encrypted"` + // KmsKeyId string `mapstructure:"kms_key_id"` +} + +type BlockDevices struct { + OMIBlockDevices `mapstructure:",squash"` + LaunchBlockDevices `mapstructure:",squash"` +} + +type OMIBlockDevices struct { + OMIMappings []BlockDevice `mapstructure:"ami_block_device_mappings"` +} + +type LaunchBlockDevices struct { + LaunchMappings []BlockDevice `mapstructure:"launch_block_device_mappings"` +} + +func buildBlockDevices(b []BlockDevice) []*oapi.BlockDeviceMapping { + var blockDevices []*oapi.BlockDeviceMapping + + for _, blockDevice := range b { + mapping := &oapi.BlockDeviceMapping{ + DeviceName: blockDevice.DeviceName, + } + + if blockDevice.NoDevice { + mapping.NoDevice = "" + } else if blockDevice.VirtualName != "" { + if strings.HasPrefix(blockDevice.VirtualName, "ephemeral") { + mapping.VirtualDeviceName = blockDevice.VirtualName + } + } else { + bsu := oapi.Bsu{ + DeleteOnVmDeletion: blockDevice.DeleteOnVmDeletion, + } + + if blockDevice.VolumeType != "" { + bsu.VolumeType = blockDevice.VolumeType + } + + if blockDevice.VolumeSize > 0 { + bsu.VolumeSize = blockDevice.VolumeSize + } + + // IOPS is only valid for io1 type + if blockDevice.VolumeType == "io1" { + bsu.Iops = blockDevice.IOPS + } + + if blockDevice.SnapshotId != "" { + bsu.SnapshotId = blockDevice.SnapshotId + } + + //missing + //BlockDevice Encrypted + //KmsKeyId + + mapping.Bsu = bsu + } + + blockDevices = append(blockDevices, mapping) + } + return blockDevices +} + +func (b *BlockDevice) Prepare(ctx *interpolate.Context) error { + if b.DeviceName == "" { + return fmt.Errorf("The `device_name` must be specified " + + "for every device in the block device mapping.") + } + // Warn that encrypted must be true when setting kms_key_id + // if b.KmsKeyId != "" && b.Encrypted == false { + // return fmt.Errorf("The device %v, must also have `encrypted: "+ + // "true` when setting a kms_key_id.", b.DeviceName) + // } + return nil +} + +func (b *BlockDevices) Prepare(ctx *interpolate.Context) (errs []error) { + for _, d := range b.OMIMappings { + if err := d.Prepare(ctx); err != nil { + errs = append(errs, fmt.Errorf("OMIMapping: %s", err.Error())) + } + } + for _, d := range b.LaunchMappings { + if err := d.Prepare(ctx); err != nil { + errs = append(errs, fmt.Errorf("LaunchMapping: %s", err.Error())) + } + } + return errs +} + +func (b *OMIBlockDevices) BuildOMIDevices() []*oapi.BlockDeviceMapping { + return buildBlockDevices(b.OMIMappings) +} + +func (b *LaunchBlockDevices) BuildLaunchDevices() []*oapi.BlockDeviceMapping { + return buildBlockDevices(b.LaunchMappings) +} diff --git a/builder/osc/common/block_device_test.go b/builder/osc/common/block_device_test.go new file mode 100644 index 000000000..c6489359a --- /dev/null +++ b/builder/osc/common/block_device_test.go @@ -0,0 +1,163 @@ +package common + +import ( + "reflect" + "testing" + + "github.com/outscale/osc-go/oapi" +) + +func TestBlockDevice(t *testing.T) { + cases := []struct { + Config *BlockDevice + Result *oapi.BlockDeviceMapping + }{ + { + Config: &BlockDevice{ + DeviceName: "/dev/sdb", + SnapshotId: "snap-1234", + VolumeType: "standard", + VolumeSize: 8, + DeleteOnVmDeletion: true, + }, + + Result: &oapi.BlockDeviceMapping{ + DeviceName: "/dev/sdb", + Bsu: oapi.Bsu{ + SnapshotId: "snap-1234", + VolumeType: "standard", + VolumeSize: 8, + DeleteOnVmDeletion: true, + }, + }, + }, + { + Config: &BlockDevice{ + DeviceName: "/dev/sdb", + VolumeSize: 8, + }, + + Result: &oapi.BlockDeviceMapping{ + DeviceName: "/dev/sdb", + Bsu: oapi.Bsu{ + VolumeSize: 8, + DeleteOnVmDeletion: false, + }, + }, + }, + { + Config: &BlockDevice{ + DeviceName: "/dev/sdb", + VolumeType: "io1", + VolumeSize: 8, + DeleteOnVmDeletion: true, + IOPS: 1000, + }, + + Result: &oapi.BlockDeviceMapping{ + DeviceName: "/dev/sdb", + Bsu: oapi.Bsu{ + VolumeType: "io1", + VolumeSize: 8, + DeleteOnVmDeletion: true, + Iops: 1000, + }, + }, + }, + { + Config: &BlockDevice{ + DeviceName: "/dev/sdb", + VolumeType: "gp2", + VolumeSize: 8, + DeleteOnVmDeletion: true, + }, + + Result: &oapi.BlockDeviceMapping{ + DeviceName: "/dev/sdb", + Bsu: oapi.Bsu{ + VolumeType: "gp2", + VolumeSize: 8, + DeleteOnVmDeletion: true, + }, + }, + }, + { + Config: &BlockDevice{ + DeviceName: "/dev/sdb", + VolumeType: "gp2", + VolumeSize: 8, + DeleteOnVmDeletion: true, + }, + + Result: &oapi.BlockDeviceMapping{ + DeviceName: "/dev/sdb", + Bsu: oapi.Bsu{ + VolumeType: "gp2", + VolumeSize: 8, + DeleteOnVmDeletion: true, + }, + }, + }, + { + Config: &BlockDevice{ + DeviceName: "/dev/sdb", + VolumeType: "standard", + DeleteOnVmDeletion: true, + }, + + Result: &oapi.BlockDeviceMapping{ + DeviceName: "/dev/sdb", + Bsu: oapi.Bsu{ + VolumeType: "standard", + DeleteOnVmDeletion: true, + }, + }, + }, + { + Config: &BlockDevice{ + DeviceName: "/dev/sdb", + VirtualName: "ephemeral0", + }, + + Result: &oapi.BlockDeviceMapping{ + DeviceName: "/dev/sdb", + VirtualDeviceName: "ephemeral0", + }, + }, + { + Config: &BlockDevice{ + DeviceName: "/dev/sdb", + NoDevice: true, + }, + + Result: &oapi.BlockDeviceMapping{ + DeviceName: "/dev/sdb", + NoDevice: "", + }, + }, + } + + for _, tc := range cases { + omiBlockDevices := OMIBlockDevices{ + OMIMappings: []BlockDevice{*tc.Config}, + } + + launchBlockDevices := LaunchBlockDevices{ + LaunchMappings: []BlockDevice{*tc.Config}, + } + + expected := []*oapi.BlockDeviceMapping{tc.Result} + + omiResults := omiBlockDevices.BuildOMIDevices() + if !reflect.DeepEqual(expected, omiResults) { + t.Fatalf("Bad block device, \nexpected: %#v\n\ngot: %#v", + expected, omiResults) + } + + launchResults := launchBlockDevices.BuildLaunchDevices() + if !reflect.DeepEqual(expected, launchResults) { + t.Fatalf("Bad block device, \nexpected: %#v\n\ngot: %#v", + expected, launchResults) + } + } +} From f6372e8ac6d4d868cd2de62b3b51db2d4fab1b77 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Tue, 29 Jan 2019 11:27:42 -0600 Subject: [PATCH 009/113] feature: add omi config to bsusurrogate config struct --- builder/osc/bsusurrogate/builder.go | 1 + builder/osc/common/omi_config.go | 171 +++++++++++++++++++ builder/osc/common/omi_config_test.go | 230 ++++++++++++++++++++++++++ builder/osc/common/template_funcs.go | 30 ++++ 4 files changed, 432 insertions(+) create mode 100644 builder/osc/common/omi_config.go create mode 100644 builder/osc/common/omi_config_test.go create mode 100644 builder/osc/common/template_funcs.go diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index 415b82e3b..3d86df9be 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -19,6 +19,7 @@ type Config struct { osccommon.AccessConfig `mapstructure:",squash"` osccommon.RunConfig `mapstructure:",squash"` osccommon.BlockDevices `mapstructure:",squash"` + osccommon.OMIConfig `mapstructure:",squash"` ctx interpolate.Context } diff --git a/builder/osc/common/omi_config.go b/builder/osc/common/omi_config.go new file mode 100644 index 000000000..11055c628 --- /dev/null +++ b/builder/osc/common/omi_config.go @@ -0,0 +1,171 @@ +package common + +import ( + "fmt" + "log" + "regexp" + + "github.com/hashicorp/packer/template/interpolate" +) + +//Temporal +type TagMap map[string]string + +// OMIConfig is for common configuration related to creating OMIs. +type OMIConfig struct { + OMIName string `mapstructure:"ami_name"` + OMIDescription string `mapstructure:"ami_description"` + OMIVirtType string `mapstructure:"ami_virtualization_type"` + OMIUsers []string `mapstructure:"ami_users"` + OMIGroups []string `mapstructure:"ami_groups"` + OMIProductCodes []string `mapstructure:"ami_product_codes"` + OMIRegions []string `mapstructure:"ami_regions"` + OMISkipRegionValidation bool `mapstructure:"skip_region_validation"` + OMITags TagMap `mapstructure:"tags"` + OMIENASupport *bool `mapstructure:"ena_support"` + OMISriovNetSupport bool `mapstructure:"sriov_support"` + OMIForceDeregister bool `mapstructure:"force_deregister"` + OMIForceDeleteSnapshot bool `mapstructure:"force_delete_snapshot"` + OMIEncryptBootVolume bool `mapstructure:"encrypt_boot"` + OMIKmsKeyId string `mapstructure:"kms_key_id"` + OMIRegionKMSKeyIDs map[string]string `mapstructure:"region_kms_key_ids"` + SnapshotTags TagMap `mapstructure:"snapshot_tags"` + SnapshotUsers []string `mapstructure:"snapshot_users"` + SnapshotGroups []string `mapstructure:"snapshot_groups"` +} + +func stringInSlice(s []string, searchstr string) bool { + for _, item := range s { + if item == searchstr { + return true + } + } + return false +} + +func (c *OMIConfig) Prepare(accessConfig *AccessConfig, ctx *interpolate.Context) []error { + var errs []error + + if c.OMIName == "" { + errs = append(errs, fmt.Errorf("ami_name must be specified")) + } + + // Make sure that if we have region_kms_key_ids defined, + // the regions in region_kms_key_ids are also in ami_regions + if len(c.OMIRegionKMSKeyIDs) > 0 { + for kmsKeyRegion := range c.OMIRegionKMSKeyIDs { + if !stringInSlice(c.OMIRegions, kmsKeyRegion) { + errs = append(errs, fmt.Errorf("Region %s is in region_kms_key_ids but not in ami_regions", kmsKeyRegion)) + } + } + } + + errs = append(errs, c.prepareRegions(accessConfig)...) + + if len(c.OMIUsers) > 0 && c.OMIEncryptBootVolume { + errs = append(errs, fmt.Errorf("Cannot share OMI with encrypted boot volume")) + } + + var kmsKeys []string + if len(c.OMIKmsKeyId) > 0 { + kmsKeys = append(kmsKeys, c.OMIKmsKeyId) + } + if len(c.OMIRegionKMSKeyIDs) > 0 { + for _, kmsKey := range c.OMIRegionKMSKeyIDs { + if len(kmsKey) == 0 { + kmsKeys = append(kmsKeys, c.OMIKmsKeyId) + } + } + } + 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.OMIKmsKeyId) == 0 && c.OMIEncryptBootVolume { + errs = append(errs, fmt.Errorf("Cannot share snapshot encrypted with default KMS key")) + } + if len(c.OMIRegionKMSKeyIDs) > 0 { + for _, kmsKey := range c.OMIRegionKMSKeyIDs { + if len(kmsKey) == 0 { + errs = append(errs, fmt.Errorf("Cannot share snapshot encrypted with default KMS key")) + } + } + } + } + + if len(c.OMIName) < 3 || len(c.OMIName) > 128 { + errs = append(errs, fmt.Errorf("ami_name must be between 3 and 128 characters long")) + } + + if c.OMIName != templateCleanOMIName(c.OMIName) { + errs = append(errs, fmt.Errorf("OMIName should only contain "+ + "alphanumeric characters, parentheses (()), square brackets ([]), spaces "+ + "( ), periods (.), slashes (/), dashes (-), single quotes ('), at-signs "+ + "(@), or underscores(_). You can use the `clean_ami_name` template "+ + "filter to automatically clean your ami name.")) + } + + if len(errs) > 0 { + return errs + } + + return nil +} + +func (c *OMIConfig) prepareRegions(accessConfig *AccessConfig) (errs []error) { + if len(c.OMIRegions) > 0 { + regionSet := make(map[string]struct{}) + regions := make([]string, 0, len(c.OMIRegions)) + + for _, region := range c.OMIRegions { + // If we already saw the region, then don't look again + if _, ok := regionSet[region]; ok { + continue + } + + // Mark that we saw the region + regionSet[region] = struct{}{} + + // Make sure that if we have region_kms_key_ids defined, + // the regions in ami_regions are also in region_kms_key_ids + if len(c.OMIRegionKMSKeyIDs) > 0 { + if _, ok := c.OMIRegionKMSKeyIDs[region]; !ok { + errs = append(errs, fmt.Errorf("Region %s is in ami_regions but not in region_kms_key_ids", region)) + } + } + if (accessConfig != nil) && (region == accessConfig.RawRegion) { + // make sure we don't try to copy to the region we originally + // create the OMI in. + log.Printf("Cannot copy OMI to AWS session region '%s', deleting it from `ami_regions`.", region) + continue + } + regions = append(regions, region) + } + + c.OMIRegions = regions + } + 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/osc/common/omi_config_test.go b/builder/osc/common/omi_config_test.go new file mode 100644 index 000000000..d52be2aae --- /dev/null +++ b/builder/osc/common/omi_config_test.go @@ -0,0 +1,230 @@ +package common + +import ( + "fmt" + "reflect" + "testing" +) + +func testOMIConfig() *OMIConfig { + return &OMIConfig{ + OMIName: "foo", + } +} + +func getFakeAccessConfig(region string) *AccessConfig { + c := testAccessConfig() + c.RawRegion = region + return c +} + +func TestOMIConfigPrepare_name(t *testing.T) { + c := testOMIConfig() + accessConf := testAccessConfig() + if err := c.Prepare(accessConf, nil); err != nil { + t.Fatalf("shouldn't have err: %s", err) + } + + c.OMIName = "" + if err := c.Prepare(accessConf, nil); err == nil { + t.Fatal("should have error") + } +} + +func TestOMIConfigPrepare_regions(t *testing.T) { + c := testOMIConfig() + c.OMIRegions = nil + + var errs []error + var err error + accessConf := testAccessConfig() + mockConn := &mockOAPIClient{} + if errs = c.prepareRegions(accessConf); len(errs) > 0 { + t.Fatalf("shouldn't have err: %#v", errs) + } + + c.OMIRegions, err = listOAPIRegions(mockConn) + if err != nil { + t.Fatalf("shouldn't have err: %s", err.Error()) + } + if errs = c.prepareRegions(accessConf); len(errs) > 0 { + t.Fatalf("shouldn't have err: %#v", errs) + } + errs = errs[:0] + + c.OMIRegions = []string{"us-east-1", "us-west-1", "us-east-1"} + if errs = c.prepareRegions(accessConf); len(errs) > 0 { + t.Fatalf("bad: %s", errs[0]) + } + + expected := []string{"us-east-1", "us-west-1"} + if !reflect.DeepEqual(c.OMIRegions, expected) { + t.Fatalf("bad: %#v", c.OMIRegions) + } + + c.OMIRegions = []string{"custom"} + if errs = c.prepareRegions(accessConf); len(errs) > 0 { + t.Fatal("shouldn't have error") + } + + c.OMIRegions = []string{"us-east-1", "us-east-2", "us-west-1"} + c.OMIRegionKMSKeyIDs = map[string]string{ + "us-east-1": "123-456-7890", + "us-west-1": "789-012-3456", + "us-east-2": "456-789-0123", + } + if errs = c.prepareRegions(accessConf); len(errs) > 0 { + t.Fatal(fmt.Sprintf("shouldn't have error: %s", errs[0])) + } + + c.OMIRegions = []string{"us-east-1", "us-east-2", "us-west-1"} + c.OMIRegionKMSKeyIDs = map[string]string{ + "us-east-1": "123-456-7890", + "us-west-1": "789-012-3456", + "us-east-2": "", + } + if errs = c.prepareRegions(accessConf); len(errs) > 0 { + t.Fatal("should have passed; we are able to use default KMS key if not sharing") + } + + c.SnapshotUsers = []string{"user-foo", "user-bar"} + c.OMIRegions = []string{"us-east-1", "us-east-2", "us-west-1"} + c.OMIRegionKMSKeyIDs = map[string]string{ + "us-east-1": "123-456-7890", + "us-west-1": "789-012-3456", + "us-east-2": "", + } + if errs = c.prepareRegions(accessConf); len(errs) > 0 { + t.Fatal("should have an error b/c can't use default KMS key if sharing") + } + + c.OMIRegions = []string{"us-east-1", "us-west-1"} + c.OMIRegionKMSKeyIDs = map[string]string{ + "us-east-1": "123-456-7890", + "us-west-1": "789-012-3456", + "us-east-2": "456-789-0123", + } + if errs = c.prepareRegions(accessConf); len(errs) > 0 { + t.Fatal("should have error b/c theres a region in the key map that isn't in omi_regions") + } + + c.OMIRegions = []string{"us-east-1", "us-west-1", "us-east-2"} + c.OMIRegionKMSKeyIDs = map[string]string{ + "us-east-1": "123-456-7890", + "us-west-1": "789-012-3456", + } + + if err := c.Prepare(accessConf, nil); err == nil { + t.Fatal("should have error b/c theres a region in in omi_regions that isn't in the key map") + } + + c.SnapshotUsers = []string{"foo", "bar"} + c.OMIKmsKeyId = "123-abc-456" + c.OMIEncryptBootVolume = true + c.OMIRegions = []string{"us-east-1", "us-west-1"} + c.OMIRegionKMSKeyIDs = map[string]string{ + "us-east-1": "123-456-7890", + "us-west-1": "", + } + if errs = c.prepareRegions(accessConf); len(errs) > 0 { + t.Fatal("should have error b/c theres a region in in omi_regions that isn't in the key map") + } + + // allow rawregion to exist in omi_regions list. + accessConf = getFakeAccessConfig("us-east-1") + c.OMIRegions = []string{"us-east-1", "us-west-1", "us-east-2"} + c.OMIRegionKMSKeyIDs = nil + if errs = c.prepareRegions(accessConf); len(errs) > 0 { + t.Fatal("should allow user to have the raw region in omi_regions") + } + +} + +func TestOMIConfigPrepare_Share_EncryptedBoot(t *testing.T) { + c := testOMIConfig() + c.OMIUsers = []string{"testAccountID"} + c.OMIEncryptBootVolume = true + + accessConf := testAccessConfig() + + c.OMIKmsKeyId = "" + if err := c.Prepare(accessConf, nil); err == nil { + t.Fatal("shouldn't be able to share omi with encrypted boot volume") + } + + c.OMIKmsKeyId = "89c3fb9a-de87-4f2a-aedc-fddc5138193c" + if err := c.Prepare(accessConf, nil); err == nil { + t.Fatal("shouldn't be able to share omi with encrypted boot volume") + } +} + +func TestOMIConfigPrepare_ValidateKmsKey(t *testing.T) { + c := testOMIConfig() + c.OMIEncryptBootVolume = 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.OMIKmsKeyId = 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.OMIKmsKeyId = invalidCase + if err := c.Prepare(accessConf, nil); err == nil { + t.Fatalf("%s should have failed KMS key validation", invalidCase) + } + } + +} + +func TestOMINameValidation(t *testing.T) { + c := testOMIConfig() + + accessConf := testAccessConfig() + + c.OMIName = "aa" + if err := c.Prepare(accessConf, nil); err == nil { + t.Fatal("shouldn't be able to have an omi name with less than 3 characters") + } + + var longOmiName string + for i := 0; i < 129; i++ { + longOmiName += "a" + } + c.OMIName = longOmiName + if err := c.Prepare(accessConf, nil); err == nil { + t.Fatal("shouldn't be able to have an omi name with great than 128 characters") + } + + c.OMIName = "+aaa" + if err := c.Prepare(accessConf, nil); err == nil { + t.Fatal("shouldn't be able to have an omi name with invalid characters") + } + + c.OMIName = "fooBAR1()[] ./-'@_" + if err := c.Prepare(accessConf, nil); err != nil { + t.Fatal("should be able to use all of the allowed OMI characters") + } + + c.OMIName = `xyz-base-2017-04-05-1934` + if err := c.Prepare(accessConf, nil); err != nil { + t.Fatalf("expected `xyz-base-2017-04-05-1934` to pass validation.") + } + +} diff --git a/builder/osc/common/template_funcs.go b/builder/osc/common/template_funcs.go new file mode 100644 index 000000000..1f63f661f --- /dev/null +++ b/builder/osc/common/template_funcs.go @@ -0,0 +1,30 @@ +package common + +import "bytes" + +func isalphanumeric(b byte) bool { + if '0' <= b && b <= '9' { + return true + } + if 'a' <= b && b <= 'z' { + return true + } + if 'A' <= b && b <= 'Z' { + return true + } + return false +} + +func templateCleanOMIName(s string) string { + allowed := []byte{'(', ')', '[', ']', ' ', '.', '/', '-', '\'', '@', '_'} + b := []byte(s) + newb := make([]byte, len(b)) + for i, c := range b { + if isalphanumeric(c) || bytes.IndexByte(allowed, c) != -1 { + newb[i] = c + } else { + newb[i] = '-' + } + } + return string(newb[:]) +} From 837aada4156d2a0ec539daa7f38a8e72ae2c48f8 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Tue, 29 Jan 2019 11:28:11 -0600 Subject: [PATCH 010/113] feature: add root block device config to bsusurrogate config struct --- builder/osc/bsusurrogate/builder.go | 5 +- builder/osc/bsusurrogate/root_block_device.go | 46 +++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 builder/osc/bsusurrogate/root_block_device.go diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index 3d86df9be..bea12dc15 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -20,7 +20,10 @@ type Config struct { osccommon.RunConfig `mapstructure:",squash"` osccommon.BlockDevices `mapstructure:",squash"` osccommon.OMIConfig `mapstructure:",squash"` - ctx interpolate.Context + + RootDevice RootBlockDevice `mapstructure:"ami_root_device"` + + ctx interpolate.Context } type Builder struct { diff --git a/builder/osc/bsusurrogate/root_block_device.go b/builder/osc/bsusurrogate/root_block_device.go new file mode 100644 index 000000000..78616f3d4 --- /dev/null +++ b/builder/osc/bsusurrogate/root_block_device.go @@ -0,0 +1,46 @@ +package bsusurrogate + +import ( + "errors" + + "github.com/hashicorp/packer/template/interpolate" +) + +type RootBlockDevice struct { + SourceDeviceName string `mapstructure:"source_device_name"` + DeviceName string `mapstructure:"device_name"` + DeleteOnVmDeletion bool `mapstructure:"delete_on_vm_deletion"` + IOPS int64 `mapstructure:"iops"` + VolumeType string `mapstructure:"volume_type"` + VolumeSize int64 `mapstructure:"volume_size"` +} + +func (c *RootBlockDevice) Prepare(ctx *interpolate.Context) []error { + var errs []error + + if c.SourceDeviceName == "" { + errs = append(errs, errors.New("source_device_name for the root_device must be specified")) + } + + if c.DeviceName == "" { + errs = append(errs, errors.New("device_name for the root_device must be specified")) + } + + if c.VolumeType == "gp2" && c.IOPS != 0 { + errs = append(errs, errors.New("iops may not be specified for a gp2 volume")) + } + + if c.IOPS < 0 { + errs = append(errs, errors.New("iops must be greater than 0")) + } + + if c.VolumeSize < 0 { + errs = append(errs, errors.New("volume_size must be greater than 0")) + } + + if len(errs) > 0 { + return errs + } + + return nil +} From 24d1d886f8e8d44ea1eb60fb9ef12e22665522c8 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Tue, 29 Jan 2019 12:18:02 -0600 Subject: [PATCH 011/113] feature: add root volume run tags config to bsusurrogate config struct --- builder/osc/bsusurrogate/builder.go | 3 +- builder/osc/common/interpolate_build_info.go | 35 +++++++++++ .../osc/common/interpolate_build_info_test.go | 62 +++++++++++++++++++ builder/osc/common/omi_config.go | 3 - builder/osc/common/tags.go | 45 ++++++++++++++ 5 files changed, 144 insertions(+), 4 deletions(-) create mode 100644 builder/osc/common/interpolate_build_info.go create mode 100644 builder/osc/common/interpolate_build_info_test.go create mode 100644 builder/osc/common/tags.go diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index bea12dc15..68f9cd0da 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -21,7 +21,8 @@ type Config struct { osccommon.BlockDevices `mapstructure:",squash"` osccommon.OMIConfig `mapstructure:",squash"` - RootDevice RootBlockDevice `mapstructure:"ami_root_device"` + RootDevice RootBlockDevice `mapstructure:"ami_root_device"` + VolumeRunTags osccommon.TagMap `mapstructure:"run_volume_tags"` ctx interpolate.Context } diff --git a/builder/osc/common/interpolate_build_info.go b/builder/osc/common/interpolate_build_info.go new file mode 100644 index 000000000..2515e9f33 --- /dev/null +++ b/builder/osc/common/interpolate_build_info.go @@ -0,0 +1,35 @@ +package common + +import ( + "github.com/hashicorp/packer/helper/multistep" + "github.com/outscale/osc-go/oapi" +) + +type BuildInfoTemplate struct { + BuildRegion string + SourceOMI string + SourceOMIName string + SourceOMITags map[string]string +} + +func extractBuildInfo(region string, state multistep.StateBag) *BuildInfoTemplate { + rawSourceOMI, hasSourceOMI := state.GetOk("source_image") + if !hasSourceOMI { + return &BuildInfoTemplate{ + BuildRegion: region, + } + } + + sourceOMI := rawSourceOMI.(*oapi.Image) + sourceOMITags := make(map[string]string, len(sourceOMI.Tags)) + for _, tag := range sourceOMI.Tags { + sourceOMITags[tag.Key] = tag.Value + } + + return &BuildInfoTemplate{ + BuildRegion: region, + SourceOMI: sourceOMI.ImageId, + SourceOMIName: sourceOMI.ImageName, + SourceOMITags: sourceOMITags, + } +} diff --git a/builder/osc/common/interpolate_build_info_test.go b/builder/osc/common/interpolate_build_info_test.go new file mode 100644 index 000000000..c15a4072b --- /dev/null +++ b/builder/osc/common/interpolate_build_info_test.go @@ -0,0 +1,62 @@ +package common + +import ( + "reflect" + "testing" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/outscale/osc-go/oapi" +) + +func testImage() *oapi.Image { + return &oapi.Image{ + ImageId: "ami-abcd1234", + ImageName: "ami_test_name", + Tags: []oapi.ResourceTag{ + { + Key: "key-1", + Value: "value-1", + }, + { + Key: "key-2", + Value: "value-2", + }, + }, + } +} + +func testState() multistep.StateBag { + state := new(multistep.BasicStateBag) + return state +} + +func TestInterpolateBuildInfo_extractBuildInfo_noSourceImage(t *testing.T) { + state := testState() + buildInfo := extractBuildInfo("foo", state) + + expected := BuildInfoTemplate{ + BuildRegion: "foo", + } + if !reflect.DeepEqual(*buildInfo, expected) { + t.Fatalf("Unexpected BuildInfoTemplate: expected %#v got %#v\n", expected, *buildInfo) + } +} + +func TestInterpolateBuildInfo_extractBuildInfo_withSourceImage(t *testing.T) { + state := testState() + state.Put("source_image", testImage()) + buildInfo := extractBuildInfo("foo", state) + + expected := BuildInfoTemplate{ + BuildRegion: "foo", + SourceOMI: "ami-abcd1234", + SourceOMIName: "ami_test_name", + SourceOMITags: map[string]string{ + "key-1": "value-1", + "key-2": "value-2", + }, + } + if !reflect.DeepEqual(*buildInfo, expected) { + t.Fatalf("Unexpected BuildInfoTemplate: expected %#v got %#v\n", expected, *buildInfo) + } +} diff --git a/builder/osc/common/omi_config.go b/builder/osc/common/omi_config.go index 11055c628..fbd1bc889 100644 --- a/builder/osc/common/omi_config.go +++ b/builder/osc/common/omi_config.go @@ -8,9 +8,6 @@ import ( "github.com/hashicorp/packer/template/interpolate" ) -//Temporal -type TagMap map[string]string - // OMIConfig is for common configuration related to creating OMIs. type OMIConfig struct { OMIName string `mapstructure:"ami_name"` diff --git a/builder/osc/common/tags.go b/builder/osc/common/tags.go new file mode 100644 index 000000000..ff58c0d67 --- /dev/null +++ b/builder/osc/common/tags.go @@ -0,0 +1,45 @@ +package common + +import ( + "fmt" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/hashicorp/packer/template/interpolate" + "github.com/outscale/osc-go/oapi" +) + +type TagMap map[string]string +type OAPI []*oapi.ResourceTag + +func (t OAPI) Report(ui packer.Ui) { + for _, tag := range t { + ui.Message(fmt.Sprintf("Adding tag: \"%s\": \"%s\"", + tag.Key, tag.Value)) + } +} + +func (t TagMap) IsSet() bool { + return len(t) > 0 +} + +func (t TagMap) OAPI(ctx interpolate.Context, region string, state multistep.StateBag) (OAPI, error) { + var oapiTags []*oapi.ResourceTag + ctx.Data = extractBuildInfo(region, state) + + for key, value := range t { + interpolatedKey, err := interpolate.Render(key, &ctx) + if err != nil { + return nil, fmt.Errorf("Error processing tag: %s:%s - %s", key, value, err) + } + interpolatedValue, err := interpolate.Render(value, &ctx) + if err != nil { + return nil, fmt.Errorf("Error processing tag: %s:%s - %s", key, value, err) + } + oapiTags = append(oapiTags, &oapi.ResourceTag{ + Key: interpolatedKey, + Value: interpolatedValue, + }) + } + return oapiTags, nil +} From ca8ab3b5b0b616252b96c778cc222775d672700f Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Tue, 29 Jan 2019 12:24:26 -0600 Subject: [PATCH 012/113] feature: implement Prepare function in bsusurrogate builder --- builder/osc/bsusurrogate/builder.go | 68 +++++++++++++++++++++++++++- builder/osc/common/template_funcs.go | 9 +++- 2 files changed, 74 insertions(+), 3 deletions(-) diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index 68f9cd0da..886d728aa 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -1,12 +1,15 @@ // The bsusurrogate package contains a packer.Builder implementation that -// builds a new EBS-backed AMI using an ephemeral instance. +// builds a new EBS-backed OMI using an ephemeral instance. package bsusurrogate import ( + "errors" + "fmt" "log" osccommon "github.com/hashicorp/packer/builder/osc/common" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" @@ -33,8 +36,69 @@ type Builder struct { } func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { - log.Println("Preparing Outscale Builder...") + b.config.ctx.Funcs = osccommon.TemplateFuncs + + err := config.Decode(&b.config, &config.DecodeOpts{ + Interpolate: true, + InterpolateContext: &b.config.ctx, + InterpolateFilter: &interpolate.RenderFilter{ + Exclude: []string{ + "omi_description", + "run_tags", + "run_volume_tags", + "snapshot_tags", + "spot_tags", + "tags", + }, + }, + }, raws...) + if err != nil { + return nil, err + } + + if b.config.PackerConfig.PackerForce { + b.config.OMIForceDeregister = true + } + + // Accumulate any errors + var errs *packer.MultiError + errs = packer.MultiErrorAppend(errs, b.config.AccessConfig.Prepare(&b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare(&b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, + b.config.OMIConfig.Prepare(&b.config.AccessConfig, &b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, b.config.BlockDevices.Prepare(&b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, b.config.RootDevice.Prepare(&b.config.ctx)...) + + if b.config.OMIVirtType == "" { + errs = packer.MultiErrorAppend(errs, errors.New("ami_virtualization_type is required.")) + } + + foundRootVolume := false + for _, launchDevice := range b.config.BlockDevices.LaunchMappings { + if launchDevice.DeviceName == b.config.RootDevice.SourceDeviceName { + foundRootVolume = true + } + } + + if !foundRootVolume { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("no volume with name '%s' is found", b.config.RootDevice.SourceDeviceName)) + } + + //TODO: Chek if this is necessary + if b.config.IsSpotVm() && ((b.config.OMIENASupport != nil && *b.config.OMIENASupport) || b.config.OMISriovNetSupport) { + errs = packer.MultiErrorAppend(errs, + fmt.Errorf("Spot instances do not support modification, which is required "+ + "when either `ena_support` or `sriov_support` are set. Please ensure "+ + "you use an OMI that already has either SR-IOV or ENA enabled.")) + } + + if errs != nil && len(errs.Errors) > 0 { + return nil, errs + } + + packer.LogSecretFilter.Set(b.config.AccessKey, b.config.SecretKey, b.config.Token) return nil, nil + } func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { diff --git a/builder/osc/common/template_funcs.go b/builder/osc/common/template_funcs.go index 1f63f661f..1b574f75b 100644 --- a/builder/osc/common/template_funcs.go +++ b/builder/osc/common/template_funcs.go @@ -1,6 +1,9 @@ package common -import "bytes" +import ( + "bytes" + "html/template" +) func isalphanumeric(b byte) bool { if '0' <= b && b <= '9' { @@ -28,3 +31,7 @@ func templateCleanOMIName(s string) string { } return string(newb[:]) } + +var TemplateFuncs = template.FuncMap{ + "clean_omi_name": templateCleanOMIName, +} From de973fba0e6105989c8bd3a34bf25faca3c3f8f3 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Tue, 29 Jan 2019 15:07:32 -0600 Subject: [PATCH 013/113] chore: add Bsusurrogate Run function skeleton --- builder/osc/bsusurrogate/builder.go | 30 ++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index 886d728aa..1aeec4e11 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -3,9 +3,11 @@ package bsusurrogate import ( + "crypto/tls" "errors" "fmt" "log" + "net/http" osccommon "github.com/hashicorp/packer/builder/osc/common" "github.com/hashicorp/packer/common" @@ -13,6 +15,7 @@ import ( "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" + "github.com/outscale/osc-go/oapi" ) const BuilderId = "digitalonus.osc.bsusurrogate" @@ -102,7 +105,32 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { } func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { - log.Println("Running Outscale Builder...") + clientConfig, err := b.config.Config() + if err != nil { + return nil, err + } + + skipClient := &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }, + } + + oapiconn := oapi.NewClient(clientConfig, skipClient) + + // Setup the state bag and initial state for the steps + state := new(multistep.BasicStateBag) + state.Put("config", &b.config) + state.Put("oapi", oapiconn) + state.Put("clientConfig", clientConfig) + state.Put("hook", hook) + state.Put("ui", ui) + + steps := []multistep.Step{} + + b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) + b.runner.Run(state) + return nil, nil } From 1281f28f6d4dcf8ea33dad68e5f02e299f934a14 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Wed, 30 Jan 2019 12:48:51 -0600 Subject: [PATCH 014/113] add prevalidate step --- builder/osc/bsusurrogate/builder.go | 34 +++++++++++-- builder/osc/bsusurrogate/builder_acc_test.go | 52 ++++++++++++++++++++ builder/osc/common/access_config.go | 19 +++++++ builder/osc/common/omi_config.go | 32 ++++++------ builder/osc/common/step_pre_validate.go | 51 +++++++++++++++++++ command/plugin.go | 2 + 6 files changed, 171 insertions(+), 19 deletions(-) create mode 100644 builder/osc/bsusurrogate/builder_acc_test.go create mode 100644 builder/osc/common/step_pre_validate.go diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index 1aeec4e11..d4f52ac40 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -27,7 +27,7 @@ type Config struct { osccommon.BlockDevices `mapstructure:",squash"` osccommon.OMIConfig `mapstructure:",squash"` - RootDevice RootBlockDevice `mapstructure:"ami_root_device"` + RootDevice RootBlockDevice `mapstructure:"omi_root_device"` VolumeRunTags osccommon.TagMap `mapstructure:"run_volume_tags"` ctx interpolate.Context @@ -39,6 +39,7 @@ type Builder struct { } func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { + b.config.ctx.Funcs = osccommon.TemplateFuncs err := config.Decode(&b.config, &config.DecodeOpts{ @@ -73,7 +74,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { errs = packer.MultiErrorAppend(errs, b.config.RootDevice.Prepare(&b.config.ctx)...) if b.config.OMIVirtType == "" { - errs = packer.MultiErrorAppend(errs, errors.New("ami_virtualization_type is required.")) + errs = packer.MultiErrorAppend(errs, errors.New("omi_virtualization_type is required.")) } foundRootVolume := false @@ -126,11 +127,38 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe state.Put("hook", hook) state.Put("ui", ui) - steps := []multistep.Step{} + //VMStep + + //omiDevices := b.config.BuildOMIDevices() + //launchDevices := b.config.BuildLaunchDevices() + + steps := []multistep.Step{ + &osccommon.StepPreValidate{ + DestOmiName: b.config.OMIName, + ForceDeregister: b.config.OMIForceDeregister, + }, + } b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) b.runner.Run(state) + // If there was an error, return that + if rawErr, ok := state.GetOk("error"); ok { + return nil, rawErr.(error) + } + + //Build the artifact + // if omis, ok := state.GetOk("omis"); ok { + // // Build the artifact and return it + // artifact := &awscommon.Artifact{ + // Amis: omis.(map[string]string), + // BuilderIdValue: BuilderId, + // Session: session, + // } + + // return artifact, nil + // } + return nil, nil } diff --git a/builder/osc/bsusurrogate/builder_acc_test.go b/builder/osc/bsusurrogate/builder_acc_test.go new file mode 100644 index 000000000..5fccd79ef --- /dev/null +++ b/builder/osc/bsusurrogate/builder_acc_test.go @@ -0,0 +1,52 @@ +/* +Deregister the test image with +aws ec2 deregister-image --image-id $(aws ec2 describe-images --output text --filters "Name=name,Values=packer-test-packer-test-dereg" --query 'Images[*].{ID:ImageId}') +*/ +package bsusurrogate + +import ( + "testing" + + builderT "github.com/hashicorp/packer/helper/builder/testing" +) + +func TestBuilderAcc_basic(t *testing.T) { + builderT.Test(t, builderT.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Builder: &Builder{}, + Template: testBuilderAccBasic, + }) +} + +func testAccPreCheck(t *testing.T) { +} + +const testBuilderAccBasic = ` +{ + "builders": [{ + "type": "test", + "region": "eu-west-2", + "vm_type": "m3.medium", + "source_omi": "ami-76b2a71e", + "ssh_username": "ubuntu", + "omi_name": "packer-test {{timestamp}}", + "omi_virtualization_type": "hvm", + "launch_block_device_mappings" : [ + { + "volume_type" : "gp2", + "device_name" : "/dev/sda1", + "delete_on_vm_deletion" : false, + "volume_size" : 10 + } + ], + "omi_root_device":{ + "source_device_name": "/dev/sda1", + "device_name": "/dev/sda2", + "delete_on_vm_deletion": true, + "volume_size": 16, + "volume_type": "gp2" + } + + }] +} +` diff --git a/builder/osc/common/access_config.go b/builder/osc/common/access_config.go index 3b76ea7bb..485811beb 100644 --- a/builder/osc/common/access_config.go +++ b/builder/osc/common/access_config.go @@ -5,6 +5,7 @@ import ( "fmt" "log" "net/http" + "os" "github.com/hashicorp/packer/template/interpolate" "github.com/outscale/osc-go/oapi" @@ -35,6 +36,24 @@ func (c *AccessConfig) Config() (*oapi.Config, error) { return c.clientConfig, nil } + //Check env variables if access configuration is not set. + + if c.AccessKey == "" { + c.AccessKey = os.Getenv("OUTSCALE_ACCESSKEYID") + } + + if c.SecretKey == "" { + c.SecretKey = os.Getenv("OUTSCALE_SECRETKEYID") + } + + if c.RawRegion == "" { + c.RawRegion = os.Getenv("OUTSCALE_REGION") + } + + if c.CustomEndpoint == "" { + c.CustomEndpoint = os.Getenv("OUTSCALE_OAPI_URL") + } + config := &oapi.Config{ AccessKey: c.AccessKey, SecretKey: c.SecretKey, diff --git a/builder/osc/common/omi_config.go b/builder/osc/common/omi_config.go index fbd1bc889..6b79afafc 100644 --- a/builder/osc/common/omi_config.go +++ b/builder/osc/common/omi_config.go @@ -10,13 +10,13 @@ import ( // OMIConfig is for common configuration related to creating OMIs. type OMIConfig struct { - OMIName string `mapstructure:"ami_name"` - OMIDescription string `mapstructure:"ami_description"` - OMIVirtType string `mapstructure:"ami_virtualization_type"` - OMIUsers []string `mapstructure:"ami_users"` - OMIGroups []string `mapstructure:"ami_groups"` - OMIProductCodes []string `mapstructure:"ami_product_codes"` - OMIRegions []string `mapstructure:"ami_regions"` + OMIName string `mapstructure:"omi_name"` + OMIDescription string `mapstructure:"omi_description"` + OMIVirtType string `mapstructure:"omi_virtualization_type"` + OMIUsers []string `mapstructure:"omi_users"` + OMIGroups []string `mapstructure:"omi_groups"` + OMIProductCodes []string `mapstructure:"omi_product_codes"` + OMIRegions []string `mapstructure:"omi_regions"` OMISkipRegionValidation bool `mapstructure:"skip_region_validation"` OMITags TagMap `mapstructure:"tags"` OMIENASupport *bool `mapstructure:"ena_support"` @@ -44,15 +44,15 @@ func (c *OMIConfig) Prepare(accessConfig *AccessConfig, ctx *interpolate.Context var errs []error if c.OMIName == "" { - errs = append(errs, fmt.Errorf("ami_name must be specified")) + errs = append(errs, fmt.Errorf("omi_name must be specified")) } // Make sure that if we have region_kms_key_ids defined, - // the regions in region_kms_key_ids are also in ami_regions + // the regions in region_kms_key_ids are also in omi_regions if len(c.OMIRegionKMSKeyIDs) > 0 { for kmsKeyRegion := range c.OMIRegionKMSKeyIDs { if !stringInSlice(c.OMIRegions, kmsKeyRegion) { - errs = append(errs, fmt.Errorf("Region %s is in region_kms_key_ids but not in ami_regions", kmsKeyRegion)) + errs = append(errs, fmt.Errorf("Region %s is in region_kms_key_ids but not in omi_regions", kmsKeyRegion)) } } } @@ -94,15 +94,15 @@ func (c *OMIConfig) Prepare(accessConfig *AccessConfig, ctx *interpolate.Context } if len(c.OMIName) < 3 || len(c.OMIName) > 128 { - errs = append(errs, fmt.Errorf("ami_name must be between 3 and 128 characters long")) + errs = append(errs, fmt.Errorf("omi_name must be between 3 and 128 characters long")) } if c.OMIName != templateCleanOMIName(c.OMIName) { errs = append(errs, fmt.Errorf("OMIName should only contain "+ "alphanumeric characters, parentheses (()), square brackets ([]), spaces "+ "( ), periods (.), slashes (/), dashes (-), single quotes ('), at-signs "+ - "(@), or underscores(_). You can use the `clean_ami_name` template "+ - "filter to automatically clean your ami name.")) + "(@), or underscores(_). You can use the `clean_omi_name` template "+ + "filter to automatically clean your omi name.")) } if len(errs) > 0 { @@ -127,16 +127,16 @@ func (c *OMIConfig) prepareRegions(accessConfig *AccessConfig) (errs []error) { regionSet[region] = struct{}{} // Make sure that if we have region_kms_key_ids defined, - // the regions in ami_regions are also in region_kms_key_ids + // the regions in omi_regions are also in region_kms_key_ids if len(c.OMIRegionKMSKeyIDs) > 0 { if _, ok := c.OMIRegionKMSKeyIDs[region]; !ok { - errs = append(errs, fmt.Errorf("Region %s is in ami_regions but not in region_kms_key_ids", region)) + errs = append(errs, fmt.Errorf("Region %s is in omi_regions but not in region_kms_key_ids", region)) } } if (accessConfig != nil) && (region == accessConfig.RawRegion) { // make sure we don't try to copy to the region we originally // create the OMI in. - log.Printf("Cannot copy OMI to AWS session region '%s', deleting it from `ami_regions`.", region) + log.Printf("Cannot copy OMI to AWS session region '%s', deleting it from `omi_regions`.", region) continue } regions = append(regions, region) diff --git a/builder/osc/common/step_pre_validate.go b/builder/osc/common/step_pre_validate.go new file mode 100644 index 000000000..2d74d9e7c --- /dev/null +++ b/builder/osc/common/step_pre_validate.go @@ -0,0 +1,51 @@ +package common + +import ( + "context" + "fmt" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/outscale/osc-go/oapi" +) + +// StepPreValidate provides an opportunity to pre-validate any configuration for +// the build before actually doing any time consuming work +// +type StepPreValidate struct { + DestOmiName string + ForceDeregister bool +} + +func (s *StepPreValidate) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + ui := state.Get("ui").(packer.Ui) + if s.ForceDeregister { + ui.Say("Force Deregister flag found, skipping prevalidating OMI Name") + return multistep.ActionContinue + } + + oapiconn := state.Get("oapi").(*oapi.Client) + + ui.Say(fmt.Sprintf("Prevalidating OMI Name: %s", s.DestOmiName)) + resp, err := oapiconn.POST_ReadImages(oapi.ReadImagesRequest{ + Filters: oapi.FiltersImage{ImageNames: []string{s.DestOmiName}}, + }) + + if err != nil { + err := fmt.Errorf("Error querying OMI: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + if len(resp.OK.Images) > 0 { + err := fmt.Errorf("Error: name conflicts with an existing OMI: %s", resp.OK.Images[0].ImageId) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + return multistep.ActionContinue +} + +func (s *StepPreValidate) Cleanup(multistep.StateBag) {} diff --git a/command/plugin.go b/command/plugin.go index f07f5f861..627c45375 100644 --- a/command/plugin.go +++ b/command/plugin.go @@ -38,6 +38,7 @@ import ( openstackbuilder "github.com/hashicorp/packer/builder/openstack" oracleclassicbuilder "github.com/hashicorp/packer/builder/oracle/classic" oracleocibuilder "github.com/hashicorp/packer/builder/oracle/oci" + oscbsusurrogatebuilder "github.com/hashicorp/packer/builder/osc/bsusurrogate" parallelsisobuilder "github.com/hashicorp/packer/builder/parallels/iso" parallelspvmbuilder "github.com/hashicorp/packer/builder/parallels/pvm" profitbricksbuilder "github.com/hashicorp/packer/builder/profitbricks" @@ -121,6 +122,7 @@ var Builders = map[string]packer.Builder{ "openstack": new(openstackbuilder.Builder), "oracle-classic": new(oracleclassicbuilder.Builder), "oracle-oci": new(oracleocibuilder.Builder), + "osc-bsusurrogate": new(oscbsusurrogatebuilder.Builder), "parallels-iso": new(parallelsisobuilder.Builder), "parallels-pvm": new(parallelspvmbuilder.Builder), "profitbricks": new(profitbricksbuilder.Builder), From 3d8b0e5228445b5e63db794620a66e1c1ce5d6f0 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Wed, 30 Jan 2019 13:04:06 -0600 Subject: [PATCH 015/113] fix: change logs in omi config --- builder/osc/common/omi_config.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/builder/osc/common/omi_config.go b/builder/osc/common/omi_config.go index 6b79afafc..eb09c7425 100644 --- a/builder/osc/common/omi_config.go +++ b/builder/osc/common/omi_config.go @@ -136,7 +136,7 @@ func (c *OMIConfig) prepareRegions(accessConfig *AccessConfig) (errs []error) { if (accessConfig != nil) && (region == accessConfig.RawRegion) { // make sure we don't try to copy to the region we originally // create the OMI in. - log.Printf("Cannot copy OMI to AWS session region '%s', deleting it from `omi_regions`.", region) + log.Printf("Cannot copy OMI to OUTSCALE session region '%s', deleting it from `omi_regions`.", region) continue } regions = append(regions, region) @@ -147,7 +147,6 @@ func (c *OMIConfig) 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:/_-]+$` From 33d1671e4cbcff8a4277686dbe450c43a8cc427a Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Wed, 30 Jan 2019 18:33:56 -0600 Subject: [PATCH 016/113] feature: bsusurrogate, add Source OMI Info step --- builder/osc/bsusurrogate/builder.go | 7 ++ builder/osc/common/build_filters.go | 39 ++++++++ builder/osc/common/run_config.go | 4 +- builder/osc/common/run_config_test.go | 4 +- builder/osc/common/step_source_omi_info.go | 102 +++++++++++++++++++++ 5 files changed, 152 insertions(+), 4 deletions(-) create mode 100644 builder/osc/common/build_filters.go create mode 100644 builder/osc/common/step_source_omi_info.go diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index d4f52ac40..21e43b6db 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -137,6 +137,13 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe DestOmiName: b.config.OMIName, ForceDeregister: b.config.OMIForceDeregister, }, + &osccommon.StepSourceOMIInfo{ + SourceOmi: b.config.SourceOmi, + EnableOMISriovNetSupport: b.config.OMISriovNetSupport, + EnableOMIENASupport: b.config.OMIENASupport, + OmiFilters: b.config.SourceOmiFilter, + OMIVirtType: b.config.OMIVirtType, //TODO: Remove if it is not used + }, } b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) diff --git a/builder/osc/common/build_filters.go b/builder/osc/common/build_filters.go new file mode 100644 index 000000000..67e7ecc1e --- /dev/null +++ b/builder/osc/common/build_filters.go @@ -0,0 +1,39 @@ +package common + +import ( + "log" + + "github.com/outscale/osc-go/oapi" +) + +func buildOMIFilters(input map[string]string) oapi.FiltersImage { + var filters oapi.FiltersImage + for k, v := range input { + filterValue := []string{v} + + switch name := k; name { + case "account_aliases": + filters.AccountAliases = filterValue + case "account_ids": + filters.AccountIds = filterValue + case "architectures": + filters.Architectures = filterValue + case "image_ids": + filters.ImageIds = filterValue + case "image_names": + filters.ImageNames = filterValue + case "image_types": + filters.ImageTypes = filterValue + case "virtualization_types": + filters.VirtualizationTypes = filterValue + case "root_device_types": + filters.RootDeviceTypes = filterValue + case "block_device_mapping_volume_type": + filters.BlockDeviceMappingVolumeType = filterValue + //Some params are missing. + default: + log.Printf("[Debug] Unknown Filter Name: %s.", name) + } + } + return filters +} diff --git a/builder/osc/common/run_config.go b/builder/osc/common/run_config.go index 44b64b01e..4ac088572 100644 --- a/builder/osc/common/run_config.go +++ b/builder/osc/common/run_config.go @@ -16,8 +16,8 @@ import ( var reShutdownBehavior = regexp.MustCompile("^(stop|terminate)$") type OmiFilterOptions struct { - Filters map[*string]*string - Owners []*string + Filters map[string]string + Owners []string MostRecent bool `mapstructure:"most_recent"` } diff --git a/builder/osc/common/run_config_test.go b/builder/osc/common/run_config_test.go index 5bdc977b7..b6416d522 100644 --- a/builder/osc/common/run_config_test.go +++ b/builder/osc/common/run_config_test.go @@ -71,7 +71,7 @@ func TestRunConfigPrepare_SourceOmiFilterOwnersBlank(t *testing.T) { c := testConfigFilter() filter_key := "name" filter_value := "foo" - c.SourceOmiFilter = OmiFilterOptions{Filters: map[*string]*string{&filter_key: &filter_value}} + c.SourceOmiFilter = OmiFilterOptions{Filters: map[string]string{filter_key: filter_value}} if err := c.Prepare(nil); len(err) != 1 { t.Fatalf("Should error if Owners is not specified)") } @@ -82,7 +82,7 @@ func TestRunConfigPrepare_SourceOmiFilterGood(t *testing.T) { owner := "123" filter_key := "name" filter_value := "foo" - goodFilter := OmiFilterOptions{Owners: []*string{&owner}, Filters: map[*string]*string{&filter_key: &filter_value}} + goodFilter := OmiFilterOptions{Owners: []string{owner}, Filters: map[string]string{filter_key: filter_value}} c.SourceOmiFilter = goodFilter if err := c.Prepare(nil); len(err) != 0 { t.Fatalf("err: %s", err) diff --git a/builder/osc/common/step_source_omi_info.go b/builder/osc/common/step_source_omi_info.go new file mode 100644 index 000000000..05c9e7d41 --- /dev/null +++ b/builder/osc/common/step_source_omi_info.go @@ -0,0 +1,102 @@ +package common + +import ( + "context" + "fmt" + "log" + "sort" + "time" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/outscale/osc-go/oapi" +) + +// StepSourceOMIInfo extracts critical information from the source OMI +// that is used throughout the OMI creation process. +// +// Produces: +// source_image *oapi.Image - the source OMI info +type StepSourceOMIInfo struct { + SourceOmi string + EnableOMISriovNetSupport bool + EnableOMIENASupport *bool + OMIVirtType string + OmiFilters OmiFilterOptions +} + +type imageSort []oapi.Image + +func (a imageSort) Len() int { return len(a) } +func (a imageSort) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a imageSort) Less(i, j int) bool { + itime, _ := time.Parse(time.RFC3339, a[i].CreationDate) + jtime, _ := time.Parse(time.RFC3339, a[j].CreationDate) + return itime.Unix() < jtime.Unix() +} + +// Returns the most recent OMI out of a slice of images. +func mostRecentOmi(images []oapi.Image) oapi.Image { + sortedImages := images + sort.Sort(imageSort(sortedImages)) + return sortedImages[len(sortedImages)-1] +} + +func (s *StepSourceOMIInfo) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + oapiconn := state.Get("oapi").(*oapi.Client) + ui := state.Get("ui").(packer.Ui) + + params := oapi.ReadImagesRequest{ + Filters: oapi.FiltersImage{}, + } + + if s.SourceOmi != "" { + params.Filters.ImageIds = []string{s.SourceOmi} + } + + // We have filters to apply + if len(s.OmiFilters.Filters) > 0 { + params.Filters = buildOMIFilters(s.OmiFilters.Filters) + } + //TODO:Check if AccountIds correspond to Owners. + if len(s.OmiFilters.Owners) > 0 { + params.Filters.AccountIds = s.OmiFilters.Owners + } + + log.Printf("Using OMI Filters %v", params) + imageResp, err := oapiconn.POST_ReadImages(params) + if err != nil { + err := fmt.Errorf("Error querying OMI: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + if len(imageResp.OK.Images) == 0 { + err := fmt.Errorf("No OMI was found matching filters: %v", params) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + if len(imageResp.OK.Images) > 1 && !s.OmiFilters.MostRecent { + err := fmt.Errorf("Your query returned more than one result. Please try a more specific search, or set most_recent to true.") + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + var image oapi.Image + if s.OmiFilters.MostRecent { + image = mostRecentOmi(imageResp.OK.Images) + } else { + image = imageResp.OK.Images[0] + } + + ui.Message(fmt.Sprintf("Found Image ID: %s", image.ImageId)) + + state.Put("source_image", image) + return multistep.ActionContinue +} + +func (s *StepSourceOMIInfo) Cleanup(multistep.StateBag) {} From fdd3b594b9f09cf593c78d2b75a2c423b8237a57 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Thu, 31 Jan 2019 10:17:39 -0600 Subject: [PATCH 017/113] fix: add function to validate if image name exists --- builder/osc/bsusurrogate/builder_acc_test.go | 2 +- builder/osc/common/step_pre_validate.go | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/builder/osc/bsusurrogate/builder_acc_test.go b/builder/osc/bsusurrogate/builder_acc_test.go index 5fccd79ef..00afeb182 100644 --- a/builder/osc/bsusurrogate/builder_acc_test.go +++ b/builder/osc/bsusurrogate/builder_acc_test.go @@ -27,7 +27,7 @@ const testBuilderAccBasic = ` "type": "test", "region": "eu-west-2", "vm_type": "m3.medium", - "source_omi": "ami-76b2a71e", + "source_omi": "ami-46260446", "ssh_username": "ubuntu", "omi_name": "packer-test {{timestamp}}", "omi_virtualization_type": "hvm", diff --git a/builder/osc/common/step_pre_validate.go b/builder/osc/common/step_pre_validate.go index 2d74d9e7c..1b31232aa 100644 --- a/builder/osc/common/step_pre_validate.go +++ b/builder/osc/common/step_pre_validate.go @@ -38,7 +38,17 @@ func (s *StepPreValidate) Run(_ context.Context, state multistep.StateBag) multi return multistep.ActionHalt } - if len(resp.OK.Images) > 0 { + //FIXME: Remove when the oAPI filters works + images := make([]oapi.Image, 0) + + for _, omi := range resp.OK.Images { + if omi.ImageName == s.DestOmiName { + images = append(images, omi) + } + } + + //if len(resp.OK.Images) > 0 { + if len(images) > 0 { err := fmt.Errorf("Error: name conflicts with an existing OMI: %s", resp.OK.Images[0].ImageId) state.Put("error", err) ui.Error(err.Error()) From e4405a0c02a9fc36e5be9088848f26d2ab1533b1 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Thu, 31 Jan 2019 14:48:46 -0600 Subject: [PATCH 018/113] feature: bsusurrogate, add Source network Info step --- builder/osc/bsusurrogate/builder.go | 9 ++ builder/osc/common/build_filters.go | 53 ++++++++ builder/osc/common/run_config.go | 4 +- builder/osc/common/step_network_info.go | 158 ++++++++++++++++++++++++ 4 files changed, 222 insertions(+), 2 deletions(-) create mode 100644 builder/osc/common/step_network_info.go diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index 21e43b6db..2329b9e02 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -144,6 +144,15 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe OmiFilters: b.config.SourceOmiFilter, OMIVirtType: b.config.OMIVirtType, //TODO: Remove if it is not used }, + &osccommon.StepNetworkInfo{ + NetId: b.config.NetId, + NetFilter: b.config.NetFilter, + SecurityGroupIds: b.config.SecurityGroupIds, + SecurityGroupFilter: b.config.SecurityGroupFilter, + SubnetId: b.config.SubnetId, + SubnetFilter: b.config.SubnetFilter, + SubregionName: b.config.Subregion, + }, } b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) diff --git a/builder/osc/common/build_filters.go b/builder/osc/common/build_filters.go index 67e7ecc1e..5ff387dfd 100644 --- a/builder/osc/common/build_filters.go +++ b/builder/osc/common/build_filters.go @@ -2,10 +2,63 @@ package common import ( "log" + "strconv" "github.com/outscale/osc-go/oapi" ) +func buildNetFilters(input map[string]string) oapi.FiltersNet { + var filters oapi.FiltersNet + for k, v := range input { + filterValue := []string{v} + switch name := k; name { + case "ip_range": + filters.IpRanges = filterValue + case "dhcp_options_set_id": + filters.DhcpOptionsSetIds = filterValue + case "is_default": + if isDefault, err := strconv.ParseBool(v); err == nil { + filters.IsDefault = isDefault + } + case "state": + filters.States = filterValue + case "tag_key": + filters.TagKeys = filterValue + case "tag_value": + filters.TagValues = filterValue + default: + log.Printf("[Debug] Unknown Filter Name: %s.", name) + } + } + return filters +} + +func buildSubnetFilters(input map[string]string) oapi.FiltersSubnet { + var filters oapi.FiltersSubnet + for k, v := range input { + filterValue := []string{v} + switch name := k; name { + case "available_ips_counts": + if ipCount, err := strconv.Atoi(v); err == nil { + filters.AvailableIpsCounts = []int64{int64(ipCount)} + } + case "ip_ranges": + filters.IpRanges = filterValue + case "net_ids": + filters.NetIds = filterValue + case "states": + filters.States = filterValue + case "subnet_ids": + filters.SubnetIds = filterValue + case "sub_region_names": + filters.SubregionNames = filterValue + default: + log.Printf("[Debug] Unknown Filter Name: %s.", name) + } + } + return filters +} + func buildOMIFilters(input map[string]string) oapi.FiltersImage { var filters oapi.FiltersImage for k, v := range input { diff --git a/builder/osc/common/run_config.go b/builder/osc/common/run_config.go index 4ac088572..cca3cf2b9 100644 --- a/builder/osc/common/run_config.go +++ b/builder/osc/common/run_config.go @@ -30,7 +30,7 @@ func (d *OmiFilterOptions) NoOwner() bool { } type SubnetFilterOptions struct { - Filters map[*string]*string + Filters map[string]string MostFree bool `mapstructure:"most_free"` Random bool `mapstructure:"random"` } @@ -40,7 +40,7 @@ func (d *SubnetFilterOptions) Empty() bool { } type NetFilterOptions struct { - Filters map[*string]*string + Filters map[string]string } func (d *NetFilterOptions) Empty() bool { diff --git a/builder/osc/common/step_network_info.go b/builder/osc/common/step_network_info.go new file mode 100644 index 000000000..e7fd68b70 --- /dev/null +++ b/builder/osc/common/step_network_info.go @@ -0,0 +1,158 @@ +package common + +import ( + "context" + "fmt" + "log" + "math/rand" + "sort" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/outscale/osc-go/oapi" +) + +// StepNetworkInfo queries OUTSCALE for information about +// NET's and Subnets that is used throughout the OMI creation process. +// +// Produces (adding them to the state bag): +// vpc_id string - the NET ID +// subnet_id string - the Subnet ID +// availability_zone string - the Subregion name +type StepNetworkInfo struct { + NetId string + NetFilter NetFilterOptions + SubnetId string + SubnetFilter SubnetFilterOptions + SubregionName string + SecurityGroupIds []string + SecurityGroupFilter SecurityGroupFilterOptions +} + +type subnetsSort []oapi.Subnet + +func (a subnetsSort) Len() int { return len(a) } +func (a subnetsSort) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a subnetsSort) Less(i, j int) bool { + return a[i].AvailableIpsCount < a[j].AvailableIpsCount +} + +// Returns the most recent OMI out of a slice of images. +func mostFreeSubnet(subnets []oapi.Subnet) oapi.Subnet { + sortedSubnets := subnets + sort.Sort(subnetsSort(sortedSubnets)) + return sortedSubnets[len(sortedSubnets)-1] +} + +func (s *StepNetworkInfo) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + oapiconn := state.Get("oapi").(*oapi.Client) + ui := state.Get("ui").(packer.Ui) + + // NET + if s.NetId == "" && !s.NetFilter.Empty() { + params := oapi.ReadNetsRequest{} + params.Filters = buildNetFilters(s.NetFilter.Filters) + s.NetFilter.Filters["state"] = "available" + + log.Printf("Using NET Filters %v", params) + + vpcResp, err := oapiconn.POST_ReadNets(params) + if err != nil { + err := fmt.Errorf("Error querying NETs: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + if len(vpcResp.OK.Nets) != 1 { + err := fmt.Errorf("Exactly one NET should match the filter, but %d NET's was found matching filters: %v", len(vpcResp.OK.Nets), params) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + s.NetId = vpcResp.OK.Nets[0].NetId + ui.Message(fmt.Sprintf("Found NET ID: %s", s.NetId)) + } + + // Subnet + if s.SubnetId == "" && !s.SubnetFilter.Empty() { + params := oapi.ReadSubnetsRequest{} + s.SubnetFilter.Filters["state"] = "available" + + if s.NetId != "" { + s.SubnetFilter.Filters["vpc-id"] = s.NetId + } + if s.SubregionName != "" { + s.SubnetFilter.Filters["availability-zone"] = s.SubregionName + } + params.Filters = buildSubnetFilters(s.SubnetFilter.Filters) + log.Printf("Using Subnet Filters %v", params) + + subnetsResp, err := oapiconn.POST_ReadSubnets(params) + if err != nil { + err := fmt.Errorf("Error querying Subnets: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + if len(subnetsResp.OK.Subnets) == 0 { + err := fmt.Errorf("No Subnets was found matching filters: %v", params) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + if len(subnetsResp.OK.Subnets) > 1 && !s.SubnetFilter.Random && !s.SubnetFilter.MostFree { + err := fmt.Errorf("Your filter matched %d Subnets. Please try a more specific search, or set random or most_free to true.", len(subnetsResp.OK.Subnets)) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + var subnet oapi.Subnet + switch { + case s.SubnetFilter.MostFree: + subnet = mostFreeSubnet(subnetsResp.OK.Subnets) + case s.SubnetFilter.Random: + subnet = subnetsResp.OK.Subnets[rand.Intn(len(subnetsResp.OK.Subnets))] + default: + subnet = subnetsResp.OK.Subnets[0] + } + s.SubnetId = subnet.SubnetId + ui.Message(fmt.Sprintf("Found Subnet ID: %s", s.SubnetId)) + } + + // Try to find Subregion and NET Id from Subnet if they are not yet found/given + if s.SubnetId != "" && (s.SubregionName == "" || s.NetId == "") { + log.Printf("[INFO] Finding Subregion and NetId for the given subnet '%s'", s.SubnetId) + resp, err := oapiconn.POST_ReadSubnets( + oapi.ReadSubnetsRequest{ + Filters: oapi.FiltersSubnet{ + SubnetIds: []string{s.SubnetId}, + }, + }) + if err != nil { + err := fmt.Errorf("Describing the subnet: %s returned error: %s.", s.SubnetId, err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + if s.SubregionName == "" { + s.SubregionName = resp.OK.Subnets[0].SubregionName + log.Printf("[INFO] SubregionName found: '%s'", s.SubregionName) + } + if s.NetId == "" { + s.NetId = resp.OK.Subnets[0].NetId + log.Printf("[INFO] NetId found: '%s'", s.NetId) + } + } + + state.Put("vpc_id", s.NetId) + state.Put("availability_zone", s.SubregionName) + state.Put("subnet_id", s.SubnetId) + return multistep.ActionContinue +} + +func (s *StepNetworkInfo) Cleanup(multistep.StateBag) {} From c24ee2c9caf54ae2e87ae0e7f1c0a81c755e81bf Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Thu, 31 Jan 2019 15:29:31 -0600 Subject: [PATCH 019/113] feature: bsusurrogate, add keypair step --- builder/osc/bsusurrogate/builder.go | 5 ++ builder/osc/common/step_key_pair.go | 123 ++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 builder/osc/common/step_key_pair.go diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index 2329b9e02..a49222184 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -153,6 +153,11 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe SubnetFilter: b.config.SubnetFilter, SubregionName: b.config.Subregion, }, + &osccommon.StepKeyPair{ + Debug: b.config.PackerDebug, + Comm: &b.config.RunConfig.Comm, + DebugKeyPath: fmt.Sprintf("oapi_%s.pem", b.config.PackerBuildName), + }, } b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) diff --git a/builder/osc/common/step_key_pair.go b/builder/osc/common/step_key_pair.go new file mode 100644 index 000000000..580046b55 --- /dev/null +++ b/builder/osc/common/step_key_pair.go @@ -0,0 +1,123 @@ +package common + +import ( + "context" + "fmt" + "os" + "runtime" + + "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/outscale/osc-go/oapi" +) + +type StepKeyPair struct { + Debug bool + Comm *communicator.Config + DebugKeyPath string + + doCleanup bool +} + +func (s *StepKeyPair) 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 := s.Comm.ReadSSHPrivateKeyFile() + if err != nil { + state.Put("error", 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 AMI") + 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 + } + + oapiconn := state.Get("oapi").(*oapi.Client) + + ui.Say(fmt.Sprintf("Creating temporary keypair: %s", s.Comm.SSHTemporaryKeyPairName)) + keyResp, err := oapiconn.POST_CreateKeypair(oapi.CreateKeypairRequest{ + KeypairName: s.Comm.SSHTemporaryKeyPairName}) + if err != nil { + state.Put("error", fmt.Errorf("Error creating temporary keypair: %s", err)) + return multistep.ActionHalt + } + + s.doCleanup = true + + // Set some data for use in future steps + s.Comm.SSHKeyPairName = s.Comm.SSHTemporaryKeyPairName + s.Comm.SSHPrivateKey = []byte(keyResp.OK.Keypair.PrivateKey) + + // If we're in debug mode, output the private key to the working + // directory. + 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("Error saving debug key: %s", err)) + return multistep.ActionHalt + } + defer f.Close() + + // Write the key out + if _, err := f.Write([]byte(keyResp.OK.Keypair.PrivateKey)); err != nil { + state.Put("error", fmt.Errorf("Error saving debug key: %s", err)) + return multistep.ActionHalt + } + + // Chmod it so that it is SSH ready + if runtime.GOOS != "windows" { + if err := f.Chmod(0600); err != nil { + state.Put("error", fmt.Errorf("Error setting permissions of debug key: %s", err)) + return multistep.ActionHalt + } + } + } + + return multistep.ActionContinue +} + +func (s *StepKeyPair) Cleanup(state multistep.StateBag) { + if !s.doCleanup { + return + } + + oapiconn := state.Get("oapi").(*oapi.Client) + ui := state.Get("ui").(packer.Ui) + + // Remove the keypair + ui.Say("Deleting temporary keypair...") + _, err := oapiconn.POST_DeleteKeypair(oapi.DeleteKeypairRequest{KeypairName: s.Comm.SSHTemporaryKeyPairName}) + if err != nil { + ui.Error(fmt.Sprintf( + "Error cleaning up keypair. Please delete the key manually: %s", s.Comm.SSHTemporaryKeyPairName)) + } + + // Also remove the physical key if we're debugging. + if s.Debug { + if err := os.Remove(s.DebugKeyPath); err != nil { + ui.Error(fmt.Sprintf( + "Error removing debug key '%s': %s", s.DebugKeyPath, err)) + } + } +} From cef9a4b9fdd0e19dccf7acf31c7d2dc23d9d960f Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Fri, 1 Feb 2019 15:20:26 -0600 Subject: [PATCH 020/113] feature: bsusurrogate, add network info step --- builder/osc/common/step_network_info.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/osc/common/step_network_info.go b/builder/osc/common/step_network_info.go index e7fd68b70..6f5c4e501 100644 --- a/builder/osc/common/step_network_info.go +++ b/builder/osc/common/step_network_info.go @@ -149,7 +149,7 @@ func (s *StepNetworkInfo) Run(_ context.Context, state multistep.StateBag) multi } } - state.Put("vpc_id", s.NetId) + state.Put("net_id", s.NetId) state.Put("availability_zone", s.SubregionName) state.Put("subnet_id", s.SubnetId) return multistep.ActionContinue From 5ef3e8123443341f6d2c5edb0af323c08789b5a6 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Fri, 1 Feb 2019 15:20:47 -0600 Subject: [PATCH 021/113] feature: bsusurrogate, add security group step --- builder/osc/bsusurrogate/builder.go | 6 + builder/osc/common/build_filters.go | 101 ++++++++++--- builder/osc/common/run_config.go | 2 +- builder/osc/common/state.go | 59 ++++++++ builder/osc/common/step_security_group.go | 175 ++++++++++++++++++++++ 5 files changed, 324 insertions(+), 19 deletions(-) create mode 100644 builder/osc/common/state.go create mode 100644 builder/osc/common/step_security_group.go diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index a49222184..945332962 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -158,6 +158,12 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Comm: &b.config.RunConfig.Comm, DebugKeyPath: fmt.Sprintf("oapi_%s.pem", b.config.PackerBuildName), }, + &osccommon.StepSecurityGroup{ + SecurityGroupFilter: b.config.SecurityGroupFilter, + SecurityGroupIds: b.config.SecurityGroupIds, + CommConfig: &b.config.RunConfig.Comm, + TemporarySGSourceCidr: b.config.TemporarySGSourceCidr, + }, } b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) diff --git a/builder/osc/common/build_filters.go b/builder/osc/common/build_filters.go index 5ff387dfd..bec8a8fd1 100644 --- a/builder/osc/common/build_filters.go +++ b/builder/osc/common/build_filters.go @@ -12,19 +12,19 @@ func buildNetFilters(input map[string]string) oapi.FiltersNet { for k, v := range input { filterValue := []string{v} switch name := k; name { - case "ip_range": + case "ip-range": filters.IpRanges = filterValue - case "dhcp_options_set_id": + case "dhcp-options-set-id": filters.DhcpOptionsSetIds = filterValue - case "is_default": + case "is-default": if isDefault, err := strconv.ParseBool(v); err == nil { filters.IsDefault = isDefault } case "state": filters.States = filterValue - case "tag_key": + case "tag-key": filters.TagKeys = filterValue - case "tag_value": + case "tag-value": filters.TagValues = filterValue default: log.Printf("[Debug] Unknown Filter Name: %s.", name) @@ -38,19 +38,19 @@ func buildSubnetFilters(input map[string]string) oapi.FiltersSubnet { for k, v := range input { filterValue := []string{v} switch name := k; name { - case "available_ips_counts": + case "available-ips-counts": if ipCount, err := strconv.Atoi(v); err == nil { filters.AvailableIpsCounts = []int64{int64(ipCount)} } - case "ip_ranges": + case "ip-ranges": filters.IpRanges = filterValue - case "net_ids": + case "net-ids": filters.NetIds = filterValue case "states": filters.States = filterValue - case "subnet_ids": + case "subnet-ids": filters.SubnetIds = filterValue - case "sub_region_names": + case "sub-region-names": filters.SubregionNames = filterValue default: log.Printf("[Debug] Unknown Filter Name: %s.", name) @@ -65,23 +65,23 @@ func buildOMIFilters(input map[string]string) oapi.FiltersImage { filterValue := []string{v} switch name := k; name { - case "account_aliases": + case "account-aliases": filters.AccountAliases = filterValue - case "account_ids": + case "account-ids": filters.AccountIds = filterValue case "architectures": filters.Architectures = filterValue - case "image_ids": + case "image-ids": filters.ImageIds = filterValue - case "image_names": + case "image-names": filters.ImageNames = filterValue - case "image_types": + case "image-types": filters.ImageTypes = filterValue - case "virtualization_types": + case "virtualization-types": filters.VirtualizationTypes = filterValue - case "root_device_types": + case "root-device-types": filters.RootDeviceTypes = filterValue - case "block_device_mapping_volume_type": + case "block-device-mapping-volume-type": filters.BlockDeviceMappingVolumeType = filterValue //Some params are missing. default: @@ -90,3 +90,68 @@ func buildOMIFilters(input map[string]string) oapi.FiltersImage { } return filters } + +func buildSecurityGroupFilters(input map[string]string) oapi.FiltersSecurityGroup { + var filters oapi.FiltersSecurityGroup + for k, v := range input { + filterValue := []string{v} + + switch name := k; name { + case "account-ids": + filters.AccountIds = filterValue + case "descriptions": + filters.Descriptions = filterValue + case "inbound-rule-account-ids": + filters.InboundRuleAccountIds = filterValue + case "inbound-rule-from-port-ranges": + if val, err := strconv.Atoi(v); err == nil { + filters.InboundRuleFromPortRanges = []int64{int64(val)} + } + case "inbound-rule-ip-ranges": + filters.InboundRuleIpRanges = filterValue + case "inbound-rule-protocols": + filters.InboundRuleProtocols = filterValue + case "inbound-rule-security-group-ids": + filters.InboundRuleSecurityGroupIds = filterValue + case "inbound-rule-security-group-names": + filters.InboundRuleSecurityGroupNames = filterValue + case "inbound-rule-to-port-ranges": + if val, err := strconv.Atoi(v); err == nil { + filters.InboundRuleToPortRanges = []int64{int64(val)} + } + case "net-ids": + filters.NetIds = filterValue + + case "outbound-rule-account-ids": + filters.OutboundRuleAccountIds = filterValue + case "outbound-rule-from-port-ranges": + if val, err := strconv.Atoi(v); err == nil { + filters.OutboundRuleFromPortRanges = []int64{int64(val)} + } + case "outbound-rule-ip-ranges": + filters.OutboundRuleIpRanges = filterValue + case "outbound-rule-protocols": + filters.OutboundRuleProtocols = filterValue + case "outbound-rule-security-group-ids": + filters.OutboundRuleSecurityGroupIds = filterValue + case "outbound-rule-security-group-names": + filters.OutboundRuleSecurityGroupNames = filterValue + case "outbound-rule-to-port-ranges": + if val, err := strconv.Atoi(v); err == nil { + filters.OutboundRuleToPortRanges = []int64{int64(val)} + } + case "security-group-ids": + filters.SecurityGroupIds = filterValue + case "security-group-names": + filters.SecurityGroupNames = filterValue + case "tags-keys": + filters.TagKeys = filterValue + case "tags-values": + filters.TagValues = filterValue + //Some params are missing. + default: + log.Printf("[Debug] Unknown Filter Name: %s.", name) + } + } + return filters +} diff --git a/builder/osc/common/run_config.go b/builder/osc/common/run_config.go index cca3cf2b9..b781a1a4b 100644 --- a/builder/osc/common/run_config.go +++ b/builder/osc/common/run_config.go @@ -48,7 +48,7 @@ func (d *NetFilterOptions) Empty() bool { } type SecurityGroupFilterOptions struct { - Filters map[*string]*string + Filters map[string]string } func (d *SecurityGroupFilterOptions) Empty() bool { diff --git a/builder/osc/common/state.go b/builder/osc/common/state.go new file mode 100644 index 000000000..701a4b293 --- /dev/null +++ b/builder/osc/common/state.go @@ -0,0 +1,59 @@ +package common + +import ( + "fmt" + "log" + + "github.com/hashicorp/packer/common" + "github.com/outscale/osc-go/oapi" +) + +type stateRefreshFunc func() (string, error) + +func waitForSecurityGroup(conn *oapi.Client, securityGroupID string) error { + errCh := make(chan error, 1) + go waitForState(errCh, "exists", securityGroupWaitFunc(conn, securityGroupID)) + err := <-errCh + return err +} + +func waitForState(errCh chan<- error, target string, refresh stateRefreshFunc) error { + err := common.Retry(2, 2, 0, func(_ uint) (bool, error) { + state, err := refresh() + if err != nil { + return false, err + } else if state == target { + return true, nil + } + return false, nil + }) + errCh <- err + return err +} + +func securityGroupWaitFunc(conn *oapi.Client, id string) stateRefreshFunc { + return func() (string, error) { + log.Printf("[Debug] Check if SG with id %s exists", id) + resp, err := conn.POST_ReadSecurityGroups(oapi.ReadSecurityGroupsRequest{ + Filters: oapi.FiltersSecurityGroup{ + SecurityGroupIds: []string{id}, + }, + }) + + log.Printf("[Debug] Read Response %+v", resp.OK) + + if err != nil { + return "", err + } + + if resp.OK == nil { + return "", fmt.Errorf("Security Group with ID %s. Not Found", id) + } + + if len(resp.OK.SecurityGroups) == 0 { + return "waiting", nil + } + + return "exists", nil + } +} diff --git a/builder/osc/common/step_security_group.go b/builder/osc/common/step_security_group.go new file mode 100644 index 000000000..7531f03a1 --- /dev/null +++ b/builder/osc/common/step_security_group.go @@ -0,0 +1,175 @@ +package common + +import ( + "context" + "fmt" + "log" + "strings" + "time" + + "github.com/hashicorp/packer/common/uuid" + "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/outscale/osc-go/oapi" +) + +type StepSecurityGroup struct { + CommConfig *communicator.Config + SecurityGroupFilter SecurityGroupFilterOptions + SecurityGroupIds []string + TemporarySGSourceCidr string + + createdGroupId string +} + +func (s *StepSecurityGroup) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + oapiconn := state.Get("oapi").(*oapi.Client) + ui := state.Get("ui").(packer.Ui) + netId := state.Get("net_id").(string) + + if len(s.SecurityGroupIds) > 0 { + resp, err := oapiconn.POST_ReadSecurityGroups( + oapi.ReadSecurityGroupsRequest{ + Filters: oapi.FiltersSecurityGroup{ + SecurityGroupIds: s.SecurityGroupIds, + }, + }, + ) + if err != nil || resp.OK == nil || len(resp.OK.SecurityGroups) <= 0 { + err := fmt.Errorf("Couldn't find specified security group: %s", err) + log.Printf("[DEBUG] %s", err.Error()) + state.Put("error", err) + return multistep.ActionHalt + } + + log.Printf("Using specified security groups: %v", s.SecurityGroupIds) + state.Put("securityGroupIds", s.SecurityGroupIds) + return multistep.ActionContinue + } + + if !s.SecurityGroupFilter.Empty() { + + params := oapi.ReadSecurityGroupsRequest{} + if netId != "" { + s.SecurityGroupFilter.Filters["net-id"] = netId + } + params.Filters = buildSecurityGroupFilters(s.SecurityGroupFilter.Filters) + + log.Printf("Using SecurityGroup Filters %v", params) + + sgResp, err := oapiconn.POST_ReadSecurityGroups(params) + if err != nil || sgResp.OK == nil { + err := fmt.Errorf("Couldn't find security groups for filter: %s", err) + log.Printf("[DEBUG] %s", err.Error()) + state.Put("error", err) + return multistep.ActionHalt + } + + securityGroupIds := []string{} + for _, sg := range sgResp.OK.SecurityGroups { + securityGroupIds = append(securityGroupIds, sg.SecurityGroupId) + } + + ui.Message(fmt.Sprintf("Found Security Group(s): %s", strings.Join(securityGroupIds, ", "))) + state.Put("securityGroupIds", securityGroupIds) + + return multistep.ActionContinue + } + + port := s.CommConfig.Port() + if port == 0 { + if s.CommConfig.Type != "none" { + panic("port must be set to a non-zero value.") + } + } + + // Create the group + groupName := fmt.Sprintf("packer_%s", uuid.TimeOrderedUUID()) + ui.Say(fmt.Sprintf("Creating temporary security group for this instance: %s", groupName)) + group := oapi.CreateSecurityGroupRequest{ + SecurityGroupName: groupName, + Description: "Temporary group for Packer", + } + + group.NetId = netId + + groupResp, err := oapiconn.POST_CreateSecurityGroup(group) + if err != nil { + ui.Error(err.Error()) + state.Put("error", err) + return multistep.ActionHalt + } + + // Set the group ID so we can delete it later + s.createdGroupId = groupResp.OK.SecurityGroup.SecurityGroupId + + // Wait for the security group become available for authorizing + log.Printf("[DEBUG] Waiting for temporary security group: %s", s.createdGroupId) + err = waitForSecurityGroup(oapiconn, s.createdGroupId) + if err == nil { + log.Printf("[DEBUG] Found security group %s", s.createdGroupId) + } else { + err := fmt.Errorf("Timed out waiting for security group %s: %s", s.createdGroupId, err) + log.Printf("[DEBUG] %s", err.Error()) + state.Put("error", err) + return multistep.ActionHalt + } + + // Authorize the SSH access for the security group + groupRules := oapi.CreateSecurityGroupRuleRequest{ + SecurityGroupId: groupResp.OK.SecurityGroup.SecurityGroupId, + Flow: "Inbound", + Rules: []oapi.SecurityGroupRule{ + oapi.SecurityGroupRule{ + FromPortRange: int64(port), + ToPortRange: int64(port), + IpRanges: []string{s.TemporarySGSourceCidr}, + IpProtocol: "tcp", + }, + }, + } + + ui.Say(fmt.Sprintf( + "Authorizing access to port %d from %s in the temporary security group...", + port, s.TemporarySGSourceCidr)) + _, err = oapiconn.POST_CreateSecurityGroupRule(groupRules) + if err != nil { + err := fmt.Errorf("Error authorizing temporary security group: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + // Set some state data for use in future steps + state.Put("securityGroupIds", []string{s.createdGroupId}) + + return multistep.ActionContinue +} + +func (s *StepSecurityGroup) Cleanup(state multistep.StateBag) { + if s.createdGroupId == "" { + return + } + + oapiconn := state.Get("oapi").(*oapi.Client) + ui := state.Get("ui").(packer.Ui) + + ui.Say("Deleting temporary security group...") + + var err error + for i := 0; i < 5; i++ { + _, err = oapiconn.POST_DeleteSecurityGroup(oapi.DeleteSecurityGroupRequest{SecurityGroupId: s.createdGroupId}) + if err == nil { + break + } + + log.Printf("Error deleting security group: %s", err) + time.Sleep(5 * time.Second) + } + + if err != nil { + ui.Error(fmt.Sprintf( + "Error cleaning up security group. Please delete the group manually: %s", s.createdGroupId)) + } +} From 7ef09bba137f44d9f60ceb37b25f455e2b97c117 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Mon, 4 Feb 2019 10:37:31 -0600 Subject: [PATCH 022/113] feature: bsusurrogate, add clean volumes and run source vm step --- builder/osc/bsusurrogate/builder.go | 22 ++ builder/osc/bsusurrogate/builder_acc_test.go | 18 +- builder/osc/common/block_device.go | 52 ++- builder/osc/common/interpolate_build_info.go | 2 +- builder/osc/common/run_config.go | 4 +- builder/osc/common/state.go | 40 +++ builder/osc/common/step_cleanup_volumes.go | 96 ++++++ builder/osc/common/step_network_info.go | 2 +- builder/osc/common/step_run_source_vm.go | 319 +++++++++++++++++++ builder/osc/common/tags.go | 10 +- 10 files changed, 546 insertions(+), 19 deletions(-) create mode 100644 builder/osc/common/step_cleanup_volumes.go create mode 100644 builder/osc/common/step_run_source_vm.go diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index 945332962..7ecc2fe87 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -164,6 +164,28 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe CommConfig: &b.config.RunConfig.Comm, TemporarySGSourceCidr: b.config.TemporarySGSourceCidr, }, + &osccommon.StepCleanupVolumes{ + BlockDevices: b.config.BlockDevices, + }, + &osccommon.StepRunSourceVm{ + AssociatePublicIpAddress: b.config.AssociatePublicIpAddress, + BlockDevices: b.config.BlockDevices, + Comm: &b.config.RunConfig.Comm, + Ctx: b.config.ctx, + Debug: b.config.PackerDebug, + BsuOptimized: b.config.BsuOptimized, + EnableT2Unlimited: b.config.EnableT2Unlimited, + ExpectedRootDevice: "ebs", // should it be bsu + IamVmProfile: b.config.IamVmProfile, + VmInitiatedShutdownBehavior: b.config.VmInitiatedShutdownBehavior, + VmType: b.config.VmType, + IsRestricted: false, + SourceOMI: b.config.SourceOmi, + Tags: b.config.RunTags, + UserData: b.config.UserData, + UserDataFile: b.config.UserDataFile, + VolumeTags: b.config.VolumeRunTags, + }, } b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) diff --git a/builder/osc/bsusurrogate/builder_acc_test.go b/builder/osc/bsusurrogate/builder_acc_test.go index 00afeb182..04b397f2a 100644 --- a/builder/osc/bsusurrogate/builder_acc_test.go +++ b/builder/osc/bsusurrogate/builder_acc_test.go @@ -26,25 +26,27 @@ const testBuilderAccBasic = ` "builders": [{ "type": "test", "region": "eu-west-2", - "vm_type": "m3.medium", + "vm_type": "c4.large", "source_omi": "ami-46260446", "ssh_username": "ubuntu", "omi_name": "packer-test {{timestamp}}", "omi_virtualization_type": "hvm", + "subregion_name": "eu-west-2a", "launch_block_device_mappings" : [ { - "volume_type" : "gp2", - "device_name" : "/dev/sda1", + "volume_type" : "io1", + "device_name" : "/dev/xvdf", "delete_on_vm_deletion" : false, - "volume_size" : 10 + "volume_size" : 10, + "iops": 300 } ], "omi_root_device":{ - "source_device_name": "/dev/sda1", - "device_name": "/dev/sda2", + "source_device_name": "/dev/xvdf", + "device_name": "/dev/sda1", "delete_on_vm_deletion": true, - "volume_size": 16, - "volume_type": "gp2" + "volume_size": 10, + "volume_type": "standard" } }] diff --git a/builder/osc/common/block_device.go b/builder/osc/common/block_device.go index fa2a16f4e..8d6ce9535 100644 --- a/builder/osc/common/block_device.go +++ b/builder/osc/common/block_device.go @@ -83,6 +83,54 @@ func buildBlockDevices(b []BlockDevice) []*oapi.BlockDeviceMapping { return blockDevices } +func buildBlockDevicesVmCreation(b []BlockDevice) []oapi.BlockDeviceMappingVmCreation { + var blockDevices []oapi.BlockDeviceMappingVmCreation + + for _, blockDevice := range b { + mapping := oapi.BlockDeviceMappingVmCreation{ + DeviceName: blockDevice.DeviceName, + } + + if blockDevice.NoDevice { + mapping.NoDevice = "" + } else if blockDevice.VirtualName != "" { + if strings.HasPrefix(blockDevice.VirtualName, "ephemeral") { + mapping.VirtualDeviceName = blockDevice.VirtualName + } + } else { + bsu := oapi.BsuToCreate{ + DeleteOnVmDeletion: blockDevice.DeleteOnVmDeletion, + } + + if blockDevice.VolumeType != "" { + bsu.VolumeType = blockDevice.VolumeType + } + + if blockDevice.VolumeSize > 0 { + bsu.VolumeSize = blockDevice.VolumeSize + } + + // IOPS is only valid for io1 type + if blockDevice.VolumeType == "io1" { + bsu.Iops = blockDevice.IOPS + } + + if blockDevice.SnapshotId != "" { + bsu.SnapshotId = blockDevice.SnapshotId + } + + //missing + //BlockDevice Encrypted + //KmsKeyId + + mapping.Bsu = bsu + } + + blockDevices = append(blockDevices, mapping) + } + return blockDevices +} + func (b *BlockDevice) Prepare(ctx *interpolate.Context) error { if b.DeviceName == "" { return fmt.Errorf("The `device_name` must be specified " + @@ -114,6 +162,6 @@ func (b *OMIBlockDevices) BuildOMIDevices() []*oapi.BlockDeviceMapping { return buildBlockDevices(b.OMIMappings) } -func (b *LaunchBlockDevices) BuildLaunchDevices() []*oapi.BlockDeviceMapping { - return buildBlockDevices(b.LaunchMappings) +func (b *LaunchBlockDevices) BuildLaunchDevices() []oapi.BlockDeviceMappingVmCreation { + return buildBlockDevicesVmCreation(b.LaunchMappings) } diff --git a/builder/osc/common/interpolate_build_info.go b/builder/osc/common/interpolate_build_info.go index 2515e9f33..a3d62a00c 100644 --- a/builder/osc/common/interpolate_build_info.go +++ b/builder/osc/common/interpolate_build_info.go @@ -20,7 +20,7 @@ func extractBuildInfo(region string, state multistep.StateBag) *BuildInfoTemplat } } - sourceOMI := rawSourceOMI.(*oapi.Image) + sourceOMI := rawSourceOMI.(oapi.Image) sourceOMITags := make(map[string]string, len(sourceOMI.Tags)) for _, tag := range sourceOMI.Tags { sourceOMITags[tag.Key] = tag.Value diff --git a/builder/osc/common/run_config.go b/builder/osc/common/run_config.go index b781a1a4b..acd13ae64 100644 --- a/builder/osc/common/run_config.go +++ b/builder/osc/common/run_config.go @@ -59,10 +59,10 @@ func (d *SecurityGroupFilterOptions) Empty() bool { // AMI and details on how to access that launched image. type RunConfig struct { AssociatePublicIpAddress bool `mapstructure:"associate_public_ip_address"` - Subregion string `mapstructure:"availability_zone"` + Subregion string `mapstructure:"subregion_name"` BlockDurationMinutes int64 `mapstructure:"block_duration_minutes"` DisableStopVm bool `mapstructure:"disable_stop_vm"` - BsuOptimized bool `mapstructure:"ebs_optimized"` + BsuOptimized bool `mapstructure:"bsu_optimized"` EnableT2Unlimited bool `mapstructure:"enable_t2_unlimited"` IamVmProfile string `mapstructure:"iam_vm_profile"` VmInitiatedShutdownBehavior string `mapstructure:"shutdown_behavior"` diff --git a/builder/osc/common/state.go b/builder/osc/common/state.go index 701a4b293..67a48b2b0 100644 --- a/builder/osc/common/state.go +++ b/builder/osc/common/state.go @@ -17,6 +17,19 @@ func waitForSecurityGroup(conn *oapi.Client, securityGroupID string) error { return err } +func waitUntilForVmRunning(conn *oapi.Client, vmID string) error { + errCh := make(chan error, 1) + go waitForState(errCh, "running", waitUntilVmStateFunc(conn, vmID)) + err := <-errCh + return err +} + +func waitUntilVmDeleted(conn *oapi.Client, vmID string) error { + errCh := make(chan error, 1) + go waitForState(errCh, "terminated", waitUntilVmStateFunc(conn, vmID)) + return <-errCh +} + func waitForState(errCh chan<- error, target string, refresh stateRefreshFunc) error { err := common.Retry(2, 2, 0, func(_ uint) (bool, error) { state, err := refresh() @@ -31,6 +44,33 @@ func waitForState(errCh chan<- error, target string, refresh stateRefreshFunc) e return err } +func waitUntilVmStateFunc(conn *oapi.Client, id string) stateRefreshFunc { + return func() (string, error) { + log.Printf("[Debug] Check if SG with id %s exists", id) + resp, err := conn.POST_ReadVms(oapi.ReadVmsRequest{ + Filters: oapi.FiltersVm{ + VmIds: []string{id}, + }, + }) + + log.Printf("[Debug] Read Response %+v", resp.OK) + + if err != nil { + return "", err + } + + if resp.OK == nil { + return "", fmt.Errorf("Vm with ID %s. Not Found", id) + } + + if len(resp.OK.Vms) == 0 { + return "pending", nil + } + + return resp.OK.Vms[0].State, nil + } +} + func securityGroupWaitFunc(conn *oapi.Client, id string) stateRefreshFunc { return func() (string, error) { log.Printf("[Debug] Check if SG with id %s exists", id) diff --git a/builder/osc/common/step_cleanup_volumes.go b/builder/osc/common/step_cleanup_volumes.go new file mode 100644 index 000000000..e49afe91d --- /dev/null +++ b/builder/osc/common/step_cleanup_volumes.go @@ -0,0 +1,96 @@ +package common + +import ( + "context" + "fmt" + "reflect" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/outscale/osc-go/oapi" +) + +// stepCleanupVolumes cleans up any orphaned volumes that were not designated to +// remain after termination of the vm. These volumes are typically ones +// that are marked as "delete on terminate:false" in the source_ami of a build. +type StepCleanupVolumes struct { + BlockDevices BlockDevices +} + +func (s *StepCleanupVolumes) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + // stepCleanupVolumes is for Cleanup only + return multistep.ActionContinue +} + +func (s *StepCleanupVolumes) Cleanup(state multistep.StateBag) { + oapiconn := state.Get("oapi").(*oapi.Client) + vmRaw := state.Get("vm") + var vm *oapi.Vm + if vmRaw != nil { + vm = vmRaw.(*oapi.Vm) + } + ui := state.Get("ui").(packer.Ui) + if vm == nil { + ui.Say("No volumes to clean up, skipping") + return + } + + ui.Say("Cleaning up any extra volumes...") + + // Collect Volume information from the cached Vm as a map of volume-id + // to device name, to compare with save list below + var vl []string + volList := make(map[string]string) + for _, bdm := range vm.BlockDeviceMappings { + if !reflect.DeepEqual(bdm.Bsu, oapi.BsuCreated{}) { + vl = append(vl, bdm.Bsu.VolumeId) + volList[bdm.Bsu.VolumeId] = bdm.DeviceName + } + } + + // Using the volume list from the cached Vm, check with Outscale for up to + // date information on them + resp, err := oapiconn.POST_ReadVolumes(oapi.ReadVolumesRequest{ + Filters: oapi.FiltersVolume{ + VolumeIds: vl, + }, + }) + + if err != nil { + ui.Say(fmt.Sprintf("Error describing volumes: %s", err)) + return + } + + // If any of the returned volumes are in a "deleting" stage or otherwise not + // available, remove them from the list of volumes + for _, v := range resp.OK.Volumes { + if v.State != "" && v.State != "available" { + delete(volList, v.VolumeId) + } + } + + if len(resp.OK.Volumes) == 0 { + ui.Say("No volumes to clean up, skipping") + return + } + + // Filter out any devices created as part of the launch mappings, since + // we'll let amazon follow the `delete_on_termination` setting. + for _, b := range s.BlockDevices.LaunchMappings { + for volKey, volName := range volList { + if volName == b.DeviceName { + delete(volList, volKey) + } + } + } + + // Destroy remaining volumes + for k := range volList { + ui.Say(fmt.Sprintf("Destroying volume (%s)...", k)) + _, err := oapiconn.POST_DeleteVolume(oapi.DeleteVolumeRequest{VolumeId: k}) + if err != nil { + ui.Say(fmt.Sprintf("Error deleting volume: %s", err)) + } + + } +} diff --git a/builder/osc/common/step_network_info.go b/builder/osc/common/step_network_info.go index 6f5c4e501..937758bae 100644 --- a/builder/osc/common/step_network_info.go +++ b/builder/osc/common/step_network_info.go @@ -150,7 +150,7 @@ func (s *StepNetworkInfo) Run(_ context.Context, state multistep.StateBag) multi } state.Put("net_id", s.NetId) - state.Put("availability_zone", s.SubregionName) + state.Put("subregion_name", s.SubregionName) state.Put("subnet_id", s.SubnetId) return multistep.ActionContinue } diff --git a/builder/osc/common/step_run_source_vm.go b/builder/osc/common/step_run_source_vm.go new file mode 100644 index 000000000..0251c759e --- /dev/null +++ b/builder/osc/common/step_run_source_vm.go @@ -0,0 +1,319 @@ +package common + +import ( + "context" + "encoding/base64" + "fmt" + "io/ioutil" + "log" + "reflect" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/outscale/osc-go/oapi" + + retry "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/hashicorp/packer/template/interpolate" +) + +type StepRunSourceVm struct { + AssociatePublicIpAddress bool + BlockDevices BlockDevices + Comm *communicator.Config + Ctx interpolate.Context + Debug bool + BsuOptimized bool + EnableT2Unlimited bool + ExpectedRootDevice string + IamVmProfile string + VmInitiatedShutdownBehavior string + VmType string + IsRestricted bool + SourceOMI string + Tags TagMap + UserData string + UserDataFile string + VolumeTags TagMap + + vmId string +} + +func (s *StepRunSourceVm) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + oapiconn := state.Get("oapi").(*oapi.Client) + + securityGroupIds := state.Get("securityGroupIds").([]string) + ui := state.Get("ui").(packer.Ui) + + userData := s.UserData + if s.UserDataFile != "" { + contents, err := ioutil.ReadFile(s.UserDataFile) + if err != nil { + state.Put("error", fmt.Errorf("Problem reading user data file: %s", err)) + return multistep.ActionHalt + } + + userData = string(contents) + } + + // Test if it is encoded already, and if not, encode it + if _, err := base64.StdEncoding.DecodeString(userData); err != nil { + log.Printf("[DEBUG] base64 encoding user data...") + userData = base64.StdEncoding.EncodeToString([]byte(userData)) + } + + ui.Say("Launching a source OUTSCALE vm...") + image, ok := state.Get("source_image").(oapi.Image) + if !ok { + state.Put("error", fmt.Errorf("source_image type assertion failed")) + return multistep.ActionHalt + } + s.SourceOMI = image.ImageId + + if s.ExpectedRootDevice != "" && image.RootDeviceType != s.ExpectedRootDevice { + state.Put("error", fmt.Errorf( + "The provided source OMI has an invalid root device type.\n"+ + "Expected '%s', got '%s'.", + s.ExpectedRootDevice, image.RootDeviceType)) + return multistep.ActionHalt + } + + var vmId string + + ui.Say("Adding tags to source vm") + if _, exists := s.Tags["Name"]; !exists { + s.Tags["Name"] = "Packer Builder" + } + + oapiTags, err := s.Tags.OAPITags(s.Ctx, oapiconn.GetConfig().Region, state) + if err != nil { + err := fmt.Errorf("Error tagging source vm: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + // volTags, err := s.VolumeTags.OAPITags(s.Ctx, oapiconn.GetConfig().Region, state) + // if err != nil { + // err := fmt.Errorf("Error tagging volumes: %s", err) + // state.Put("error", err) + // ui.Error(err.Error()) + // return multistep.ActionHalt + // } + + subregion := state.Get("subregion_name").(string) + runOpts := oapi.CreateVmsRequest{ + ImageId: s.SourceOMI, + VmType: s.VmType, + UserData: userData, + MaxVmsCount: 1, + MinVmsCount: 1, + Placement: oapi.Placement{SubregionName: subregion}, + BsuOptimized: s.BsuOptimized, + BlockDeviceMappings: s.BlockDevices.BuildLaunchDevices(), + //IamVmProfile: oapi.IamVmProfileSpecification{Name: &s.IamVmProfile}, + } + + // if s.EnableT2Unlimited { + // creditOption := "unlimited" + // runOpts.CreditSpecification = &oapi.CreditSpecificationRequest{CpuCredits: &creditOption} + // } + + // Collect tags for tagging on resource creation + // var tagSpecs []oapi.ResourceTag + + // if len(oapiTags) > 0 { + // runTags := &oapi.ResourceTag{ + // ResourceType: aws.String("vm"), + // Tags: oapiTags, + // } + + // tagSpecs = append(tagSpecs, runTags) + // } + + // if len(volTags) > 0 { + // runVolTags := &oapi.TagSpecification{ + // ResourceType: aws.String("volume"), + // Tags: volTags, + // } + + // tagSpecs = append(tagSpecs, runVolTags) + // } + + // // If our region supports it, set tag specifications + // if len(tagSpecs) > 0 && !s.IsRestricted { + // runOpts.SetTagSpecifications(tagSpecs) + // oapiTags.Report(ui) + // volTags.Report(ui) + // } + + if s.Comm.SSHKeyPairName != "" { + runOpts.KeypairName = s.Comm.SSHKeyPairName + } + + subnetId := state.Get("subnet_id").(string) + + if subnetId != "" && s.AssociatePublicIpAddress { + runOpts.Nics = []oapi.NicForVmCreation{ + { + DeviceNumber: 0, + //AssociatePublicIpAddress: s.AssociatePublicIpAddress, + SubnetId: subnetId, + SecurityGroupIds: securityGroupIds, + DeleteOnVmDeletion: true, + }, + } + } else { + runOpts.SubnetId = subnetId + runOpts.SecurityGroupIds = securityGroupIds + } + + if s.ExpectedRootDevice == "bsu" { + runOpts.VmInitiatedShutdownBehavior = s.VmInitiatedShutdownBehavior + } + + runResp, err := oapiconn.POST_CreateVms(runOpts) + if err != nil { + err := fmt.Errorf("Error launching source vm: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + vmId = runResp.OK.Vms[0].VmId + + // Set the vm ID so that the cleanup works properly + s.vmId = vmId + + ui.Message(fmt.Sprintf("Vm ID: %s", vmId)) + ui.Say(fmt.Sprintf("Waiting for vm (%v) to become ready...", vmId)) + + request := oapi.ReadVmsRequest{ + Filters: oapi.FiltersVm{ + VmIds: []string{vmId}, + }, + } + if err := waitUntilForVmRunning(oapiconn, vmId); err != nil { + err := fmt.Errorf("Error waiting for vm (%s) to become ready: %s", vmId, err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + //TODO:Set Vm and Volume Tags, + //TODO: LinkPublicIp i + + resp, err := oapiconn.POST_ReadVms(request) + + r := resp.OK + + if err != nil || len(r.Vms) == 0 { + err := fmt.Errorf("Error finding source vm.") + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + vm := r.Vms[0] + + if s.Debug { + if vm.PublicDnsName != "" { + ui.Message(fmt.Sprintf("Public DNS: %s", vm.PublicDnsName)) + } + + if vm.PublicIp != "" { + ui.Message(fmt.Sprintf("Public IP: %s", vm.PublicIp)) + } + + if vm.PrivateIp != "" { + ui.Message(fmt.Sprintf("Private IP: %s", vm.PublicIp)) + } + } + + state.Put("vm", vm) + + // If we're in a region that doesn't support tagging on vm creation, + // do that now. + + if s.IsRestricted { + oapiTags.Report(ui) + // Retry creating tags for about 2.5 minutes + err = retry.Retry(0.2, 30, 11, func(_ uint) (bool, error) { + _, err := oapiconn.POST_CreateTags(oapi.CreateTagsRequest{ + Tags: oapiTags, + ResourceIds: []string{vmId}, + }) + if err == nil { + return true, nil + } + //TODO: improve error + if awsErr, ok := err.(awserr.Error); ok { + if awsErr.Code() == "InvalidVmID.NotFound" { + return false, nil + } + } + return true, err + }) + + if err != nil { + err := fmt.Errorf("Error tagging source vm: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + // Now tag volumes + + volumeIds := make([]string, 0) + for _, v := range vm.BlockDeviceMappings { + if bsu := v.Bsu; !reflect.DeepEqual(bsu, oapi.BsuCreated{}) { + volumeIds = append(volumeIds, bsu.VolumeId) + } + } + + if len(volumeIds) > 0 && s.VolumeTags.IsSet() { + ui.Say("Adding tags to source BSU Volumes") + + volumeTags, err := s.VolumeTags.OAPITags(s.Ctx, oapiconn.GetConfig().Region, state) + if err != nil { + err := fmt.Errorf("Error tagging source BSU Volumes on %s: %s", vm.VmId, err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + volumeTags.Report(ui) + + _, err = oapiconn.POST_CreateTags(oapi.CreateTagsRequest{ + ResourceIds: volumeIds, + Tags: volumeTags, + }) + + if err != nil { + err := fmt.Errorf("Error tagging source BSU Volumes on %s: %s", vm.VmId, err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + } + + return multistep.ActionContinue +} + +func (s *StepRunSourceVm) Cleanup(state multistep.StateBag) { + + oapiconn := state.Get("oapi").(*oapi.Client) + ui := state.Get("ui").(packer.Ui) + + // Terminate the source vm if it exists + if s.vmId != "" { + ui.Say("Terminating the source OUTSCALE vm...") + if _, err := oapiconn.POST_DeleteVms(oapi.DeleteVmsRequest{VmIds: []string{s.vmId}}); err != nil { + ui.Error(fmt.Sprintf("Error terminating vm, may still be around: %s", err)) + return + } + + if err := waitUntilVmDeleted(oapiconn, s.vmId); err != nil { + ui.Error(err.Error()) + } + } +} diff --git a/builder/osc/common/tags.go b/builder/osc/common/tags.go index ff58c0d67..0f70bac4a 100644 --- a/builder/osc/common/tags.go +++ b/builder/osc/common/tags.go @@ -10,9 +10,9 @@ import ( ) type TagMap map[string]string -type OAPI []*oapi.ResourceTag +type OAPITags []oapi.ResourceTag -func (t OAPI) Report(ui packer.Ui) { +func (t OAPITags) Report(ui packer.Ui) { for _, tag := range t { ui.Message(fmt.Sprintf("Adding tag: \"%s\": \"%s\"", tag.Key, tag.Value)) @@ -23,8 +23,8 @@ func (t TagMap) IsSet() bool { return len(t) > 0 } -func (t TagMap) OAPI(ctx interpolate.Context, region string, state multistep.StateBag) (OAPI, error) { - var oapiTags []*oapi.ResourceTag +func (t TagMap) OAPITags(ctx interpolate.Context, region string, state multistep.StateBag) (OAPITags, error) { + var oapiTags []oapi.ResourceTag ctx.Data = extractBuildInfo(region, state) for key, value := range t { @@ -36,7 +36,7 @@ func (t TagMap) OAPI(ctx interpolate.Context, region string, state multistep.Sta if err != nil { return nil, fmt.Errorf("Error processing tag: %s:%s - %s", key, value, err) } - oapiTags = append(oapiTags, &oapi.ResourceTag{ + oapiTags = append(oapiTags, oapi.ResourceTag{ Key: interpolatedKey, Value: interpolatedValue, }) From 1df7f15f53045ae55f4ae4ea9513a2e64394c60f Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Mon, 4 Feb 2019 11:43:35 -0600 Subject: [PATCH 023/113] fix: namming in step keypair --- builder/osc/common/step_key_pair.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/osc/common/step_key_pair.go b/builder/osc/common/step_key_pair.go index 580046b55..effc9eec6 100644 --- a/builder/osc/common/step_key_pair.go +++ b/builder/osc/common/step_key_pair.go @@ -37,7 +37,7 @@ func (s *StepKeyPair) Run(_ context.Context, state multistep.StateBag) multistep } if s.Comm.SSHAgentAuth && s.Comm.SSHKeyPairName == "" { - ui.Say("Using SSH Agent with key pair in Source AMI") + ui.Say("Using SSH Agent with key pair in Source OMI") return multistep.ActionContinue } From b0c4784b964ac02599b2a1d468c40dbb869ac075 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Mon, 4 Feb 2019 11:58:15 -0600 Subject: [PATCH 024/113] feature: bsusurrogate, add clean get password step --- builder/osc/bsusurrogate/builder.go | 6 + builder/osc/common/step_get_password.go | 176 ++++++++++++++++++++++++ 2 files changed, 182 insertions(+) create mode 100644 builder/osc/common/step_get_password.go diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index 7ecc2fe87..810b73dfa 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -186,6 +186,12 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe UserDataFile: b.config.UserDataFile, VolumeTags: b.config.VolumeRunTags, }, + &osccommon.StepGetPassword{ + Debug: b.config.PackerDebug, + Comm: &b.config.RunConfig.Comm, + Timeout: b.config.WindowsPasswordTimeout, + BuildName: b.config.PackerBuildName, + }, } b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) diff --git a/builder/osc/common/step_get_password.go b/builder/osc/common/step_get_password.go new file mode 100644 index 000000000..d26b9bc2f --- /dev/null +++ b/builder/osc/common/step_get_password.go @@ -0,0 +1,176 @@ +package common + +import ( + "context" + "crypto/rsa" + "crypto/x509" + "encoding/base64" + "encoding/pem" + "errors" + "fmt" + "log" + "time" + + commonhelper "github.com/hashicorp/packer/helper/common" + "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/outscale/osc-go/oapi" +) + +// StepGetPassword reads the password from a Windows server and sets it +// on the WinRM config. +type StepGetPassword struct { + Debug bool + Comm *communicator.Config + Timeout time.Duration + BuildName string +} + +func (s *StepGetPassword) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + ui := state.Get("ui").(packer.Ui) + + // Skip if we're not using winrm + if s.Comm.Type != "winrm" { + log.Printf("[INFO] Not using winrm communicator, skipping get password...") + return multistep.ActionContinue + } + + // If we already have a password, skip it + if s.Comm.WinRMPassword != "" { + ui.Say("Skipping waiting for password since WinRM password set...") + return multistep.ActionContinue + } + + // Get the password + var password string + var err error + cancel := make(chan struct{}) + waitDone := make(chan bool, 1) + go func() { + ui.Say("Waiting for auto-generated password for vm...") + ui.Message( + "It is normal for this process to take up to 15 minutes,\n" + + "but it usually takes around 5. Please wait.") + password, err = s.waitForPassword(state, cancel) + waitDone <- true + }() + + timeout := time.After(s.Timeout) +WaitLoop: + for { + // Wait for either SSH to become available, a timeout to occur, + // or an interrupt to come through. + select { + case <-waitDone: + if err != nil { + ui.Error(fmt.Sprintf("Error waiting for password: %s", err)) + state.Put("error", err) + return multistep.ActionHalt + } + + ui.Message(fmt.Sprintf(" \nPassword retrieved!")) + s.Comm.WinRMPassword = password + break WaitLoop + case <-timeout: + err := fmt.Errorf("Timeout waiting for password.") + state.Put("error", err) + ui.Error(err.Error()) + close(cancel) + return multistep.ActionHalt + case <-time.After(1 * time.Second): + if _, ok := state.GetOk(multistep.StateCancelled); ok { + // The step sequence was cancelled, so cancel waiting for password + // and just start the halting process. + close(cancel) + log.Println("[WARN] Interrupt detected, quitting waiting for password.") + return multistep.ActionHalt + } + } + } + + // In debug-mode, we output the password + if s.Debug { + ui.Message(fmt.Sprintf( + "Password (since debug is enabled): %s", s.Comm.WinRMPassword)) + } + // store so that we can access this later during provisioning + + commonhelper.SetSharedState("winrm_password", s.Comm.WinRMPassword, s.BuildName) + packer.LogSecretFilter.Set(s.Comm.WinRMPassword) + + return multistep.ActionContinue +} + +func (s *StepGetPassword) Cleanup(multistep.StateBag) { + commonhelper.RemoveSharedStateFile("winrm_password", s.BuildName) +} + +func (s *StepGetPassword) waitForPassword(state multistep.StateBag, cancel <-chan struct{}) (string, error) { + oapiconn := state.Get("oapi").(*oapi.Client) + vm := state.Get("vm").(oapi.Vm) + privateKey := s.Comm.SSHPrivateKey + + for { + select { + case <-cancel: + log.Println("[INFO] Retrieve password wait cancelled. Exiting loop.") + return "", errors.New("Retrieve password wait cancelled") + case <-time.After(5 * time.Second): + } + + resp, err := oapiconn.POST_ReadAdminPassword(oapi.ReadAdminPasswordRequest{ + VmId: vm.VmId, + }) + if err != nil { + err := fmt.Errorf("Error retrieving auto-generated vm password: %s", err) + return "", err + } + + if resp.OK.AdminPassword != "" { + decryptedPassword, err := decryptPasswordDataWithPrivateKey( + resp.OK.AdminPassword, []byte(privateKey)) + if err != nil { + err := fmt.Errorf("Error decrypting auto-generated vm password: %s", err) + return "", err + } + + return decryptedPassword, nil + } + + log.Printf("[DEBUG] Password is blank, will retry...") + } +} + +func decryptPasswordDataWithPrivateKey(passwordData string, pemBytes []byte) (string, error) { + encryptedPasswd, err := base64.StdEncoding.DecodeString(passwordData) + if err != nil { + return "", err + } + + block, _ := pem.Decode(pemBytes) + var asn1Bytes []byte + if _, ok := block.Headers["DEK-Info"]; ok { + return "", errors.New("encrypted private key isn't yet supported") + /* + asn1Bytes, err = x509.DecryptPEMBlock(block, password) + if err != nil { + return "", err + } + */ + } else { + asn1Bytes = block.Bytes + } + + key, err := x509.ParsePKCS1PrivateKey(asn1Bytes) + if err != nil { + return "", err + } + + out, err := rsa.DecryptPKCS1v15(nil, key, encryptedPasswd) + if err != nil { + return "", err + } + + return string(out), nil +} From 957bdae441ba959d5b40abf5652b67343aed2c28 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Mon, 4 Feb 2019 12:17:32 -0600 Subject: [PATCH 025/113] feature: bsusurrogate, add clean connect step --- builder/osc/bsusurrogate/builder.go | 8 +++ builder/osc/common/ssh.go | 84 +++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 builder/osc/common/ssh.go diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index 810b73dfa..85a60af3d 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -11,6 +11,7 @@ import ( osccommon "github.com/hashicorp/packer/builder/osc/common" "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" @@ -192,6 +193,13 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Timeout: b.config.WindowsPasswordTimeout, BuildName: b.config.PackerBuildName, }, + &communicator.StepConnect{ + Config: &b.config.RunConfig.Comm, + Host: osccommon.SSHHost( + oapiconn, + b.config.Comm.SSHInterface), + SSHConfig: b.config.RunConfig.Comm.SSHConfigFunc(), + }, } b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) diff --git a/builder/osc/common/ssh.go b/builder/osc/common/ssh.go new file mode 100644 index 000000000..751c3c925 --- /dev/null +++ b/builder/osc/common/ssh.go @@ -0,0 +1,84 @@ +package common + +import ( + "errors" + "fmt" + "time" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/outscale/osc-go/oapi" +) + +type oapiDescriber interface { + POST_ReadVms(oapi.ReadVmsRequest) (*oapi.POST_ReadVmsResponses, error) +} + +var ( + // modified in tests + sshHostSleepDuration = time.Second +) + +// SSHHost returns a function that can be given to the SSH communicator +// for determining the SSH address based on the vm DNS name. +func SSHHost(e oapiDescriber, sshInterface string) func(multistep.StateBag) (string, error) { + return func(state multistep.StateBag) (string, error) { + const tries = 2 + // <= with current structure to check result of describing `tries` times + for j := 0; j <= tries; j++ { + var host string + i := state.Get("vm").(oapi.Vm) + if sshInterface != "" { + switch sshInterface { + case "public_ip": + if i.PublicIp != "" { + host = i.PublicIp + } + case "private_ip": + if i.PrivateIp != "" { + host = i.PrivateIp + } + case "public_dns": + if i.PublicDnsName != "" { + host = i.PublicDnsName + } + case "private_dns": + if i.PrivateDnsName != "" { + host = i.PrivateDnsName + } + default: + panic(fmt.Sprintf("Unknown interface type: %s", sshInterface)) + } + } else if i.NetId != "" { + if i.PublicIp != "" { + host = i.PublicIp + } else if i.PrivateIp != "" { + host = i.PrivateIp + } + } else if i.PublicDnsName != "" { + host = i.PublicDnsName + } + + if host != "" { + return host, nil + } + + r, err := e.POST_ReadVms(oapi.ReadVmsRequest{ + Filters: oapi.FiltersVm{ + VmIds: []string{i.VmId}, + }, + }) + if err != nil { + return "", err + } + + if len(r.OK.Vms) == 0 { + return "", fmt.Errorf("vm not found: %s", i.VmId) + } + + state.Put("vm", r.OK.Vms[0]) + time.Sleep(sshHostSleepDuration) + } + + return "", errors.New("couldn't determine address for vm") + } +} From 3ed7c7ff3379b05de180f6e9af201718738a086f Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Mon, 4 Feb 2019 12:25:37 -0600 Subject: [PATCH 026/113] feature: bsusurrogate, add provision and cleanup temp keys step --- builder/osc/bsusurrogate/builder.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index 85a60af3d..028b06cfb 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -200,6 +200,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe b.config.Comm.SSHInterface), SSHConfig: b.config.RunConfig.Comm.SSHConfigFunc(), }, + &common.StepProvision{}, + &common.StepCleanupTempKeys{ + Comm: &b.config.RunConfig.Comm, + }, } b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) From 52962f2355e1781639d37b76c0abf0346e70d9bd Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Mon, 4 Feb 2019 12:58:26 -0600 Subject: [PATCH 027/113] feature: bsusurrogate, add stop bsu backed vm step --- builder/osc/bsusurrogate/builder.go | 4 + builder/osc/common/state.go | 6 ++ builder/osc/common/step_stop_bsu_backed_vm.go | 95 +++++++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 builder/osc/common/step_stop_bsu_backed_vm.go diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index 028b06cfb..49c804a1d 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -204,6 +204,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &common.StepCleanupTempKeys{ Comm: &b.config.RunConfig.Comm, }, + &osccommon.StepStopBSUBackedVm{ + Skip: false, + DisableStopVm: b.config.DisableStopVm, + }, } b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) diff --git a/builder/osc/common/state.go b/builder/osc/common/state.go index 67a48b2b0..cf882ad42 100644 --- a/builder/osc/common/state.go +++ b/builder/osc/common/state.go @@ -30,6 +30,12 @@ func waitUntilVmDeleted(conn *oapi.Client, vmID string) error { return <-errCh } +func waitUntilVmStopped(conn *oapi.Client, vmID string) error { + errCh := make(chan error, 1) + go waitForState(errCh, "stopped", waitUntilVmStateFunc(conn, vmID)) + return <-errCh +} + func waitForState(errCh chan<- error, target string, refresh stateRefreshFunc) error { err := common.Retry(2, 2, 0, func(_ uint) (bool, error) { state, err := refresh() diff --git a/builder/osc/common/step_stop_bsu_backed_vm.go b/builder/osc/common/step_stop_bsu_backed_vm.go new file mode 100644 index 000000000..d3b987ac6 --- /dev/null +++ b/builder/osc/common/step_stop_bsu_backed_vm.go @@ -0,0 +1,95 @@ +package common + +import ( + "context" + "fmt" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/outscale/osc-go/oapi" +) + +type StepStopBSUBackedVm struct { + Skip bool + DisableStopVm bool +} + +func (s *StepStopBSUBackedVm) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + oapiconn := state.Get("oapi").(*oapi.Client) + vm := state.Get("vm").(*oapi.Vm) + ui := state.Get("ui").(packer.Ui) + + // Skip when it is a spot vm + if s.Skip { + return multistep.ActionContinue + } + + var err error + + if !s.DisableStopVm { + // Stop the vm so we can create an AMI from it + ui.Say("Stopping the source vm...") + + // Amazon EC2 API follows an eventual consistency model. + + // This means that if you run a command to modify or describe a resource + // that you just created, its ID might not have propagated throughout + // the system, and you will get an error responding that the resource + // does not exist. + + // Work around this by retrying a few times, up to about 5 minutes. + err := common.Retry(10, 60, 6, func(i uint) (bool, error) { + ui.Message(fmt.Sprintf("Stopping vm, attempt %d", i+1)) + + _, err = oapiconn.POST_StopVms(oapi.StopVmsRequest{ + VmIds: []string{vm.VmId}, + }) + + if err == nil { + // success + return true, nil + } + + if awsErr, ok := err.(awserr.Error); ok { + if awsErr.Code() == "InvalidVmID.NotFound" { + ui.Message(fmt.Sprintf( + "Error stopping vm; will retry ..."+ + "Error: %s", err)) + // retry + return false, nil + } + } + // errored, but not in expected way. Don't want to retry + return true, err + }) + + if err != nil { + err := fmt.Errorf("Error stopping vm: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + } else { + ui.Say("Automatic vm stop disabled. Please stop vm manually.") + } + + // Wait for the vm to actually stop + ui.Say("Waiting for the vm to stop...") + err = waitUntilVmStopped(oapiconn, vm.VmId) + + if err != nil { + err := fmt.Errorf("Error waiting for vm to stop: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + return multistep.ActionContinue +} + +func (s *StepStopBSUBackedVm) Cleanup(multistep.StateBag) { + // No cleanup... +} From 09b899bb84832b1ca3387ab2af610d59f27f9db9 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Mon, 4 Feb 2019 13:08:33 -0600 Subject: [PATCH 028/113] fix: change name to keypair key path file --- builder/amazon/ebssurrogate/builder.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/amazon/ebssurrogate/builder.go b/builder/amazon/ebssurrogate/builder.go index 0c1219063..ad5126cc0 100644 --- a/builder/amazon/ebssurrogate/builder.go +++ b/builder/amazon/ebssurrogate/builder.go @@ -218,7 +218,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack &awscommon.StepKeyPair{ Debug: b.config.PackerDebug, Comm: &b.config.RunConfig.Comm, - DebugKeyPath: fmt.Sprintf("ec2_%s.pem", b.config.PackerBuildName), + DebugKeyPath: fmt.Sprintf("ec2_%s", b.config.PackerBuildName), }, &awscommon.StepSecurityGroup{ SecurityGroupFilter: b.config.SecurityGroupFilter, From 871df8be85b88f13901dd1781921b71fe0d1d7a0 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Mon, 4 Feb 2019 13:47:27 -0600 Subject: [PATCH 029/113] feature: bsusurrogate, add StepUpdateBSUBackedVm and StepSnapshotVolumes step --- builder/osc/bsusurrogate/builder.go | 9 +- .../osc/bsusurrogate/step_snapshop_volumes.go | 107 ++++++++++++++++++ builder/osc/common/state.go | 33 ++++++ builder/osc/common/step_update_bsu_vm.go | 63 +++++++++++ 4 files changed, 211 insertions(+), 1 deletion(-) create mode 100644 builder/osc/bsusurrogate/step_snapshop_volumes.go create mode 100644 builder/osc/common/step_update_bsu_vm.go diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index 49c804a1d..0ab42f9a5 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -131,7 +131,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe //VMStep //omiDevices := b.config.BuildOMIDevices() - //launchDevices := b.config.BuildLaunchDevices() + launchDevices := b.config.BuildLaunchDevices() steps := []multistep.Step{ &osccommon.StepPreValidate{ @@ -208,6 +208,13 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Skip: false, DisableStopVm: b.config.DisableStopVm, }, + &osccommon.StepUpdateBSUBackedVm{ + EnableAMISriovNetSupport: b.config.OMISriovNetSupport, + EnableAMIENASupport: b.config.OMIENASupport, + }, + &StepSnapshotVolumes{ + LaunchDevices: launchDevices, + }, } b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) diff --git a/builder/osc/bsusurrogate/step_snapshop_volumes.go b/builder/osc/bsusurrogate/step_snapshop_volumes.go new file mode 100644 index 000000000..22f3c3f45 --- /dev/null +++ b/builder/osc/bsusurrogate/step_snapshop_volumes.go @@ -0,0 +1,107 @@ +package bsusurrogate + +import ( + "context" + "fmt" + "sync" + "time" + + multierror "github.com/hashicorp/go-multierror" + osccommon "github.com/hashicorp/packer/builder/osc/common" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/outscale/osc-go/oapi" +) + +// StepSnapshotVolumes creates snapshots of the created volumes. +// +// Produces: +// snapshot_ids map[string]string - IDs of the created snapshots +type StepSnapshotVolumes struct { + LaunchDevices []oapi.BlockDeviceMappingVmCreation + snapshotIds map[string]string +} + +func (s *StepSnapshotVolumes) snapshotVolume(ctx context.Context, deviceName string, state multistep.StateBag) error { + oapiconn := state.Get("oapi").(*oapi.Client) + ui := state.Get("ui").(packer.Ui) + vm := state.Get("vm").(*oapi.Vm) + + var volumeId string + for _, volume := range vm.BlockDeviceMappings { + if volume.DeviceName == deviceName { + volumeId = volume.Bsu.VolumeId + } + } + if volumeId == "" { + return fmt.Errorf("Volume ID for device %s not found", deviceName) + } + + ui.Say(fmt.Sprintf("Creating snapshot of EBS Volume %s...", volumeId)) + description := fmt.Sprintf("Packer: %s", time.Now().String()) + + createSnapResp, err := oapiconn.POST_CreateSnapshot(oapi.CreateSnapshotRequest{ + VolumeId: volumeId, + Description: description, + }) + if err != nil { + return err + } + + // Set the snapshot ID so we can delete it later + s.snapshotIds[deviceName] = createSnapResp.OK.Snapshot.SnapshotId + + // Wait for snapshot to be created + err = osccommon.WaitUntilSnapshotCompleted(oapiconn, createSnapResp.OK.Snapshot.SnapshotId) + return err +} + +func (s *StepSnapshotVolumes) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + ui := state.Get("ui").(packer.Ui) + + s.snapshotIds = map[string]string{} + + var wg sync.WaitGroup + var errs *multierror.Error + for _, device := range s.LaunchDevices { + wg.Add(1) + go func(device oapi.BlockDeviceMappingVmCreation) { + defer wg.Done() + if err := s.snapshotVolume(ctx, device.DeviceName, state); err != nil { + errs = multierror.Append(errs, err) + } + }(device) + } + + wg.Wait() + + if errs != nil { + state.Put("error", errs) + ui.Error(errs.Error()) + return multistep.ActionHalt + } + + state.Put("snapshot_ids", s.snapshotIds) + return multistep.ActionContinue +} + +func (s *StepSnapshotVolumes) Cleanup(state multistep.StateBag) { + if len(s.snapshotIds) == 0 { + return + } + + _, cancelled := state.GetOk(multistep.StateCancelled) + _, halted := state.GetOk(multistep.StateHalted) + + if cancelled || halted { + oapiconn := state.Get("oapi").(*oapi.Client) + ui := state.Get("ui").(packer.Ui) + ui.Say("Removing snapshots since we cancelled or halted...") + for _, snapshotId := range s.snapshotIds { + _, err := oapiconn.POST_DeleteSnapshot(oapi.DeleteSnapshotRequest{SnapshotId: snapshotId}) + if err != nil { + ui.Error(fmt.Sprintf("Error: %s", err)) + } + } + } +} diff --git a/builder/osc/common/state.go b/builder/osc/common/state.go index cf882ad42..0f6c90986 100644 --- a/builder/osc/common/state.go +++ b/builder/osc/common/state.go @@ -36,6 +36,12 @@ func waitUntilVmStopped(conn *oapi.Client, vmID string) error { return <-errCh } +func WaitUntilSnapshotCompleted(conn *oapi.Client, vmID string) error { + errCh := make(chan error, 1) + go waitForState(errCh, "completed", waitUntilSnapshotStateFunc(conn, vmID)) + return <-errCh +} + func waitForState(errCh chan<- error, target string, refresh stateRefreshFunc) error { err := common.Retry(2, 2, 0, func(_ uint) (bool, error) { state, err := refresh() @@ -77,6 +83,33 @@ func waitUntilVmStateFunc(conn *oapi.Client, id string) stateRefreshFunc { } } +func waitUntilSnapshotStateFunc(conn *oapi.Client, id string) stateRefreshFunc { + return func() (string, error) { + log.Printf("[Debug] Check if Snapshot with id %s exists", id) + resp, err := conn.POST_ReadSnapshots(oapi.ReadSnapshotsRequest{ + Filters: oapi.FiltersSnapshot{ + SnapshotIds: []string{id}, + }, + }) + + log.Printf("[Debug] Read Response %+v", resp.OK) + + if err != nil { + return "", err + } + + if resp.OK == nil { + return "", fmt.Errorf("Vm with ID %s. Not Found", id) + } + + if len(resp.OK.Snapshots) == 0 { + return "pending", nil + } + + return resp.OK.Snapshots[0].State, nil + } +} + func securityGroupWaitFunc(conn *oapi.Client, id string) stateRefreshFunc { return func() (string, error) { log.Printf("[Debug] Check if SG with id %s exists", id) diff --git a/builder/osc/common/step_update_bsu_vm.go b/builder/osc/common/step_update_bsu_vm.go new file mode 100644 index 000000000..e348916a8 --- /dev/null +++ b/builder/osc/common/step_update_bsu_vm.go @@ -0,0 +1,63 @@ +package common + +import ( + "context" + + "github.com/hashicorp/packer/helper/multistep" +) + +type StepUpdateBSUBackedVm struct { + EnableAMIENASupport *bool + EnableAMISriovNetSupport bool +} + +func (s *StepUpdateBSUBackedVm) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + // oapiconn := state.Get("oapi").(*oapi.Client) + // vm := state.Get("vm").(*oapi.Vm) + // ui := state.Get("ui").(packer.Ui) + + // Set SriovNetSupport to "simple". See http://goo.gl/icuXh5 + // As of February 2017, this applies to C3, C4, D2, I2, R3, and M4 (excluding m4.16xlarge) + // if s.EnableAMISriovNetSupport { + // ui.Say("Enabling Enhanced Networking (SR-IOV)...") + // simple := "simple" + // _, err := oapiconn.POST_UpdateVm(oapi.UpdateVmRequest{ + // VmId: vm.VmId, + // SriovNetSupport: &oapi.AttributeValue{Value: &simple}, + // }) + // if err != nil { + // err := fmt.Errorf("Error enabling Enhanced Networking (SR-IOV) on %s: %s", *vm.VmId, err) + // state.Put("error", err) + // ui.Error(err.Error()) + // return multistep.ActionHalt + // } + // } + + // Handle EnaSupport flag. + // As of February 2017, this applies to C5, I3, P2, R4, X1, and m4.16xlarge + // if s.EnableAMIENASupport != nil { + // var prefix string + // if *s.EnableAMIENASupport { + // prefix = "En" + // } else { + // prefix = "Dis" + // } + // ui.Say(fmt.Sprintf("%sabling Enhanced Networking (ENA)...", prefix)) + // _, err := oapiconn.UpdateVmAttribute(&oapi.UpdateVmAttributeInput{ + // VmId: vm.VmId, + // EnaSupport: &oapi.AttributeBooleanValue{Value: aws.Bool(*s.EnableAMIENASupport)}, + // }) + // if err != nil { + // err := fmt.Errorf("Error %sabling Enhanced Networking (ENA) on %s: %s", strings.ToLower(prefix), *vm.VmId, err) + // state.Put("error", err) + // ui.Error(err.Error()) + // return multistep.ActionHalt + // } + // } + + return multistep.ActionContinue +} + +func (s *StepUpdateBSUBackedVm) Cleanup(state multistep.StateBag) { + // No cleanup... +} From 9c63f4cd92c91993db32172f5e1790bb8ae055a0 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Mon, 4 Feb 2019 16:03:59 -0600 Subject: [PATCH 030/113] feature: bsusurrogate, add DeregisterOMI step --- builder/osc/bsusurrogate/builder.go | 7 ++ builder/osc/common/step_deregister_omi.go | 110 ++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 builder/osc/common/step_deregister_omi.go diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index 0ab42f9a5..f97fc08f8 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -215,6 +215,13 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &StepSnapshotVolumes{ LaunchDevices: launchDevices, }, + &osccommon.StepDeregisterOMI{ + AccessConfig: &b.config.AccessConfig, + ForceDeregister: b.config.OMIForceDeregister, + ForceDeleteSnapshot: b.config.OMIForceDeleteSnapshot, + OMIName: b.config.OMIName, + Regions: b.config.OMIRegions, + }, } b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) diff --git a/builder/osc/common/step_deregister_omi.go b/builder/osc/common/step_deregister_omi.go new file mode 100644 index 000000000..4d735ac3d --- /dev/null +++ b/builder/osc/common/step_deregister_omi.go @@ -0,0 +1,110 @@ +package common + +import ( + "context" + "crypto/tls" + "fmt" + "net/http" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/outscale/osc-go/oapi" +) + +type StepDeregisterOMI struct { + AccessConfig *AccessConfig + ForceDeregister bool + ForceDeleteSnapshot bool + OMIName string + Regions []string +} + +func (s *StepDeregisterOMI) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + // Check for force deregister + if !s.ForceDeregister { + return multistep.ActionContinue + } + + ui := state.Get("ui").(packer.Ui) + oapiconn := state.Get("oapi").(*oapi.Client) + // Add the session region to list of regions will will deregister OMIs in + regions := append(s.Regions, oapiconn.GetConfig().Region) + + for _, region := range regions { + // get new connection for each region in which we need to deregister vms + config, err := s.AccessConfig.Config() + if err != nil { + return multistep.ActionHalt + } + + newConfig := &oapi.Config{ + UserAgent: config.UserAgent, + SecretKey: config.SecretKey, + Service: config.Service, + Region: region, //New region + URL: config.URL, + } + + skipClient := &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }, + } + + regionconn := oapi.NewClient(newConfig, skipClient) + + resp, err := regionconn.POST_ReadImages(oapi.ReadImagesRequest{ + Filters: oapi.FiltersImage{ + ImageNames: []string{s.OMIName}, + AccountAliases: []string{"self"}, + }, + }) + + if err != nil { + err := fmt.Errorf("Error describing OMI: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + // Deregister image(s) by name + for _, i := range resp.OK.Images { + //We are supposing that DeleteImage does the same action as DeregisterImage + _, err := regionconn.POST_DeleteImage(oapi.DeleteImageRequest{ + ImageId: i.ImageId, + }) + + if err != nil { + err := fmt.Errorf("Error deregistering existing OMI: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + ui.Say(fmt.Sprintf("Deregistered OMI %s, id: %s", s.OMIName, i.ImageId)) + + // Delete snapshot(s) by image + if s.ForceDeleteSnapshot { + for _, b := range i.BlockDeviceMappings { + if b.Bsu.SnapshotId != "" { + _, err := regionconn.POST_DeleteSnapshot(oapi.DeleteSnapshotRequest{ + SnapshotId: b.Bsu.SnapshotId, + }) + + if err != nil { + err := fmt.Errorf("Error deleting existing snapshot: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + ui.Say(fmt.Sprintf("Deleted snapshot: %s", b.Bsu.SnapshotId)) + } + } + } + } + } + + return multistep.ActionContinue +} + +func (s *StepDeregisterOMI) Cleanup(state multistep.StateBag) { +} From b46636a39b5d5ab46733b1e96cf680bb390d862d Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Mon, 4 Feb 2019 17:12:47 -0600 Subject: [PATCH 031/113] feature: bsusurrogate, add RegisterOMI step --- builder/osc/bsusurrogate/builder.go | 7 +- builder/osc/bsusurrogate/step_register_omi.go | 148 ++++++++++++++++++ builder/osc/common/block_device.go | 48 +++++- builder/osc/common/state.go | 41 ++++- 4 files changed, 238 insertions(+), 6 deletions(-) create mode 100644 builder/osc/bsusurrogate/step_register_omi.go diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index f97fc08f8..a0e16f00e 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -130,7 +130,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe //VMStep - //omiDevices := b.config.BuildOMIDevices() + omiDevices := b.config.BuildOMIDevices() launchDevices := b.config.BuildLaunchDevices() steps := []multistep.Step{ @@ -222,6 +222,11 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe OMIName: b.config.OMIName, Regions: b.config.OMIRegions, }, + &StepRegisterOMI{ + RootDevice: b.config.RootDevice, + OMIDevices: omiDevices, + LaunchDevices: launchDevices, + }, } b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) diff --git a/builder/osc/bsusurrogate/step_register_omi.go b/builder/osc/bsusurrogate/step_register_omi.go new file mode 100644 index 000000000..1dd4c1f00 --- /dev/null +++ b/builder/osc/bsusurrogate/step_register_omi.go @@ -0,0 +1,148 @@ +package bsusurrogate + +import ( + "context" + "fmt" + + osccommon "github.com/hashicorp/packer/builder/osc/common" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/outscale/osc-go/oapi" +) + +// StepRegisterOMI creates the OMI. +type StepRegisterOMI struct { + RootDevice RootBlockDevice + OMIDevices []oapi.BlockDeviceMappingImage + LaunchDevices []oapi.BlockDeviceMappingVmCreation + image *oapi.Image +} + +func (s *StepRegisterOMI) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + config := state.Get("config").(*Config) + oapiconn := state.Get("oapi").(*oapi.Client) + snapshotIds := state.Get("snapshot_ids").(map[string]string) + ui := state.Get("ui").(packer.Ui) + + ui.Say("Registering the OMI...") + + blockDevices := s.combineDevices(snapshotIds) + + registerOpts := oapi.CreateImageRequest{ + ImageName: config.OMIName, + Architecture: "x86_64", + RootDeviceName: s.RootDevice.DeviceName, + BlockDeviceMappings: blockDevices, + } + + registerResp, err := oapiconn.POST_CreateImage(registerOpts) + if err != nil { + state.Put("error", fmt.Errorf("Error registering OMI: %s", err)) + ui.Error(state.Get("error").(error).Error()) + return multistep.ActionHalt + } + + // Set the OMI ID in the state + ui.Say(fmt.Sprintf("OMI: %s", registerResp.OK.Image.ImageId)) + omis := make(map[string]string) + omis[oapiconn.GetConfig().Region] = registerResp.OK.Image.ImageId + state.Put("omis", omis) + + // Wait for the image to become ready + ui.Say("Waiting for OMI to become ready...") + if err := osccommon.WaitUntilImageAvailable(oapiconn, registerResp.OK.Image.ImageId); err != nil { + err := fmt.Errorf("Error waiting for OMI: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + imagesResp, err := oapiconn.POST_ReadImages(oapi.ReadImagesRequest{ + Filters: oapi.FiltersImage{ + ImageIds: []string{registerResp.OK.Image.ImageId}, + }, + }) + + if err != nil { + err := fmt.Errorf("Error searching for OMI: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + s.image = &imagesResp.OK.Images[0] + + snapshots := make(map[string][]string) + for _, blockDeviceMapping := range imagesResp.OK.Images[0].BlockDeviceMappings { + if blockDeviceMapping.Bsu.SnapshotId != "" { + snapshots[oapiconn.GetConfig().Region] = append(snapshots[oapiconn.GetConfig().Region], blockDeviceMapping.Bsu.SnapshotId) + } + } + state.Put("snapshots", snapshots) + + return multistep.ActionContinue +} + +func (s *StepRegisterOMI) Cleanup(state multistep.StateBag) { + if s.image == nil { + return + } + + _, cancelled := state.GetOk(multistep.StateCancelled) + _, halted := state.GetOk(multistep.StateHalted) + if !cancelled && !halted { + return + } + + oapiconn := state.Get("oapi").(*oapi.Client) + ui := state.Get("ui").(packer.Ui) + + ui.Say("Deregistering the OMI because cancellation or error...") + deregisterOpts := oapi.DeleteImageRequest{ImageId: s.image.ImageId} + if _, err := oapiconn.POST_DeleteImage(deregisterOpts); err != nil { + ui.Error(fmt.Sprintf("Error deregistering OMI, may still be around: %s", err)) + return + } +} + +func (s *StepRegisterOMI) combineDevices(snapshotIds map[string]string) []oapi.BlockDeviceMappingImage { + devices := map[string]oapi.BlockDeviceMappingImage{} + + for _, device := range s.OMIDevices { + devices[device.DeviceName] = device + } + + // Devices in launch_block_device_mappings override any with + // the same name in ami_block_device_mappings, except for the + // one designated as the root device in ami_root_device + for _, device := range s.LaunchDevices { + snapshotId, ok := snapshotIds[device.DeviceName] + if ok { + device.Bsu.SnapshotId = snapshotId + } + if device.DeviceName == s.RootDevice.SourceDeviceName { + device.DeviceName = s.RootDevice.DeviceName + } + devices[device.DeviceName] = copyToDeviceMappingImage(device) + } + + blockDevices := []oapi.BlockDeviceMappingImage{} + for _, device := range devices { + blockDevices = append(blockDevices, device) + } + return blockDevices +} + +func copyToDeviceMappingImage(device oapi.BlockDeviceMappingVmCreation) oapi.BlockDeviceMappingImage { + deviceImage := oapi.BlockDeviceMappingImage{ + DeviceName: device.DeviceName, + VirtualDeviceName: device.VirtualDeviceName, + Bsu: oapi.BsuToCreate{ + DeleteOnVmDeletion: device.Bsu.DeleteOnVmDeletion, + Iops: device.Bsu.Iops, + SnapshotId: device.Bsu.SnapshotId, + VolumeSize: device.Bsu.VolumeSize, + VolumeType: device.Bsu.VolumeType, + }, + } + return deviceImage +} diff --git a/builder/osc/common/block_device.go b/builder/osc/common/block_device.go index 8d6ce9535..420d112da 100644 --- a/builder/osc/common/block_device.go +++ b/builder/osc/common/block_device.go @@ -28,7 +28,7 @@ type BlockDevices struct { } type OMIBlockDevices struct { - OMIMappings []BlockDevice `mapstructure:"ami_block_device_mappings"` + OMIMappings []BlockDevice `mapstructure:"omi_block_device_mappings"` } type LaunchBlockDevices struct { @@ -83,6 +83,48 @@ func buildBlockDevices(b []BlockDevice) []*oapi.BlockDeviceMapping { return blockDevices } +func buildBlockDevicesImage(b []BlockDevice) []oapi.BlockDeviceMappingImage { + var blockDevices []oapi.BlockDeviceMappingImage + + for _, blockDevice := range b { + mapping := oapi.BlockDeviceMappingImage{ + DeviceName: blockDevice.DeviceName, + } + + if blockDevice.VirtualName != "" { + if strings.HasPrefix(blockDevice.VirtualName, "ephemeral") { + mapping.VirtualDeviceName = blockDevice.VirtualName + } + } else { + bsu := oapi.BsuToCreate{ + DeleteOnVmDeletion: blockDevice.DeleteOnVmDeletion, + } + + if blockDevice.VolumeType != "" { + bsu.VolumeType = blockDevice.VolumeType + } + + if blockDevice.VolumeSize > 0 { + bsu.VolumeSize = blockDevice.VolumeSize + } + + // IOPS is only valid for io1 type + if blockDevice.VolumeType == "io1" { + bsu.Iops = blockDevice.IOPS + } + + if blockDevice.SnapshotId != "" { + bsu.SnapshotId = blockDevice.SnapshotId + } + + mapping.Bsu = bsu + } + + blockDevices = append(blockDevices, mapping) + } + return blockDevices +} + func buildBlockDevicesVmCreation(b []BlockDevice) []oapi.BlockDeviceMappingVmCreation { var blockDevices []oapi.BlockDeviceMappingVmCreation @@ -158,8 +200,8 @@ func (b *BlockDevices) Prepare(ctx *interpolate.Context) (errs []error) { return errs } -func (b *OMIBlockDevices) BuildOMIDevices() []*oapi.BlockDeviceMapping { - return buildBlockDevices(b.OMIMappings) +func (b *OMIBlockDevices) BuildOMIDevices() []oapi.BlockDeviceMappingImage { + return buildBlockDevicesImage(b.OMIMappings) } func (b *LaunchBlockDevices) BuildLaunchDevices() []oapi.BlockDeviceMappingVmCreation { diff --git a/builder/osc/common/state.go b/builder/osc/common/state.go index 0f6c90986..ed8941268 100644 --- a/builder/osc/common/state.go +++ b/builder/osc/common/state.go @@ -36,9 +36,15 @@ func waitUntilVmStopped(conn *oapi.Client, vmID string) error { return <-errCh } -func WaitUntilSnapshotCompleted(conn *oapi.Client, vmID string) error { +func WaitUntilSnapshotCompleted(conn *oapi.Client, id string) error { errCh := make(chan error, 1) - go waitForState(errCh, "completed", waitUntilSnapshotStateFunc(conn, vmID)) + go waitForState(errCh, "completed", waitUntilSnapshotStateFunc(conn, id)) + return <-errCh +} + +func WaitUntilImageAvailable(conn *oapi.Client, imageID string) error { + errCh := make(chan error, 1) + go waitForState(errCh, "available", waitUntilImageStateFunc(conn, imageID)) return <-errCh } @@ -110,6 +116,37 @@ func waitUntilSnapshotStateFunc(conn *oapi.Client, id string) stateRefreshFunc { } } +func waitUntilImageStateFunc(conn *oapi.Client, id string) stateRefreshFunc { + return func() (string, error) { + log.Printf("[Debug] Check if Image with id %s exists", id) + resp, err := conn.POST_ReadImages(oapi.ReadImagesRequest{ + Filters: oapi.FiltersImage{ + ImageIds: []string{id}, + }, + }) + + log.Printf("[Debug] Read Response %+v", resp.OK) + + if err != nil { + return "", err + } + + if resp.OK == nil { + return "", fmt.Errorf("Vm with ID %s. Not Found", id) + } + + if len(resp.OK.Images) == 0 { + return "pending", nil + } + + if resp.OK.Images[0].State == "failed" { + return resp.OK.Images[0].State, fmt.Errorf("Image (%s) creation is failed", id) + } + + return resp.OK.Images[0].State, nil + } +} + func securityGroupWaitFunc(conn *oapi.Client, id string) stateRefreshFunc { return func() (string, error) { log.Printf("[Debug] Check if SG with id %s exists", id) From 2c4b2b8657b4bf992b33e10d4b2958c54312639c Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Tue, 5 Feb 2019 13:18:44 -0600 Subject: [PATCH 032/113] feature: bsusurrogate, add StepUpdateOMIAttributes step --- builder/osc/bsusurrogate/builder.go | 5 ++ builder/osc/common/omi_config.go | 86 ++++-------------- builder/osc/common/omi_config_test.go | 98 ++------------------ builder/osc/common/step_update_omi.go | 125 ++++++++++++++++++++++++++ 4 files changed, 154 insertions(+), 160 deletions(-) create mode 100644 builder/osc/common/step_update_omi.go diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index a0e16f00e..80f05c3f0 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -227,6 +227,11 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe OMIDevices: omiDevices, LaunchDevices: launchDevices, }, + &osccommon.StepUpdateOMIAttributes{ + AccountIds: b.config.OMIAccountIDs, + SnapshotAccountIds: b.config.SnapshotAccountIDs, + Ctx: b.config.ctx, + }, } b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) diff --git a/builder/osc/common/omi_config.go b/builder/osc/common/omi_config.go index eb09c7425..684f6fca4 100644 --- a/builder/osc/common/omi_config.go +++ b/builder/osc/common/omi_config.go @@ -10,25 +10,22 @@ import ( // OMIConfig is for common configuration related to creating OMIs. type OMIConfig struct { - OMIName string `mapstructure:"omi_name"` - OMIDescription string `mapstructure:"omi_description"` - OMIVirtType string `mapstructure:"omi_virtualization_type"` - OMIUsers []string `mapstructure:"omi_users"` - OMIGroups []string `mapstructure:"omi_groups"` - OMIProductCodes []string `mapstructure:"omi_product_codes"` - OMIRegions []string `mapstructure:"omi_regions"` - OMISkipRegionValidation bool `mapstructure:"skip_region_validation"` - OMITags TagMap `mapstructure:"tags"` - OMIENASupport *bool `mapstructure:"ena_support"` - OMISriovNetSupport bool `mapstructure:"sriov_support"` - OMIForceDeregister bool `mapstructure:"force_deregister"` - OMIForceDeleteSnapshot bool `mapstructure:"force_delete_snapshot"` - OMIEncryptBootVolume bool `mapstructure:"encrypt_boot"` - OMIKmsKeyId string `mapstructure:"kms_key_id"` - OMIRegionKMSKeyIDs map[string]string `mapstructure:"region_kms_key_ids"` - SnapshotTags TagMap `mapstructure:"snapshot_tags"` - SnapshotUsers []string `mapstructure:"snapshot_users"` - SnapshotGroups []string `mapstructure:"snapshot_groups"` + OMIName string `mapstructure:"omi_name"` + OMIDescription string `mapstructure:"omi_description"` + OMIVirtType string `mapstructure:"omi_virtualization_type"` + OMIAccountIDs []string `mapstructure:"omi_account_ids"` + OMIGroups []string `mapstructure:"omi_groups"` + OMIProductCodes []string `mapstructure:"omi_product_codes"` + OMIRegions []string `mapstructure:"omi_regions"` + OMISkipRegionValidation bool `mapstructure:"skip_region_validation"` + OMITags TagMap `mapstructure:"tags"` + OMIENASupport *bool `mapstructure:"ena_support"` + OMISriovNetSupport bool `mapstructure:"sriov_support"` + OMIForceDeregister bool `mapstructure:"force_deregister"` + OMIForceDeleteSnapshot bool `mapstructure:"force_delete_snapshot"` + SnapshotTags TagMap `mapstructure:"snapshot_tags"` + SnapshotAccountIDs []string `mapstructure:"snapshot_account_ids"` + SnapshotGroups []string `mapstructure:"snapshot_groups"` } func stringInSlice(s []string, searchstr string) bool { @@ -47,52 +44,8 @@ func (c *OMIConfig) Prepare(accessConfig *AccessConfig, ctx *interpolate.Context errs = append(errs, fmt.Errorf("omi_name must be specified")) } - // Make sure that if we have region_kms_key_ids defined, - // the regions in region_kms_key_ids are also in omi_regions - if len(c.OMIRegionKMSKeyIDs) > 0 { - for kmsKeyRegion := range c.OMIRegionKMSKeyIDs { - if !stringInSlice(c.OMIRegions, kmsKeyRegion) { - errs = append(errs, fmt.Errorf("Region %s is in region_kms_key_ids but not in omi_regions", kmsKeyRegion)) - } - } - } - errs = append(errs, c.prepareRegions(accessConfig)...) - if len(c.OMIUsers) > 0 && c.OMIEncryptBootVolume { - errs = append(errs, fmt.Errorf("Cannot share OMI with encrypted boot volume")) - } - - var kmsKeys []string - if len(c.OMIKmsKeyId) > 0 { - kmsKeys = append(kmsKeys, c.OMIKmsKeyId) - } - if len(c.OMIRegionKMSKeyIDs) > 0 { - for _, kmsKey := range c.OMIRegionKMSKeyIDs { - if len(kmsKey) == 0 { - kmsKeys = append(kmsKeys, c.OMIKmsKeyId) - } - } - } - 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.OMIKmsKeyId) == 0 && c.OMIEncryptBootVolume { - errs = append(errs, fmt.Errorf("Cannot share snapshot encrypted with default KMS key")) - } - if len(c.OMIRegionKMSKeyIDs) > 0 { - for _, kmsKey := range c.OMIRegionKMSKeyIDs { - if len(kmsKey) == 0 { - errs = append(errs, fmt.Errorf("Cannot share snapshot encrypted with default KMS key")) - } - } - } - } - if len(c.OMIName) < 3 || len(c.OMIName) > 128 { errs = append(errs, fmt.Errorf("omi_name must be between 3 and 128 characters long")) } @@ -126,13 +79,6 @@ func (c *OMIConfig) prepareRegions(accessConfig *AccessConfig) (errs []error) { // Mark that we saw the region regionSet[region] = struct{}{} - // Make sure that if we have region_kms_key_ids defined, - // the regions in omi_regions are also in region_kms_key_ids - if len(c.OMIRegionKMSKeyIDs) > 0 { - if _, ok := c.OMIRegionKMSKeyIDs[region]; !ok { - errs = append(errs, fmt.Errorf("Region %s is in omi_regions but not in region_kms_key_ids", region)) - } - } if (accessConfig != nil) && (region == accessConfig.RawRegion) { // make sure we don't try to copy to the region we originally // create the OMI in. diff --git a/builder/osc/common/omi_config_test.go b/builder/osc/common/omi_config_test.go index d52be2aae..512a93972 100644 --- a/builder/osc/common/omi_config_test.go +++ b/builder/osc/common/omi_config_test.go @@ -68,64 +68,35 @@ func TestOMIConfigPrepare_regions(t *testing.T) { } c.OMIRegions = []string{"us-east-1", "us-east-2", "us-west-1"} - c.OMIRegionKMSKeyIDs = map[string]string{ - "us-east-1": "123-456-7890", - "us-west-1": "789-012-3456", - "us-east-2": "456-789-0123", - } + if errs = c.prepareRegions(accessConf); len(errs) > 0 { t.Fatal(fmt.Sprintf("shouldn't have error: %s", errs[0])) } c.OMIRegions = []string{"us-east-1", "us-east-2", "us-west-1"} - c.OMIRegionKMSKeyIDs = map[string]string{ - "us-east-1": "123-456-7890", - "us-west-1": "789-012-3456", - "us-east-2": "", - } + if errs = c.prepareRegions(accessConf); len(errs) > 0 { t.Fatal("should have passed; we are able to use default KMS key if not sharing") } - c.SnapshotUsers = []string{"user-foo", "user-bar"} + c.SnapshotAccountIDs = []string{"user-foo", "user-bar"} c.OMIRegions = []string{"us-east-1", "us-east-2", "us-west-1"} - c.OMIRegionKMSKeyIDs = map[string]string{ - "us-east-1": "123-456-7890", - "us-west-1": "789-012-3456", - "us-east-2": "", - } + if errs = c.prepareRegions(accessConf); len(errs) > 0 { t.Fatal("should have an error b/c can't use default KMS key if sharing") } c.OMIRegions = []string{"us-east-1", "us-west-1"} - c.OMIRegionKMSKeyIDs = map[string]string{ - "us-east-1": "123-456-7890", - "us-west-1": "789-012-3456", - "us-east-2": "456-789-0123", - } + if errs = c.prepareRegions(accessConf); len(errs) > 0 { t.Fatal("should have error b/c theres a region in the key map that isn't in omi_regions") } c.OMIRegions = []string{"us-east-1", "us-west-1", "us-east-2"} - c.OMIRegionKMSKeyIDs = map[string]string{ - "us-east-1": "123-456-7890", - "us-west-1": "789-012-3456", - } - if err := c.Prepare(accessConf, nil); err == nil { - t.Fatal("should have error b/c theres a region in in omi_regions that isn't in the key map") - } - - c.SnapshotUsers = []string{"foo", "bar"} - c.OMIKmsKeyId = "123-abc-456" - c.OMIEncryptBootVolume = true + c.SnapshotAccountIDs = []string{"foo", "bar"} c.OMIRegions = []string{"us-east-1", "us-west-1"} - c.OMIRegionKMSKeyIDs = map[string]string{ - "us-east-1": "123-456-7890", - "us-west-1": "", - } + if errs = c.prepareRegions(accessConf); len(errs) > 0 { t.Fatal("should have error b/c theres a region in in omi_regions that isn't in the key map") } @@ -133,66 +104,13 @@ func TestOMIConfigPrepare_regions(t *testing.T) { // allow rawregion to exist in omi_regions list. accessConf = getFakeAccessConfig("us-east-1") c.OMIRegions = []string{"us-east-1", "us-west-1", "us-east-2"} - c.OMIRegionKMSKeyIDs = nil + if errs = c.prepareRegions(accessConf); len(errs) > 0 { t.Fatal("should allow user to have the raw region in omi_regions") } } -func TestOMIConfigPrepare_Share_EncryptedBoot(t *testing.T) { - c := testOMIConfig() - c.OMIUsers = []string{"testAccountID"} - c.OMIEncryptBootVolume = true - - accessConf := testAccessConfig() - - c.OMIKmsKeyId = "" - if err := c.Prepare(accessConf, nil); err == nil { - t.Fatal("shouldn't be able to share omi with encrypted boot volume") - } - - c.OMIKmsKeyId = "89c3fb9a-de87-4f2a-aedc-fddc5138193c" - if err := c.Prepare(accessConf, nil); err == nil { - t.Fatal("shouldn't be able to share omi with encrypted boot volume") - } -} - -func TestOMIConfigPrepare_ValidateKmsKey(t *testing.T) { - c := testOMIConfig() - c.OMIEncryptBootVolume = 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.OMIKmsKeyId = 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.OMIKmsKeyId = invalidCase - if err := c.Prepare(accessConf, nil); err == nil { - t.Fatalf("%s should have failed KMS key validation", invalidCase) - } - } - -} - func TestOMINameValidation(t *testing.T) { c := testOMIConfig() diff --git a/builder/osc/common/step_update_omi.go b/builder/osc/common/step_update_omi.go new file mode 100644 index 000000000..52aeca335 --- /dev/null +++ b/builder/osc/common/step_update_omi.go @@ -0,0 +1,125 @@ +package common + +import ( + "context" + "crypto/tls" + "fmt" + "net/http" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/hashicorp/packer/template/interpolate" + "github.com/outscale/osc-go/oapi" +) + +type StepUpdateOMIAttributes struct { + AccountIds []string + SnapshotAccountIds []string + Ctx interpolate.Context +} + +func (s *StepUpdateOMIAttributes) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + oapiconn := state.Get("oapi").(*oapi.Client) + config := state.Get("config").(*oapi.Config) + ui := state.Get("ui").(packer.Ui) + omis := state.Get("omis").(map[string]string) + snapshots := state.Get("snapshots").(map[string][]string) + + // Determine if there is any work to do. + valid := false + valid = valid || (s.AccountIds != nil && len(s.AccountIds) > 0) + valid = valid || (s.SnapshotAccountIds != nil && len(s.SnapshotAccountIds) > 0) + + if !valid { + return multistep.ActionContinue + } + + s.Ctx.Data = extractBuildInfo(oapiconn.GetConfig().Region, state) + + updateSnapshoptRequest := oapi.UpdateSnapshotRequest{ + PermissionsToCreateVolume: oapi.PermissionsOnResourceCreation{ + Additions: oapi.PermissionsOnResource{ + AccountIds: s.AccountIds, + GlobalPermission: true, + }, + }, + } + + updateImageRequest := oapi.UpdateImageRequest{ + PermissionsToLaunch: oapi.PermissionsOnResourceCreation{ + Additions: oapi.PermissionsOnResource{ + AccountIds: s.AccountIds, + GlobalPermission: true, + }, + }, + } + + // Updating image attributes + for region, omi := range omis { + ui.Say(fmt.Sprintf("Updating attributes on OMI (%s)...", omi)) + newConfig := &oapi.Config{ + UserAgent: config.UserAgent, + SecretKey: config.SecretKey, + Service: config.Service, + Region: region, //New region + URL: config.URL, + } + + skipClient := &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }, + } + + regionconn := oapi.NewClient(newConfig, skipClient) + + ui.Message(fmt.Sprintf("Updating: %s", omi)) + updateImageRequest.ImageId = omi + _, err := regionconn.POST_UpdateImage(updateImageRequest) + if err != nil { + err := fmt.Errorf("Error updating OMI: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + + // Updating snapshot attributes + for region, region_snapshots := range snapshots { + for _, snapshot := range region_snapshots { + ui.Say(fmt.Sprintf("Updating attributes on snapshot (%s)...", snapshot)) + newConfig := &oapi.Config{ + UserAgent: config.UserAgent, + SecretKey: config.SecretKey, + Service: config.Service, + Region: region, //New region + URL: config.URL, + } + + skipClient := &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }, + } + + regionconn := oapi.NewClient(newConfig, skipClient) + + ui.Message(fmt.Sprintf("Updating: %s", snapshot)) + updateSnapshoptRequest.SnapshotId = snapshot + _, err := regionconn.POST_UpdateSnapshot(updateSnapshoptRequest) + if err != nil { + err := fmt.Errorf("Error updating snapshot: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + } + } + + return multistep.ActionContinue +} + +func (s *StepUpdateOMIAttributes) Cleanup(state multistep.StateBag) { + // No cleanup... +} From 3bcebc1af6e5e641f10cd401f3e359a4561a7c53 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Tue, 5 Feb 2019 14:11:43 -0600 Subject: [PATCH 033/113] feature: bsusurrogate, add CreateTags step --- builder/osc/bsusurrogate/builder.go | 5 + builder/osc/common/step_create_tags.go | 151 +++++++++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 builder/osc/common/step_create_tags.go diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index 80f05c3f0..25a19e195 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -232,6 +232,11 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe SnapshotAccountIds: b.config.SnapshotAccountIDs, Ctx: b.config.ctx, }, + &osccommon.StepCreateTags{ + Tags: b.config.OMITags, + SnapshotTags: b.config.SnapshotTags, + Ctx: b.config.ctx, + }, } b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) diff --git a/builder/osc/common/step_create_tags.go b/builder/osc/common/step_create_tags.go new file mode 100644 index 000000000..082ee905c --- /dev/null +++ b/builder/osc/common/step_create_tags.go @@ -0,0 +1,151 @@ +package common + +import ( + "context" + "crypto/tls" + "fmt" + "net/http" + + "github.com/aws/aws-sdk-go/aws/awserr" + retry "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/hashicorp/packer/template/interpolate" + "github.com/outscale/osc-go/oapi" +) + +type StepCreateTags struct { + Tags TagMap + SnapshotTags TagMap + Ctx interpolate.Context +} + +func (s *StepCreateTags) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + oapiconn := state.Get("oapi").(*oapi.Client) + config := state.Get("config").(*oapi.Config) + ui := state.Get("ui").(packer.Ui) + amis := state.Get("amis").(map[string]string) + + if !s.Tags.IsSet() && !s.SnapshotTags.IsSet() { + return multistep.ActionContinue + } + + // Adds tags to OMIs and snapshots + for region, ami := range amis { + ui.Say(fmt.Sprintf("Adding tags to OMI (%s)...", ami)) + + newConfig := &oapi.Config{ + UserAgent: config.UserAgent, + SecretKey: config.SecretKey, + Service: config.Service, + Region: region, //New region + URL: config.URL, + } + + skipClient := &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }, + } + + regionConn := oapi.NewClient(newConfig, skipClient) + + // Retrieve image list for given OMI + resourceIds := []string{ami} + imageResp, err := regionConn.POST_ReadImages(oapi.ReadImagesRequest{ + Filters: oapi.FiltersImage{ + ImageIds: resourceIds, + }, + }) + + if err != nil { + err := fmt.Errorf("Error retrieving details for OMI (%s): %s", ami, err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + if len(imageResp.OK.Images) == 0 { + err := fmt.Errorf("Error retrieving details for OMI (%s), no images found", ami) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + image := imageResp.OK.Images[0] + snapshotIds := []string{} + + // Add only those with a Snapshot ID, i.e. not Ephemeral + for _, device := range image.BlockDeviceMappings { + if device.Bsu.SnapshotId != "" { + ui.Say(fmt.Sprintf("Tagging snapshot: %s", device.Bsu.SnapshotId)) + resourceIds = append(resourceIds, device.Bsu.SnapshotId) + snapshotIds = append(snapshotIds, device.Bsu.SnapshotId) + } + } + + // Convert tags to oapi.Tag format + ui.Say("Creating OMI tags") + amiTags, err := s.Tags.OAPITags(s.Ctx, oapiconn.GetConfig().Region, state) + if err != nil { + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + amiTags.Report(ui) + + ui.Say("Creating snapshot tags") + snapshotTags, err := s.SnapshotTags.OAPITags(s.Ctx, oapiconn.GetConfig().Region, state) + if err != nil { + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + snapshotTags.Report(ui) + + // Retry creating tags for about 2.5 minutes + err = retry.Retry(0.2, 30, 11, func(_ uint) (bool, error) { + // Tag images and snapshots + _, err := regionConn.POST_CreateTags(oapi.CreateTagsRequest{ + ResourceIds: resourceIds, + Tags: amiTags, + }) + if awsErr, ok := err.(awserr.Error); ok { + if awsErr.Code() == "InvalidOMIID.NotFound" || + awsErr.Code() == "InvalidSnapshot.NotFound" { + return false, nil + } + } + + // Override tags on snapshots + if len(snapshotTags) > 0 { + _, err = regionConn.POST_CreateTags(oapi.CreateTagsRequest{ + ResourceIds: snapshotIds, + Tags: snapshotTags, + }) + } + if err == nil { + return true, nil + } + if awsErr, ok := err.(awserr.Error); ok { + if awsErr.Code() == "InvalidSnapshot.NotFound" { + return false, nil + } + } + return true, err + }) + + if err != nil { + err := fmt.Errorf("Error adding tags to Resources (%#v): %s", resourceIds, err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + + return multistep.ActionContinue +} + +func (s *StepCreateTags) Cleanup(state multistep.StateBag) { + // No cleanup... +} From 1c69d55a1fad7f9125af6a085b3f739f372689fa Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Tue, 5 Feb 2019 14:43:46 -0600 Subject: [PATCH 034/113] feature: bsusurrogate, run implementation add artifact --- builder/osc/bsusurrogate/builder.go | 18 ++-- builder/osc/common/artifact.go | 132 +++++++++++++++++++++++++ builder/osc/common/step_create_tags.go | 2 +- builder/osc/common/step_update_omi.go | 2 +- 4 files changed, 143 insertions(+), 11 deletions(-) create mode 100644 builder/osc/common/artifact.go diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index 25a19e195..dfd182e90 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -248,16 +248,16 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe } //Build the artifact - // if omis, ok := state.GetOk("omis"); ok { - // // Build the artifact and return it - // artifact := &awscommon.Artifact{ - // Amis: omis.(map[string]string), - // BuilderIdValue: BuilderId, - // Session: session, - // } + if omis, ok := state.GetOk("omis"); ok { + // Build the artifact and return it + artifact := &osccommon.Artifact{ + Amis: omis.(map[string]string), + BuilderIdValue: BuilderId, + Config: clientConfig, + } - // return artifact, nil - // } + return artifact, nil + } return nil, nil } diff --git a/builder/osc/common/artifact.go b/builder/osc/common/artifact.go new file mode 100644 index 000000000..af22bdefe --- /dev/null +++ b/builder/osc/common/artifact.go @@ -0,0 +1,132 @@ +package common + +import ( + "crypto/tls" + "fmt" + "log" + "net/http" + "sort" + "strings" + + "github.com/hashicorp/packer/packer" + "github.com/outscale/osc-go/oapi" +) + +// Artifact is an artifact implementation that contains built OMIs. +type Artifact struct { + // A map of regions to OMI IDs. + Amis map[string]string + + // BuilderId is the unique ID for the builder that created this OMI + BuilderIdValue string + + // OAPI connection for performing API stuff. + Config *oapi.Config +} + +func (a *Artifact) BuilderId() string { + return a.BuilderIdValue +} + +func (*Artifact) Files() []string { + // We have no files + return nil +} + +func (a *Artifact) Id() string { + parts := make([]string, 0, len(a.Amis)) + for region, amiId := range a.Amis { + parts = append(parts, fmt.Sprintf("%s:%s", region, amiId)) + } + + sort.Strings(parts) + return strings.Join(parts, ",") +} + +func (a *Artifact) String() string { + amiStrings := make([]string, 0, len(a.Amis)) + for region, id := range a.Amis { + single := fmt.Sprintf("%s: %s", region, id) + amiStrings = append(amiStrings, single) + } + + sort.Strings(amiStrings) + return fmt.Sprintf("OMIs were created:\n%s\n", strings.Join(amiStrings, "\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.Amis { + log.Printf("Deregistering image ID (%s) from region (%s)", imageId, region) + + newConfig := &oapi.Config{ + UserAgent: a.Config.UserAgent, + SecretKey: a.Config.SecretKey, + Service: a.Config.Service, + Region: region, //New region + URL: a.Config.URL, + } + + skipClient := &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }, + } + + regionConn := oapi.NewClient(newConfig, skipClient) + + // Get image metadata + imageResp, err := regionConn.POST_ReadImages(oapi.ReadImagesRequest{ + Filters: oapi.FiltersImage{ + ImageIds: []string{imageId}, + }, + }) + if err != nil { + errors = append(errors, err) + } + if len(imageResp.OK.Images) == 0 { + err := fmt.Errorf("Error retrieving details for OMI (%s), no images found", imageId) + errors = append(errors, err) + } + + // Deregister ami + input := oapi.DeleteImageRequest{ + ImageId: imageId, + } + if _, err := regionConn.POST_DeleteImage(input); err != nil { + errors = append(errors, err) + } + + // TODO: Delete the snapshots associated with an OMI too + } + + if len(errors) > 0 { + if len(errors) == 1 { + return errors[0] + } else { + return &packer.MultiError{Errors: errors} + } + } + + return nil +} + +func (a *Artifact) stateAtlasMetadata() interface{} { + metadata := make(map[string]string) + for region, imageId := range a.Amis { + k := fmt.Sprintf("region.%s", region) + metadata[k] = imageId + } + + return metadata +} diff --git a/builder/osc/common/step_create_tags.go b/builder/osc/common/step_create_tags.go index 082ee905c..e3cd317de 100644 --- a/builder/osc/common/step_create_tags.go +++ b/builder/osc/common/step_create_tags.go @@ -22,7 +22,7 @@ type StepCreateTags struct { func (s *StepCreateTags) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { oapiconn := state.Get("oapi").(*oapi.Client) - config := state.Get("config").(*oapi.Config) + config := state.Get("clientConfig").(*oapi.Config) ui := state.Get("ui").(packer.Ui) amis := state.Get("amis").(map[string]string) diff --git a/builder/osc/common/step_update_omi.go b/builder/osc/common/step_update_omi.go index 52aeca335..e49068b7f 100644 --- a/builder/osc/common/step_update_omi.go +++ b/builder/osc/common/step_update_omi.go @@ -20,7 +20,7 @@ type StepUpdateOMIAttributes struct { func (s *StepUpdateOMIAttributes) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { oapiconn := state.Get("oapi").(*oapi.Client) - config := state.Get("config").(*oapi.Config) + config := state.Get("clientConfig").(*oapi.Config) ui := state.Get("ui").(packer.Ui) omis := state.Get("omis").(map[string]string) snapshots := state.Get("snapshots").(map[string][]string) From ae444a3250ccb2597284f79b4bf55ddbc7d3b1df Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Wed, 6 Feb 2019 09:31:12 -0600 Subject: [PATCH 035/113] fix: change the debugKeyPath name in osc bsusurrogate builder --- builder/osc/bsusurrogate/builder.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index dfd182e90..5df1a63b9 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -157,7 +157,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &osccommon.StepKeyPair{ Debug: b.config.PackerDebug, Comm: &b.config.RunConfig.Comm, - DebugKeyPath: fmt.Sprintf("oapi_%s.pem", b.config.PackerBuildName), + DebugKeyPath: fmt.Sprintf("oapi_%s", b.config.PackerBuildName), }, &osccommon.StepSecurityGroup{ SecurityGroupFilter: b.config.SecurityGroupFilter, From 996ee893976c2c9238df77b9c1bae948ed56abed Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Thu, 7 Feb 2019 10:33:48 -0600 Subject: [PATCH 036/113] change amis to omis in artifact --- builder/osc/bsu/builder.go | 0 builder/osc/common/artifact.go | 14 +++++++------- 2 files changed, 7 insertions(+), 7 deletions(-) create mode 100644 builder/osc/bsu/builder.go diff --git a/builder/osc/bsu/builder.go b/builder/osc/bsu/builder.go new file mode 100644 index 000000000..e69de29bb diff --git a/builder/osc/common/artifact.go b/builder/osc/common/artifact.go index af22bdefe..6174ce4fa 100644 --- a/builder/osc/common/artifact.go +++ b/builder/osc/common/artifact.go @@ -15,7 +15,7 @@ import ( // Artifact is an artifact implementation that contains built OMIs. type Artifact struct { // A map of regions to OMI IDs. - Amis map[string]string + Omis map[string]string // BuilderId is the unique ID for the builder that created this OMI BuilderIdValue string @@ -34,8 +34,8 @@ func (*Artifact) Files() []string { } func (a *Artifact) Id() string { - parts := make([]string, 0, len(a.Amis)) - for region, amiId := range a.Amis { + parts := make([]string, 0, len(a.Omis)) + for region, amiId := range a.Omis { parts = append(parts, fmt.Sprintf("%s:%s", region, amiId)) } @@ -44,8 +44,8 @@ func (a *Artifact) Id() string { } func (a *Artifact) String() string { - amiStrings := make([]string, 0, len(a.Amis)) - for region, id := range a.Amis { + amiStrings := make([]string, 0, len(a.Omis)) + for region, id := range a.Omis { single := fmt.Sprintf("%s: %s", region, id) amiStrings = append(amiStrings, single) } @@ -66,7 +66,7 @@ func (a *Artifact) State(name string) interface{} { func (a *Artifact) Destroy() error { errors := make([]error, 0) - for region, imageId := range a.Amis { + for region, imageId := range a.Omis { log.Printf("Deregistering image ID (%s) from region (%s)", imageId, region) newConfig := &oapi.Config{ @@ -123,7 +123,7 @@ func (a *Artifact) Destroy() error { func (a *Artifact) stateAtlasMetadata() interface{} { metadata := make(map[string]string) - for region, imageId := range a.Amis { + for region, imageId := range a.Omis { k := fmt.Sprintf("region.%s", region) metadata[k] = imageId } From d2d794f6dc159c4bb51636c720a91568dc5a0d5b Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Thu, 7 Feb 2019 14:55:12 -0600 Subject: [PATCH 037/113] fix: undefined variable correction --- builder/osc/bsusurrogate/builder.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index 5df1a63b9..61b7de20c 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -19,7 +19,7 @@ import ( "github.com/outscale/osc-go/oapi" ) -const BuilderId = "digitalonus.osc.bsusurrogate" +const BuilderId = "oapi.outscale.bsusurrogate" type Config struct { common.PackerConfig `mapstructure:",squash"` @@ -251,7 +251,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe if omis, ok := state.GetOk("omis"); ok { // Build the artifact and return it artifact := &osccommon.Artifact{ - Amis: omis.(map[string]string), + Omis: omis.(map[string]string), BuilderIdValue: BuilderId, Config: clientConfig, } From 91bdf5c212abd593509a3bb7405d416a47e26755 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Thu, 7 Feb 2019 14:56:47 -0600 Subject: [PATCH 038/113] feature: bsu, builder structure and test --- builder/osc/bsu/builder.go | 49 +++++++++++++++++++++++++++++++++ builder/osc/bsu/builder_test.go | 27 ++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 builder/osc/bsu/builder_test.go diff --git a/builder/osc/bsu/builder.go b/builder/osc/bsu/builder.go index e69de29bb..eccddfc30 100644 --- a/builder/osc/bsu/builder.go +++ b/builder/osc/bsu/builder.go @@ -0,0 +1,49 @@ +// The amazonebs package contains a packer.Builder implementation that +// builds OMIs for Outscale OAPI. +// +// In general, there are two types of OMIs that can be created: ebs-backed or +// instance-store. This builder _only_ builds ebs-backed images. +package bsu + +import ( + "log" + + osccommon "github.com/hashicorp/packer/builder/osc/common" + "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/hashicorp/packer/template/interpolate" +) + +// The unique ID for this builder +const BuilderId = "oapi.outscale.bsu" + +type Config struct { + common.PackerConfig `mapstructure:",squash"` + osccommon.AccessConfig `mapstructure:",squash"` + osccommon.OMIConfig `mapstructure:",squash"` + osccommon.BlockDevices `mapstructure:",squash"` + osccommon.RunConfig `mapstructure:",squash"` + VolumeRunTags osccommon.TagMap `mapstructure:"run_volume_tags"` + + ctx interpolate.Context +} + +type Builder struct { + config Config + runner multistep.Runner +} + +func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { + log.Println("[Debug] BSU Builder Prerare function") + return nil, nil +} + +func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { + log.Println("[Debug] BSU Builder Run function") + return nil, nil +} + +func (b *Builder) Cancel() { + log.Println("[Debug] BSU Builder Run function") +} diff --git a/builder/osc/bsu/builder_test.go b/builder/osc/bsu/builder_test.go new file mode 100644 index 000000000..9f91f8184 --- /dev/null +++ b/builder/osc/bsu/builder_test.go @@ -0,0 +1,27 @@ +package bsu + +import ( + "testing" + + "github.com/hashicorp/packer/packer" +) + +func testConfig() map[string]interface{} { + return map[string]interface{}{ + "access_key": "foo", + "secret_key": "bar", + "source_omi": "foo", + "vm_type": "foo", + "region": "us-east-1", + "ssh_username": "root", + "omi_name": "foo", + } +} + +func TestBuilder_ImplementsBuilder(t *testing.T) { + var raw interface{} + raw = &Builder{} + if _, ok := raw.(packer.Builder); !ok { + t.Fatalf("Builder should be a builder") + } +} From 85d601dd8100cb3a39793ae5ad633c3715710d9c Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Thu, 7 Feb 2019 16:13:35 -0600 Subject: [PATCH 039/113] feature: bsu, prepare function and test --- builder/osc/bsu/builder.go | 38 +++++++++++- builder/osc/bsu/builder_test.go | 104 ++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+), 1 deletion(-) diff --git a/builder/osc/bsu/builder.go b/builder/osc/bsu/builder.go index eccddfc30..4d27171c5 100644 --- a/builder/osc/bsu/builder.go +++ b/builder/osc/bsu/builder.go @@ -10,6 +10,7 @@ import ( osccommon "github.com/hashicorp/packer/builder/osc/common" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" @@ -35,7 +36,42 @@ type Builder struct { } func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { - log.Println("[Debug] BSU Builder Prerare function") + b.config.ctx.Funcs = osccommon.TemplateFuncs + err := config.Decode(&b.config, &config.DecodeOpts{ + Interpolate: true, + InterpolateContext: &b.config.ctx, + InterpolateFilter: &interpolate.RenderFilter{ + Exclude: []string{ + "omi_description", + "run_tags", + "run_volume_tags", + "spot_tags", + "snapshot_tags", + "tags", + }, + }, + }, raws...) + if err != nil { + return nil, err + } + + if b.config.PackerConfig.PackerForce { + b.config.OMIForceDeregister = true + } + + // Accumulate any errors + var errs *packer.MultiError + errs = packer.MultiErrorAppend(errs, b.config.AccessConfig.Prepare(&b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, + b.config.OMIConfig.Prepare(&b.config.AccessConfig, &b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, b.config.BlockDevices.Prepare(&b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare(&b.config.ctx)...) + + if errs != nil && len(errs.Errors) > 0 { + return nil, errs + } + + packer.LogSecretFilter.Set(b.config.AccessKey, b.config.SecretKey, b.config.Token) return nil, nil } diff --git a/builder/osc/bsu/builder_test.go b/builder/osc/bsu/builder_test.go index 9f91f8184..1736044df 100644 --- a/builder/osc/bsu/builder_test.go +++ b/builder/osc/bsu/builder_test.go @@ -25,3 +25,107 @@ func TestBuilder_ImplementsBuilder(t *testing.T) { t.Fatalf("Builder should be a builder") } } + +func TestBuilder_Prepare_BadType(t *testing.T) { + b := &Builder{} + c := map[string]interface{}{ + "access_key": []string{}, + } + + warnings, err := b.Prepare(c) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err == nil { + t.Fatalf("prepare should fail") + } +} + +func TestBuilderPrepare_OMIName(t *testing.T) { + var b Builder + config := testConfig() + + // Test good + config["omi_name"] = "foo" + config["skip_region_validation"] = true + warnings, err := b.Prepare(config) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + // Test bad + config["omi_name"] = "foo {{" + b = Builder{} + warnings, err = b.Prepare(config) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err == nil { + t.Fatal("should have error") + } + + // Test bad + delete(config, "omi_name") + b = Builder{} + warnings, err = b.Prepare(config) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err == nil { + t.Fatal("should have error") + } +} + +func TestBuilderPrepare_InvalidKey(t *testing.T) { + var b Builder + config := testConfig() + + // Add a random key + config["i_should_not_be_valid"] = true + warnings, err := b.Prepare(config) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err == nil { + t.Fatal("should have error") + } +} + +func TestBuilderPrepare_InvalidShutdownBehavior(t *testing.T) { + var b Builder + config := testConfig() + + // Test good + config["shutdown_behavior"] = "terminate" + config["skip_region_validation"] = true + warnings, err := b.Prepare(config) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + // Test good + config["shutdown_behavior"] = "stop" + warnings, err = b.Prepare(config) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + // Test bad + config["shutdown_behavior"] = "foobar" + warnings, err = b.Prepare(config) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err == nil { + t.Fatal("should have error") + } +} From 4c04df26fdc07e95a0668212ce984c1ab7fe15cd Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Thu, 7 Feb 2019 16:23:36 -0600 Subject: [PATCH 040/113] feature: bsu, cancel function implementation --- builder/osc/bsu/builder.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/builder/osc/bsu/builder.go b/builder/osc/bsu/builder.go index 4d27171c5..8a57a615c 100644 --- a/builder/osc/bsu/builder.go +++ b/builder/osc/bsu/builder.go @@ -81,5 +81,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe } func (b *Builder) Cancel() { - log.Println("[Debug] BSU Builder Run function") + if b.runner != nil { + log.Println("Cancelling the step runner...") + b.runner.Cancel() + } } From 1c8e9a7dd8762ea7761c12c9cb8149f7895ecd01 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Fri, 8 Feb 2019 16:41:06 -0600 Subject: [PATCH 041/113] feature: bsu, run implementation add step prevalidate --- builder/osc/bsu/builder.go | 40 +++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/builder/osc/bsu/builder.go b/builder/osc/bsu/builder.go index 8a57a615c..6995463e6 100644 --- a/builder/osc/bsu/builder.go +++ b/builder/osc/bsu/builder.go @@ -6,7 +6,9 @@ package bsu import ( + "crypto/tls" "log" + "net/http" osccommon "github.com/hashicorp/packer/builder/osc/common" "github.com/hashicorp/packer/common" @@ -14,6 +16,7 @@ import ( "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" + "github.com/outscale/osc-go/oapi" ) // The unique ID for this builder @@ -76,7 +79,42 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { } func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { - log.Println("[Debug] BSU Builder Run function") + clientConfig, err := b.config.Config() + if err != nil { + return nil, err + } + + skipClient := &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }, + } + + oapiconn := oapi.NewClient(clientConfig, skipClient) + + // Setup the state bag and initial state for the steps + state := new(multistep.BasicStateBag) + state.Put("config", &b.config) + state.Put("oapi", oapiconn) + state.Put("clientConfig", clientConfig) + state.Put("hook", hook) + state.Put("ui", ui) + + steps := []multistep.Step{ + &osccommon.StepPreValidate{ + DestOmiName: b.config.OMIName, + ForceDeregister: b.config.OMIForceDeregister, + }, + } + + b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) + b.runner.Run(state) + + // If there was an error, return that + if rawErr, ok := state.GetOk("error"); ok { + return nil, rawErr.(error) + } + return nil, nil } From 4847e79b8d9084ed6a986e53a581bb92fc8182fd Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Mon, 11 Feb 2019 09:55:47 -0600 Subject: [PATCH 042/113] feature: bsu, run implementation add steps before createOMI step --- builder/osc/bsu/builder.go | 83 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/builder/osc/bsu/builder.go b/builder/osc/bsu/builder.go index 6995463e6..550f2ad38 100644 --- a/builder/osc/bsu/builder.go +++ b/builder/osc/bsu/builder.go @@ -7,11 +7,13 @@ package bsu import ( "crypto/tls" + "fmt" "log" "net/http" osccommon "github.com/hashicorp/packer/builder/osc/common" "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" @@ -105,6 +107,87 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe DestOmiName: b.config.OMIName, ForceDeregister: b.config.OMIForceDeregister, }, + &osccommon.StepSourceOMIInfo{ + SourceOmi: b.config.SourceOmi, + EnableOMISriovNetSupport: b.config.OMISriovNetSupport, + EnableOMIENASupport: b.config.OMIENASupport, + OmiFilters: b.config.SourceOmiFilter, + OMIVirtType: b.config.OMIVirtType, //TODO: Remove if it is not used + }, + &osccommon.StepNetworkInfo{ + NetId: b.config.NetId, + NetFilter: b.config.NetFilter, + SecurityGroupIds: b.config.SecurityGroupIds, + SecurityGroupFilter: b.config.SecurityGroupFilter, + SubnetId: b.config.SubnetId, + SubnetFilter: b.config.SubnetFilter, + SubregionName: b.config.Subregion, + }, + &osccommon.StepKeyPair{ + Debug: b.config.PackerDebug, + Comm: &b.config.RunConfig.Comm, + DebugKeyPath: fmt.Sprintf("oapi_%s", b.config.PackerBuildName), + }, + &osccommon.StepSecurityGroup{ + SecurityGroupFilter: b.config.SecurityGroupFilter, + SecurityGroupIds: b.config.SecurityGroupIds, + CommConfig: &b.config.RunConfig.Comm, + TemporarySGSourceCidr: b.config.TemporarySGSourceCidr, + }, + &osccommon.StepCleanupVolumes{ + BlockDevices: b.config.BlockDevices, + }, + &osccommon.StepRunSourceVm{ + AssociatePublicIpAddress: b.config.AssociatePublicIpAddress, + BlockDevices: b.config.BlockDevices, + Comm: &b.config.RunConfig.Comm, + Ctx: b.config.ctx, + Debug: b.config.PackerDebug, + BsuOptimized: b.config.BsuOptimized, + EnableT2Unlimited: b.config.EnableT2Unlimited, + ExpectedRootDevice: "ebs", // should it be bsu + IamVmProfile: b.config.IamVmProfile, + VmInitiatedShutdownBehavior: b.config.VmInitiatedShutdownBehavior, + VmType: b.config.VmType, + IsRestricted: false, + SourceOMI: b.config.SourceOmi, + Tags: b.config.RunTags, + UserData: b.config.UserData, + UserDataFile: b.config.UserDataFile, + VolumeTags: b.config.VolumeRunTags, + }, + &osccommon.StepGetPassword{ + Debug: b.config.PackerDebug, + Comm: &b.config.RunConfig.Comm, + Timeout: b.config.WindowsPasswordTimeout, + BuildName: b.config.PackerBuildName, + }, + &communicator.StepConnect{ + Config: &b.config.RunConfig.Comm, + Host: osccommon.SSHHost( + oapiconn, + b.config.Comm.SSHInterface), + SSHConfig: b.config.RunConfig.Comm.SSHConfigFunc(), + }, + &common.StepProvision{}, + &common.StepCleanupTempKeys{ + Comm: &b.config.RunConfig.Comm, + }, + &osccommon.StepStopBSUBackedVm{ + Skip: false, + DisableStopVm: b.config.DisableStopVm, + }, + &osccommon.StepUpdateBSUBackedVm{ + EnableAMISriovNetSupport: b.config.OMISriovNetSupport, + EnableAMIENASupport: b.config.OMIENASupport, + }, + &osccommon.StepDeregisterOMI{ + AccessConfig: &b.config.AccessConfig, + ForceDeregister: b.config.OMIForceDeregister, + ForceDeleteSnapshot: b.config.OMIForceDeleteSnapshot, + OMIName: b.config.OMIName, + Regions: b.config.OMIRegions, + }, } b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) From 83c9a3d4c89a802af1a6ddf69917e8901951f981 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Mon, 11 Feb 2019 12:36:04 -0600 Subject: [PATCH 043/113] feature: bsu, run implementation add createOMI step --- builder/osc/bsu/builder.go | 1 + builder/osc/bsu/step_create_omi.go | 116 +++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 builder/osc/bsu/step_create_omi.go diff --git a/builder/osc/bsu/builder.go b/builder/osc/bsu/builder.go index 550f2ad38..3c534b206 100644 --- a/builder/osc/bsu/builder.go +++ b/builder/osc/bsu/builder.go @@ -188,6 +188,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe OMIName: b.config.OMIName, Regions: b.config.OMIRegions, }, + &stepCreateOMI{}, } b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) diff --git a/builder/osc/bsu/step_create_omi.go b/builder/osc/bsu/step_create_omi.go new file mode 100644 index 000000000..102b43a4f --- /dev/null +++ b/builder/osc/bsu/step_create_omi.go @@ -0,0 +1,116 @@ +package bsu + +import ( + "context" + "fmt" + "log" + + osccommon "github.com/hashicorp/packer/builder/osc/common" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/outscale/osc-go/oapi" +) + +type stepCreateOMI struct { + image *oapi.Image +} + +func (s *stepCreateOMI) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + config := state.Get("config").(*Config) + oapiconn := state.Get("oapi").(*oapi.Client) + vm := state.Get("vm").(*oapi.Vm) + ui := state.Get("ui").(packer.Ui) + + // Create the image + omiName := config.OMIName + + ui.Say(fmt.Sprintf("Creating unencrypted OMI %s from vm %s", omiName, vm.VmId)) + createOpts := oapi.CreateImageRequest{ + VmId: vm.VmId, + ImageName: omiName, + BlockDeviceMappings: config.BlockDevices.BuildOMIDevices(), + } + + resp, err := oapiconn.POST_CreateImage(createOpts) + if err != nil || resp.OK == nil { + err := fmt.Errorf("Error creating OMI: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + image := resp.OK.Image + + // Set the OMI ID in the state + ui.Message(fmt.Sprintf("OMI: %s", image.ImageId)) + omis := make(map[string]string) + omis[oapiconn.GetConfig().Region] = image.ImageId + state.Put("omis", omis) + + // Wait for the image to become ready + ui.Say("Waiting for OMI to become ready...") + if err := osccommon.WaitUntilImageAvailable(oapiconn, image.ImageId); err != nil { + log.Printf("Error waiting for OMI: %s", err) + imagesResp, err := oapiconn.POST_ReadImages(oapi.ReadImagesRequest{ + Filters: oapi.FiltersImage{ + ImageIds: []string{image.ImageId}, + }, + }) + if err != nil { + log.Printf("Unable to determine reason waiting for OMI failed: %s", err) + err = fmt.Errorf("Unknown error waiting for OMI.") + } else { + stateReason := imagesResp.OK.Images[0].StateComment + err = fmt.Errorf("Error waiting for OMI. Reason: %s", stateReason) + } + + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + imagesResp, err := oapiconn.POST_ReadImages(oapi.ReadImagesRequest{ + Filters: oapi.FiltersImage{ + ImageIds: []string{image.ImageId}, + }, + }) + if err != nil { + err := fmt.Errorf("Error searching for OMI: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + s.image = &imagesResp.OK.Images[0] + + snapshots := make(map[string][]string) + for _, blockDeviceMapping := range imagesResp.OK.Images[0].BlockDeviceMappings { + if blockDeviceMapping.Bsu.SnapshotId != "" { + snapshots[oapiconn.GetConfig().Region] = append(snapshots[oapiconn.GetConfig().Region], blockDeviceMapping.Bsu.SnapshotId) + } + } + state.Put("snapshots", snapshots) + + return multistep.ActionContinue +} + +func (s *stepCreateOMI) Cleanup(state multistep.StateBag) { + if s.image == nil { + return + } + + _, cancelled := state.GetOk(multistep.StateCancelled) + _, halted := state.GetOk(multistep.StateHalted) + if !cancelled && !halted { + return + } + + oapiconn := state.Get("oapi").(*oapi.Client) + ui := state.Get("ui").(packer.Ui) + + ui.Say("Deregistering the OMI because cancellation or error...") + DeleteOpts := oapi.DeleteImageRequest{ImageId: s.image.ImageId} + if _, err := oapiconn.POST_DeleteImage(DeleteOpts); err != nil { + ui.Error(fmt.Sprintf("Error Deleting OMI, may still be around: %s", err)) + return + } +} From 972dcc2b2512bda8cf95c9198d08b7744aae7477 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Mon, 11 Feb 2019 12:51:05 -0600 Subject: [PATCH 044/113] feature: bsu, run implementation add steps after createOMI step --- builder/osc/bsu/builder.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/builder/osc/bsu/builder.go b/builder/osc/bsu/builder.go index 3c534b206..833017dd3 100644 --- a/builder/osc/bsu/builder.go +++ b/builder/osc/bsu/builder.go @@ -189,6 +189,16 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Regions: b.config.OMIRegions, }, &stepCreateOMI{}, + &osccommon.StepUpdateOMIAttributes{ + AccountIds: b.config.OMIAccountIDs, + SnapshotAccountIds: b.config.SnapshotAccountIDs, + Ctx: b.config.ctx, + }, + &osccommon.StepCreateTags{ + Tags: b.config.OMITags, + SnapshotTags: b.config.SnapshotTags, + Ctx: b.config.ctx, + }, } b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) From 4779b028f1f3669264d57d4671a36b87f94d4ae1 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Mon, 11 Feb 2019 15:11:14 -0600 Subject: [PATCH 045/113] feature: bsu, run implementation add artifact --- builder/osc/bsu/builder.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/builder/osc/bsu/builder.go b/builder/osc/bsu/builder.go index 833017dd3..1a08fdbc1 100644 --- a/builder/osc/bsu/builder.go +++ b/builder/osc/bsu/builder.go @@ -209,6 +209,18 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe return nil, rawErr.(error) } + //Build the artifact + if omis, ok := state.GetOk("omis"); !ok { + // Build the artifact and return it + artifact := &osccommon.Artifact{ + Omis: omis.(map[string]string), + BuilderIdValue: BuilderId, + Config: clientConfig, + } + + return artifact, nil + } + return nil, nil } From c4e69d31691ed4e791589c6e3212d76af151985c Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Mon, 11 Feb 2019 16:43:16 -0600 Subject: [PATCH 046/113] wip: add bsu plugin acc testing --- builder/osc/bsu/builder_acc_test.go | 55 ++++++++++++++++++++++ builder/osc/common/step_source_omi_info.go | 4 +- command/plugin.go | 2 + 3 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 builder/osc/bsu/builder_acc_test.go diff --git a/builder/osc/bsu/builder_acc_test.go b/builder/osc/bsu/builder_acc_test.go new file mode 100644 index 000000000..441820e8d --- /dev/null +++ b/builder/osc/bsu/builder_acc_test.go @@ -0,0 +1,55 @@ +/* +Deregister the test image with +aws oapi deregister-image --image-id $(aws oapi describe-images --output text --filters "Name=name,Values=packer-test-packer-test-dereg" --query 'Images[*].{ID:ImageId}') +*/ +package bsu + +import ( + "crypto/tls" + "net/http" + "testing" + + "github.com/hashicorp/packer/builder/osc/common" + builderT "github.com/hashicorp/packer/helper/builder/testing" + "github.com/outscale/osc-go/oapi" +) + +func TestBuilderAcc_basic(t *testing.T) { + builderT.Test(t, builderT.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Builder: &Builder{}, + Template: testBuilderAccBasic, + }) +} + +func testAccPreCheck(t *testing.T) { +} + +func testOAPIConn() (*oapi.Client, error) { + access := &common.AccessConfig{RawRegion: "us-east-1"} + clientConfig, err := access.Config() + if err != nil { + return nil, err + } + + skipClient := &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }, + } + + return oapi.NewClient(clientConfig, skipClient), nil +} + +const testBuilderAccBasic = ` +{ + "builders": [{ + "type": "test", + "region": "eu-west-2", + "vm_type": "m3.medium", + "source_omi": "omi-76b2a71e", + "ssh_username": "ubuntu", + "omi_name": "packer-test {{timestamp}}" + }] +} +` diff --git a/builder/osc/common/step_source_omi_info.go b/builder/osc/common/step_source_omi_info.go index 05c9e7d41..f602b5cc7 100644 --- a/builder/osc/common/step_source_omi_info.go +++ b/builder/osc/common/step_source_omi_info.go @@ -63,7 +63,7 @@ func (s *StepSourceOMIInfo) Run(_ context.Context, state multistep.StateBag) mul params.Filters.AccountIds = s.OmiFilters.Owners } - log.Printf("Using OMI Filters %v", params) + log.Printf("Using OMI Filters %#v", params) imageResp, err := oapiconn.POST_ReadImages(params) if err != nil { err := fmt.Errorf("Error querying OMI: %s", err) @@ -73,7 +73,7 @@ func (s *StepSourceOMIInfo) Run(_ context.Context, state multistep.StateBag) mul } if len(imageResp.OK.Images) == 0 { - err := fmt.Errorf("No OMI was found matching filters: %v", params) + err := fmt.Errorf("No OMI was found matching filters: %#v", params) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt diff --git a/command/plugin.go b/command/plugin.go index 627c45375..e44708122 100644 --- a/command/plugin.go +++ b/command/plugin.go @@ -38,6 +38,7 @@ import ( openstackbuilder "github.com/hashicorp/packer/builder/openstack" oracleclassicbuilder "github.com/hashicorp/packer/builder/oracle/classic" oracleocibuilder "github.com/hashicorp/packer/builder/oracle/oci" + oscbsubuilder "github.com/hashicorp/packer/builder/osc/bsu" oscbsusurrogatebuilder "github.com/hashicorp/packer/builder/osc/bsusurrogate" parallelsisobuilder "github.com/hashicorp/packer/builder/parallels/iso" parallelspvmbuilder "github.com/hashicorp/packer/builder/parallels/pvm" @@ -122,6 +123,7 @@ var Builders = map[string]packer.Builder{ "openstack": new(openstackbuilder.Builder), "oracle-classic": new(oracleclassicbuilder.Builder), "oracle-oci": new(oracleocibuilder.Builder), + "osc-bsu": new(oscbsubuilder.Builder), "osc-bsusurrogate": new(oscbsusurrogatebuilder.Builder), "parallels-iso": new(parallelsisobuilder.Builder), "parallels-pvm": new(parallelspvmbuilder.Builder), From a4966d9823ae11ec4aad039b7181e05e04a7e9ec Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Tue, 12 Feb 2019 15:12:19 -0600 Subject: [PATCH 047/113] add ExpectedRunDevice constant --- builder/osc/bsu/builder.go | 2 +- builder/osc/bsu/builder_acc_test.go | 2 +- builder/osc/bsusurrogate/builder.go | 2 +- builder/osc/common/step_run_source_vm.go | 4 ++++ 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/builder/osc/bsu/builder.go b/builder/osc/bsu/builder.go index 1a08fdbc1..f0d804d37 100644 --- a/builder/osc/bsu/builder.go +++ b/builder/osc/bsu/builder.go @@ -145,7 +145,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Debug: b.config.PackerDebug, BsuOptimized: b.config.BsuOptimized, EnableT2Unlimited: b.config.EnableT2Unlimited, - ExpectedRootDevice: "ebs", // should it be bsu + ExpectedRootDevice: osccommon.RunSourceVmBSUExpectedRootDevice, IamVmProfile: b.config.IamVmProfile, VmInitiatedShutdownBehavior: b.config.VmInitiatedShutdownBehavior, VmType: b.config.VmType, diff --git a/builder/osc/bsu/builder_acc_test.go b/builder/osc/bsu/builder_acc_test.go index 441820e8d..900c640bf 100644 --- a/builder/osc/bsu/builder_acc_test.go +++ b/builder/osc/bsu/builder_acc_test.go @@ -47,7 +47,7 @@ const testBuilderAccBasic = ` "type": "test", "region": "eu-west-2", "vm_type": "m3.medium", - "source_omi": "omi-76b2a71e", + "source_omi": "ami-76b2a71e", "ssh_username": "ubuntu", "omi_name": "packer-test {{timestamp}}" }] diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index 61b7de20c..1649fcede 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -176,7 +176,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Debug: b.config.PackerDebug, BsuOptimized: b.config.BsuOptimized, EnableT2Unlimited: b.config.EnableT2Unlimited, - ExpectedRootDevice: "ebs", // should it be bsu + ExpectedRootDevice: osccommon.RunSourceVmBSUExpectedRootDevice, IamVmProfile: b.config.IamVmProfile, VmInitiatedShutdownBehavior: b.config.VmInitiatedShutdownBehavior, VmType: b.config.VmType, diff --git a/builder/osc/common/step_run_source_vm.go b/builder/osc/common/step_run_source_vm.go index 0251c759e..38e175a0d 100644 --- a/builder/osc/common/step_run_source_vm.go +++ b/builder/osc/common/step_run_source_vm.go @@ -18,6 +18,10 @@ import ( "github.com/hashicorp/packer/template/interpolate" ) +const ( + RunSourceVmBSUExpectedRootDevice = "ebs" +) + type StepRunSourceVm struct { AssociatePublicIpAddress bool BlockDevices BlockDevices From 52621a3dd20bea1e5d894ec54c381d6f507b7c7b Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Tue, 12 Feb 2019 15:15:38 -0600 Subject: [PATCH 048/113] chore: remove unencrypted work in log when image is creating --- builder/osc/bsu/step_create_omi.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/osc/bsu/step_create_omi.go b/builder/osc/bsu/step_create_omi.go index 102b43a4f..8c6d73aa0 100644 --- a/builder/osc/bsu/step_create_omi.go +++ b/builder/osc/bsu/step_create_omi.go @@ -24,7 +24,7 @@ func (s *stepCreateOMI) Run(ctx context.Context, state multistep.StateBag) multi // Create the image omiName := config.OMIName - ui.Say(fmt.Sprintf("Creating unencrypted OMI %s from vm %s", omiName, vm.VmId)) + ui.Say(fmt.Sprintf("Creating OMI %s from vm %s", omiName, vm.VmId)) createOpts := oapi.CreateImageRequest{ VmId: vm.VmId, ImageName: omiName, From 6e6e51809536443f37f3443181e59fa7ccddec36 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Wed, 13 Feb 2019 11:32:48 -0600 Subject: [PATCH 049/113] fix: change image id on bsu acceptance test --- builder/osc/bsu/builder_acc_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/osc/bsu/builder_acc_test.go b/builder/osc/bsu/builder_acc_test.go index 900c640bf..7a2de6611 100644 --- a/builder/osc/bsu/builder_acc_test.go +++ b/builder/osc/bsu/builder_acc_test.go @@ -47,7 +47,7 @@ const testBuilderAccBasic = ` "type": "test", "region": "eu-west-2", "vm_type": "m3.medium", - "source_omi": "ami-76b2a71e", + "source_omi": "ami-46260446", "ssh_username": "ubuntu", "omi_name": "packer-test {{timestamp}}" }] From 0c47ee55e6820e55346303e75c5f9a35148c1654 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Fri, 15 Feb 2019 11:41:36 -0600 Subject: [PATCH 050/113] feature: add chroot builder structure --- builder/osc/chroot/builder.go | 53 +++++++++++++++++++++++++++++++++++ command/plugin.go | 2 ++ 2 files changed, 55 insertions(+) create mode 100644 builder/osc/chroot/builder.go diff --git a/builder/osc/chroot/builder.go b/builder/osc/chroot/builder.go new file mode 100644 index 000000000..532a7d6a5 --- /dev/null +++ b/builder/osc/chroot/builder.go @@ -0,0 +1,53 @@ +// The chroot package is able to create an Outscale OMI without requiring +// the launch of a new instance for every build. It does this by attaching +// and mounting the root volume of another OMI and chrooting into that +// directory. It then creates an OMI from that attached drive. +package chroot + +import ( + "errors" + "runtime" + + osccommon "github.com/hashicorp/packer/builder/osc/common" + "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/hashicorp/packer/template/interpolate" +) + +// The unique ID for this builder +const BuilderId = "oapi.outscale.chroot" + +// Config is the configuration that is chained through the steps and +// settable from the template. +type Config struct { + common.PackerConfig `mapstructure:",squash"` + osccommon.OMIBlockDevices `mapstructure:",squash"` + osccommon.OMIConfig `mapstructure:",squash"` + osccommon.AccessConfig `mapstructure:",squash"` + + ctx interpolate.Context +} + +type wrappedCommandTemplate struct { + Command string +} + +type Builder struct { + config Config + runner multistep.Runner +} + +func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { + return nil, nil +} + +func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { + if runtime.GOOS != "linux" { + return nil, errors.New("The outscale-chroot builder only works on Linux environments.") + } + return nil, nil +} + +func (b *Builder) Cancel() { +} diff --git a/command/plugin.go b/command/plugin.go index e44708122..cfe9c417d 100644 --- a/command/plugin.go +++ b/command/plugin.go @@ -40,6 +40,7 @@ import ( oracleocibuilder "github.com/hashicorp/packer/builder/oracle/oci" oscbsubuilder "github.com/hashicorp/packer/builder/osc/bsu" oscbsusurrogatebuilder "github.com/hashicorp/packer/builder/osc/bsusurrogate" + oscchrootbuilder "github.com/hashicorp/packer/builder/osc/chroot" parallelsisobuilder "github.com/hashicorp/packer/builder/parallels/iso" parallelspvmbuilder "github.com/hashicorp/packer/builder/parallels/pvm" profitbricksbuilder "github.com/hashicorp/packer/builder/profitbricks" @@ -125,6 +126,7 @@ var Builders = map[string]packer.Builder{ "oracle-oci": new(oracleocibuilder.Builder), "osc-bsu": new(oscbsubuilder.Builder), "osc-bsusurrogate": new(oscbsusurrogatebuilder.Builder), + "osc-chroot": new(oscchrootbuilder.Builder), "parallels-iso": new(parallelsisobuilder.Builder), "parallels-pvm": new(parallelspvmbuilder.Builder), "profitbricks": new(profitbricksbuilder.Builder), From 30d5b1f7c2fb684371284ca1910589ab913cc719 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Fri, 15 Feb 2019 11:44:46 -0600 Subject: [PATCH 051/113] feature: add chroot builder configuration --- builder/osc/chroot/builder.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/builder/osc/chroot/builder.go b/builder/osc/chroot/builder.go index 532a7d6a5..69cc31cf6 100644 --- a/builder/osc/chroot/builder.go +++ b/builder/osc/chroot/builder.go @@ -26,6 +26,24 @@ type Config struct { osccommon.OMIConfig `mapstructure:",squash"` osccommon.AccessConfig `mapstructure:",squash"` + ChrootMounts [][]string `mapstructure:"chroot_mounts"` + CommandWrapper string `mapstructure:"command_wrapper"` + CopyFiles []string `mapstructure:"copy_files"` + DevicePath string `mapstructure:"device_path"` + NVMEDevicePath string `mapstructure:"nvme_device_path"` + FromScratch bool `mapstructure:"from_scratch"` + MountOptions []string `mapstructure:"mount_options"` + MountPartition string `mapstructure:"mount_partition"` + MountPath string `mapstructure:"mount_path"` + PostMountCommands []string `mapstructure:"post_mount_commands"` + PreMountCommands []string `mapstructure:"pre_mount_commands"` + RootDeviceName string `mapstructure:"root_device_name"` + RootVolumeSize int64 `mapstructure:"root_volume_size"` + RootVolumeType string `mapstructure:"root_volume_type"` + SourceOMI string `mapstructure:"source_omi"` + SourceOMIFilter osccommon.OmiFilterOptions `mapstructure:"source_omi_filter"` + RootVolumeTags osccommon.TagMap `mapstructure:"root_volume_tags"` + ctx interpolate.Context } From 0d5ce8b9b9876141249c7037afb82a3cd042a669 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Fri, 15 Feb 2019 11:45:19 -0600 Subject: [PATCH 052/113] feature: add chroot build cancel function implementation --- builder/osc/chroot/builder.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/builder/osc/chroot/builder.go b/builder/osc/chroot/builder.go index 69cc31cf6..094eb5de2 100644 --- a/builder/osc/chroot/builder.go +++ b/builder/osc/chroot/builder.go @@ -6,6 +6,7 @@ package chroot import ( "errors" + "log" "runtime" osccommon "github.com/hashicorp/packer/builder/osc/common" @@ -68,4 +69,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe } func (b *Builder) Cancel() { + if b.runner != nil { + log.Println("Cancelling the step runner...") + b.runner.Cancel() + } } From 2f87427fd4e2fe1dcbd354f4241d1b5c6f5122ac Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Fri, 15 Feb 2019 14:52:41 -0600 Subject: [PATCH 053/113] feature: add chroot build prepare function implementation --- builder/osc/chroot/builder.go | 121 +++++++++++++++++++++++++++++++++- 1 file changed, 120 insertions(+), 1 deletion(-) diff --git a/builder/osc/chroot/builder.go b/builder/osc/chroot/builder.go index 094eb5de2..2feb8083e 100644 --- a/builder/osc/chroot/builder.go +++ b/builder/osc/chroot/builder.go @@ -11,6 +11,7 @@ import ( osccommon "github.com/hashicorp/packer/builder/osc/common" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" @@ -58,7 +59,125 @@ type Builder struct { } func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { - return nil, nil + b.config.ctx.Funcs = osccommon.TemplateFuncs + err := config.Decode(&b.config, &config.DecodeOpts{ + Interpolate: true, + InterpolateContext: &b.config.ctx, + InterpolateFilter: &interpolate.RenderFilter{ + Exclude: []string{ + "omi_description", + "snapshot_tags", + "tags", + "root_volume_tags", + "command_wrapper", + "post_mount_commands", + "pre_mount_commands", + "mount_path", + }, + }, + }, raws...) + if err != nil { + return nil, err + } + + if b.config.PackerConfig.PackerForce { + b.config.OMIForceDeregister = true + } + + // Defaults + if b.config.ChrootMounts == nil { + b.config.ChrootMounts = make([][]string, 0) + } + + if len(b.config.ChrootMounts) == 0 { + b.config.ChrootMounts = [][]string{ + {"proc", "proc", "/proc"}, + {"sysfs", "sysfs", "/sys"}, + {"bind", "/dev", "/dev"}, + {"devpts", "devpts", "/dev/pts"}, + {"binfmt_misc", "binfmt_misc", "/proc/sys/fs/binfmt_misc"}, + } + } + + // set default copy file if we're not giving our own + if b.config.CopyFiles == nil { + b.config.CopyFiles = make([]string, 0) + if !b.config.FromScratch { + b.config.CopyFiles = []string{"/etc/resolv.conf"} + } + } + + if b.config.CommandWrapper == "" { + b.config.CommandWrapper = "{{.Command}}" + } + + if b.config.MountPath == "" { + b.config.MountPath = "/mnt/packer-outscale-chroot-volumes/{{.Device}}" + } + + if b.config.MountPartition == "" { + b.config.MountPartition = "1" + } + + // Accumulate any errors or warnings + var errs *packer.MultiError + var warns []string + + errs = packer.MultiErrorAppend(errs, b.config.AccessConfig.Prepare(&b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, + b.config.OMIConfig.Prepare(&b.config.AccessConfig, &b.config.ctx)...) + + for _, mounts := range b.config.ChrootMounts { + if len(mounts) != 3 { + errs = packer.MultiErrorAppend( + errs, errors.New("Each chroot_mounts entry should be three elements.")) + break + } + } + + if b.config.FromScratch { + if b.config.SourceOMI != "" || !b.config.SourceOMIFilter.Empty() { + warns = append(warns, "source_omi and source_omi_filter are unused when from_scratch is true") + } + if b.config.RootVolumeSize == 0 { + errs = packer.MultiErrorAppend( + errs, errors.New("root_volume_size is required with from_scratch.")) + } + if len(b.config.PreMountCommands) == 0 { + errs = packer.MultiErrorAppend( + errs, errors.New("pre_mount_commands is required with from_scratch.")) + } + if b.config.OMIVirtType == "" { + errs = packer.MultiErrorAppend( + errs, errors.New("omi_virtualization_type is required with from_scratch.")) + } + if b.config.RootDeviceName == "" { + errs = packer.MultiErrorAppend( + errs, errors.New("root_device_name is required with from_scratch.")) + } + if len(b.config.OMIMappings) == 0 { + errs = packer.MultiErrorAppend( + errs, errors.New("omi_block_device_mappings is required with from_scratch.")) + } + } else { + if b.config.SourceOMI == "" && b.config.SourceOMIFilter.Empty() { + errs = packer.MultiErrorAppend( + errs, errors.New("source_omi or source_omi_filter is required.")) + } + if len(b.config.OMIMappings) != 0 { + warns = append(warns, "omi_block_device_mappings are unused when from_scratch is false") + } + if b.config.RootDeviceName != "" { + warns = append(warns, "root_device_name is unused when from_scratch is false") + } + } + + if errs != nil && len(errs.Errors) > 0 { + return warns, errs + } + + packer.LogSecretFilter.Set(b.config.AccessKey, b.config.SecretKey, b.config.Token) + return warns, nil } func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { From e8ef12e41c600e5a74901c1c08ca9adae3988a5e Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Wed, 20 Feb 2019 18:41:47 -0600 Subject: [PATCH 054/113] test: fix unit test in block device security group and build info --- builder/osc/common/block_device_test.go | 188 +++++++++++++++--- .../osc/common/interpolate_build_info_test.go | 4 +- builder/osc/common/step_security_group.go | 2 +- 3 files changed, 164 insertions(+), 30 deletions(-) diff --git a/builder/osc/common/block_device_test.go b/builder/osc/common/block_device_test.go index c6489359a..144b91f31 100644 --- a/builder/osc/common/block_device_test.go +++ b/builder/osc/common/block_device_test.go @@ -7,10 +7,10 @@ import ( "github.com/outscale/osc-go/oapi" ) -func TestBlockDevice(t *testing.T) { +func TestBlockDevice_LaunchDevices(t *testing.T) { cases := []struct { Config *BlockDevice - Result *oapi.BlockDeviceMapping + Result oapi.BlockDeviceMappingVmCreation }{ { Config: &BlockDevice{ @@ -21,9 +21,9 @@ func TestBlockDevice(t *testing.T) { DeleteOnVmDeletion: true, }, - Result: &oapi.BlockDeviceMapping{ + Result: oapi.BlockDeviceMappingVmCreation{ DeviceName: "/dev/sdb", - Bsu: oapi.Bsu{ + Bsu: oapi.BsuToCreate{ SnapshotId: "snap-1234", VolumeType: "standard", VolumeSize: 8, @@ -37,9 +37,9 @@ func TestBlockDevice(t *testing.T) { VolumeSize: 8, }, - Result: &oapi.BlockDeviceMapping{ + Result: oapi.BlockDeviceMappingVmCreation{ DeviceName: "/dev/sdb", - Bsu: oapi.Bsu{ + Bsu: oapi.BsuToCreate{ VolumeSize: 8, DeleteOnVmDeletion: false, }, @@ -54,9 +54,9 @@ func TestBlockDevice(t *testing.T) { IOPS: 1000, }, - Result: &oapi.BlockDeviceMapping{ + Result: oapi.BlockDeviceMappingVmCreation{ DeviceName: "/dev/sdb", - Bsu: oapi.Bsu{ + Bsu: oapi.BsuToCreate{ VolumeType: "io1", VolumeSize: 8, DeleteOnVmDeletion: true, @@ -72,9 +72,9 @@ func TestBlockDevice(t *testing.T) { DeleteOnVmDeletion: true, }, - Result: &oapi.BlockDeviceMapping{ + Result: oapi.BlockDeviceMappingVmCreation{ DeviceName: "/dev/sdb", - Bsu: oapi.Bsu{ + Bsu: oapi.BsuToCreate{ VolumeType: "gp2", VolumeSize: 8, DeleteOnVmDeletion: true, @@ -89,9 +89,9 @@ func TestBlockDevice(t *testing.T) { DeleteOnVmDeletion: true, }, - Result: &oapi.BlockDeviceMapping{ + Result: oapi.BlockDeviceMappingVmCreation{ DeviceName: "/dev/sdb", - Bsu: oapi.Bsu{ + Bsu: oapi.BsuToCreate{ VolumeType: "gp2", VolumeSize: 8, DeleteOnVmDeletion: true, @@ -105,9 +105,9 @@ func TestBlockDevice(t *testing.T) { DeleteOnVmDeletion: true, }, - Result: &oapi.BlockDeviceMapping{ + Result: oapi.BlockDeviceMappingVmCreation{ DeviceName: "/dev/sdb", - Bsu: oapi.Bsu{ + Bsu: oapi.BsuToCreate{ VolumeType: "standard", DeleteOnVmDeletion: true, }, @@ -119,7 +119,7 @@ func TestBlockDevice(t *testing.T) { VirtualName: "ephemeral0", }, - Result: &oapi.BlockDeviceMapping{ + Result: oapi.BlockDeviceMappingVmCreation{ DeviceName: "/dev/sdb", VirtualDeviceName: "ephemeral0", }, @@ -130,34 +130,168 @@ func TestBlockDevice(t *testing.T) { NoDevice: true, }, - Result: &oapi.BlockDeviceMapping{ + Result: oapi.BlockDeviceMappingVmCreation{ DeviceName: "/dev/sdb", NoDevice: "", }, }, } + for _, tc := range cases { + + launchBlockDevices := LaunchBlockDevices{ + LaunchMappings: []BlockDevice{*tc.Config}, + } + + expected := []oapi.BlockDeviceMappingVmCreation{tc.Result} + + launchResults := launchBlockDevices.BuildLaunchDevices() + if !reflect.DeepEqual(expected, launchResults) { + t.Fatalf("Bad block device, \nexpected: %#v\n\ngot: %#v", + expected, launchResults) + } + } +} + +func TestBlockDevice_OMI(t *testing.T) { + cases := []struct { + Config *BlockDevice + Result oapi.BlockDeviceMappingImage + }{ + { + Config: &BlockDevice{ + DeviceName: "/dev/sdb", + SnapshotId: "snap-1234", + VolumeType: "standard", + VolumeSize: 8, + DeleteOnVmDeletion: true, + }, + + Result: oapi.BlockDeviceMappingImage{ + DeviceName: "/dev/sdb", + Bsu: oapi.BsuToCreate{ + SnapshotId: "snap-1234", + VolumeType: "standard", + VolumeSize: 8, + DeleteOnVmDeletion: true, + }, + }, + }, + { + Config: &BlockDevice{ + DeviceName: "/dev/sdb", + VolumeSize: 8, + }, + + Result: oapi.BlockDeviceMappingImage{ + DeviceName: "/dev/sdb", + Bsu: oapi.BsuToCreate{ + VolumeSize: 8, + DeleteOnVmDeletion: false, + }, + }, + }, + { + Config: &BlockDevice{ + DeviceName: "/dev/sdb", + VolumeType: "io1", + VolumeSize: 8, + DeleteOnVmDeletion: true, + IOPS: 1000, + }, + + Result: oapi.BlockDeviceMappingImage{ + DeviceName: "/dev/sdb", + Bsu: oapi.BsuToCreate{ + VolumeType: "io1", + VolumeSize: 8, + DeleteOnVmDeletion: true, + Iops: 1000, + }, + }, + }, + { + Config: &BlockDevice{ + DeviceName: "/dev/sdb", + VolumeType: "gp2", + VolumeSize: 8, + DeleteOnVmDeletion: true, + }, + + Result: oapi.BlockDeviceMappingImage{ + DeviceName: "/dev/sdb", + Bsu: oapi.BsuToCreate{ + VolumeType: "gp2", + VolumeSize: 8, + DeleteOnVmDeletion: true, + }, + }, + }, + { + Config: &BlockDevice{ + DeviceName: "/dev/sdb", + VolumeType: "gp2", + VolumeSize: 8, + DeleteOnVmDeletion: true, + }, + + Result: oapi.BlockDeviceMappingImage{ + DeviceName: "/dev/sdb", + Bsu: oapi.BsuToCreate{ + VolumeType: "gp2", + VolumeSize: 8, + DeleteOnVmDeletion: true, + }, + }, + }, + { + Config: &BlockDevice{ + DeviceName: "/dev/sdb", + VolumeType: "standard", + DeleteOnVmDeletion: true, + }, + + Result: oapi.BlockDeviceMappingImage{ + DeviceName: "/dev/sdb", + Bsu: oapi.BsuToCreate{ + VolumeType: "standard", + DeleteOnVmDeletion: true, + }, + }, + }, + { + Config: &BlockDevice{ + DeviceName: "/dev/sdb", + VirtualName: "ephemeral0", + }, + + Result: oapi.BlockDeviceMappingImage{ + DeviceName: "/dev/sdb", + VirtualDeviceName: "ephemeral0", + }, + }, + { + Config: &BlockDevice{ + DeviceName: "/dev/sdb", + }, + + Result: oapi.BlockDeviceMappingImage{ + DeviceName: "/dev/sdb", + }, + }, + } + for _, tc := range cases { omiBlockDevices := OMIBlockDevices{ OMIMappings: []BlockDevice{*tc.Config}, } - launchBlockDevices := LaunchBlockDevices{ - LaunchMappings: []BlockDevice{*tc.Config}, - } - - expected := []*oapi.BlockDeviceMapping{tc.Result} + expected := []oapi.BlockDeviceMappingImage{tc.Result} omiResults := omiBlockDevices.BuildOMIDevices() if !reflect.DeepEqual(expected, omiResults) { t.Fatalf("Bad block device, \nexpected: %#v\n\ngot: %#v", expected, omiResults) } - - launchResults := launchBlockDevices.BuildLaunchDevices() - if !reflect.DeepEqual(expected, launchResults) { - t.Fatalf("Bad block device, \nexpected: %#v\n\ngot: %#v", - expected, launchResults) - } } } diff --git a/builder/osc/common/interpolate_build_info_test.go b/builder/osc/common/interpolate_build_info_test.go index c15a4072b..c4d146833 100644 --- a/builder/osc/common/interpolate_build_info_test.go +++ b/builder/osc/common/interpolate_build_info_test.go @@ -8,8 +8,8 @@ import ( "github.com/outscale/osc-go/oapi" ) -func testImage() *oapi.Image { - return &oapi.Image{ +func testImage() oapi.Image { + return oapi.Image{ ImageId: "ami-abcd1234", ImageName: "ami_test_name", Tags: []oapi.ResourceTag{ diff --git a/builder/osc/common/step_security_group.go b/builder/osc/common/step_security_group.go index 7531f03a1..1948c6435 100644 --- a/builder/osc/common/step_security_group.go +++ b/builder/osc/common/step_security_group.go @@ -121,7 +121,7 @@ func (s *StepSecurityGroup) Run(_ context.Context, state multistep.StateBag) mul SecurityGroupId: groupResp.OK.SecurityGroup.SecurityGroupId, Flow: "Inbound", Rules: []oapi.SecurityGroupRule{ - oapi.SecurityGroupRule{ + { FromPortRange: int64(port), ToPortRange: int64(port), IpRanges: []string{s.TemporarySGSourceCidr}, From c9234e12a200678171f4b5552d9b1dbb4856bc03 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Wed, 20 Feb 2019 18:43:05 -0600 Subject: [PATCH 055/113] add missing vendor dependencies --- go.mod | 1 + go.sum | 3 + .../github.com/outscale/osc-go/oapi/client.go | 10477 ++++++++++++++++ .../outscale/osc-go/oapi/interface.go | 1213 ++ .../outscale/osc-go/oapi/provider.go | 527 + .../github.com/outscale/osc-go/oapi/types.go | 5660 +++++++++ .../github.com/outscale/osc-go/utils/utils.go | 27 + vendor/modules.txt | 3 + 8 files changed, 17911 insertions(+) create mode 100644 vendor/github.com/outscale/osc-go/oapi/client.go create mode 100644 vendor/github.com/outscale/osc-go/oapi/interface.go create mode 100644 vendor/github.com/outscale/osc-go/oapi/provider.go create mode 100644 vendor/github.com/outscale/osc-go/oapi/types.go create mode 100644 vendor/github.com/outscale/osc-go/utils/utils.go diff --git a/go.mod b/go.mod index c426e46cd..661ece0da 100644 --- a/go.mod +++ b/go.mod @@ -97,6 +97,7 @@ require ( github.com/olekukonko/tablewriter v0.0.0-20180105111133-96aac992fc8b github.com/openzipkin/zipkin-go v0.1.6 // indirect github.com/oracle/oci-go-sdk v1.8.0 + github.com/outscale/osc-go v0.0.1 github.com/packer-community/winrmcp v0.0.0-20180921204643-0fd363d6159a github.com/pierrec/lz4 v2.0.5+incompatible github.com/pkg/errors v0.8.0 diff --git a/go.sum b/go.sum index 238f23104..88c1c04b9 100644 --- a/go.sum +++ b/go.sum @@ -64,6 +64,7 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= +github.com/aws/aws-sdk-go v1.16.22/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.16.24 h1:I/A3Hwbgs3IEAP6v1bFpHKXiT7wZDoToX9cb00nxZnM= github.com/aws/aws-sdk-go v1.16.24/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -348,6 +349,8 @@ github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTm github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/oracle/oci-go-sdk v1.8.0 h1:4SO45bKV0I3/Mn1os3ANDZmV0eSE5z5CLdSUIkxtyzs= github.com/oracle/oci-go-sdk v1.8.0/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= +github.com/outscale/osc-go v0.0.1 h1:hvBtORyu7sWSKW1norGlfIP8C7c2aegI2Vkq75SRPCE= +github.com/outscale/osc-go v0.0.1/go.mod h1:hJLmXzqU/t07qQYh90I0TqZzu9s85Zs6FMrxk3ukiFM= github.com/packer-community/winrmcp v0.0.0-20180921204643-0fd363d6159a h1:A3QMuteviunoaY/8ex+RKFqwhcZJ/Cf3fCW3IwL2wx4= github.com/packer-community/winrmcp v0.0.0-20180921204643-0fd363d6159a/go.mod h1:f6Izs6JvFTdnRbziASagjZ2vmf55NSIkC/weStxCHqk= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs= diff --git a/vendor/github.com/outscale/osc-go/oapi/client.go b/vendor/github.com/outscale/osc-go/oapi/client.go new file mode 100644 index 000000000..8a2bfc560 --- /dev/null +++ b/vendor/github.com/outscale/osc-go/oapi/client.go @@ -0,0 +1,10477 @@ +// GENERATED FILE: DO NOT EDIT! + +package oapi + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "log" + "net/http" + "net/url" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/signer/v4" + "github.com/outscale/osc-go/utils" +) + +type Client struct { + service string + + signer *v4.Signer + + client *http.Client + + config *Config +} + +type Config struct { + AccessKey string + SecretKey string + Region string + URL string + + //Only Used for OAPI + Service string + + // User agent for client + UserAgent string +} + +func (c Config) ServiceURL() string { + s := fmt.Sprintf("https://%s.%s.%s", c.Service, c.Region, c.URL) + + u, err := url.Parse(s) + if err != nil { + panic(err) + } + + return u.String() +} + +// NewClient creates an API client. +func NewClient(config *Config, c *http.Client) *Client { + client := &Client{} + client.service = config.ServiceURL() + if c != nil { + client.client = c + } else { + client.client = http.DefaultClient + } + + s := &v4.Signer{ + Credentials: credentials.NewStaticCredentials(config.AccessKey, + config.SecretKey, ""), + } + + client.signer = s + client.config = config + + return client +} + +func (c *Client) GetConfig() *Config { + return c.config +} + +// Sign ... +func (c *Client) Sign(req *http.Request, body []byte) error { + reader := strings.NewReader(string(body)) + timestamp := time.Now() + _, err := c.signer.Sign(req, reader, "oapi", c.config.Region, timestamp) + utils.DebugRequest(req) + return err + +} + +// Do ... +func (c *Client) Do(req *http.Request) (*http.Response, error) { + resp, err := c.client.Do(req) + if err != nil { + log.Printf("[DEBUG] Error in Do Request %s", err) + } + + if resp != nil { + utils.DebugResponse(resp) + } else { + log.Println("[DEBUG] No response to show.") + } + + return resp, err +} + +// +func (client *Client) POST_AcceptNetPeering( + acceptnetpeeringrequest AcceptNetPeeringRequest, +) ( + response *POST_AcceptNetPeeringResponses, + err error, +) { + path := client.service + "/AcceptNetPeering" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(acceptnetpeeringrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_AcceptNetPeeringResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &AcceptNetPeeringResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 409: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code409 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_AuthenticateAccount( + authenticateaccountrequest AuthenticateAccountRequest, +) ( + response *POST_AuthenticateAccountResponses, + err error, +) { + path := client.service + "/AuthenticateAccount" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(authenticateaccountrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_AuthenticateAccountResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &AuthenticateAccountResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_CheckSignature( + checksignaturerequest CheckSignatureRequest, +) ( + response *POST_CheckSignatureResponses, + err error, +) { + path := client.service + "/CheckSignature" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(checksignaturerequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CheckSignatureResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CheckSignatureResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_CopyAccount( + copyaccountrequest CopyAccountRequest, +) ( + response *POST_CopyAccountResponses, + err error, +) { + path := client.service + "/CopyAccount" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(copyaccountrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CopyAccountResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CopyAccountResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateAccount( + createaccountrequest CreateAccountRequest, +) ( + response *POST_CreateAccountResponses, + err error, +) { + path := client.service + "/CreateAccount" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createaccountrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateAccountResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateAccountResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateApiKey( + createapikeyrequest CreateApiKeyRequest, +) ( + response *POST_CreateApiKeyResponses, + err error, +) { + path := client.service + "/CreateApiKey" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createapikeyrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateApiKeyResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateApiKeyResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateClientGateway( + createclientgatewayrequest CreateClientGatewayRequest, +) ( + response *POST_CreateClientGatewayResponses, + err error, +) { + path := client.service + "/CreateClientGateway" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createclientgatewayrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateClientGatewayResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateClientGatewayResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateDhcpOptions( + createdhcpoptionsrequest CreateDhcpOptionsRequest, +) ( + response *POST_CreateDhcpOptionsResponses, + err error, +) { + path := client.service + "/CreateDhcpOptions" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createdhcpoptionsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateDhcpOptionsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateDhcpOptionsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateDirectLink( + createdirectlinkrequest CreateDirectLinkRequest, +) ( + response *POST_CreateDirectLinkResponses, + err error, +) { + path := client.service + "/CreateDirectLink" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createdirectlinkrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateDirectLinkResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateDirectLinkResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateDirectLinkInterface( + createdirectlinkinterfacerequest CreateDirectLinkInterfaceRequest, +) ( + response *POST_CreateDirectLinkInterfaceResponses, + err error, +) { + path := client.service + "/CreateDirectLinkInterface" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createdirectlinkinterfacerequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateDirectLinkInterfaceResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateDirectLinkInterfaceResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateImage( + createimagerequest CreateImageRequest, +) ( + response *POST_CreateImageResponses, + err error, +) { + path := client.service + "/CreateImage" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createimagerequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateImageResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateImageResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateImageExportTask( + createimageexporttaskrequest CreateImageExportTaskRequest, +) ( + response *POST_CreateImageExportTaskResponses, + err error, +) { + path := client.service + "/CreateImageExportTask" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createimageexporttaskrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateImageExportTaskResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateImageExportTaskResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateInternetService( + createinternetservicerequest CreateInternetServiceRequest, +) ( + response *POST_CreateInternetServiceResponses, + err error, +) { + path := client.service + "/CreateInternetService" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createinternetservicerequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateInternetServiceResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateInternetServiceResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateKeypair( + createkeypairrequest CreateKeypairRequest, +) ( + response *POST_CreateKeypairResponses, + err error, +) { + path := client.service + "/CreateKeypair" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createkeypairrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateKeypairResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateKeypairResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 409: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code409 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateListenerRule( + createlistenerrulerequest CreateListenerRuleRequest, +) ( + response *POST_CreateListenerRuleResponses, + err error, +) { + path := client.service + "/CreateListenerRule" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createlistenerrulerequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateListenerRuleResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateListenerRuleResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateLoadBalancer( + createloadbalancerrequest CreateLoadBalancerRequest, +) ( + response *POST_CreateLoadBalancerResponses, + err error, +) { + path := client.service + "/CreateLoadBalancer" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createloadbalancerrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateLoadBalancerResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateLoadBalancerResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateLoadBalancerListeners( + createloadbalancerlistenersrequest CreateLoadBalancerListenersRequest, +) ( + response *POST_CreateLoadBalancerListenersResponses, + err error, +) { + path := client.service + "/CreateLoadBalancerListeners" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createloadbalancerlistenersrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateLoadBalancerListenersResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateLoadBalancerListenersResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateLoadBalancerPolicy( + createloadbalancerpolicyrequest CreateLoadBalancerPolicyRequest, +) ( + response *POST_CreateLoadBalancerPolicyResponses, + err error, +) { + path := client.service + "/CreateLoadBalancerPolicy" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createloadbalancerpolicyrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateLoadBalancerPolicyResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateLoadBalancerPolicyResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateNatService( + createnatservicerequest CreateNatServiceRequest, +) ( + response *POST_CreateNatServiceResponses, + err error, +) { + path := client.service + "/CreateNatService" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createnatservicerequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateNatServiceResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateNatServiceResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateNet( + createnetrequest CreateNetRequest, +) ( + response *POST_CreateNetResponses, + err error, +) { + path := client.service + "/CreateNet" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createnetrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateNetResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateNetResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 409: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code409 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateNetAccessPoint( + createnetaccesspointrequest CreateNetAccessPointRequest, +) ( + response *POST_CreateNetAccessPointResponses, + err error, +) { + path := client.service + "/CreateNetAccessPoint" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createnetaccesspointrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateNetAccessPointResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateNetAccessPointResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateNetPeering( + createnetpeeringrequest CreateNetPeeringRequest, +) ( + response *POST_CreateNetPeeringResponses, + err error, +) { + path := client.service + "/CreateNetPeering" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createnetpeeringrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateNetPeeringResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateNetPeeringResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateNic( + createnicrequest CreateNicRequest, +) ( + response *POST_CreateNicResponses, + err error, +) { + path := client.service + "/CreateNic" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createnicrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateNicResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateNicResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_CreatePolicy( + createpolicyrequest CreatePolicyRequest, +) ( + response *POST_CreatePolicyResponses, + err error, +) { + path := client.service + "/CreatePolicy" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createpolicyrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreatePolicyResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreatePolicyResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_CreatePublicIp( + createpubliciprequest CreatePublicIpRequest, +) ( + response *POST_CreatePublicIpResponses, + err error, +) { + path := client.service + "/CreatePublicIp" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createpubliciprequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreatePublicIpResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreatePublicIpResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateRoute( + createrouterequest CreateRouteRequest, +) ( + response *POST_CreateRouteResponses, + err error, +) { + path := client.service + "/CreateRoute" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createrouterequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateRouteResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateRouteResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateRouteTable( + createroutetablerequest CreateRouteTableRequest, +) ( + response *POST_CreateRouteTableResponses, + err error, +) { + path := client.service + "/CreateRouteTable" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createroutetablerequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateRouteTableResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateRouteTableResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateSecurityGroup( + createsecuritygrouprequest CreateSecurityGroupRequest, +) ( + response *POST_CreateSecurityGroupResponses, + err error, +) { + path := client.service + "/CreateSecurityGroup" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createsecuritygrouprequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateSecurityGroupResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateSecurityGroupResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateSecurityGroupRule( + createsecuritygrouprulerequest CreateSecurityGroupRuleRequest, +) ( + response *POST_CreateSecurityGroupRuleResponses, + err error, +) { + path := client.service + "/CreateSecurityGroupRule" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createsecuritygrouprulerequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateSecurityGroupRuleResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateSecurityGroupRuleResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateServerCertificate( + createservercertificaterequest CreateServerCertificateRequest, +) ( + response *POST_CreateServerCertificateResponses, + err error, +) { + path := client.service + "/CreateServerCertificate" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createservercertificaterequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateServerCertificateResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateServerCertificateResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateSnapshot( + createsnapshotrequest CreateSnapshotRequest, +) ( + response *POST_CreateSnapshotResponses, + err error, +) { + path := client.service + "/CreateSnapshot" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createsnapshotrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateSnapshotResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateSnapshotResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateSnapshotExportTask( + createsnapshotexporttaskrequest CreateSnapshotExportTaskRequest, +) ( + response *POST_CreateSnapshotExportTaskResponses, + err error, +) { + path := client.service + "/CreateSnapshotExportTask" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createsnapshotexporttaskrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateSnapshotExportTaskResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateSnapshotExportTaskResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateSubnet( + createsubnetrequest CreateSubnetRequest, +) ( + response *POST_CreateSubnetResponses, + err error, +) { + path := client.service + "/CreateSubnet" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createsubnetrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateSubnetResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateSubnetResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 409: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code409 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateTags( + createtagsrequest CreateTagsRequest, +) ( + response *POST_CreateTagsResponses, + err error, +) { + path := client.service + "/CreateTags" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createtagsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateTagsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateTagsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateUser( + createuserrequest CreateUserRequest, +) ( + response *POST_CreateUserResponses, + err error, +) { + path := client.service + "/CreateUser" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createuserrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateUserResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateUserResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateUserGroup( + createusergrouprequest CreateUserGroupRequest, +) ( + response *POST_CreateUserGroupResponses, + err error, +) { + path := client.service + "/CreateUserGroup" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createusergrouprequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateUserGroupResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateUserGroupResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateVirtualGateway( + createvirtualgatewayrequest CreateVirtualGatewayRequest, +) ( + response *POST_CreateVirtualGatewayResponses, + err error, +) { + path := client.service + "/CreateVirtualGateway" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createvirtualgatewayrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateVirtualGatewayResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateVirtualGatewayResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateVms( + createvmsrequest CreateVmsRequest, +) ( + response *POST_CreateVmsResponses, + err error, +) { + path := client.service + "/CreateVms" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createvmsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateVmsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateVmsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateVolume( + createvolumerequest CreateVolumeRequest, +) ( + response *POST_CreateVolumeResponses, + err error, +) { + path := client.service + "/CreateVolume" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createvolumerequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateVolumeResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateVolumeResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + return nil, checkErrorResponse(resp) + } + return +} + +// +func (client *Client) POST_CreateVpnConnection( + createvpnconnectionrequest CreateVpnConnectionRequest, +) ( + response *POST_CreateVpnConnectionResponses, + err error, +) { + path := client.service + "/CreateVpnConnection" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createvpnconnectionrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateVpnConnectionResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateVpnConnectionResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_CreateVpnConnectionRoute( + createvpnconnectionrouterequest CreateVpnConnectionRouteRequest, +) ( + response *POST_CreateVpnConnectionRouteResponses, + err error, +) { + path := client.service + "/CreateVpnConnectionRoute" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(createvpnconnectionrouterequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_CreateVpnConnectionRouteResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &CreateVpnConnectionRouteResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteApiKey( + deleteapikeyrequest DeleteApiKeyRequest, +) ( + response *POST_DeleteApiKeyResponses, + err error, +) { + path := client.service + "/DeleteApiKey" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deleteapikeyrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteApiKeyResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteApiKeyResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteClientGateway( + deleteclientgatewayrequest DeleteClientGatewayRequest, +) ( + response *POST_DeleteClientGatewayResponses, + err error, +) { + path := client.service + "/DeleteClientGateway" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deleteclientgatewayrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteClientGatewayResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteClientGatewayResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteDhcpOptions( + deletedhcpoptionsrequest DeleteDhcpOptionsRequest, +) ( + response *POST_DeleteDhcpOptionsResponses, + err error, +) { + path := client.service + "/DeleteDhcpOptions" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deletedhcpoptionsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteDhcpOptionsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteDhcpOptionsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteDirectLink( + deletedirectlinkrequest DeleteDirectLinkRequest, +) ( + response *POST_DeleteDirectLinkResponses, + err error, +) { + path := client.service + "/DeleteDirectLink" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deletedirectlinkrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteDirectLinkResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteDirectLinkResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteDirectLinkInterface( + deletedirectlinkinterfacerequest DeleteDirectLinkInterfaceRequest, +) ( + response *POST_DeleteDirectLinkInterfaceResponses, + err error, +) { + path := client.service + "/DeleteDirectLinkInterface" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deletedirectlinkinterfacerequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteDirectLinkInterfaceResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteDirectLinkInterfaceResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteExportTask( + deleteexporttaskrequest DeleteExportTaskRequest, +) ( + response *POST_DeleteExportTaskResponses, + err error, +) { + path := client.service + "/DeleteExportTask" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deleteexporttaskrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteExportTaskResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteExportTaskResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteImage( + deleteimagerequest DeleteImageRequest, +) ( + response *POST_DeleteImageResponses, + err error, +) { + path := client.service + "/DeleteImage" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deleteimagerequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteImageResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteImageResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteInternetService( + deleteinternetservicerequest DeleteInternetServiceRequest, +) ( + response *POST_DeleteInternetServiceResponses, + err error, +) { + path := client.service + "/DeleteInternetService" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deleteinternetservicerequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteInternetServiceResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteInternetServiceResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteKeypair( + deletekeypairrequest DeleteKeypairRequest, +) ( + response *POST_DeleteKeypairResponses, + err error, +) { + path := client.service + "/DeleteKeypair" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deletekeypairrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteKeypairResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteKeypairResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteListenerRule( + deletelistenerrulerequest DeleteListenerRuleRequest, +) ( + response *POST_DeleteListenerRuleResponses, + err error, +) { + path := client.service + "/DeleteListenerRule" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deletelistenerrulerequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteListenerRuleResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteListenerRuleResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteLoadBalancer( + deleteloadbalancerrequest DeleteLoadBalancerRequest, +) ( + response *POST_DeleteLoadBalancerResponses, + err error, +) { + path := client.service + "/DeleteLoadBalancer" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deleteloadbalancerrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteLoadBalancerResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteLoadBalancerResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteLoadBalancerListeners( + deleteloadbalancerlistenersrequest DeleteLoadBalancerListenersRequest, +) ( + response *POST_DeleteLoadBalancerListenersResponses, + err error, +) { + path := client.service + "/DeleteLoadBalancerListeners" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deleteloadbalancerlistenersrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteLoadBalancerListenersResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteLoadBalancerListenersResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteLoadBalancerPolicy( + deleteloadbalancerpolicyrequest DeleteLoadBalancerPolicyRequest, +) ( + response *POST_DeleteLoadBalancerPolicyResponses, + err error, +) { + path := client.service + "/DeleteLoadBalancerPolicy" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deleteloadbalancerpolicyrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteLoadBalancerPolicyResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteLoadBalancerPolicyResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteNatService( + deletenatservicerequest DeleteNatServiceRequest, +) ( + response *POST_DeleteNatServiceResponses, + err error, +) { + path := client.service + "/DeleteNatService" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deletenatservicerequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteNatServiceResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteNatServiceResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteNet( + deletenetrequest DeleteNetRequest, +) ( + response *POST_DeleteNetResponses, + err error, +) { + path := client.service + "/DeleteNet" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deletenetrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteNetResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteNetResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteNetAccessPoints( + deletenetaccesspointsrequest DeleteNetAccessPointsRequest, +) ( + response *POST_DeleteNetAccessPointsResponses, + err error, +) { + path := client.service + "/DeleteNetAccessPoints" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deletenetaccesspointsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteNetAccessPointsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteNetAccessPointsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteNetPeering( + deletenetpeeringrequest DeleteNetPeeringRequest, +) ( + response *POST_DeleteNetPeeringResponses, + err error, +) { + path := client.service + "/DeleteNetPeering" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deletenetpeeringrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteNetPeeringResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteNetPeeringResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 409: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code409 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteNic( + deletenicrequest DeleteNicRequest, +) ( + response *POST_DeleteNicResponses, + err error, +) { + path := client.service + "/DeleteNic" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deletenicrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteNicResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteNicResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_DeletePolicy( + deletepolicyrequest DeletePolicyRequest, +) ( + response *POST_DeletePolicyResponses, + err error, +) { + path := client.service + "/DeletePolicy" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deletepolicyrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeletePolicyResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeletePolicyResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_DeletePublicIp( + deletepubliciprequest DeletePublicIpRequest, +) ( + response *POST_DeletePublicIpResponses, + err error, +) { + path := client.service + "/DeletePublicIp" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deletepubliciprequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeletePublicIpResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeletePublicIpResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteRoute( + deleterouterequest DeleteRouteRequest, +) ( + response *POST_DeleteRouteResponses, + err error, +) { + path := client.service + "/DeleteRoute" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deleterouterequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteRouteResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteRouteResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteRouteTable( + deleteroutetablerequest DeleteRouteTableRequest, +) ( + response *POST_DeleteRouteTableResponses, + err error, +) { + path := client.service + "/DeleteRouteTable" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deleteroutetablerequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteRouteTableResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteRouteTableResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteSecurityGroup( + deletesecuritygrouprequest DeleteSecurityGroupRequest, +) ( + response *POST_DeleteSecurityGroupResponses, + err error, +) { + path := client.service + "/DeleteSecurityGroup" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deletesecuritygrouprequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteSecurityGroupResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteSecurityGroupResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteSecurityGroupRule( + deletesecuritygrouprulerequest DeleteSecurityGroupRuleRequest, +) ( + response *POST_DeleteSecurityGroupRuleResponses, + err error, +) { + path := client.service + "/DeleteSecurityGroupRule" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deletesecuritygrouprulerequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteSecurityGroupRuleResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteSecurityGroupRuleResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteServerCertificate( + deleteservercertificaterequest DeleteServerCertificateRequest, +) ( + response *POST_DeleteServerCertificateResponses, + err error, +) { + path := client.service + "/DeleteServerCertificate" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deleteservercertificaterequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteServerCertificateResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteServerCertificateResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteSnapshot( + deletesnapshotrequest DeleteSnapshotRequest, +) ( + response *POST_DeleteSnapshotResponses, + err error, +) { + path := client.service + "/DeleteSnapshot" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deletesnapshotrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteSnapshotResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteSnapshotResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteSubnet( + deletesubnetrequest DeleteSubnetRequest, +) ( + response *POST_DeleteSubnetResponses, + err error, +) { + path := client.service + "/DeleteSubnet" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deletesubnetrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteSubnetResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteSubnetResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteTags( + deletetagsrequest DeleteTagsRequest, +) ( + response *POST_DeleteTagsResponses, + err error, +) { + path := client.service + "/DeleteTags" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deletetagsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteTagsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteTagsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteUser( + deleteuserrequest DeleteUserRequest, +) ( + response *POST_DeleteUserResponses, + err error, +) { + path := client.service + "/DeleteUser" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deleteuserrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteUserResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteUserResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteUserGroup( + deleteusergrouprequest DeleteUserGroupRequest, +) ( + response *POST_DeleteUserGroupResponses, + err error, +) { + path := client.service + "/DeleteUserGroup" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deleteusergrouprequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteUserGroupResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteUserGroupResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteVirtualGateway( + deletevirtualgatewayrequest DeleteVirtualGatewayRequest, +) ( + response *POST_DeleteVirtualGatewayResponses, + err error, +) { + path := client.service + "/DeleteVirtualGateway" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deletevirtualgatewayrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteVirtualGatewayResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteVirtualGatewayResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteVms( + deletevmsrequest DeleteVmsRequest, +) ( + response *POST_DeleteVmsResponses, + err error, +) { + path := client.service + "/DeleteVms" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deletevmsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteVmsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteVmsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteVolume( + deletevolumerequest DeleteVolumeRequest, +) ( + response *POST_DeleteVolumeResponses, + err error, +) { + path := client.service + "/DeleteVolume" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deletevolumerequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteVolumeResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteVolumeResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteVpnConnection( + deletevpnconnectionrequest DeleteVpnConnectionRequest, +) ( + response *POST_DeleteVpnConnectionResponses, + err error, +) { + path := client.service + "/DeleteVpnConnection" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deletevpnconnectionrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteVpnConnectionResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteVpnConnectionResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_DeleteVpnConnectionRoute( + deletevpnconnectionrouterequest DeleteVpnConnectionRouteRequest, +) ( + response *POST_DeleteVpnConnectionRouteResponses, + err error, +) { + path := client.service + "/DeleteVpnConnectionRoute" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deletevpnconnectionrouterequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeleteVpnConnectionRouteResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeleteVpnConnectionRouteResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_DeregisterUserInUserGroup( + deregisteruserinusergrouprequest DeregisterUserInUserGroupRequest, +) ( + response *POST_DeregisterUserInUserGroupResponses, + err error, +) { + path := client.service + "/DeregisterUserInUserGroup" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deregisteruserinusergrouprequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeregisterUserInUserGroupResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeregisterUserInUserGroupResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_DeregisterVmsInLoadBalancer( + deregistervmsinloadbalancerrequest DeregisterVmsInLoadBalancerRequest, +) ( + response *POST_DeregisterVmsInLoadBalancerResponses, + err error, +) { + path := client.service + "/DeregisterVmsInLoadBalancer" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(deregistervmsinloadbalancerrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_DeregisterVmsInLoadBalancerResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &DeregisterVmsInLoadBalancerResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_LinkInternetService( + linkinternetservicerequest LinkInternetServiceRequest, +) ( + response *POST_LinkInternetServiceResponses, + err error, +) { + path := client.service + "/LinkInternetService" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(linkinternetservicerequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_LinkInternetServiceResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &LinkInternetServiceResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_LinkNic( + linknicrequest LinkNicRequest, +) ( + response *POST_LinkNicResponses, + err error, +) { + path := client.service + "/LinkNic" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(linknicrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_LinkNicResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &LinkNicResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_LinkPolicy( + linkpolicyrequest LinkPolicyRequest, +) ( + response *POST_LinkPolicyResponses, + err error, +) { + path := client.service + "/LinkPolicy" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(linkpolicyrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_LinkPolicyResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &LinkPolicyResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_LinkPrivateIps( + linkprivateipsrequest LinkPrivateIpsRequest, +) ( + response *POST_LinkPrivateIpsResponses, + err error, +) { + path := client.service + "/LinkPrivateIps" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(linkprivateipsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_LinkPrivateIpsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &LinkPrivateIpsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_LinkPublicIp( + linkpubliciprequest LinkPublicIpRequest, +) ( + response *POST_LinkPublicIpResponses, + err error, +) { + path := client.service + "/LinkPublicIp" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(linkpubliciprequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_LinkPublicIpResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &LinkPublicIpResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_LinkRouteTable( + linkroutetablerequest LinkRouteTableRequest, +) ( + response *POST_LinkRouteTableResponses, + err error, +) { + path := client.service + "/LinkRouteTable" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(linkroutetablerequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_LinkRouteTableResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &LinkRouteTableResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_LinkVirtualGateway( + linkvirtualgatewayrequest LinkVirtualGatewayRequest, +) ( + response *POST_LinkVirtualGatewayResponses, + err error, +) { + path := client.service + "/LinkVirtualGateway" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(linkvirtualgatewayrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_LinkVirtualGatewayResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &LinkVirtualGatewayResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_LinkVolume( + linkvolumerequest LinkVolumeRequest, +) ( + response *POST_LinkVolumeResponses, + err error, +) { + path := client.service + "/LinkVolume" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(linkvolumerequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_LinkVolumeResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &LinkVolumeResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_PurchaseReservedVmsOffer( + purchasereservedvmsofferrequest PurchaseReservedVmsOfferRequest, +) ( + response *POST_PurchaseReservedVmsOfferResponses, + err error, +) { + path := client.service + "/PurchaseReservedVmsOffer" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(purchasereservedvmsofferrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_PurchaseReservedVmsOfferResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &PurchaseReservedVmsOfferResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadAccount( + readaccountrequest ReadAccountRequest, +) ( + response *POST_ReadAccountResponses, + err error, +) { + path := client.service + "/ReadAccount" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readaccountrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadAccountResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadAccountResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadAccountConsumption( + readaccountconsumptionrequest ReadAccountConsumptionRequest, +) ( + response *POST_ReadAccountConsumptionResponses, + err error, +) { + path := client.service + "/ReadAccountConsumption" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readaccountconsumptionrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadAccountConsumptionResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadAccountConsumptionResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadAdminPassword( + readadminpasswordrequest ReadAdminPasswordRequest, +) ( + response *POST_ReadAdminPasswordResponses, + err error, +) { + path := client.service + "/ReadAdminPassword" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readadminpasswordrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadAdminPasswordResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadAdminPasswordResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadApiKeys( + readapikeysrequest ReadApiKeysRequest, +) ( + response *POST_ReadApiKeysResponses, + err error, +) { + path := client.service + "/ReadApiKeys" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readapikeysrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadApiKeysResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadApiKeysResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadApiLogs( + readapilogsrequest ReadApiLogsRequest, +) ( + response *POST_ReadApiLogsResponses, + err error, +) { + path := client.service + "/ReadApiLogs" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readapilogsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadApiLogsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadApiLogsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadBillableDigest( + readbillabledigestrequest ReadBillableDigestRequest, +) ( + response *POST_ReadBillableDigestResponses, + err error, +) { + path := client.service + "/ReadBillableDigest" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readbillabledigestrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadBillableDigestResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadBillableDigestResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadCatalog( + readcatalogrequest ReadCatalogRequest, +) ( + response *POST_ReadCatalogResponses, + err error, +) { + path := client.service + "/ReadCatalog" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readcatalogrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadCatalogResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadCatalogResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadClientGateways( + readclientgatewaysrequest ReadClientGatewaysRequest, +) ( + response *POST_ReadClientGatewaysResponses, + err error, +) { + path := client.service + "/ReadClientGateways" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readclientgatewaysrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadClientGatewaysResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadClientGatewaysResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadConsoleOutput( + readconsoleoutputrequest ReadConsoleOutputRequest, +) ( + response *POST_ReadConsoleOutputResponses, + err error, +) { + path := client.service + "/ReadConsoleOutput" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readconsoleoutputrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadConsoleOutputResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadConsoleOutputResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadDhcpOptions( + readdhcpoptionsrequest ReadDhcpOptionsRequest, +) ( + response *POST_ReadDhcpOptionsResponses, + err error, +) { + path := client.service + "/ReadDhcpOptions" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readdhcpoptionsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadDhcpOptionsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadDhcpOptionsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadDirectLinkInterfaces( + readdirectlinkinterfacesrequest ReadDirectLinkInterfacesRequest, +) ( + response *POST_ReadDirectLinkInterfacesResponses, + err error, +) { + path := client.service + "/ReadDirectLinkInterfaces" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readdirectlinkinterfacesrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadDirectLinkInterfacesResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadDirectLinkInterfacesResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadDirectLinks( + readdirectlinksrequest ReadDirectLinksRequest, +) ( + response *POST_ReadDirectLinksResponses, + err error, +) { + path := client.service + "/ReadDirectLinks" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readdirectlinksrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadDirectLinksResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadDirectLinksResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadImageExportTasks( + readimageexporttasksrequest ReadImageExportTasksRequest, +) ( + response *POST_ReadImageExportTasksResponses, + err error, +) { + path := client.service + "/ReadImageExportTasks" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readimageexporttasksrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadImageExportTasksResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadImageExportTasksResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadImages( + readimagesrequest ReadImagesRequest, +) ( + response *POST_ReadImagesResponses, + err error, +) { + path := client.service + "/ReadImages" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readimagesrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadImagesResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadImagesResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadInternetServices( + readinternetservicesrequest ReadInternetServicesRequest, +) ( + response *POST_ReadInternetServicesResponses, + err error, +) { + path := client.service + "/ReadInternetServices" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readinternetservicesrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadInternetServicesResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadInternetServicesResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadKeypairs( + readkeypairsrequest ReadKeypairsRequest, +) ( + response *POST_ReadKeypairsResponses, + err error, +) { + path := client.service + "/ReadKeypairs" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readkeypairsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadKeypairsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadKeypairsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadListenerRules( + readlistenerrulesrequest ReadListenerRulesRequest, +) ( + response *POST_ReadListenerRulesResponses, + err error, +) { + path := client.service + "/ReadListenerRules" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readlistenerrulesrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + utils.DebugRequest(req) + resp, err := client.Do(req) + if resp != nil { + utils.DebugResponse(resp) + } + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadListenerRulesResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadListenerRulesResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadLoadBalancers( + readloadbalancersrequest ReadLoadBalancersRequest, +) ( + response *POST_ReadLoadBalancersResponses, + err error, +) { + path := client.service + "/ReadLoadBalancers" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readloadbalancersrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadLoadBalancersResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadLoadBalancersResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadLocations( + readlocationsrequest ReadLocationsRequest, +) ( + response *POST_ReadLocationsResponses, + err error, +) { + path := client.service + "/ReadLocations" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readlocationsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadLocationsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadLocationsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadNatServices( + readnatservicesrequest ReadNatServicesRequest, +) ( + response *POST_ReadNatServicesResponses, + err error, +) { + path := client.service + "/ReadNatServices" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readnatservicesrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadNatServicesResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadNatServicesResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadNetAccessPointServices( + readnetaccesspointservicesrequest ReadNetAccessPointServicesRequest, +) ( + response *POST_ReadNetAccessPointServicesResponses, + err error, +) { + path := client.service + "/ReadNetAccessPointServices" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readnetaccesspointservicesrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadNetAccessPointServicesResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadNetAccessPointServicesResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadNetAccessPoints( + readnetaccesspointsrequest ReadNetAccessPointsRequest, +) ( + response *POST_ReadNetAccessPointsResponses, + err error, +) { + path := client.service + "/ReadNetAccessPoints" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readnetaccesspointsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadNetAccessPointsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadNetAccessPointsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadNetPeerings( + readnetpeeringsrequest ReadNetPeeringsRequest, +) ( + response *POST_ReadNetPeeringsResponses, + err error, +) { + path := client.service + "/ReadNetPeerings" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readnetpeeringsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadNetPeeringsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadNetPeeringsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadNets( + readnetsrequest ReadNetsRequest, +) ( + response *POST_ReadNetsResponses, + err error, +) { + path := client.service + "/ReadNets" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readnetsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadNetsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadNetsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadNics( + readnicsrequest ReadNicsRequest, +) ( + response *POST_ReadNicsResponses, + err error, +) { + path := client.service + "/ReadNics" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readnicsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadNicsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadNicsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadPolicies( + readpoliciesrequest ReadPoliciesRequest, +) ( + response *POST_ReadPoliciesResponses, + err error, +) { + path := client.service + "/ReadPolicies" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readpoliciesrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadPoliciesResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadPoliciesResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadPrefixLists( + readprefixlistsrequest ReadPrefixListsRequest, +) ( + response *POST_ReadPrefixListsResponses, + err error, +) { + path := client.service + "/ReadPrefixLists" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readprefixlistsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadPrefixListsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadPrefixListsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadProductTypes( + readproducttypesrequest ReadProductTypesRequest, +) ( + response *POST_ReadProductTypesResponses, + err error, +) { + path := client.service + "/ReadProductTypes" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readproducttypesrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadProductTypesResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadProductTypesResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadPublicCatalog( + readpubliccatalogrequest ReadPublicCatalogRequest, +) ( + response *POST_ReadPublicCatalogResponses, + err error, +) { + path := client.service + "/ReadPublicCatalog" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readpubliccatalogrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadPublicCatalogResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadPublicCatalogResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadPublicIpRanges( + readpubliciprangesrequest ReadPublicIpRangesRequest, +) ( + response *POST_ReadPublicIpRangesResponses, + err error, +) { + path := client.service + "/ReadPublicIpRanges" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readpubliciprangesrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadPublicIpRangesResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadPublicIpRangesResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadPublicIps( + readpublicipsrequest ReadPublicIpsRequest, +) ( + response *POST_ReadPublicIpsResponses, + err error, +) { + path := client.service + "/ReadPublicIps" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readpublicipsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadPublicIpsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadPublicIpsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadQuotas( + readquotasrequest ReadQuotasRequest, +) ( + response *POST_ReadQuotasResponses, + err error, +) { + path := client.service + "/ReadQuotas" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readquotasrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadQuotasResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadQuotasResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadRegionConfig( + readregionconfigrequest ReadRegionConfigRequest, +) ( + response *POST_ReadRegionConfigResponses, + err error, +) { + path := client.service + "/ReadRegionConfig" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readregionconfigrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadRegionConfigResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadRegionConfigResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadRegions( + readregionsrequest ReadRegionsRequest, +) ( + response *POST_ReadRegionsResponses, + err error, +) { + path := client.service + "/ReadRegions" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readregionsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadRegionsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadRegionsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadReservedVmOffers( + readreservedvmoffersrequest ReadReservedVmOffersRequest, +) ( + response *POST_ReadReservedVmOffersResponses, + err error, +) { + path := client.service + "/ReadReservedVmOffers" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readreservedvmoffersrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadReservedVmOffersResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadReservedVmOffersResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadReservedVms( + readreservedvmsrequest ReadReservedVmsRequest, +) ( + response *POST_ReadReservedVmsResponses, + err error, +) { + path := client.service + "/ReadReservedVms" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readreservedvmsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + utils.DebugRequest(req) + resp, err := client.Do(req) + if resp != nil { + utils.DebugResponse(resp) + } + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadReservedVmsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadReservedVmsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadRouteTables( + readroutetablesrequest ReadRouteTablesRequest, +) ( + response *POST_ReadRouteTablesResponses, + err error, +) { + path := client.service + "/ReadRouteTables" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readroutetablesrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadRouteTablesResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadRouteTablesResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadSecurityGroups( + readsecuritygroupsrequest ReadSecurityGroupsRequest, +) ( + response *POST_ReadSecurityGroupsResponses, + err error, +) { + path := client.service + "/ReadSecurityGroups" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readsecuritygroupsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadSecurityGroupsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadSecurityGroupsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadServerCertificates( + readservercertificatesrequest ReadServerCertificatesRequest, +) ( + response *POST_ReadServerCertificatesResponses, + err error, +) { + path := client.service + "/ReadServerCertificates" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readservercertificatesrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadServerCertificatesResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadServerCertificatesResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadSnapshotExportTasks( + readsnapshotexporttasksrequest ReadSnapshotExportTasksRequest, +) ( + response *POST_ReadSnapshotExportTasksResponses, + err error, +) { + path := client.service + "/ReadSnapshotExportTasks" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readsnapshotexporttasksrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadSnapshotExportTasksResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadSnapshotExportTasksResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadSnapshots( + readsnapshotsrequest ReadSnapshotsRequest, +) ( + response *POST_ReadSnapshotsResponses, + err error, +) { + path := client.service + "/ReadSnapshots" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readsnapshotsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadSnapshotsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadSnapshotsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadSubnets( + readsubnetsrequest ReadSubnetsRequest, +) ( + response *POST_ReadSubnetsResponses, + err error, +) { + path := client.service + "/ReadSubnets" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readsubnetsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadSubnetsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadSubnetsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadSubregions( + readsubregionsrequest ReadSubregionsRequest, +) ( + response *POST_ReadSubregionsResponses, + err error, +) { + path := client.service + "/ReadSubregions" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readsubregionsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadSubregionsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadSubregionsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadTags( + readtagsrequest ReadTagsRequest, +) ( + response *POST_ReadTagsResponses, + err error, +) { + path := client.service + "/ReadTags" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readtagsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadTagsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadTagsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadUserGroups( + readusergroupsrequest ReadUserGroupsRequest, +) ( + response *POST_ReadUserGroupsResponses, + err error, +) { + path := client.service + "/ReadUserGroups" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readusergroupsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadUserGroupsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadUserGroupsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadUsers( + readusersrequest ReadUsersRequest, +) ( + response *POST_ReadUsersResponses, + err error, +) { + path := client.service + "/ReadUsers" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readusersrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadUsersResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadUsersResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadVirtualGateways( + readvirtualgatewaysrequest ReadVirtualGatewaysRequest, +) ( + response *POST_ReadVirtualGatewaysResponses, + err error, +) { + path := client.service + "/ReadVirtualGateways" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readvirtualgatewaysrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadVirtualGatewaysResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadVirtualGatewaysResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadVmTypes( + readvmtypesrequest ReadVmTypesRequest, +) ( + response *POST_ReadVmTypesResponses, + err error, +) { + path := client.service + "/ReadVmTypes" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readvmtypesrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadVmTypesResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadVmTypesResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadVms( + readvmsrequest ReadVmsRequest, +) ( + response *POST_ReadVmsResponses, + err error, +) { + path := client.service + "/ReadVms" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readvmsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadVmsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadVmsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadVmsHealth( + readvmshealthrequest ReadVmsHealthRequest, +) ( + response *POST_ReadVmsHealthResponses, + err error, +) { + path := client.service + "/ReadVmsHealth" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readvmshealthrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadVmsHealthResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadVmsHealthResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadVmsState( + readvmsstaterequest ReadVmsStateRequest, +) ( + response *POST_ReadVmsStateResponses, + err error, +) { + path := client.service + "/ReadVmsState" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readvmsstaterequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadVmsStateResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadVmsStateResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadVolumes( + readvolumesrequest ReadVolumesRequest, +) ( + response *POST_ReadVolumesResponses, + err error, +) { + path := client.service + "/ReadVolumes" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readvolumesrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadVolumesResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadVolumesResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_ReadVpnConnections( + readvpnconnectionsrequest ReadVpnConnectionsRequest, +) ( + response *POST_ReadVpnConnectionsResponses, + err error, +) { + path := client.service + "/ReadVpnConnections" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(readvpnconnectionsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ReadVpnConnectionsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ReadVpnConnectionsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_RebootVms( + rebootvmsrequest RebootVmsRequest, +) ( + response *POST_RebootVmsResponses, + err error, +) { + path := client.service + "/RebootVms" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(rebootvmsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_RebootVmsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &RebootVmsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_RegisterUserInUserGroup( + registeruserinusergrouprequest RegisterUserInUserGroupRequest, +) ( + response *POST_RegisterUserInUserGroupResponses, + err error, +) { + path := client.service + "/RegisterUserInUserGroup" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(registeruserinusergrouprequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_RegisterUserInUserGroupResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &RegisterUserInUserGroupResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_RegisterVmsInLoadBalancer( + registervmsinloadbalancerrequest RegisterVmsInLoadBalancerRequest, +) ( + response *POST_RegisterVmsInLoadBalancerResponses, + err error, +) { + path := client.service + "/RegisterVmsInLoadBalancer" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(registervmsinloadbalancerrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_RegisterVmsInLoadBalancerResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &RegisterVmsInLoadBalancerResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_RejectNetPeering( + rejectnetpeeringrequest RejectNetPeeringRequest, +) ( + response *POST_RejectNetPeeringResponses, + err error, +) { + path := client.service + "/RejectNetPeering" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(rejectnetpeeringrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_RejectNetPeeringResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &RejectNetPeeringResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 409: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code409 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_ResetAccountPassword( + resetaccountpasswordrequest ResetAccountPasswordRequest, +) ( + response *POST_ResetAccountPasswordResponses, + err error, +) { + path := client.service + "/ResetAccountPassword" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(resetaccountpasswordrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_ResetAccountPasswordResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ResetAccountPasswordResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_SendResetPasswordEmail( + sendresetpasswordemailrequest SendResetPasswordEmailRequest, +) ( + response *POST_SendResetPasswordEmailResponses, + err error, +) { + path := client.service + "/SendResetPasswordEmail" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(sendresetpasswordemailrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_SendResetPasswordEmailResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &SendResetPasswordEmailResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_StartVms( + startvmsrequest StartVmsRequest, +) ( + response *POST_StartVmsResponses, + err error, +) { + path := client.service + "/StartVms" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(startvmsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_StartVmsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &StartVmsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_StopVms( + stopvmsrequest StopVmsRequest, +) ( + response *POST_StopVmsResponses, + err error, +) { + path := client.service + "/StopVms" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(stopvmsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_StopVmsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &StopVmsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_UnlinkInternetService( + unlinkinternetservicerequest UnlinkInternetServiceRequest, +) ( + response *POST_UnlinkInternetServiceResponses, + err error, +) { + path := client.service + "/UnlinkInternetService" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(unlinkinternetservicerequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + utils.DebugRequest(req) + resp, err := client.Do(req) + if resp != nil { + utils.DebugResponse(resp) + } + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_UnlinkInternetServiceResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &UnlinkInternetServiceResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_UnlinkNic( + unlinknicrequest UnlinkNicRequest, +) ( + response *POST_UnlinkNicResponses, + err error, +) { + path := client.service + "/UnlinkNic" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(unlinknicrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_UnlinkNicResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &UnlinkNicResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_UnlinkPolicy( + unlinkpolicyrequest UnlinkPolicyRequest, +) ( + response *POST_UnlinkPolicyResponses, + err error, +) { + path := client.service + "/UnlinkPolicy" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(unlinkpolicyrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_UnlinkPolicyResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &UnlinkPolicyResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_UnlinkPrivateIps( + unlinkprivateipsrequest UnlinkPrivateIpsRequest, +) ( + response *POST_UnlinkPrivateIpsResponses, + err error, +) { + path := client.service + "/UnlinkPrivateIps" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(unlinkprivateipsrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_UnlinkPrivateIpsResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &UnlinkPrivateIpsResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_UnlinkPublicIp( + unlinkpubliciprequest UnlinkPublicIpRequest, +) ( + response *POST_UnlinkPublicIpResponses, + err error, +) { + path := client.service + "/UnlinkPublicIp" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(unlinkpubliciprequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_UnlinkPublicIpResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &UnlinkPublicIpResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_UnlinkRouteTable( + unlinkroutetablerequest UnlinkRouteTableRequest, +) ( + response *POST_UnlinkRouteTableResponses, + err error, +) { + path := client.service + "/UnlinkRouteTable" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(unlinkroutetablerequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_UnlinkRouteTableResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &UnlinkRouteTableResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_UnlinkVirtualGateway( + unlinkvirtualgatewayrequest UnlinkVirtualGatewayRequest, +) ( + response *POST_UnlinkVirtualGatewayResponses, + err error, +) { + path := client.service + "/UnlinkVirtualGateway" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(unlinkvirtualgatewayrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_UnlinkVirtualGatewayResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &UnlinkVirtualGatewayResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_UnlinkVolume( + unlinkvolumerequest UnlinkVolumeRequest, +) ( + response *POST_UnlinkVolumeResponses, + err error, +) { + path := client.service + "/UnlinkVolume" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(unlinkvolumerequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_UnlinkVolumeResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &UnlinkVolumeResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_UpdateAccount( + updateaccountrequest UpdateAccountRequest, +) ( + response *POST_UpdateAccountResponses, + err error, +) { + path := client.service + "/UpdateAccount" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(updateaccountrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_UpdateAccountResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &UpdateAccountResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_UpdateApiKey( + updateapikeyrequest UpdateApiKeyRequest, +) ( + response *POST_UpdateApiKeyResponses, + err error, +) { + path := client.service + "/UpdateApiKey" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(updateapikeyrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_UpdateApiKeyResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &UpdateApiKeyResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_UpdateHealthCheck( + updatehealthcheckrequest UpdateHealthCheckRequest, +) ( + response *POST_UpdateHealthCheckResponses, + err error, +) { + path := client.service + "/UpdateHealthCheck" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(updatehealthcheckrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_UpdateHealthCheckResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &UpdateHealthCheckResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_UpdateImage( + updateimagerequest UpdateImageRequest, +) ( + response *POST_UpdateImageResponses, + err error, +) { + path := client.service + "/UpdateImage" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(updateimagerequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_UpdateImageResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &UpdateImageResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_UpdateKeypair( + updatekeypairrequest UpdateKeypairRequest, +) ( + response *POST_UpdateKeypairResponses, + err error, +) { + path := client.service + "/UpdateKeypair" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(updatekeypairrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_UpdateKeypairResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &UpdateKeypairResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_UpdateListenerRule( + updatelistenerrulerequest UpdateListenerRuleRequest, +) ( + response *POST_UpdateListenerRuleResponses, + err error, +) { + path := client.service + "/UpdateListenerRule" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(updatelistenerrulerequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_UpdateListenerRuleResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &UpdateListenerRuleResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_UpdateLoadBalancer( + updateloadbalancerrequest UpdateLoadBalancerRequest, +) ( + response *POST_UpdateLoadBalancerResponses, + err error, +) { + path := client.service + "/UpdateLoadBalancer" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(updateloadbalancerrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_UpdateLoadBalancerResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &UpdateLoadBalancerResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_UpdateNet( + updatenetrequest UpdateNetRequest, +) ( + response *POST_UpdateNetResponses, + err error, +) { + path := client.service + "/UpdateNet" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(updatenetrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_UpdateNetResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &UpdateNetResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_UpdateNetAccessPoint( + updatenetaccesspointrequest UpdateNetAccessPointRequest, +) ( + response *POST_UpdateNetAccessPointResponses, + err error, +) { + path := client.service + "/UpdateNetAccessPoint" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(updatenetaccesspointrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_UpdateNetAccessPointResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &UpdateNetAccessPointResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_UpdateNic( + updatenicrequest UpdateNicRequest, +) ( + response *POST_UpdateNicResponses, + err error, +) { + path := client.service + "/UpdateNic" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(updatenicrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_UpdateNicResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &UpdateNicResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_UpdateRoute( + updaterouterequest UpdateRouteRequest, +) ( + response *POST_UpdateRouteResponses, + err error, +) { + path := client.service + "/UpdateRoute" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(updaterouterequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_UpdateRouteResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &UpdateRouteResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_UpdateRoutePropagation( + updateroutepropagationrequest UpdateRoutePropagationRequest, +) ( + response *POST_UpdateRoutePropagationResponses, + err error, +) { + path := client.service + "/UpdateRoutePropagation" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(updateroutepropagationrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_UpdateRoutePropagationResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &UpdateRoutePropagationResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_UpdateServerCertificate( + updateservercertificaterequest UpdateServerCertificateRequest, +) ( + response *POST_UpdateServerCertificateResponses, + err error, +) { + path := client.service + "/UpdateServerCertificate" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(updateservercertificaterequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_UpdateServerCertificateResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &UpdateServerCertificateResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_UpdateSnapshot( + updatesnapshotrequest UpdateSnapshotRequest, +) ( + response *POST_UpdateSnapshotResponses, + err error, +) { + path := client.service + "/UpdateSnapshot" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(updatesnapshotrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_UpdateSnapshotResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &UpdateSnapshotResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +// +func (client *Client) POST_UpdateUser( + updateuserrequest UpdateUserRequest, +) ( + response *POST_UpdateUserResponses, + err error, +) { + path := client.service + "/UpdateUser" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(updateuserrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_UpdateUserResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &UpdateUserResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_UpdateUserGroup( + updateusergrouprequest UpdateUserGroupRequest, +) ( + response *POST_UpdateUserGroupResponses, + err error, +) { + path := client.service + "/UpdateUserGroup" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(updateusergrouprequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_UpdateUserGroupResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &UpdateUserGroupResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + default: + break + } + return +} + +// +func (client *Client) POST_UpdateVm( + updatevmrequest UpdateVmRequest, +) ( + response *POST_UpdateVmResponses, + err error, +) { + path := client.service + "/UpdateVm" + body := new(bytes.Buffer) + json.NewEncoder(body).Encode(updatevmrequest) + req, err := http.NewRequest("POST", path, body) + reqHeaders := make(http.Header) + reqHeaders.Set("Content-Type", "application/json") + req.Header = reqHeaders + client.Sign(req, body.Bytes()) + if err != nil { + return + } + utils.DebugRequest(req) + resp, err := client.Do(req) + if resp != nil { + utils.DebugResponse(resp) + } + if err != nil { + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, checkErrorResponse(resp) + } + response = &POST_UpdateVmResponses{} + switch { + case resp.StatusCode == 200: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &UpdateVmResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.OK = result + case resp.StatusCode == 400: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code400 = result + case resp.StatusCode == 401: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code401 = result + case resp.StatusCode == 500: + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + result := &ErrorResponse{} + err = json.Unmarshal(body, result) + if err != nil { + return nil, err + } + response.Code500 = result + default: + break + } + return +} + +func checkErrorResponse(resp *http.Response) error { + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return fmt.Errorf("error reading response error body %s", err) + } + + reason, errFmt := fmtErrorResponse(body) + if errFmt != nil { + return fmt.Errorf("error formating error resonse %s", err) + } + + return fmt.Errorf("error, status code %d, reason: %s", resp.StatusCode, reason) +} + +func fmtErrorResponse(errBody []byte) (string, error) { + result := &ErrorResponse{} + err := json.Unmarshal(errBody, result) + if err != nil { + return "", err + } + + errors, errPretty := json.MarshalIndent(result, "", " ") + if errPretty != nil { + return "", err + } + + return string(errors), nil +} + +var _ OAPIClient = (*Client)(nil) diff --git a/vendor/github.com/outscale/osc-go/oapi/interface.go b/vendor/github.com/outscale/osc-go/oapi/interface.go new file mode 100644 index 000000000..96aeebc5d --- /dev/null +++ b/vendor/github.com/outscale/osc-go/oapi/interface.go @@ -0,0 +1,1213 @@ +package oapi + +type OAPIClient interface { + POST_AcceptNetPeering( + acceptnetpeeringrequest AcceptNetPeeringRequest, + ) ( + response *POST_AcceptNetPeeringResponses, + err error, + ) + + POST_AuthenticateAccount( + authenticateaccountrequest AuthenticateAccountRequest, + ) ( + response *POST_AuthenticateAccountResponses, + err error, + ) + + POST_CheckSignature( + checksignaturerequest CheckSignatureRequest, + ) ( + response *POST_CheckSignatureResponses, + err error, + ) + + POST_CopyAccount( + copyaccountrequest CopyAccountRequest, + ) ( + response *POST_CopyAccountResponses, + err error, + ) + + POST_CreateAccount( + createaccountrequest CreateAccountRequest, + ) ( + response *POST_CreateAccountResponses, + err error, + ) + + POST_CreateApiKey( + createapikeyrequest CreateApiKeyRequest, + ) ( + response *POST_CreateApiKeyResponses, + err error, + ) + + POST_CreateClientGateway( + createclientgatewayrequest CreateClientGatewayRequest, + ) ( + response *POST_CreateClientGatewayResponses, + err error, + ) + + POST_CreateDhcpOptions( + createdhcpoptionsrequest CreateDhcpOptionsRequest, + ) ( + response *POST_CreateDhcpOptionsResponses, + err error, + ) + + POST_CreateDirectLink( + createdirectlinkrequest CreateDirectLinkRequest, + ) ( + response *POST_CreateDirectLinkResponses, + err error, + ) + + POST_CreateDirectLinkInterface( + createdirectlinkinterfacerequest CreateDirectLinkInterfaceRequest, + ) ( + response *POST_CreateDirectLinkInterfaceResponses, + err error, + ) + + POST_CreateImage( + createimagerequest CreateImageRequest, + ) ( + response *POST_CreateImageResponses, + err error, + ) + + POST_CreateImageExportTask( + createimageexporttaskrequest CreateImageExportTaskRequest, + ) ( + response *POST_CreateImageExportTaskResponses, + err error, + ) + + POST_CreateInternetService( + createinternetservicerequest CreateInternetServiceRequest, + ) ( + response *POST_CreateInternetServiceResponses, + err error, + ) + + POST_CreateKeypair( + createkeypairrequest CreateKeypairRequest, + ) ( + response *POST_CreateKeypairResponses, + err error, + ) + + POST_CreateListenerRule( + createlistenerrulerequest CreateListenerRuleRequest, + ) ( + response *POST_CreateListenerRuleResponses, + err error, + ) + + POST_CreateLoadBalancer( + createloadbalancerrequest CreateLoadBalancerRequest, + ) ( + response *POST_CreateLoadBalancerResponses, + err error, + ) + + POST_CreateLoadBalancerListeners( + createloadbalancerlistenersrequest CreateLoadBalancerListenersRequest, + ) ( + response *POST_CreateLoadBalancerListenersResponses, + err error, + ) + + POST_CreateLoadBalancerPolicy( + createloadbalancerpolicyrequest CreateLoadBalancerPolicyRequest, + ) ( + response *POST_CreateLoadBalancerPolicyResponses, + err error, + ) + + POST_CreateNatService( + createnatservicerequest CreateNatServiceRequest, + ) ( + response *POST_CreateNatServiceResponses, + err error, + ) + + POST_CreateNet( + createnetrequest CreateNetRequest, + ) ( + response *POST_CreateNetResponses, + err error, + ) + + POST_CreateNetAccessPoint( + createnetaccesspointrequest CreateNetAccessPointRequest, + ) ( + response *POST_CreateNetAccessPointResponses, + err error, + ) + + POST_CreateNetPeering( + createnetpeeringrequest CreateNetPeeringRequest, + ) ( + response *POST_CreateNetPeeringResponses, + err error, + ) + + POST_CreateNic( + createnicrequest CreateNicRequest, + ) ( + response *POST_CreateNicResponses, + err error, + ) + + POST_CreatePolicy( + createpolicyrequest CreatePolicyRequest, + ) ( + response *POST_CreatePolicyResponses, + err error, + ) + + POST_CreatePublicIp( + createpubliciprequest CreatePublicIpRequest, + ) ( + response *POST_CreatePublicIpResponses, + err error, + ) + + POST_CreateRoute( + createrouterequest CreateRouteRequest, + ) ( + response *POST_CreateRouteResponses, + err error, + ) + + POST_CreateRouteTable( + createroutetablerequest CreateRouteTableRequest, + ) ( + response *POST_CreateRouteTableResponses, + err error, + ) + + POST_CreateSecurityGroup( + createsecuritygrouprequest CreateSecurityGroupRequest, + ) ( + response *POST_CreateSecurityGroupResponses, + err error, + ) + + POST_CreateSecurityGroupRule( + createsecuritygrouprulerequest CreateSecurityGroupRuleRequest, + ) ( + response *POST_CreateSecurityGroupRuleResponses, + err error, + ) + + POST_CreateServerCertificate( + createservercertificaterequest CreateServerCertificateRequest, + ) ( + response *POST_CreateServerCertificateResponses, + err error, + ) + + POST_CreateSnapshot( + createsnapshotrequest CreateSnapshotRequest, + ) ( + response *POST_CreateSnapshotResponses, + err error, + ) + + POST_CreateSnapshotExportTask( + createsnapshotexporttaskrequest CreateSnapshotExportTaskRequest, + ) ( + response *POST_CreateSnapshotExportTaskResponses, + err error, + ) + + POST_CreateSubnet( + createsubnetrequest CreateSubnetRequest, + ) ( + response *POST_CreateSubnetResponses, + err error, + ) + + POST_CreateTags( + createtagsrequest CreateTagsRequest, + ) ( + response *POST_CreateTagsResponses, + err error, + ) + + POST_CreateUser( + createuserrequest CreateUserRequest, + ) ( + response *POST_CreateUserResponses, + err error, + ) + + POST_CreateUserGroup( + createusergrouprequest CreateUserGroupRequest, + ) ( + response *POST_CreateUserGroupResponses, + err error, + ) + + POST_CreateVirtualGateway( + createvirtualgatewayrequest CreateVirtualGatewayRequest, + ) ( + response *POST_CreateVirtualGatewayResponses, + err error, + ) + + POST_CreateVms( + createvmsrequest CreateVmsRequest, + ) ( + response *POST_CreateVmsResponses, + err error, + ) + + POST_CreateVolume( + createvolumerequest CreateVolumeRequest, + ) ( + response *POST_CreateVolumeResponses, + err error, + ) + + POST_CreateVpnConnection( + createvpnconnectionrequest CreateVpnConnectionRequest, + ) ( + response *POST_CreateVpnConnectionResponses, + err error, + ) + + POST_CreateVpnConnectionRoute( + createvpnconnectionrouterequest CreateVpnConnectionRouteRequest, + ) ( + response *POST_CreateVpnConnectionRouteResponses, + err error, + ) + + POST_DeleteApiKey( + deleteapikeyrequest DeleteApiKeyRequest, + ) ( + response *POST_DeleteApiKeyResponses, + err error, + ) + + POST_DeleteClientGateway( + deleteclientgatewayrequest DeleteClientGatewayRequest, + ) ( + response *POST_DeleteClientGatewayResponses, + err error, + ) + + POST_DeleteDhcpOptions( + deletedhcpoptionsrequest DeleteDhcpOptionsRequest, + ) ( + response *POST_DeleteDhcpOptionsResponses, + err error, + ) + + POST_DeleteDirectLink( + deletedirectlinkrequest DeleteDirectLinkRequest, + ) ( + response *POST_DeleteDirectLinkResponses, + err error, + ) + + POST_DeleteDirectLinkInterface( + deletedirectlinkinterfacerequest DeleteDirectLinkInterfaceRequest, + ) ( + response *POST_DeleteDirectLinkInterfaceResponses, + err error, + ) + + POST_DeleteExportTask( + deleteexporttaskrequest DeleteExportTaskRequest, + ) ( + response *POST_DeleteExportTaskResponses, + err error, + ) + + POST_DeleteImage( + deleteimagerequest DeleteImageRequest, + ) ( + response *POST_DeleteImageResponses, + err error, + ) + + POST_DeleteInternetService( + deleteinternetservicerequest DeleteInternetServiceRequest, + ) ( + response *POST_DeleteInternetServiceResponses, + err error, + ) + + POST_DeleteKeypair( + deletekeypairrequest DeleteKeypairRequest, + ) ( + response *POST_DeleteKeypairResponses, + err error, + ) + + POST_DeleteListenerRule( + deletelistenerrulerequest DeleteListenerRuleRequest, + ) ( + response *POST_DeleteListenerRuleResponses, + err error, + ) + + POST_DeleteLoadBalancer( + deleteloadbalancerrequest DeleteLoadBalancerRequest, + ) ( + response *POST_DeleteLoadBalancerResponses, + err error, + ) + + POST_DeleteLoadBalancerListeners( + deleteloadbalancerlistenersrequest DeleteLoadBalancerListenersRequest, + ) ( + response *POST_DeleteLoadBalancerListenersResponses, + err error, + ) + + POST_DeleteLoadBalancerPolicy( + deleteloadbalancerpolicyrequest DeleteLoadBalancerPolicyRequest, + ) ( + response *POST_DeleteLoadBalancerPolicyResponses, + err error, + ) + + POST_DeleteNatService( + deletenatservicerequest DeleteNatServiceRequest, + ) ( + response *POST_DeleteNatServiceResponses, + err error, + ) + + POST_DeleteNet( + deletenetrequest DeleteNetRequest, + ) ( + response *POST_DeleteNetResponses, + err error, + ) + + POST_DeleteNetAccessPoints( + deletenetaccesspointsrequest DeleteNetAccessPointsRequest, + ) ( + response *POST_DeleteNetAccessPointsResponses, + err error, + ) + + POST_DeleteNetPeering( + deletenetpeeringrequest DeleteNetPeeringRequest, + ) ( + response *POST_DeleteNetPeeringResponses, + err error, + ) + + POST_DeleteNic( + deletenicrequest DeleteNicRequest, + ) ( + response *POST_DeleteNicResponses, + err error, + ) + + POST_DeletePolicy( + deletepolicyrequest DeletePolicyRequest, + ) ( + response *POST_DeletePolicyResponses, + err error, + ) + + POST_DeletePublicIp( + deletepubliciprequest DeletePublicIpRequest, + ) ( + response *POST_DeletePublicIpResponses, + err error, + ) + + POST_DeleteRoute( + deleterouterequest DeleteRouteRequest, + ) ( + response *POST_DeleteRouteResponses, + err error, + ) + + POST_DeleteRouteTable( + deleteroutetablerequest DeleteRouteTableRequest, + ) ( + response *POST_DeleteRouteTableResponses, + err error, + ) + + POST_DeleteSecurityGroup( + deletesecuritygrouprequest DeleteSecurityGroupRequest, + ) ( + response *POST_DeleteSecurityGroupResponses, + err error, + ) + + POST_DeleteSecurityGroupRule( + deletesecuritygrouprulerequest DeleteSecurityGroupRuleRequest, + ) ( + response *POST_DeleteSecurityGroupRuleResponses, + err error, + ) + + POST_DeleteServerCertificate( + deleteservercertificaterequest DeleteServerCertificateRequest, + ) ( + response *POST_DeleteServerCertificateResponses, + err error, + ) + + POST_DeleteSnapshot( + deletesnapshotrequest DeleteSnapshotRequest, + ) ( + response *POST_DeleteSnapshotResponses, + err error, + ) + + POST_DeleteSubnet( + deletesubnetrequest DeleteSubnetRequest, + ) ( + response *POST_DeleteSubnetResponses, + err error, + ) + + POST_DeleteTags( + deletetagsrequest DeleteTagsRequest, + ) ( + response *POST_DeleteTagsResponses, + err error, + ) + + POST_DeleteUser( + deleteuserrequest DeleteUserRequest, + ) ( + response *POST_DeleteUserResponses, + err error, + ) + + POST_DeleteUserGroup( + deleteusergrouprequest DeleteUserGroupRequest, + ) ( + response *POST_DeleteUserGroupResponses, + err error, + ) + + POST_DeleteVirtualGateway( + deletevirtualgatewayrequest DeleteVirtualGatewayRequest, + ) ( + response *POST_DeleteVirtualGatewayResponses, + err error, + ) + + POST_DeleteVms( + deletevmsrequest DeleteVmsRequest, + ) ( + response *POST_DeleteVmsResponses, + err error, + ) + + POST_DeleteVolume( + deletevolumerequest DeleteVolumeRequest, + ) ( + response *POST_DeleteVolumeResponses, + err error, + ) + + POST_DeleteVpnConnection( + deletevpnconnectionrequest DeleteVpnConnectionRequest, + ) ( + response *POST_DeleteVpnConnectionResponses, + err error, + ) + + POST_DeleteVpnConnectionRoute( + deletevpnconnectionrouterequest DeleteVpnConnectionRouteRequest, + ) ( + response *POST_DeleteVpnConnectionRouteResponses, + err error, + ) + + POST_DeregisterUserInUserGroup( + deregisteruserinusergrouprequest DeregisterUserInUserGroupRequest, + ) ( + response *POST_DeregisterUserInUserGroupResponses, + err error, + ) + + POST_DeregisterVmsInLoadBalancer( + deregistervmsinloadbalancerrequest DeregisterVmsInLoadBalancerRequest, + ) ( + response *POST_DeregisterVmsInLoadBalancerResponses, + err error, + ) + + POST_LinkInternetService( + linkinternetservicerequest LinkInternetServiceRequest, + ) ( + response *POST_LinkInternetServiceResponses, + err error, + ) + + POST_LinkNic( + linknicrequest LinkNicRequest, + ) ( + response *POST_LinkNicResponses, + err error, + ) + + POST_LinkPolicy( + linkpolicyrequest LinkPolicyRequest, + ) ( + response *POST_LinkPolicyResponses, + err error, + ) + + POST_LinkPrivateIps( + linkprivateipsrequest LinkPrivateIpsRequest, + ) ( + response *POST_LinkPrivateIpsResponses, + err error, + ) + + POST_LinkPublicIp( + linkpubliciprequest LinkPublicIpRequest, + ) ( + response *POST_LinkPublicIpResponses, + err error, + ) + + POST_LinkRouteTable( + linkroutetablerequest LinkRouteTableRequest, + ) ( + response *POST_LinkRouteTableResponses, + err error, + ) + + POST_LinkVirtualGateway( + linkvirtualgatewayrequest LinkVirtualGatewayRequest, + ) ( + response *POST_LinkVirtualGatewayResponses, + err error, + ) + + POST_LinkVolume( + linkvolumerequest LinkVolumeRequest, + ) ( + response *POST_LinkVolumeResponses, + err error, + ) + + POST_PurchaseReservedVmsOffer( + purchasereservedvmsofferrequest PurchaseReservedVmsOfferRequest, + ) ( + response *POST_PurchaseReservedVmsOfferResponses, + err error, + ) + + POST_ReadAccount( + readaccountrequest ReadAccountRequest, + ) ( + response *POST_ReadAccountResponses, + err error, + ) + + POST_ReadAccountConsumption( + readaccountconsumptionrequest ReadAccountConsumptionRequest, + ) ( + response *POST_ReadAccountConsumptionResponses, + err error, + ) + + POST_ReadAdminPassword( + readadminpasswordrequest ReadAdminPasswordRequest, + ) ( + response *POST_ReadAdminPasswordResponses, + err error, + ) + + POST_ReadApiKeys( + readapikeysrequest ReadApiKeysRequest, + ) ( + response *POST_ReadApiKeysResponses, + err error, + ) + + POST_ReadApiLogs( + readapilogsrequest ReadApiLogsRequest, + ) ( + response *POST_ReadApiLogsResponses, + err error, + ) + + POST_ReadBillableDigest( + readbillabledigestrequest ReadBillableDigestRequest, + ) ( + response *POST_ReadBillableDigestResponses, + err error, + ) + + POST_ReadCatalog( + readcatalogrequest ReadCatalogRequest, + ) ( + response *POST_ReadCatalogResponses, + err error, + ) + + POST_ReadClientGateways( + readclientgatewaysrequest ReadClientGatewaysRequest, + ) ( + response *POST_ReadClientGatewaysResponses, + err error, + ) + + POST_ReadConsoleOutput( + readconsoleoutputrequest ReadConsoleOutputRequest, + ) ( + response *POST_ReadConsoleOutputResponses, + err error, + ) + + POST_ReadDhcpOptions( + readdhcpoptionsrequest ReadDhcpOptionsRequest, + ) ( + response *POST_ReadDhcpOptionsResponses, + err error, + ) + + POST_ReadDirectLinkInterfaces( + readdirectlinkinterfacesrequest ReadDirectLinkInterfacesRequest, + ) ( + response *POST_ReadDirectLinkInterfacesResponses, + err error, + ) + + POST_ReadDirectLinks( + readdirectlinksrequest ReadDirectLinksRequest, + ) ( + response *POST_ReadDirectLinksResponses, + err error, + ) + + POST_ReadImageExportTasks( + readimageexporttasksrequest ReadImageExportTasksRequest, + ) ( + response *POST_ReadImageExportTasksResponses, + err error, + ) + + POST_ReadImages( + readimagesrequest ReadImagesRequest, + ) ( + response *POST_ReadImagesResponses, + err error, + ) + + POST_ReadInternetServices( + readinternetservicesrequest ReadInternetServicesRequest, + ) ( + response *POST_ReadInternetServicesResponses, + err error, + ) + + POST_ReadKeypairs( + readkeypairsrequest ReadKeypairsRequest, + ) ( + response *POST_ReadKeypairsResponses, + err error, + ) + + POST_ReadListenerRules( + readlistenerrulesrequest ReadListenerRulesRequest, + ) ( + response *POST_ReadListenerRulesResponses, + err error, + ) + + POST_ReadLoadBalancers( + readloadbalancersrequest ReadLoadBalancersRequest, + ) ( + response *POST_ReadLoadBalancersResponses, + err error, + ) + + POST_ReadLocations( + readlocationsrequest ReadLocationsRequest, + ) ( + response *POST_ReadLocationsResponses, + err error, + ) + + POST_ReadNatServices( + readnatservicesrequest ReadNatServicesRequest, + ) ( + response *POST_ReadNatServicesResponses, + err error, + ) + + POST_ReadNetAccessPointServices( + readnetaccesspointservicesrequest ReadNetAccessPointServicesRequest, + ) ( + response *POST_ReadNetAccessPointServicesResponses, + err error, + ) + + POST_ReadNetAccessPoints( + readnetaccesspointsrequest ReadNetAccessPointsRequest, + ) ( + response *POST_ReadNetAccessPointsResponses, + err error, + ) + + POST_ReadNetPeerings( + readnetpeeringsrequest ReadNetPeeringsRequest, + ) ( + response *POST_ReadNetPeeringsResponses, + err error, + ) + + POST_ReadNets( + readnetsrequest ReadNetsRequest, + ) ( + response *POST_ReadNetsResponses, + err error, + ) + + POST_ReadNics( + readnicsrequest ReadNicsRequest, + ) ( + response *POST_ReadNicsResponses, + err error, + ) + + POST_ReadPolicies( + readpoliciesrequest ReadPoliciesRequest, + ) ( + response *POST_ReadPoliciesResponses, + err error, + ) + + POST_ReadPrefixLists( + readprefixlistsrequest ReadPrefixListsRequest, + ) ( + response *POST_ReadPrefixListsResponses, + err error, + ) + + POST_ReadProductTypes( + readproducttypesrequest ReadProductTypesRequest, + ) ( + response *POST_ReadProductTypesResponses, + err error, + ) + + POST_ReadPublicCatalog( + readpubliccatalogrequest ReadPublicCatalogRequest, + ) ( + response *POST_ReadPublicCatalogResponses, + err error, + ) + + POST_ReadPublicIpRanges( + readpubliciprangesrequest ReadPublicIpRangesRequest, + ) ( + response *POST_ReadPublicIpRangesResponses, + err error, + ) + + POST_ReadPublicIps( + readpublicipsrequest ReadPublicIpsRequest, + ) ( + response *POST_ReadPublicIpsResponses, + err error, + ) + + POST_ReadQuotas( + readquotasrequest ReadQuotasRequest, + ) ( + response *POST_ReadQuotasResponses, + err error, + ) + + POST_ReadRegionConfig( + readregionconfigrequest ReadRegionConfigRequest, + ) ( + response *POST_ReadRegionConfigResponses, + err error, + ) + + POST_ReadRegions( + readregionsrequest ReadRegionsRequest, + ) ( + response *POST_ReadRegionsResponses, + err error, + ) + + POST_ReadReservedVmOffers( + readreservedvmoffersrequest ReadReservedVmOffersRequest, + ) ( + response *POST_ReadReservedVmOffersResponses, + err error, + ) + + POST_ReadReservedVms( + readreservedvmsrequest ReadReservedVmsRequest, + ) ( + response *POST_ReadReservedVmsResponses, + err error, + ) + + POST_ReadRouteTables( + readroutetablesrequest ReadRouteTablesRequest, + ) ( + response *POST_ReadRouteTablesResponses, + err error, + ) + + POST_ReadSecurityGroups( + readsecuritygroupsrequest ReadSecurityGroupsRequest, + ) ( + response *POST_ReadSecurityGroupsResponses, + err error, + ) + + POST_ReadServerCertificates( + readservercertificatesrequest ReadServerCertificatesRequest, + ) ( + response *POST_ReadServerCertificatesResponses, + err error, + ) + + POST_ReadSnapshotExportTasks( + readsnapshotexporttasksrequest ReadSnapshotExportTasksRequest, + ) ( + response *POST_ReadSnapshotExportTasksResponses, + err error, + ) + + POST_ReadSnapshots( + readsnapshotsrequest ReadSnapshotsRequest, + ) ( + response *POST_ReadSnapshotsResponses, + err error, + ) + + POST_ReadSubnets( + readsubnetsrequest ReadSubnetsRequest, + ) ( + response *POST_ReadSubnetsResponses, + err error, + ) + + POST_ReadSubregions( + readsubregionsrequest ReadSubregionsRequest, + ) ( + response *POST_ReadSubregionsResponses, + err error, + ) + + POST_ReadTags( + readtagsrequest ReadTagsRequest, + ) ( + response *POST_ReadTagsResponses, + err error, + ) + + POST_ReadUserGroups( + readusergroupsrequest ReadUserGroupsRequest, + ) ( + response *POST_ReadUserGroupsResponses, + err error, + ) + + POST_ReadUsers( + readusersrequest ReadUsersRequest, + ) ( + response *POST_ReadUsersResponses, + err error, + ) + + POST_ReadVirtualGateways( + readvirtualgatewaysrequest ReadVirtualGatewaysRequest, + ) ( + response *POST_ReadVirtualGatewaysResponses, + err error, + ) + POST_ReadVmTypes( + readvmtypesrequest ReadVmTypesRequest, + ) ( + response *POST_ReadVmTypesResponses, + err error, + ) + + POST_ReadVms( + readvmsrequest ReadVmsRequest, + ) ( + response *POST_ReadVmsResponses, + err error, + ) + + POST_ReadVmsHealth( + readvmshealthrequest ReadVmsHealthRequest, + ) ( + response *POST_ReadVmsHealthResponses, + err error, + ) + + POST_ReadVmsState( + readvmsstaterequest ReadVmsStateRequest, + ) ( + response *POST_ReadVmsStateResponses, + err error, + ) + + POST_ReadVolumes( + readvolumesrequest ReadVolumesRequest, + ) ( + response *POST_ReadVolumesResponses, + err error, + ) + + POST_ReadVpnConnections( + readvpnconnectionsrequest ReadVpnConnectionsRequest, + ) ( + response *POST_ReadVpnConnectionsResponses, + err error, + ) + + POST_RebootVms( + rebootvmsrequest RebootVmsRequest, + ) ( + response *POST_RebootVmsResponses, + err error, + ) + + POST_RegisterUserInUserGroup( + registeruserinusergrouprequest RegisterUserInUserGroupRequest, + ) ( + response *POST_RegisterUserInUserGroupResponses, + err error, + ) + + POST_RegisterVmsInLoadBalancer( + registervmsinloadbalancerrequest RegisterVmsInLoadBalancerRequest, + ) ( + response *POST_RegisterVmsInLoadBalancerResponses, + err error, + ) + + POST_RejectNetPeering( + rejectnetpeeringrequest RejectNetPeeringRequest, + ) ( + response *POST_RejectNetPeeringResponses, + err error, + ) + + POST_ResetAccountPassword( + resetaccountpasswordrequest ResetAccountPasswordRequest, + ) ( + response *POST_ResetAccountPasswordResponses, + err error, + ) + + POST_SendResetPasswordEmail( + sendresetpasswordemailrequest SendResetPasswordEmailRequest, + ) ( + response *POST_SendResetPasswordEmailResponses, + err error, + ) + + POST_StartVms( + startvmsrequest StartVmsRequest, + ) ( + response *POST_StartVmsResponses, + err error, + ) + + POST_StopVms( + stopvmsrequest StopVmsRequest, + ) ( + response *POST_StopVmsResponses, + err error, + ) + + POST_UnlinkInternetService( + unlinkinternetservicerequest UnlinkInternetServiceRequest, + ) ( + response *POST_UnlinkInternetServiceResponses, + err error, + ) + + POST_UnlinkNic( + unlinknicrequest UnlinkNicRequest, + ) ( + response *POST_UnlinkNicResponses, + err error, + ) + + POST_UnlinkPolicy( + unlinkpolicyrequest UnlinkPolicyRequest, + ) ( + response *POST_UnlinkPolicyResponses, + err error, + ) + + POST_UnlinkPrivateIps( + unlinkprivateipsrequest UnlinkPrivateIpsRequest, + ) ( + response *POST_UnlinkPrivateIpsResponses, + err error, + ) + + POST_UnlinkPublicIp( + unlinkpubliciprequest UnlinkPublicIpRequest, + ) ( + response *POST_UnlinkPublicIpResponses, + err error, + ) + + POST_UnlinkRouteTable( + unlinkroutetablerequest UnlinkRouteTableRequest, + ) ( + response *POST_UnlinkRouteTableResponses, + err error, + ) + + POST_UnlinkVirtualGateway( + unlinkvirtualgatewayrequest UnlinkVirtualGatewayRequest, + ) ( + response *POST_UnlinkVirtualGatewayResponses, + err error, + ) + + POST_UnlinkVolume( + unlinkvolumerequest UnlinkVolumeRequest, + ) ( + response *POST_UnlinkVolumeResponses, + err error, + ) + + POST_UpdateAccount( + updateaccountrequest UpdateAccountRequest, + ) ( + response *POST_UpdateAccountResponses, + err error, + ) + + POST_UpdateApiKey( + updateapikeyrequest UpdateApiKeyRequest, + ) ( + response *POST_UpdateApiKeyResponses, + err error, + ) + + POST_UpdateHealthCheck( + updatehealthcheckrequest UpdateHealthCheckRequest, + ) ( + response *POST_UpdateHealthCheckResponses, + err error, + ) + + POST_UpdateImage( + updateimagerequest UpdateImageRequest, + ) ( + response *POST_UpdateImageResponses, + err error, + ) + + POST_UpdateKeypair( + updatekeypairrequest UpdateKeypairRequest, + ) ( + response *POST_UpdateKeypairResponses, + err error, + ) + + POST_UpdateListenerRule( + updatelistenerrulerequest UpdateListenerRuleRequest, + ) ( + response *POST_UpdateListenerRuleResponses, + err error, + ) + + POST_UpdateLoadBalancer( + updateloadbalancerrequest UpdateLoadBalancerRequest, + ) ( + response *POST_UpdateLoadBalancerResponses, + err error, + ) + + POST_UpdateNet( + updatenetrequest UpdateNetRequest, + ) ( + response *POST_UpdateNetResponses, + err error, + ) + + POST_UpdateNetAccessPoint( + updatenetaccesspointrequest UpdateNetAccessPointRequest, + ) ( + response *POST_UpdateNetAccessPointResponses, + err error, + ) + + POST_UpdateNic( + updatenicrequest UpdateNicRequest, + ) ( + response *POST_UpdateNicResponses, + err error, + ) + + POST_UpdateRoute( + updaterouterequest UpdateRouteRequest, + ) ( + response *POST_UpdateRouteResponses, + err error, + ) + + POST_UpdateRoutePropagation( + updateroutepropagationrequest UpdateRoutePropagationRequest, + ) ( + response *POST_UpdateRoutePropagationResponses, + err error, + ) + + POST_UpdateServerCertificate( + updateservercertificaterequest UpdateServerCertificateRequest, + ) ( + response *POST_UpdateServerCertificateResponses, + err error, + ) + + POST_UpdateSnapshot( + updatesnapshotrequest UpdateSnapshotRequest, + ) ( + response *POST_UpdateSnapshotResponses, + err error, + ) + + POST_UpdateUser( + updateuserrequest UpdateUserRequest, + ) ( + response *POST_UpdateUserResponses, + err error, + ) + + POST_UpdateUserGroup( + updateusergrouprequest UpdateUserGroupRequest, + ) ( + response *POST_UpdateUserGroupResponses, + err error, + ) + + POST_UpdateVm( + updatevmrequest UpdateVmRequest, + ) ( + response *POST_UpdateVmResponses, + err error, + ) +} diff --git a/vendor/github.com/outscale/osc-go/oapi/provider.go b/vendor/github.com/outscale/osc-go/oapi/provider.go new file mode 100644 index 000000000..0ae1b4d3b --- /dev/null +++ b/vendor/github.com/outscale/osc-go/oapi/provider.go @@ -0,0 +1,527 @@ +// GENERATED FILE: DO NOT EDIT! + +package oapi + +// To create a server, first write a class that implements this interface. +// Then pass an instance of it to Initialize(). +type Provider interface { + + // + POST_AcceptNetPeering(parameters *POST_AcceptNetPeeringParameters, responses *POST_AcceptNetPeeringResponses) (err error) + + // + POST_AuthenticateAccount(parameters *POST_AuthenticateAccountParameters, responses *POST_AuthenticateAccountResponses) (err error) + + // + POST_CheckSignature(parameters *POST_CheckSignatureParameters, responses *POST_CheckSignatureResponses) (err error) + + // + POST_CopyAccount(parameters *POST_CopyAccountParameters, responses *POST_CopyAccountResponses) (err error) + + // + POST_CreateAccount(parameters *POST_CreateAccountParameters, responses *POST_CreateAccountResponses) (err error) + + // + POST_CreateApiKey(parameters *POST_CreateApiKeyParameters, responses *POST_CreateApiKeyResponses) (err error) + + // + POST_CreateClientGateway(parameters *POST_CreateClientGatewayParameters, responses *POST_CreateClientGatewayResponses) (err error) + + // + POST_CreateDhcpOptions(parameters *POST_CreateDhcpOptionsParameters, responses *POST_CreateDhcpOptionsResponses) (err error) + + // + POST_CreateDirectLink(parameters *POST_CreateDirectLinkParameters, responses *POST_CreateDirectLinkResponses) (err error) + + // + POST_CreateDirectLinkInterface(parameters *POST_CreateDirectLinkInterfaceParameters, responses *POST_CreateDirectLinkInterfaceResponses) (err error) + + // + POST_CreateImage(parameters *POST_CreateImageParameters, responses *POST_CreateImageResponses) (err error) + + // + POST_CreateImageExportTask(parameters *POST_CreateImageExportTaskParameters, responses *POST_CreateImageExportTaskResponses) (err error) + + // + POST_CreateInternetService(parameters *POST_CreateInternetServiceParameters, responses *POST_CreateInternetServiceResponses) (err error) + + // + POST_CreateKeypair(parameters *POST_CreateKeypairParameters, responses *POST_CreateKeypairResponses) (err error) + + // + POST_CreateListenerRule(parameters *POST_CreateListenerRuleParameters, responses *POST_CreateListenerRuleResponses) (err error) + + // + POST_CreateLoadBalancer(parameters *POST_CreateLoadBalancerParameters, responses *POST_CreateLoadBalancerResponses) (err error) + + // + POST_CreateLoadBalancerListeners(parameters *POST_CreateLoadBalancerListenersParameters, responses *POST_CreateLoadBalancerListenersResponses) (err error) + + // + POST_CreateLoadBalancerPolicy(parameters *POST_CreateLoadBalancerPolicyParameters, responses *POST_CreateLoadBalancerPolicyResponses) (err error) + + // + POST_CreateNatService(parameters *POST_CreateNatServiceParameters, responses *POST_CreateNatServiceResponses) (err error) + + // + POST_CreateNet(parameters *POST_CreateNetParameters, responses *POST_CreateNetResponses) (err error) + + // + POST_CreateNetAccessPoint(parameters *POST_CreateNetAccessPointParameters, responses *POST_CreateNetAccessPointResponses) (err error) + + // + POST_CreateNetPeering(parameters *POST_CreateNetPeeringParameters, responses *POST_CreateNetPeeringResponses) (err error) + + // + POST_CreateNic(parameters *POST_CreateNicParameters, responses *POST_CreateNicResponses) (err error) + + // + POST_CreatePolicy(parameters *POST_CreatePolicyParameters, responses *POST_CreatePolicyResponses) (err error) + + // + POST_CreatePublicIp(parameters *POST_CreatePublicIpParameters, responses *POST_CreatePublicIpResponses) (err error) + + // + POST_CreateRoute(parameters *POST_CreateRouteParameters, responses *POST_CreateRouteResponses) (err error) + + // + POST_CreateRouteTable(parameters *POST_CreateRouteTableParameters, responses *POST_CreateRouteTableResponses) (err error) + + // + POST_CreateSecurityGroup(parameters *POST_CreateSecurityGroupParameters, responses *POST_CreateSecurityGroupResponses) (err error) + + // + POST_CreateSecurityGroupRule(parameters *POST_CreateSecurityGroupRuleParameters, responses *POST_CreateSecurityGroupRuleResponses) (err error) + + // + POST_CreateServerCertificate(parameters *POST_CreateServerCertificateParameters, responses *POST_CreateServerCertificateResponses) (err error) + + // + POST_CreateSnapshot(parameters *POST_CreateSnapshotParameters, responses *POST_CreateSnapshotResponses) (err error) + + // + POST_CreateSnapshotExportTask(parameters *POST_CreateSnapshotExportTaskParameters, responses *POST_CreateSnapshotExportTaskResponses) (err error) + + // + POST_CreateSubnet(parameters *POST_CreateSubnetParameters, responses *POST_CreateSubnetResponses) (err error) + + // + POST_CreateTags(parameters *POST_CreateTagsParameters, responses *POST_CreateTagsResponses) (err error) + + // + POST_CreateUser(parameters *POST_CreateUserParameters, responses *POST_CreateUserResponses) (err error) + + // + POST_CreateUserGroup(parameters *POST_CreateUserGroupParameters, responses *POST_CreateUserGroupResponses) (err error) + + // + POST_CreateVirtualGateway(parameters *POST_CreateVirtualGatewayParameters, responses *POST_CreateVirtualGatewayResponses) (err error) + + // + POST_CreateVms(parameters *POST_CreateVmsParameters, responses *POST_CreateVmsResponses) (err error) + + // + POST_CreateVolume(parameters *POST_CreateVolumeParameters, responses *POST_CreateVolumeResponses) (err error) + + // + POST_CreateVpnConnection(parameters *POST_CreateVpnConnectionParameters, responses *POST_CreateVpnConnectionResponses) (err error) + + // + POST_CreateVpnConnectionRoute(parameters *POST_CreateVpnConnectionRouteParameters, responses *POST_CreateVpnConnectionRouteResponses) (err error) + + // + POST_DeleteApiKey(parameters *POST_DeleteApiKeyParameters, responses *POST_DeleteApiKeyResponses) (err error) + + // + POST_DeleteClientGateway(parameters *POST_DeleteClientGatewayParameters, responses *POST_DeleteClientGatewayResponses) (err error) + + // + POST_DeleteDhcpOptions(parameters *POST_DeleteDhcpOptionsParameters, responses *POST_DeleteDhcpOptionsResponses) (err error) + + // + POST_DeleteDirectLink(parameters *POST_DeleteDirectLinkParameters, responses *POST_DeleteDirectLinkResponses) (err error) + + // + POST_DeleteDirectLinkInterface(parameters *POST_DeleteDirectLinkInterfaceParameters, responses *POST_DeleteDirectLinkInterfaceResponses) (err error) + + // + POST_DeleteExportTask(parameters *POST_DeleteExportTaskParameters, responses *POST_DeleteExportTaskResponses) (err error) + + // + POST_DeleteImage(parameters *POST_DeleteImageParameters, responses *POST_DeleteImageResponses) (err error) + + // + POST_DeleteInternetService(parameters *POST_DeleteInternetServiceParameters, responses *POST_DeleteInternetServiceResponses) (err error) + + // + POST_DeleteKeypair(parameters *POST_DeleteKeypairParameters, responses *POST_DeleteKeypairResponses) (err error) + + // + POST_DeleteListenerRule(parameters *POST_DeleteListenerRuleParameters, responses *POST_DeleteListenerRuleResponses) (err error) + + // + POST_DeleteLoadBalancer(parameters *POST_DeleteLoadBalancerParameters, responses *POST_DeleteLoadBalancerResponses) (err error) + + // + POST_DeleteLoadBalancerListeners(parameters *POST_DeleteLoadBalancerListenersParameters, responses *POST_DeleteLoadBalancerListenersResponses) (err error) + + // + POST_DeleteLoadBalancerPolicy(parameters *POST_DeleteLoadBalancerPolicyParameters, responses *POST_DeleteLoadBalancerPolicyResponses) (err error) + + // + POST_DeleteNatService(parameters *POST_DeleteNatServiceParameters, responses *POST_DeleteNatServiceResponses) (err error) + + // + POST_DeleteNet(parameters *POST_DeleteNetParameters, responses *POST_DeleteNetResponses) (err error) + + // + POST_DeleteNetAccessPoints(parameters *POST_DeleteNetAccessPointsParameters, responses *POST_DeleteNetAccessPointsResponses) (err error) + + // + POST_DeleteNetPeering(parameters *POST_DeleteNetPeeringParameters, responses *POST_DeleteNetPeeringResponses) (err error) + + // + POST_DeleteNic(parameters *POST_DeleteNicParameters, responses *POST_DeleteNicResponses) (err error) + + // + POST_DeletePolicy(parameters *POST_DeletePolicyParameters, responses *POST_DeletePolicyResponses) (err error) + + // + POST_DeletePublicIp(parameters *POST_DeletePublicIpParameters, responses *POST_DeletePublicIpResponses) (err error) + + // + POST_DeleteRoute(parameters *POST_DeleteRouteParameters, responses *POST_DeleteRouteResponses) (err error) + + // + POST_DeleteRouteTable(parameters *POST_DeleteRouteTableParameters, responses *POST_DeleteRouteTableResponses) (err error) + + // + POST_DeleteSecurityGroup(parameters *POST_DeleteSecurityGroupParameters, responses *POST_DeleteSecurityGroupResponses) (err error) + + // + POST_DeleteSecurityGroupRule(parameters *POST_DeleteSecurityGroupRuleParameters, responses *POST_DeleteSecurityGroupRuleResponses) (err error) + + // + POST_DeleteServerCertificate(parameters *POST_DeleteServerCertificateParameters, responses *POST_DeleteServerCertificateResponses) (err error) + + // + POST_DeleteSnapshot(parameters *POST_DeleteSnapshotParameters, responses *POST_DeleteSnapshotResponses) (err error) + + // + POST_DeleteSubnet(parameters *POST_DeleteSubnetParameters, responses *POST_DeleteSubnetResponses) (err error) + + // + POST_DeleteTags(parameters *POST_DeleteTagsParameters, responses *POST_DeleteTagsResponses) (err error) + + // + POST_DeleteUser(parameters *POST_DeleteUserParameters, responses *POST_DeleteUserResponses) (err error) + + // + POST_DeleteUserGroup(parameters *POST_DeleteUserGroupParameters, responses *POST_DeleteUserGroupResponses) (err error) + + // + POST_DeleteVirtualGateway(parameters *POST_DeleteVirtualGatewayParameters, responses *POST_DeleteVirtualGatewayResponses) (err error) + + // + POST_DeleteVms(parameters *POST_DeleteVmsParameters, responses *POST_DeleteVmsResponses) (err error) + + // + POST_DeleteVolume(parameters *POST_DeleteVolumeParameters, responses *POST_DeleteVolumeResponses) (err error) + + // + POST_DeleteVpnConnection(parameters *POST_DeleteVpnConnectionParameters, responses *POST_DeleteVpnConnectionResponses) (err error) + + // + POST_DeleteVpnConnectionRoute(parameters *POST_DeleteVpnConnectionRouteParameters, responses *POST_DeleteVpnConnectionRouteResponses) (err error) + + // + POST_DeregisterUserInUserGroup(parameters *POST_DeregisterUserInUserGroupParameters, responses *POST_DeregisterUserInUserGroupResponses) (err error) + + // + POST_DeregisterVmsInLoadBalancer(parameters *POST_DeregisterVmsInLoadBalancerParameters, responses *POST_DeregisterVmsInLoadBalancerResponses) (err error) + + // + POST_LinkInternetService(parameters *POST_LinkInternetServiceParameters, responses *POST_LinkInternetServiceResponses) (err error) + + // + POST_LinkNic(parameters *POST_LinkNicParameters, responses *POST_LinkNicResponses) (err error) + + // + POST_LinkPolicy(parameters *POST_LinkPolicyParameters, responses *POST_LinkPolicyResponses) (err error) + + // + POST_LinkPrivateIps(parameters *POST_LinkPrivateIpsParameters, responses *POST_LinkPrivateIpsResponses) (err error) + + // + POST_LinkPublicIp(parameters *POST_LinkPublicIpParameters, responses *POST_LinkPublicIpResponses) (err error) + + // + POST_LinkRouteTable(parameters *POST_LinkRouteTableParameters, responses *POST_LinkRouteTableResponses) (err error) + + // + POST_LinkVirtualGateway(parameters *POST_LinkVirtualGatewayParameters, responses *POST_LinkVirtualGatewayResponses) (err error) + + // + POST_LinkVolume(parameters *POST_LinkVolumeParameters, responses *POST_LinkVolumeResponses) (err error) + + // + POST_PurchaseReservedVmsOffer(parameters *POST_PurchaseReservedVmsOfferParameters, responses *POST_PurchaseReservedVmsOfferResponses) (err error) + + // + POST_ReadAccount(parameters *POST_ReadAccountParameters, responses *POST_ReadAccountResponses) (err error) + + // + POST_ReadAccountConsumption(parameters *POST_ReadAccountConsumptionParameters, responses *POST_ReadAccountConsumptionResponses) (err error) + + // + POST_ReadAdminPassword(parameters *POST_ReadAdminPasswordParameters, responses *POST_ReadAdminPasswordResponses) (err error) + + // + POST_ReadApiKeys(parameters *POST_ReadApiKeysParameters, responses *POST_ReadApiKeysResponses) (err error) + + // + POST_ReadApiLogs(parameters *POST_ReadApiLogsParameters, responses *POST_ReadApiLogsResponses) (err error) + + // + POST_ReadBillableDigest(parameters *POST_ReadBillableDigestParameters, responses *POST_ReadBillableDigestResponses) (err error) + + // + POST_ReadCatalog(parameters *POST_ReadCatalogParameters, responses *POST_ReadCatalogResponses) (err error) + + // + POST_ReadClientGateways(parameters *POST_ReadClientGatewaysParameters, responses *POST_ReadClientGatewaysResponses) (err error) + + // + POST_ReadConsoleOutput(parameters *POST_ReadConsoleOutputParameters, responses *POST_ReadConsoleOutputResponses) (err error) + + // + POST_ReadDhcpOptions(parameters *POST_ReadDhcpOptionsParameters, responses *POST_ReadDhcpOptionsResponses) (err error) + + // + POST_ReadDirectLinkInterfaces(parameters *POST_ReadDirectLinkInterfacesParameters, responses *POST_ReadDirectLinkInterfacesResponses) (err error) + + // + POST_ReadDirectLinks(parameters *POST_ReadDirectLinksParameters, responses *POST_ReadDirectLinksResponses) (err error) + + // + POST_ReadImageExportTasks(parameters *POST_ReadImageExportTasksParameters, responses *POST_ReadImageExportTasksResponses) (err error) + + // + POST_ReadImages(parameters *POST_ReadImagesParameters, responses *POST_ReadImagesResponses) (err error) + + // + POST_ReadInternetServices(parameters *POST_ReadInternetServicesParameters, responses *POST_ReadInternetServicesResponses) (err error) + + // + POST_ReadKeypairs(parameters *POST_ReadKeypairsParameters, responses *POST_ReadKeypairsResponses) (err error) + + // + POST_ReadListenerRules(parameters *POST_ReadListenerRulesParameters, responses *POST_ReadListenerRulesResponses) (err error) + + // + POST_ReadLoadBalancers(parameters *POST_ReadLoadBalancersParameters, responses *POST_ReadLoadBalancersResponses) (err error) + + // + POST_ReadLocations(parameters *POST_ReadLocationsParameters, responses *POST_ReadLocationsResponses) (err error) + + // + POST_ReadNatServices(parameters *POST_ReadNatServicesParameters, responses *POST_ReadNatServicesResponses) (err error) + + // + POST_ReadNetAccessPointServices(parameters *POST_ReadNetAccessPointServicesParameters, responses *POST_ReadNetAccessPointServicesResponses) (err error) + + // + POST_ReadNetAccessPoints(parameters *POST_ReadNetAccessPointsParameters, responses *POST_ReadNetAccessPointsResponses) (err error) + + // + POST_ReadNetPeerings(parameters *POST_ReadNetPeeringsParameters, responses *POST_ReadNetPeeringsResponses) (err error) + + // + POST_ReadNets(parameters *POST_ReadNetsParameters, responses *POST_ReadNetsResponses) (err error) + + // + POST_ReadNics(parameters *POST_ReadNicsParameters, responses *POST_ReadNicsResponses) (err error) + + // + POST_ReadPolicies(parameters *POST_ReadPoliciesParameters, responses *POST_ReadPoliciesResponses) (err error) + + // + POST_ReadPrefixLists(parameters *POST_ReadPrefixListsParameters, responses *POST_ReadPrefixListsResponses) (err error) + + // + POST_ReadProductTypes(parameters *POST_ReadProductTypesParameters, responses *POST_ReadProductTypesResponses) (err error) + + // + POST_ReadPublicCatalog(parameters *POST_ReadPublicCatalogParameters, responses *POST_ReadPublicCatalogResponses) (err error) + + // + POST_ReadPublicIpRanges(parameters *POST_ReadPublicIpRangesParameters, responses *POST_ReadPublicIpRangesResponses) (err error) + + // + POST_ReadPublicIps(parameters *POST_ReadPublicIpsParameters, responses *POST_ReadPublicIpsResponses) (err error) + + // + POST_ReadQuotas(parameters *POST_ReadQuotasParameters, responses *POST_ReadQuotasResponses) (err error) + + // + POST_ReadRegionConfig(parameters *POST_ReadRegionConfigParameters, responses *POST_ReadRegionConfigResponses) (err error) + + // + POST_ReadRegions(parameters *POST_ReadRegionsParameters, responses *POST_ReadRegionsResponses) (err error) + + // + POST_ReadReservedVmOffers(parameters *POST_ReadReservedVmOffersParameters, responses *POST_ReadReservedVmOffersResponses) (err error) + + // + POST_ReadReservedVms(parameters *POST_ReadReservedVmsParameters, responses *POST_ReadReservedVmsResponses) (err error) + + // + POST_ReadRouteTables(parameters *POST_ReadRouteTablesParameters, responses *POST_ReadRouteTablesResponses) (err error) + + // + POST_ReadSecurityGroups(parameters *POST_ReadSecurityGroupsParameters, responses *POST_ReadSecurityGroupsResponses) (err error) + + // + POST_ReadServerCertificates(parameters *POST_ReadServerCertificatesParameters, responses *POST_ReadServerCertificatesResponses) (err error) + + // + POST_ReadSnapshotExportTasks(parameters *POST_ReadSnapshotExportTasksParameters, responses *POST_ReadSnapshotExportTasksResponses) (err error) + + // + POST_ReadSnapshots(parameters *POST_ReadSnapshotsParameters, responses *POST_ReadSnapshotsResponses) (err error) + + // + POST_ReadSubnets(parameters *POST_ReadSubnetsParameters, responses *POST_ReadSubnetsResponses) (err error) + + // + POST_ReadSubregions(parameters *POST_ReadSubregionsParameters, responses *POST_ReadSubregionsResponses) (err error) + + // + POST_ReadTags(parameters *POST_ReadTagsParameters, responses *POST_ReadTagsResponses) (err error) + + // + POST_ReadUserGroups(parameters *POST_ReadUserGroupsParameters, responses *POST_ReadUserGroupsResponses) (err error) + + // + POST_ReadUsers(parameters *POST_ReadUsersParameters, responses *POST_ReadUsersResponses) (err error) + + // + POST_ReadVirtualGateways(parameters *POST_ReadVirtualGatewaysParameters, responses *POST_ReadVirtualGatewaysResponses) (err error) + + // + POST_ReadVmTypes(parameters *POST_ReadVmTypesParameters, responses *POST_ReadVmTypesResponses) (err error) + + // + POST_ReadVms(parameters *POST_ReadVmsParameters, responses *POST_ReadVmsResponses) (err error) + + // + POST_ReadVmsHealth(parameters *POST_ReadVmsHealthParameters, responses *POST_ReadVmsHealthResponses) (err error) + + // + POST_ReadVmsState(parameters *POST_ReadVmsStateParameters, responses *POST_ReadVmsStateResponses) (err error) + + // + POST_ReadVolumes(parameters *POST_ReadVolumesParameters, responses *POST_ReadVolumesResponses) (err error) + + // + POST_ReadVpnConnections(parameters *POST_ReadVpnConnectionsParameters, responses *POST_ReadVpnConnectionsResponses) (err error) + + // + POST_RebootVms(parameters *POST_RebootVmsParameters, responses *POST_RebootVmsResponses) (err error) + + // + POST_RegisterUserInUserGroup(parameters *POST_RegisterUserInUserGroupParameters, responses *POST_RegisterUserInUserGroupResponses) (err error) + + // + POST_RegisterVmsInLoadBalancer(parameters *POST_RegisterVmsInLoadBalancerParameters, responses *POST_RegisterVmsInLoadBalancerResponses) (err error) + + // + POST_RejectNetPeering(parameters *POST_RejectNetPeeringParameters, responses *POST_RejectNetPeeringResponses) (err error) + + // + POST_ResetAccountPassword(parameters *POST_ResetAccountPasswordParameters, responses *POST_ResetAccountPasswordResponses) (err error) + + // + POST_SendResetPasswordEmail(parameters *POST_SendResetPasswordEmailParameters, responses *POST_SendResetPasswordEmailResponses) (err error) + + // + POST_StartVms(parameters *POST_StartVmsParameters, responses *POST_StartVmsResponses) (err error) + + // + POST_StopVms(parameters *POST_StopVmsParameters, responses *POST_StopVmsResponses) (err error) + + // + POST_UnlinkInternetService(parameters *POST_UnlinkInternetServiceParameters, responses *POST_UnlinkInternetServiceResponses) (err error) + + // + POST_UnlinkNic(parameters *POST_UnlinkNicParameters, responses *POST_UnlinkNicResponses) (err error) + + // + POST_UnlinkPolicy(parameters *POST_UnlinkPolicyParameters, responses *POST_UnlinkPolicyResponses) (err error) + + // + POST_UnlinkPrivateIps(parameters *POST_UnlinkPrivateIpsParameters, responses *POST_UnlinkPrivateIpsResponses) (err error) + + // + POST_UnlinkPublicIp(parameters *POST_UnlinkPublicIpParameters, responses *POST_UnlinkPublicIpResponses) (err error) + + // + POST_UnlinkRouteTable(parameters *POST_UnlinkRouteTableParameters, responses *POST_UnlinkRouteTableResponses) (err error) + + // + POST_UnlinkVirtualGateway(parameters *POST_UnlinkVirtualGatewayParameters, responses *POST_UnlinkVirtualGatewayResponses) (err error) + + // + POST_UnlinkVolume(parameters *POST_UnlinkVolumeParameters, responses *POST_UnlinkVolumeResponses) (err error) + + // + POST_UpdateAccount(parameters *POST_UpdateAccountParameters, responses *POST_UpdateAccountResponses) (err error) + + // + POST_UpdateApiKey(parameters *POST_UpdateApiKeyParameters, responses *POST_UpdateApiKeyResponses) (err error) + + // + POST_UpdateHealthCheck(parameters *POST_UpdateHealthCheckParameters, responses *POST_UpdateHealthCheckResponses) (err error) + + // + POST_UpdateImage(parameters *POST_UpdateImageParameters, responses *POST_UpdateImageResponses) (err error) + + // + POST_UpdateKeypair(parameters *POST_UpdateKeypairParameters, responses *POST_UpdateKeypairResponses) (err error) + + // + POST_UpdateListenerRule(parameters *POST_UpdateListenerRuleParameters, responses *POST_UpdateListenerRuleResponses) (err error) + + // + POST_UpdateLoadBalancer(parameters *POST_UpdateLoadBalancerParameters, responses *POST_UpdateLoadBalancerResponses) (err error) + + // + POST_UpdateNet(parameters *POST_UpdateNetParameters, responses *POST_UpdateNetResponses) (err error) + + // + POST_UpdateNetAccessPoint(parameters *POST_UpdateNetAccessPointParameters, responses *POST_UpdateNetAccessPointResponses) (err error) + + // + POST_UpdateNic(parameters *POST_UpdateNicParameters, responses *POST_UpdateNicResponses) (err error) + + // + POST_UpdateRoute(parameters *POST_UpdateRouteParameters, responses *POST_UpdateRouteResponses) (err error) + + // + POST_UpdateRoutePropagation(parameters *POST_UpdateRoutePropagationParameters, responses *POST_UpdateRoutePropagationResponses) (err error) + + // + POST_UpdateServerCertificate(parameters *POST_UpdateServerCertificateParameters, responses *POST_UpdateServerCertificateResponses) (err error) + + // + POST_UpdateSnapshot(parameters *POST_UpdateSnapshotParameters, responses *POST_UpdateSnapshotResponses) (err error) + + // + POST_UpdateUser(parameters *POST_UpdateUserParameters, responses *POST_UpdateUserResponses) (err error) + + // + POST_UpdateUserGroup(parameters *POST_UpdateUserGroupParameters, responses *POST_UpdateUserGroupResponses) (err error) + + // + POST_UpdateVm(parameters *POST_UpdateVmParameters, responses *POST_UpdateVmResponses) (err error) +} diff --git a/vendor/github.com/outscale/osc-go/oapi/types.go b/vendor/github.com/outscale/osc-go/oapi/types.go new file mode 100644 index 000000000..81e9539de --- /dev/null +++ b/vendor/github.com/outscale/osc-go/oapi/types.go @@ -0,0 +1,5660 @@ +// GENERATED FILE: DO NOT EDIT! + +package oapi + +// Types used by the API. +// implements the service definition of AcceptNetPeeringRequest +type AcceptNetPeeringRequest struct { + DryRun bool `json:"DryRun,omitempty"` + NetPeeringId string `json:"NetPeeringId,omitempty"` +} + +// implements the service definition of AcceptNetPeeringResponse +type AcceptNetPeeringResponse struct { + NetPeering NetPeering `json:"NetPeering,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of AccepterNet +type AccepterNet struct { + AccountId string `json:"AccountId,omitempty"` + IpRange string `json:"IpRange,omitempty"` + NetId string `json:"NetId,omitempty"` +} + +// implements the service definition of AccessLog +type AccessLog struct { + IsEnabled bool `json:"IsEnabled,omitempty"` + OsuBucketName string `json:"OsuBucketName,omitempty"` + OsuBucketPrefix string `json:"OsuBucketPrefix,omitempty"` + PublicationInterval int64 `json:"PublicationInterval,omitempty"` +} + +// implements the service definition of Account +type Account struct { + AccountId string `json:"AccountId,omitempty"` + City string `json:"City,omitempty"` + CompanyName string `json:"CompanyName,omitempty"` + Country string `json:"Country,omitempty"` + CustomerId string `json:"CustomerId,omitempty"` + Email string `json:"Email,omitempty"` + FirstName string `json:"FirstName,omitempty"` + JobTitle string `json:"JobTitle,omitempty"` + LastName string `json:"LastName,omitempty"` + Mobile string `json:"Mobile,omitempty"` + Phone string `json:"Phone,omitempty"` + StateProvince string `json:"StateProvince,omitempty"` + VatNumber string `json:"VatNumber,omitempty"` + ZipCode string `json:"ZipCode,omitempty"` +} + +// implements the service definition of ApiKey +type ApiKey struct { + AccountId string `json:"AccountId,omitempty"` + ApiKeyId string `json:"ApiKeyId,omitempty"` + SecretKey string `json:"SecretKey,omitempty"` + State string `json:"State,omitempty"` + Tags []ResourceTag `json:"Tags,omitempty"` + UserName string `json:"UserName,omitempty"` +} + +// implements the service definition of ApplicationStickyCookiePolicy +type ApplicationStickyCookiePolicy struct { + CookieName string `json:"CookieName,omitempty"` + PolicyName string `json:"PolicyName,omitempty"` +} + +// implements the service definition of Attribute +type Attribute struct { + Key string `json:"Key,omitempty"` + Value string `json:"Value,omitempty"` +} + +// implements the service definition of AuthenticateAccountRequest +type AuthenticateAccountRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Login string `json:"Login,omitempty"` + Password string `json:"Password,omitempty"` +} + +// implements the service definition of AuthenticateAccountResponse +type AuthenticateAccountResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of BackendVmsHealth +type BackendVmsHealth struct { + Description string `json:"Description,omitempty"` + State string `json:"State,omitempty"` + StateReason string `json:"StateReason,omitempty"` + VmId string `json:"VmId,omitempty"` +} + +// implements the service definition of BlockDeviceMapping +type BlockDeviceMapping struct { + Bsu Bsu `json:"Bsu,omitempty"` + DeviceName string `json:"DeviceName,omitempty"` + NoDevice string `json:"NoDevice,omitempty"` + VirtualDeviceName string `json:"VirtualDeviceName,omitempty"` +} + +// implements the service definition of BlockDeviceMappingCreated +type BlockDeviceMappingCreated struct { + Bsu BsuCreated `json:"Bsu,omitempty"` + DeviceName string `json:"DeviceName,omitempty"` +} + +// implements the service definition of BlockDeviceMappingImage +type BlockDeviceMappingImage struct { + Bsu BsuToCreate `json:"Bsu,omitempty"` + DeviceName string `json:"DeviceName,omitempty"` + VirtualDeviceName string `json:"VirtualDeviceName,omitempty"` +} + +// implements the service definition of BlockDeviceMappingVmCreation +type BlockDeviceMappingVmCreation struct { + Bsu BsuToCreate `json:"Bsu,omitempty"` + DeviceName string `json:"DeviceName,omitempty"` + NoDevice string `json:"NoDevice,omitempty"` + VirtualDeviceName string `json:"VirtualDeviceName,omitempty"` +} + +// implements the service definition of BlockDeviceMappingVmUpdate +type BlockDeviceMappingVmUpdate struct { + Bsu BsuToUpdateVm `json:"Bsu,omitempty"` + DeviceName string `json:"DeviceName,omitempty"` + NoDevice string `json:"NoDevice,omitempty"` + VirtualDeviceName string `json:"VirtualDeviceName,omitempty"` +} + +// implements the service definition of Bsu +type Bsu struct { + DeleteOnVmDeletion *bool `json:"DeleteOnVmDeletion,omitempty"` + Iops int64 `json:"Iops,omitempty"` + LinkDate string `json:"LinkDate,omitempty"` + SnapshotId string `json:"SnapshotId,omitempty"` + VolumeId string `json:"VolumeId,omitempty"` + VolumeSize int64 `json:"VolumeSize,omitempty"` + VolumeType string `json:"VolumeType,omitempty"` +} + +// implements the service definition of BsuCreated +type BsuCreated struct { + DeleteOnVmDeletion *bool `json:"DeleteOnVmDeletion,omitempty"` + LinkDate string `json:"LinkDate,omitempty"` + State string `json:"State,omitempty"` + VolumeId string `json:"VolumeId,omitempty"` +} + +// implements the service definition of BsuToCreate +type BsuToCreate struct { + DeleteOnVmDeletion *bool `json:"DeleteOnVmDeletion,omitempty"` + Iops int64 `json:"Iops,omitempty"` + SnapshotId string `json:"SnapshotId,omitempty"` + VolumeSize int64 `json:"VolumeSize,omitempty"` + VolumeType string `json:"VolumeType,omitempty"` +} + +// implements the service definition of BsuToUpdateVm +type BsuToUpdateVm struct { + DeleteOnVmDeletion *bool `json:"DeleteOnVmDeletion,omitempty"` + VolumeId string `json:"VolumeId,omitempty"` +} + +// implements the service definition of CatalogAttribute +type CatalogAttribute struct { + Key string `json:"Key,omitempty"` + Value string `json:"Value,omitempty"` +} + +// implements the service definition of CatalogEntry +type CatalogEntry struct { + CatalogAttributes []CatalogAttribute `json:"CatalogAttributes,omitempty"` + EntryKey string `json:"EntryKey,omitempty"` + EntryValue string `json:"EntryValue,omitempty"` + ShortDescription string `json:"ShortDescription,omitempty"` +} + +// implements the service definition of Catalog_0 +type Catalog_0 struct { + Domain string `json:"Domain,omitempty"` + Instance string `json:"Instance,omitempty"` + SourceRegionName string `json:"SourceRegionName,omitempty"` + TargetRegionName string `json:"TargetRegionName,omitempty"` + Version string `json:"Version,omitempty"` +} + +// implements the service definition of Catalog_1 +type Catalog_1 struct { + CatalogAttributes []CatalogAttribute `json:"CatalogAttributes,omitempty"` + CatalogEntries []CatalogEntry `json:"CatalogEntries,omitempty"` +} + +// implements the service definition of CheckSignatureRequest +type CheckSignatureRequest struct { + ApiKeyId string `json:"ApiKeyId,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + RegionName string `json:"RegionName,omitempty"` + RequestDate string `json:"RequestDate,omitempty"` + Service string `json:"Service,omitempty"` + Signature string `json:"Signature,omitempty"` + SignedContent string `json:"SignedContent,omitempty"` +} + +// implements the service definition of CheckSignatureResponse +type CheckSignatureResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ClientGateway +type ClientGateway struct { + BgpAsn int64 `json:"BgpAsn,omitempty"` + ClientGatewayId string `json:"ClientGatewayId,omitempty"` + ConnectionType string `json:"ConnectionType,omitempty"` + PublicIp string `json:"PublicIp,omitempty"` + State string `json:"State,omitempty"` + Tags []ResourceTag `json:"Tags,omitempty"` +} + +// implements the service definition of ConsumptionEntries +type ConsumptionEntries struct { + Category string `json:"Category,omitempty"` + ConsumptionValue string `json:"ConsumptionValue,omitempty"` + Entry string `json:"Entry,omitempty"` + ResourceType string `json:"ResourceType,omitempty"` + Service string `json:"Service,omitempty"` + ShortDescription string `json:"ShortDescription,omitempty"` +} + +// implements the service definition of CopyAccountRequest +type CopyAccountRequest struct { + DestinationRegionName string `json:"DestinationRegionName,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + QuotaProfile string `json:"QuotaProfile,omitempty"` +} + +// implements the service definition of CopyAccountResponse +type CopyAccountResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of CreateAccountRequest +type CreateAccountRequest struct { + AccountId string `json:"AccountId,omitempty"` + ApiKeys []ApiKey `json:"ApiKeys,omitempty"` + City string `json:"City,omitempty"` + CompanyName string `json:"CompanyName,omitempty"` + Country string `json:"Country,omitempty"` + CustomerId string `json:"CustomerId,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + Email string `json:"Email,omitempty"` + FirstName string `json:"FirstName,omitempty"` + JobTitle string `json:"JobTitle,omitempty"` + LastName string `json:"LastName,omitempty"` + Mobile string `json:"Mobile,omitempty"` + Password string `json:"Password,omitempty"` + Phone string `json:"Phone,omitempty"` + QuotaProfile string `json:"QuotaProfile,omitempty"` + StateProvince string `json:"StateProvince,omitempty"` + VatNumber string `json:"VatNumber,omitempty"` + ZipCode string `json:"ZipCode,omitempty"` +} + +// implements the service definition of CreateAccountResponse +type CreateAccountResponse struct { + Account Account `json:"Account,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of CreateApiKeyRequest +type CreateApiKeyRequest struct { + ApiKeyId string `json:"ApiKeyId,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + SecretKey string `json:"SecretKey,omitempty"` + Tags []ResourceTag `json:"Tags,omitempty"` + UserName string `json:"UserName,omitempty"` +} + +// implements the service definition of CreateApiKeyResponse +type CreateApiKeyResponse struct { + ApiKey ApiKey `json:"ApiKey,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of CreateClientGatewayRequest +type CreateClientGatewayRequest struct { + BgpAsn int64 `json:"BgpAsn,omitempty"` + ConnectionType string `json:"ConnectionType,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + PublicIp string `json:"PublicIp,omitempty"` +} + +// implements the service definition of CreateClientGatewayResponse +type CreateClientGatewayResponse struct { + ClientGateway ClientGateway `json:"ClientGateway,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of CreateDhcpOptionsRequest +type CreateDhcpOptionsRequest struct { + DomainName string `json:"DomainName,omitempty"` + DomainNameServers []string `json:"DomainNameServers,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + NtpServers []string `json:"NtpServers,omitempty"` +} + +// implements the service definition of CreateDhcpOptionsResponse +type CreateDhcpOptionsResponse struct { + DhcpOptionsSet DhcpOptionsSet `json:"DhcpOptionsSet,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of CreateDirectLinkInterfaceRequest +type CreateDirectLinkInterfaceRequest struct { + DirectLinkId string `json:"DirectLinkId,omitempty"` + DirectLinkInterface DirectLinkInterface `json:"DirectLinkInterface,omitempty"` + DryRun bool `json:"DryRun,omitempty"` +} + +// implements the service definition of CreateDirectLinkInterfaceResponse +type CreateDirectLinkInterfaceResponse struct { + DirectLinkInterface DirectLinkInterfaces `json:"DirectLinkInterface,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of CreateDirectLinkRequest +type CreateDirectLinkRequest struct { + Bandwidth string `json:"Bandwidth,omitempty"` + DirectLinkName string `json:"DirectLinkName,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + Location string `json:"Location,omitempty"` +} + +// implements the service definition of CreateDirectLinkResponse +type CreateDirectLinkResponse struct { + DirectLink DirectLink `json:"DirectLink,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of CreateImageExportTaskRequest +type CreateImageExportTaskRequest struct { + DryRun bool `json:"DryRun,omitempty"` + ImageId string `json:"ImageId,omitempty"` + OsuExport OsuExport `json:"OsuExport,omitempty"` +} + +// implements the service definition of CreateImageExportTaskResponse +type CreateImageExportTaskResponse struct { + ImageExportTask ImageExportTask `json:"ImageExportTask,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of CreateImageRequest +type CreateImageRequest struct { + Architecture string `json:"Architecture,omitempty"` + BlockDeviceMappings []BlockDeviceMappingImage `json:"BlockDeviceMappings,omitempty"` + Description string `json:"Description,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + FileLocation string `json:"FileLocation,omitempty"` + ImageName string `json:"ImageName,omitempty"` + NoReboot bool `json:"NoReboot,omitempty"` + RootDeviceName string `json:"RootDeviceName,omitempty"` + SourceImageId string `json:"SourceImageId,omitempty"` + SourceRegionName string `json:"SourceRegionName,omitempty"` + VmId string `json:"VmId,omitempty"` +} + +// implements the service definition of CreateImageResponse +type CreateImageResponse struct { + Image Image `json:"Image,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of CreateInternetServiceRequest +type CreateInternetServiceRequest struct { + DryRun bool `json:"DryRun,omitempty"` +} + +// implements the service definition of CreateInternetServiceResponse +type CreateInternetServiceResponse struct { + InternetService InternetService `json:"InternetService,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of CreateKeypairRequest +type CreateKeypairRequest struct { + DryRun bool `json:"DryRun,omitempty"` + KeypairName string `json:"KeypairName,omitempty"` + PublicKey string `json:"PublicKey,omitempty"` +} + +// implements the service definition of CreateKeypairResponse +type CreateKeypairResponse struct { + Keypair KeypairCreated `json:"Keypair,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of CreateListenerRuleRequest +type CreateListenerRuleRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Listener LoadBalancerLight `json:"Listener,omitempty"` + ListenerRule ListenerRule `json:"ListenerRule,omitempty"` + VmIds []string `json:"VmIds,omitempty"` +} + +// implements the service definition of CreateListenerRuleResponse +type CreateListenerRuleResponse struct { + ListenerId string `json:"ListenerId,omitempty"` + ListenerRule ListenerRule `json:"ListenerRule,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + VmIds []string `json:"VmIds,omitempty"` +} + +// implements the service definition of CreateLoadBalancerListenersRequest +type CreateLoadBalancerListenersRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Listeners []ListenerForCreation `json:"Listeners,omitempty"` + LoadBalancerName string `json:"LoadBalancerName,omitempty"` +} + +// implements the service definition of CreateLoadBalancerListenersResponse +type CreateLoadBalancerListenersResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of CreateLoadBalancerPolicyRequest +type CreateLoadBalancerPolicyRequest struct { + CookieName string `json:"CookieName,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + LoadBalancerName string `json:"LoadBalancerName,omitempty"` + PolicyName string `json:"PolicyName,omitempty"` + PolicyType string `json:"PolicyType,omitempty"` +} + +// implements the service definition of CreateLoadBalancerPolicyResponse +type CreateLoadBalancerPolicyResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of CreateLoadBalancerRequest +type CreateLoadBalancerRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Listeners []ListenerForCreation `json:"Listeners,omitempty"` + LoadBalancerName string `json:"LoadBalancerName,omitempty"` + LoadBalancerType string `json:"LoadBalancerType,omitempty"` + SecurityGroups []string `json:"SecurityGroups,omitempty"` + Subnets []string `json:"Subnets,omitempty"` + SubregionNames []string `json:"SubregionNames,omitempty"` + Tags []ResourceTag `json:"Tags,omitempty"` +} + +// implements the service definition of CreateLoadBalancerResponse +type CreateLoadBalancerResponse struct { + LoadBalancer LoadBalancer `json:"LoadBalancer,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of CreateNatServiceRequest +type CreateNatServiceRequest struct { + DryRun bool `json:"DryRun,omitempty"` + PublicIpId string `json:"PublicIpId,omitempty"` + SubnetId string `json:"SubnetId,omitempty"` +} + +// implements the service definition of CreateNatServiceResponse +type CreateNatServiceResponse struct { + NatService NatService `json:"NatService,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of CreateNetAccessPointRequest +type CreateNetAccessPointRequest struct { + DryRun bool `json:"DryRun,omitempty"` + NetId string `json:"NetId,omitempty"` + PrefixListName string `json:"PrefixListName,omitempty"` + RouteTableIds []string `json:"RouteTableIds,omitempty"` +} + +// implements the service definition of CreateNetAccessPointResponse +type CreateNetAccessPointResponse struct { + NetAccessPoint NetAccessPoint `json:"NetAccessPoint,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of CreateNetPeeringRequest +type CreateNetPeeringRequest struct { + AccepterNetId string `json:"AccepterNetId,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + SourceNetId string `json:"SourceNetId,omitempty"` +} + +// implements the service definition of CreateNetPeeringResponse +type CreateNetPeeringResponse struct { + NetPeering NetPeering `json:"NetPeering,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of CreateNetRequest +type CreateNetRequest struct { + DryRun bool `json:"DryRun,omitempty"` + IpRange string `json:"IpRange,omitempty"` + Tenancy string `json:"Tenancy,omitempty"` +} + +// implements the service definition of CreateNetResponse +type CreateNetResponse struct { + Net Net `json:"Net,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of CreateNicRequest +type CreateNicRequest struct { + Description string `json:"Description,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + PrivateIps []PrivateIpLight `json:"PrivateIps,omitempty"` + SecurityGroupIds []string `json:"SecurityGroupIds,omitempty"` + SubnetId string `json:"SubnetId,omitempty"` +} + +// implements the service definition of CreateNicResponse +type CreateNicResponse struct { + Nic Nic `json:"Nic,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of CreatePolicyRequest +type CreatePolicyRequest struct { + Description string `json:"Description,omitempty"` + Document string `json:"Document,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + Path string `json:"Path,omitempty"` + PolicyName string `json:"PolicyName,omitempty"` +} + +// implements the service definition of CreatePolicyResponse +type CreatePolicyResponse struct { + Policy Policy `json:"Policy,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of CreatePublicIpRequest +type CreatePublicIpRequest struct { + DryRun bool `json:"DryRun,omitempty"` +} + +// implements the service definition of CreatePublicIpResponse +type CreatePublicIpResponse struct { + PublicIp PublicIp `json:"PublicIp,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of CreateRouteRequest +type CreateRouteRequest struct { + DestinationIpRange string `json:"DestinationIpRange,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + GatewayId string `json:"GatewayId,omitempty"` + NatServiceId string `json:"NatServiceId,omitempty"` + NetPeeringId string `json:"NetPeeringId,omitempty"` + NicId string `json:"NicId,omitempty"` + RouteTableId string `json:"RouteTableId,omitempty"` + VmId string `json:"VmId,omitempty"` +} + +// implements the service definition of CreateRouteResponse +type CreateRouteResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + Route Route `json:"Route,omitempty"` +} + +// implements the service definition of CreateRouteTableRequest +type CreateRouteTableRequest struct { + DryRun bool `json:"DryRun,omitempty"` + NetId string `json:"NetId,omitempty"` +} + +// implements the service definition of CreateRouteTableResponse +type CreateRouteTableResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + RouteTable RouteTable `json:"RouteTable,omitempty"` +} + +// implements the service definition of CreateSecurityGroupRequest +type CreateSecurityGroupRequest struct { + Description string `json:"Description,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + NetId string `json:"NetId,omitempty"` + SecurityGroupName string `json:"SecurityGroupName,omitempty"` +} + +// implements the service definition of CreateSecurityGroupResponse +type CreateSecurityGroupResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + SecurityGroup SecurityGroup `json:"SecurityGroup,omitempty"` +} + +// implements the service definition of CreateSecurityGroupRuleRequest +type CreateSecurityGroupRuleRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Flow string `json:"Flow,omitempty"` + FromPortRange int64 `json:"FromPortRange,omitempty"` + IpProtocol string `json:"IpProtocol,omitempty"` + IpRange string `json:"IpRange,omitempty"` + Rules []SecurityGroupRule `json:"Rules,omitempty"` + SecurityGroupAccountIdToLink string `json:"SecurityGroupAccountIdToLink,omitempty"` + SecurityGroupId string `json:"SecurityGroupId,omitempty"` + SecurityGroupNameToLink string `json:"SecurityGroupNameToLink,omitempty"` + ToPortRange int64 `json:"ToPortRange,omitempty"` +} + +// implements the service definition of CreateSecurityGroupRuleResponse +type CreateSecurityGroupRuleResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + SecurityGroupRule SecurityGroupRule `json:"SecurityGroupRule,omitempty"` +} + +// implements the service definition of CreateServerCertificateRequest +type CreateServerCertificateRequest struct { + DryRun bool `json:"DryRun,omitempty"` + PrivateKey string `json:"PrivateKey,omitempty"` + ServerCertificateBody string `json:"ServerCertificateBody,omitempty"` + ServerCertificateChain string `json:"ServerCertificateChain,omitempty"` + ServerCertificateName string `json:"ServerCertificateName,omitempty"` + ServerCertificatePath string `json:"ServerCertificatePath,omitempty"` +} + +// implements the service definition of CreateServerCertificateResponse +type CreateServerCertificateResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + ServerCertificate ServerCertificate `json:"ServerCertificate,omitempty"` +} + +// implements the service definition of CreateSnapshotExportTaskRequest +type CreateSnapshotExportTaskRequest struct { + DryRun bool `json:"DryRun,omitempty"` + OsuExport OsuExport `json:"OsuExport,omitempty"` + SnapshotId string `json:"SnapshotId,omitempty"` +} + +// implements the service definition of CreateSnapshotExportTaskResponse +type CreateSnapshotExportTaskResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + SnapshotExportTask SnapshotExportTask `json:"SnapshotExportTask,omitempty"` +} + +// implements the service definition of CreateSnapshotRequest +type CreateSnapshotRequest struct { + Description string `json:"Description,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + FileLocation string `json:"FileLocation,omitempty"` + SnapshotSize int64 `json:"SnapshotSize,omitempty"` + SourceRegionName string `json:"SourceRegionName,omitempty"` + SourceSnapshotId string `json:"SourceSnapshotId,omitempty"` + VolumeId string `json:"VolumeId,omitempty"` +} + +// implements the service definition of CreateSnapshotResponse +type CreateSnapshotResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + Snapshot Snapshot `json:"Snapshot,omitempty"` +} + +// implements the service definition of CreateSubnetRequest +type CreateSubnetRequest struct { + DryRun bool `json:"DryRun,omitempty"` + IpRange string `json:"IpRange,omitempty"` + NetId string `json:"NetId,omitempty"` + SubregionName string `json:"SubregionName,omitempty"` +} + +// implements the service definition of CreateSubnetResponse +type CreateSubnetResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + Subnet Subnet `json:"Subnet,omitempty"` +} + +// implements the service definition of CreateTagsRequest +type CreateTagsRequest struct { + DryRun bool `json:"DryRun,omitempty"` + ResourceIds []string `json:"ResourceIds,omitempty"` + Tags []ResourceTag `json:"Tags,omitempty"` +} + +// implements the service definition of CreateTagsResponse +type CreateTagsResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of CreateUserGroupRequest +type CreateUserGroupRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Path string `json:"Path,omitempty"` + UserGroupName string `json:"UserGroupName,omitempty"` +} + +// implements the service definition of CreateUserGroupResponse +type CreateUserGroupResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + UserGroup UserGroup `json:"UserGroup,omitempty"` +} + +// implements the service definition of CreateUserRequest +type CreateUserRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Path string `json:"Path,omitempty"` + UserName string `json:"UserName,omitempty"` +} + +// implements the service definition of CreateUserResponse +type CreateUserResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + User User `json:"User,omitempty"` +} + +// implements the service definition of CreateVirtualGatewayRequest +type CreateVirtualGatewayRequest struct { + ConnectionType string `json:"ConnectionType,omitempty"` + DryRun bool `json:"DryRun,omitempty"` +} + +// implements the service definition of CreateVirtualGatewayResponse +type CreateVirtualGatewayResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + VirtualGateway VirtualGateway `json:"VirtualGateway,omitempty"` +} + +// implements the service definition of CreateVmsRequest +type CreateVmsRequest struct { + BlockDeviceMappings []BlockDeviceMappingVmCreation `json:"BlockDeviceMappings,omitempty"` + BsuOptimized bool `json:"BsuOptimized,omitempty"` + ClientToken string `json:"ClientToken,omitempty"` + DeletionProtection bool `json:"DeletionProtection,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + ImageId string `json:"ImageId,omitempty"` + KeypairName string `json:"KeypairName,omitempty"` + MaxVmsCount int64 `json:"MaxVmsCount,omitempty"` + MinVmsCount int64 `json:"MinVmsCount,omitempty"` + Nics []NicForVmCreation `json:"Nics,omitempty"` + Placement Placement `json:"Placement,omitempty"` + PrivateIps []string `json:"PrivateIps,omitempty"` + SecurityGroupIds []string `json:"SecurityGroupIds,omitempty"` + SecurityGroups []string `json:"SecurityGroups,omitempty"` + SubnetId string `json:"SubnetId,omitempty"` + UserData string `json:"UserData,omitempty"` + VmInitiatedShutdownBehavior string `json:"VmInitiatedShutdownBehavior,omitempty"` + VmType string `json:"VmType,omitempty"` +} + +// implements the service definition of CreateVmsResponse +type CreateVmsResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + Vms []Vm `json:"Vms,omitempty"` +} + +// implements the service definition of CreateVolumeRequest +type CreateVolumeRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Iops int64 `json:"Iops,omitempty"` + Size int64 `json:"Size,omitempty"` + SnapshotId string `json:"SnapshotId,omitempty"` + SubregionName string `json:"SubregionName,omitempty"` + VolumeType string `json:"VolumeType,omitempty"` +} + +// implements the service definition of CreateVolumeResponse +type CreateVolumeResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + Volume Volume `json:"Volume,omitempty"` +} + +// implements the service definition of CreateVpnConnectionRequest +type CreateVpnConnectionRequest struct { + ClientGatewayId string `json:"ClientGatewayId,omitempty"` + ConnectionType string `json:"ConnectionType,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + StaticRoutesOnly bool `json:"StaticRoutesOnly,omitempty"` + VirtualGatewayId string `json:"VirtualGatewayId,omitempty"` +} + +// implements the service definition of CreateVpnConnectionResponse +type CreateVpnConnectionResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + VpnConnection VpnConnection `json:"VpnConnection,omitempty"` +} + +// implements the service definition of CreateVpnConnectionRouteRequest +type CreateVpnConnectionRouteRequest struct { + DestinationIpRange string `json:"DestinationIpRange,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + VpnConnectionId string `json:"VpnConnectionId,omitempty"` +} + +// implements the service definition of CreateVpnConnectionRouteResponse +type CreateVpnConnectionRouteResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteApiKeyRequest +type DeleteApiKeyRequest struct { + ApiKeyId string `json:"ApiKeyId,omitempty"` + DryRun bool `json:"DryRun,omitempty"` +} + +// implements the service definition of DeleteApiKeyResponse +type DeleteApiKeyResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteClientGatewayRequest +type DeleteClientGatewayRequest struct { + ClientGatewayId string `json:"ClientGatewayId,omitempty"` + DryRun bool `json:"DryRun,omitempty"` +} + +// implements the service definition of DeleteClientGatewayResponse +type DeleteClientGatewayResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteDhcpOptionsRequest +type DeleteDhcpOptionsRequest struct { + DhcpOptionsSetId string `json:"DhcpOptionsSetId,omitempty"` + DryRun bool `json:"DryRun,omitempty"` +} + +// implements the service definition of DeleteDhcpOptionsResponse +type DeleteDhcpOptionsResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteDirectLinkInterfaceRequest +type DeleteDirectLinkInterfaceRequest struct { + DirectLinkInterfaceId string `json:"DirectLinkInterfaceId,omitempty"` + DryRun bool `json:"DryRun,omitempty"` +} + +// implements the service definition of DeleteDirectLinkInterfaceResponse +type DeleteDirectLinkInterfaceResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteDirectLinkRequest +type DeleteDirectLinkRequest struct { + DirectLinkId string `json:"DirectLinkId,omitempty"` + DryRun bool `json:"DryRun,omitempty"` +} + +// implements the service definition of DeleteDirectLinkResponse +type DeleteDirectLinkResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteExportTaskRequest +type DeleteExportTaskRequest struct { + DryRun bool `json:"DryRun,omitempty"` + ExportTaskId string `json:"ExportTaskId,omitempty"` +} + +// implements the service definition of DeleteExportTaskResponse +type DeleteExportTaskResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteImageRequest +type DeleteImageRequest struct { + DryRun bool `json:"DryRun,omitempty"` + ImageId string `json:"ImageId,omitempty"` +} + +// implements the service definition of DeleteImageResponse +type DeleteImageResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteInternetServiceRequest +type DeleteInternetServiceRequest struct { + DryRun bool `json:"DryRun,omitempty"` + InternetServiceId string `json:"InternetServiceId,omitempty"` +} + +// implements the service definition of DeleteInternetServiceResponse +type DeleteInternetServiceResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteKeypairRequest +type DeleteKeypairRequest struct { + DryRun bool `json:"DryRun,omitempty"` + KeypairName string `json:"KeypairName,omitempty"` +} + +// implements the service definition of DeleteKeypairResponse +type DeleteKeypairResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteListenerRuleRequest +type DeleteListenerRuleRequest struct { + DryRun bool `json:"DryRun,omitempty"` + ListenerRuleName string `json:"ListenerRuleName,omitempty"` +} + +// implements the service definition of DeleteListenerRuleResponse +type DeleteListenerRuleResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteLoadBalancerListenersRequest +type DeleteLoadBalancerListenersRequest struct { + DryRun bool `json:"DryRun,omitempty"` + LoadBalancerName string `json:"LoadBalancerName,omitempty"` + LoadBalancerPorts []int64 `json:"LoadBalancerPorts,omitempty"` +} + +// implements the service definition of DeleteLoadBalancerListenersResponse +type DeleteLoadBalancerListenersResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteLoadBalancerPolicyRequest +type DeleteLoadBalancerPolicyRequest struct { + DryRun bool `json:"DryRun,omitempty"` + LoadBalancerName string `json:"LoadBalancerName,omitempty"` + PolicyName string `json:"PolicyName,omitempty"` +} + +// implements the service definition of DeleteLoadBalancerPolicyResponse +type DeleteLoadBalancerPolicyResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteLoadBalancerRequest +type DeleteLoadBalancerRequest struct { + DryRun bool `json:"DryRun,omitempty"` + LoadBalancerName string `json:"LoadBalancerName,omitempty"` +} + +// implements the service definition of DeleteLoadBalancerResponse +type DeleteLoadBalancerResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteNatServiceRequest +type DeleteNatServiceRequest struct { + DryRun bool `json:"DryRun,omitempty"` + NatServiceId string `json:"NatServiceId,omitempty"` +} + +// implements the service definition of DeleteNatServiceResponse +type DeleteNatServiceResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteNetAccessPointsRequest +type DeleteNetAccessPointsRequest struct { + DryRun bool `json:"DryRun,omitempty"` + NetAccessPointIds []string `json:"NetAccessPointIds,omitempty"` +} + +// implements the service definition of DeleteNetAccessPointsResponse +type DeleteNetAccessPointsResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteNetPeeringRequest +type DeleteNetPeeringRequest struct { + DryRun bool `json:"DryRun,omitempty"` + NetPeeringId string `json:"NetPeeringId,omitempty"` +} + +// implements the service definition of DeleteNetPeeringResponse +type DeleteNetPeeringResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteNetRequest +type DeleteNetRequest struct { + DryRun bool `json:"DryRun,omitempty"` + NetId string `json:"NetId,omitempty"` +} + +// implements the service definition of DeleteNetResponse +type DeleteNetResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteNicRequest +type DeleteNicRequest struct { + DryRun bool `json:"DryRun,omitempty"` + NicId string `json:"NicId,omitempty"` +} + +// implements the service definition of DeleteNicResponse +type DeleteNicResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeletePolicyRequest +type DeletePolicyRequest struct { + DryRun bool `json:"DryRun,omitempty"` + PolicyId string `json:"PolicyId,omitempty"` +} + +// implements the service definition of DeletePolicyResponse +type DeletePolicyResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeletePublicIpRequest +type DeletePublicIpRequest struct { + DryRun bool `json:"DryRun,omitempty"` + PublicIp string `json:"PublicIp,omitempty"` + PublicIpId string `json:"PublicIpId,omitempty"` +} + +// implements the service definition of DeletePublicIpResponse +type DeletePublicIpResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteRouteRequest +type DeleteRouteRequest struct { + DestinationIpRange string `json:"DestinationIpRange,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + RouteTableId string `json:"RouteTableId,omitempty"` +} + +// implements the service definition of DeleteRouteResponse +type DeleteRouteResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteRouteTableRequest +type DeleteRouteTableRequest struct { + DryRun bool `json:"DryRun,omitempty"` + RouteTableId string `json:"RouteTableId,omitempty"` +} + +// implements the service definition of DeleteRouteTableResponse +type DeleteRouteTableResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteSecurityGroupRequest +type DeleteSecurityGroupRequest struct { + DryRun bool `json:"DryRun,omitempty"` + SecurityGroupId string `json:"SecurityGroupId,omitempty"` + SecurityGroupName string `json:"SecurityGroupName,omitempty"` +} + +// implements the service definition of DeleteSecurityGroupResponse +type DeleteSecurityGroupResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteSecurityGroupRuleRequest +type DeleteSecurityGroupRuleRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Flow string `json:"Flow,omitempty"` + FromPortRange int64 `json:"FromPortRange,omitempty"` + IpProtocol string `json:"IpProtocol,omitempty"` + IpRange string `json:"IpRange,omitempty"` + Rules []SecurityGroupRule `json:"Rules,omitempty"` + SecurityGroupAccountIdToUnlink string `json:"SecurityGroupAccountIdToUnlink,omitempty"` + SecurityGroupId string `json:"SecurityGroupId,omitempty"` + SecurityGroupNameToUnlink string `json:"SecurityGroupNameToUnlink,omitempty"` + ToPortRange int64 `json:"ToPortRange,omitempty"` +} + +// implements the service definition of DeleteSecurityGroupRuleResponse +type DeleteSecurityGroupRuleResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteServerCertificateRequest +type DeleteServerCertificateRequest struct { + DryRun bool `json:"DryRun,omitempty"` + ServerCertificateName string `json:"ServerCertificateName,omitempty"` +} + +// implements the service definition of DeleteServerCertificateResponse +type DeleteServerCertificateResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteSnapshotRequest +type DeleteSnapshotRequest struct { + DryRun bool `json:"DryRun,omitempty"` + SnapshotId string `json:"SnapshotId,omitempty"` +} + +// implements the service definition of DeleteSnapshotResponse +type DeleteSnapshotResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteSubnetRequest +type DeleteSubnetRequest struct { + DryRun bool `json:"DryRun,omitempty"` + SubnetId string `json:"SubnetId,omitempty"` +} + +// implements the service definition of DeleteSubnetResponse +type DeleteSubnetResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteTagsRequest +type DeleteTagsRequest struct { + DryRun bool `json:"DryRun,omitempty"` + ResourceIds []string `json:"ResourceIds,omitempty"` + Tags []ResourceTag `json:"Tags,omitempty"` +} + +// implements the service definition of DeleteTagsResponse +type DeleteTagsResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteUserGroupRequest +type DeleteUserGroupRequest struct { + DryRun bool `json:"DryRun,omitempty"` + UserGroupName string `json:"UserGroupName,omitempty"` +} + +// implements the service definition of DeleteUserGroupResponse +type DeleteUserGroupResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteUserRequest +type DeleteUserRequest struct { + DryRun bool `json:"DryRun,omitempty"` + UserName string `json:"UserName,omitempty"` +} + +// implements the service definition of DeleteUserResponse +type DeleteUserResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteVirtualGatewayRequest +type DeleteVirtualGatewayRequest struct { + DryRun bool `json:"DryRun,omitempty"` + VirtualGatewayId string `json:"VirtualGatewayId,omitempty"` +} + +// implements the service definition of DeleteVirtualGatewayResponse +type DeleteVirtualGatewayResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteVmsRequest +type DeleteVmsRequest struct { + DryRun bool `json:"DryRun,omitempty"` + VmIds []string `json:"VmIds,omitempty"` +} + +// implements the service definition of DeleteVmsResponse +type DeleteVmsResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + Vms []VmState `json:"Vms,omitempty"` +} + +// implements the service definition of DeleteVolumeRequest +type DeleteVolumeRequest struct { + DryRun bool `json:"DryRun,omitempty"` + VolumeId string `json:"VolumeId,omitempty"` +} + +// implements the service definition of DeleteVolumeResponse +type DeleteVolumeResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteVpnConnectionRequest +type DeleteVpnConnectionRequest struct { + DryRun bool `json:"DryRun,omitempty"` + VpnConnectionId string `json:"VpnConnectionId,omitempty"` +} + +// implements the service definition of DeleteVpnConnectionResponse +type DeleteVpnConnectionResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeleteVpnConnectionRouteRequest +type DeleteVpnConnectionRouteRequest struct { + DestinationIpRange string `json:"DestinationIpRange,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + VpnConnectionId string `json:"VpnConnectionId,omitempty"` +} + +// implements the service definition of DeleteVpnConnectionRouteResponse +type DeleteVpnConnectionRouteResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeregisterUserInUserGroupRequest +type DeregisterUserInUserGroupRequest struct { + DryRun bool `json:"DryRun,omitempty"` + UserGroupName string `json:"UserGroupName,omitempty"` + UserName string `json:"UserName,omitempty"` +} + +// implements the service definition of DeregisterUserInUserGroupResponse +type DeregisterUserInUserGroupResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DeregisterVmsInLoadBalancerRequest +type DeregisterVmsInLoadBalancerRequest struct { + BackendVmsIds []string `json:"BackendVmsIds,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + LoadBalancerName string `json:"LoadBalancerName,omitempty"` +} + +// implements the service definition of DeregisterVmsInLoadBalancerResponse +type DeregisterVmsInLoadBalancerResponse struct { + BackendVmsIds []string `json:"BackendVmsIds,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of DhcpOptionsSet +type DhcpOptionsSet struct { + Default bool `json:"Default,omitempty"` + DhcpOptionsName string `json:"DhcpOptionsName,omitempty"` + DhcpOptionsSetId string `json:"DhcpOptionsSetId,omitempty"` + DomainName string `json:"DomainName,omitempty"` + DomainNameServers []string `json:"DomainNameServers,omitempty"` + NtpServers []string `json:"NtpServers,omitempty"` + Tags []ResourceTag `json:"Tags,omitempty"` +} + +// implements the service definition of DirectLink +type DirectLink struct { + AccountId string `json:"AccountId,omitempty"` + Bandwidth string `json:"Bandwidth,omitempty"` + DirectLinkId string `json:"DirectLinkId,omitempty"` + DirectLinkName string `json:"DirectLinkName,omitempty"` + Location string `json:"Location,omitempty"` + RegionName string `json:"RegionName,omitempty"` + State string `json:"State,omitempty"` +} + +// implements the service definition of DirectLinkInterface +type DirectLinkInterface struct { + BgpAsn int64 `json:"BgpAsn,omitempty"` + BgpKey string `json:"BgpKey,omitempty"` + ClientPrivateIp string `json:"ClientPrivateIp,omitempty"` + DirectLinkInterfaceName string `json:"DirectLinkInterfaceName,omitempty"` + OutscalePrivateIp string `json:"OutscalePrivateIp,omitempty"` + VirtualGatewayId string `json:"VirtualGatewayId,omitempty"` + Vlan int64 `json:"Vlan,omitempty"` +} + +// implements the service definition of DirectLinkInterfaces +type DirectLinkInterfaces struct { + AccountId string `json:"AccountId,omitempty"` + BgpAsn int64 `json:"BgpAsn,omitempty"` + BgpKey string `json:"BgpKey,omitempty"` + ClientPrivateIp string `json:"ClientPrivateIp,omitempty"` + DirectLinkId string `json:"DirectLinkId,omitempty"` + DirectLinkInterfaceId string `json:"DirectLinkInterfaceId,omitempty"` + DirectLinkInterfaceName string `json:"DirectLinkInterfaceName,omitempty"` + InterfaceType string `json:"InterfaceType,omitempty"` + Location string `json:"Location,omitempty"` + OutscalePrivateIp string `json:"OutscalePrivateIp,omitempty"` + State string `json:"State,omitempty"` + VirtualGatewayId string `json:"VirtualGatewayId,omitempty"` + Vlan int64 `json:"Vlan,omitempty"` +} + +// implements the service definition of ErrorResponse +type ErrorResponse struct { + Errors []Errors `json:"Errors,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of Errors +type Errors struct { + Code string `json:"Code,omitempty"` + Details string `json:"Details,omitempty"` + Type string `json:"Type,omitempty"` +} + +// implements the service definition of FiltersApiLog +type FiltersApiLog struct { + QueryAccessKeys []string `json:"QueryAccessKeys,omitempty"` + QueryApiNames []string `json:"QueryApiNames,omitempty"` + QueryCallNames []string `json:"QueryCallNames,omitempty"` + QueryDateAfter string `json:"QueryDateAfter,omitempty"` + QueryDateBefore string `json:"QueryDateBefore,omitempty"` + QueryIpAddresses []string `json:"QueryIpAddresses,omitempty"` + QueryUserAgents []string `json:"QueryUserAgents,omitempty"` + ResponseIds []string `json:"ResponseIds,omitempty"` + ResponseStatusCodes []int64 `json:"ResponseStatusCodes,omitempty"` +} + +// implements the service definition of FiltersDhcpOptions +type FiltersDhcpOptions struct { + Defaults []string `json:"Defaults,omitempty"` + DhcpOptionsSetIds []string `json:"DhcpOptionsSetIds,omitempty"` + DomainNameServers []string `json:"DomainNameServers,omitempty"` + DomainNames []string `json:"DomainNames,omitempty"` + NtpServers []string `json:"NtpServers,omitempty"` + TagKeys []string `json:"TagKeys,omitempty"` + TagValues []string `json:"TagValues,omitempty"` + Tags []string `json:"Tags,omitempty"` +} + +// implements the service definition of FiltersExportTask +type FiltersExportTask struct { + TaskIds []string `json:"TaskIds,omitempty"` +} + +// implements the service definition of FiltersImage +type FiltersImage struct { + AccountAliases []string `json:"AccountAliases,omitempty"` + AccountIds []string `json:"AccountIds,omitempty"` + Architectures []string `json:"Architectures,omitempty"` + BlockDeviceMappingDeleteOnVmTermination bool `json:"BlockDeviceMappingDeleteOnVmTermination,omitempty"` + BlockDeviceMappingDeviceNames []string `json:"BlockDeviceMappingDeviceNames,omitempty"` + BlockDeviceMappingSnapshotIds []string `json:"BlockDeviceMappingSnapshotIds,omitempty"` + BlockDeviceMappingVolumeSize []int64 `json:"BlockDeviceMappingVolumeSize,omitempty"` + BlockDeviceMappingVolumeType []string `json:"BlockDeviceMappingVolumeType,omitempty"` + Descriptions []string `json:"Descriptions,omitempty"` + Hypervisors []string `json:"Hypervisors,omitempty"` + ImageIds []string `json:"ImageIds,omitempty"` + ImageNames []string `json:"ImageNames,omitempty"` + ImageTypes []string `json:"ImageTypes,omitempty"` + KernelIds []string `json:"KernelIds,omitempty"` + ManifestLocation []string `json:"ManifestLocation,omitempty"` + PermissionsToLaunchAccountIds []string `json:"PermissionsToLaunchAccountIds,omitempty"` + PermissionsToLaunchGlobalPermission bool `json:"PermissionsToLaunchGlobalPermission,omitempty"` + ProductCodes []string `json:"ProductCodes,omitempty"` + RamDiskIds []string `json:"RamDiskIds,omitempty"` + RootDeviceNames []string `json:"RootDeviceNames,omitempty"` + RootDeviceTypes []string `json:"RootDeviceTypes,omitempty"` + States []string `json:"States,omitempty"` + System []string `json:"System,omitempty"` + TagKeys []string `json:"TagKeys,omitempty"` + TagValues []string `json:"TagValues,omitempty"` + Tags []string `json:"Tags,omitempty"` + VirtualizationTypes []string `json:"VirtualizationTypes,omitempty"` +} + +// implements the service definition of FiltersInternetService +type FiltersInternetService struct { + InternetServiceIds []string `json:"InternetServiceIds,omitempty"` +} + +// implements the service definition of FiltersKeypair +type FiltersKeypair struct { + KeypairFingerprints []string `json:"KeypairFingerprints,omitempty"` + KeypairNames []string `json:"KeypairNames,omitempty"` +} + +// implements the service definition of FiltersLoadBalancer +type FiltersLoadBalancer struct { + LoadBalancerNames []string `json:"LoadBalancerNames,omitempty"` +} + +// implements the service definition of FiltersNatService +type FiltersNatService struct { + NatServiceIds []string `json:"NatServiceIds,omitempty"` + NetIds []string `json:"NetIds,omitempty"` + States []string `json:"States,omitempty"` + SubnetIds []string `json:"SubnetIds,omitempty"` + TagKeys []string `json:"TagKeys,omitempty"` + TagValues []string `json:"TagValues,omitempty"` + Tags []string `json:"Tags,omitempty"` +} + +// implements the service definition of FiltersNet +type FiltersNet struct { + DhcpOptionsSetIds []string `json:"DhcpOptionsSetIds,omitempty"` + IpRanges []string `json:"IpRanges,omitempty"` + IsDefault bool `json:"IsDefault,omitempty"` + NetIds []string `json:"NetIds,omitempty"` + States []string `json:"States,omitempty"` + TagKeys []string `json:"TagKeys,omitempty"` + TagValues []string `json:"TagValues,omitempty"` + Tags []string `json:"Tags,omitempty"` +} + +// implements the service definition of FiltersNetPeering +type FiltersNetPeering struct { + AccepterNetAccountIds []string `json:"AccepterNetAccountIds,omitempty"` + AccepterNetIpRanges []string `json:"AccepterNetIpRanges,omitempty"` + AccepterNetNetIds []string `json:"AccepterNetNetIds,omitempty"` + NetPeeringIds []string `json:"NetPeeringIds,omitempty"` + SourceNetAccountIds []string `json:"SourceNetAccountIds,omitempty"` + SourceNetIpRanges []string `json:"SourceNetIpRanges,omitempty"` + SourceNetNetIds []string `json:"SourceNetNetIds,omitempty"` + StateMessages []string `json:"StateMessages,omitempty"` + StateNames []string `json:"StateNames,omitempty"` + TagKeys []string `json:"TagKeys,omitempty"` + TagValues []string `json:"TagValues,omitempty"` + Tags []string `json:"Tags,omitempty"` +} + +// implements the service definition of FiltersNic +type FiltersNic struct { + AccountIds []string `json:"AccountIds,omitempty"` + ActivatedChecks []string `json:"ActivatedChecks,omitempty"` + Descriptions []string `json:"Descriptions,omitempty"` + LinkNicDeleteOnVmDeletion bool `json:"LinkNicDeleteOnVmDeletion,omitempty"` + LinkNicLinkDates []string `json:"LinkNicLinkDates,omitempty"` + LinkNicLinkNicIds []string `json:"LinkNicLinkNicIds,omitempty"` + LinkNicSortNumbers []int64 `json:"LinkNicSortNumbers,omitempty"` + LinkNicStates []string `json:"LinkNicStates,omitempty"` + LinkNicVmAccountIds []string `json:"LinkNicVmAccountIds,omitempty"` + LinkNicVmIds []string `json:"LinkNicVmIds,omitempty"` + LinkPublicIpAccountIds []string `json:"LinkPublicIpAccountIds,omitempty"` + LinkPublicIpLinkPublicIpIds []string `json:"LinkPublicIpLinkPublicIpIds,omitempty"` + LinkPublicIpPublicIpIds []string `json:"LinkPublicIpPublicIpIds,omitempty"` + LinkPublicIpPublicIps []string `json:"LinkPublicIpPublicIps,omitempty"` + MacAddresses []string `json:"MacAddresses,omitempty"` + NetIds []string `json:"NetIds,omitempty"` + NicIds []string `json:"NicIds,omitempty"` + PrivateDnsNames []string `json:"PrivateDnsNames,omitempty"` + PrivateIpsLinkPublicIpAccountIds []string `json:"PrivateIpsLinkPublicIpAccountIds,omitempty"` + PrivateIpsLinkPublicIpPublicIps []string `json:"PrivateIpsLinkPublicIpPublicIps,omitempty"` + PrivateIpsPrimaryIp bool `json:"PrivateIpsPrimaryIp,omitempty"` + PrivateIpsPrivateIps []string `json:"PrivateIpsPrivateIps,omitempty"` + SecurityGroupIds []string `json:"SecurityGroupIds,omitempty"` + SecurityGroupNames []string `json:"SecurityGroupNames,omitempty"` + States []string `json:"States,omitempty"` + SubnetIds []string `json:"SubnetIds,omitempty"` + SubregionNames []string `json:"SubregionNames,omitempty"` +} + +// implements the service definition of FiltersOldFormat +type FiltersOldFormat struct { + Name string `json:"Name,omitempty"` + Values []string `json:"Values,omitempty"` +} + +// implements the service definition of FiltersPublicIp +type FiltersPublicIp struct { + LinkPublicIpIds []string `json:"LinkPublicIpIds,omitempty"` + NicAccountIds []string `json:"NicAccountIds,omitempty"` + NicIds []string `json:"NicIds,omitempty"` + Placements []string `json:"Placements,omitempty"` + PrivateIps []string `json:"PrivateIps,omitempty"` + PublicIpIds []string `json:"PublicIpIds,omitempty"` + PublicIps []string `json:"PublicIps,omitempty"` + VmIds []string `json:"VmIds,omitempty"` +} + +// implements the service definition of FiltersRouteTable +type FiltersRouteTable struct { + LinkRouteTableIds []string `json:"LinkRouteTableIds,omitempty"` + LinkRouteTableLinkRouteTableIds []string `json:"LinkRouteTableLinkRouteTableIds,omitempty"` + LinkRouteTableMain bool `json:"LinkRouteTableMain,omitempty"` + LinkSubnetIds []string `json:"LinkSubnetIds,omitempty"` + NetIds []string `json:"NetIds,omitempty"` + RouteCreationMethods []string `json:"RouteCreationMethods,omitempty"` + RouteDestinationIpRanges []string `json:"RouteDestinationIpRanges,omitempty"` + RouteDestinationPrefixListIds []string `json:"RouteDestinationPrefixListIds,omitempty"` + RouteGatewayIds []string `json:"RouteGatewayIds,omitempty"` + RouteNatServiceIds []string `json:"RouteNatServiceIds,omitempty"` + RouteNetPeeringIds []string `json:"RouteNetPeeringIds,omitempty"` + RouteStates []string `json:"RouteStates,omitempty"` + RouteTableIds []string `json:"RouteTableIds,omitempty"` + RouteVmIds []string `json:"RouteVmIds,omitempty"` + TagKeys []string `json:"TagKeys,omitempty"` + TagValues []string `json:"TagValues,omitempty"` + Tags []string `json:"Tags,omitempty"` +} + +// implements the service definition of FiltersSecurityGroup +type FiltersSecurityGroup struct { + AccountIds []string `json:"AccountIds,omitempty"` + Descriptions []string `json:"Descriptions,omitempty"` + InboundRuleAccountIds []string `json:"InboundRuleAccountIds,omitempty"` + InboundRuleFromPortRanges []int64 `json:"InboundRuleFromPortRanges,omitempty"` + InboundRuleIpRanges []string `json:"InboundRuleIpRanges,omitempty"` + InboundRuleProtocols []string `json:"InboundRuleProtocols,omitempty"` + InboundRuleSecurityGroupIds []string `json:"InboundRuleSecurityGroupIds,omitempty"` + InboundRuleSecurityGroupNames []string `json:"InboundRuleSecurityGroupNames,omitempty"` + InboundRuleToPortRanges []int64 `json:"InboundRuleToPortRanges,omitempty"` + NetIds []string `json:"NetIds,omitempty"` + OutboundRuleAccountIds []string `json:"OutboundRuleAccountIds,omitempty"` + OutboundRuleFromPortRanges []int64 `json:"OutboundRuleFromPortRanges,omitempty"` + OutboundRuleIpRanges []string `json:"OutboundRuleIpRanges,omitempty"` + OutboundRuleProtocols []string `json:"OutboundRuleProtocols,omitempty"` + OutboundRuleSecurityGroupIds []string `json:"OutboundRuleSecurityGroupIds,omitempty"` + OutboundRuleSecurityGroupNames []string `json:"OutboundRuleSecurityGroupNames,omitempty"` + OutboundRuleToPortRanges []int64 `json:"OutboundRuleToPortRanges,omitempty"` + SecurityGroupIds []string `json:"SecurityGroupIds,omitempty"` + SecurityGroupNames []string `json:"SecurityGroupNames,omitempty"` + TagKeys []string `json:"TagKeys,omitempty"` + TagValues []string `json:"TagValues,omitempty"` + Tags []string `json:"Tags,omitempty"` +} + +// implements the service definition of FiltersServices +type FiltersServices struct { + Attributes []Attribute `json:"Attributes,omitempty"` + Endpoint string `json:"Endpoint,omitempty"` + Schema string `json:"Schema,omitempty"` + ServiceName string `json:"ServiceName,omitempty"` +} + +// implements the service definition of FiltersSnapshot +type FiltersSnapshot struct { + AccountAliases []string `json:"AccountAliases,omitempty"` + AccountIds []string `json:"AccountIds,omitempty"` + Descriptions []string `json:"Descriptions,omitempty"` + PermissionsToCreateVolumeAccountIds []string `json:"PermissionsToCreateVolumeAccountIds,omitempty"` + PermissionsToCreateVolumeGlobalPermission bool `json:"PermissionsToCreateVolumeGlobalPermission,omitempty"` + Progresses []int64 `json:"Progresses,omitempty"` + SnapshotIds []string `json:"SnapshotIds,omitempty"` + States []string `json:"States,omitempty"` + TagKeys []string `json:"TagKeys,omitempty"` + TagValues []string `json:"TagValues,omitempty"` + Tags []string `json:"Tags,omitempty"` + VolumeIds []string `json:"VolumeIds,omitempty"` + VolumeSizes []int64 `json:"VolumeSizes,omitempty"` +} + +// implements the service definition of FiltersSubnet +type FiltersSubnet struct { + AvailableIpsCounts []int64 `json:"AvailableIpsCounts,omitempty"` + IpRanges []string `json:"IpRanges,omitempty"` + NetIds []string `json:"NetIds,omitempty"` + States []string `json:"States,omitempty"` + SubnetIds []string `json:"SubnetIds,omitempty"` + SubregionNames []string `json:"SubregionNames,omitempty"` +} + +// implements the service definition of FiltersTag +type FiltersTag struct { + Keys []string `json:"Keys,omitempty"` + ResourceIds []string `json:"ResourceIds,omitempty"` + ResourceTypes []string `json:"ResourceTypes,omitempty"` + Values []string `json:"Values,omitempty"` +} + +// implements the service definition of FiltersUserGroup +type FiltersUserGroup struct { + Paths []string `json:"Paths,omitempty"` + UserNames []string `json:"UserNames,omitempty"` +} + +// implements the service definition of FiltersVm +type FiltersVm struct { + AccountIds []string `json:"AccountIds,omitempty"` + ActivatedCheck bool `json:"ActivatedCheck,omitempty"` + Architectures []string `json:"Architectures,omitempty"` + BlockDeviceMappingDeleteOnVmDeletion *bool `json:"BlockDeviceMappingDeleteOnVmDeletion,omitempty"` + BlockDeviceMappingDeviceNames []string `json:"BlockDeviceMappingDeviceNames,omitempty"` + BlockDeviceMappingLinkDates []string `json:"BlockDeviceMappingLinkDates,omitempty"` + BlockDeviceMappingStates []string `json:"BlockDeviceMappingStates,omitempty"` + BlockDeviceMappingVolumeIds []string `json:"BlockDeviceMappingVolumeIds,omitempty"` + Comments []string `json:"Comments,omitempty"` + CreationDates []string `json:"CreationDates,omitempty"` + DnsNames []string `json:"DnsNames,omitempty"` + Hypervisors []string `json:"Hypervisors,omitempty"` + ImageIds []string `json:"ImageIds,omitempty"` + KernelIds []string `json:"KernelIds,omitempty"` + KeypairNames []string `json:"KeypairNames,omitempty"` + LaunchSortNumbers []int64 `json:"LaunchSortNumbers,omitempty"` + LinkNicDeleteOnVmDeletion bool `json:"LinkNicDeleteOnVmDeletion,omitempty"` + LinkNicLinkDates []string `json:"LinkNicLinkDates,omitempty"` + LinkNicLinkNicIds []string `json:"LinkNicLinkNicIds,omitempty"` + LinkNicLinkPublicIpIds []string `json:"LinkNicLinkPublicIpIds,omitempty"` + LinkNicNicIds []string `json:"LinkNicNicIds,omitempty"` + LinkNicNicSortNumbers []int64 `json:"LinkNicNicSortNumbers,omitempty"` + LinkNicPublicIpAccountIds []string `json:"LinkNicPublicIpAccountIds,omitempty"` + LinkNicPublicIpIds []string `json:"LinkNicPublicIpIds,omitempty"` + LinkNicPublicIps []string `json:"LinkNicPublicIps,omitempty"` + LinkNicStates []string `json:"LinkNicStates,omitempty"` + LinkNicVmAccountIds []string `json:"LinkNicVmAccountIds,omitempty"` + LinkNicVmIds []string `json:"LinkNicVmIds,omitempty"` + MonitoringStates []string `json:"MonitoringStates,omitempty"` + NetIds []string `json:"NetIds,omitempty"` + NicAccountIds []string `json:"NicAccountIds,omitempty"` + NicActivatedCheck bool `json:"NicActivatedCheck,omitempty"` + NicDescriptions []string `json:"NicDescriptions,omitempty"` + NicMacAddresses []string `json:"NicMacAddresses,omitempty"` + NicNetIds []string `json:"NicNetIds,omitempty"` + NicNicIds []string `json:"NicNicIds,omitempty"` + NicPrivateDnsNames []string `json:"NicPrivateDnsNames,omitempty"` + NicSecurityGroupIds []string `json:"NicSecurityGroupIds,omitempty"` + NicSecurityGroupNames []string `json:"NicSecurityGroupNames,omitempty"` + NicStates []string `json:"NicStates,omitempty"` + NicSubnetIds []string `json:"NicSubnetIds,omitempty"` + NicSubregionNames []string `json:"NicSubregionNames,omitempty"` + PlacementGroups []string `json:"PlacementGroups,omitempty"` + PrivateDnsNames []string `json:"PrivateDnsNames,omitempty"` + PrivateIpLinkPrivateIpAccountIds []string `json:"PrivateIpLinkPrivateIpAccountIds,omitempty"` + PrivateIpLinkPublicIps []string `json:"PrivateIpLinkPublicIps,omitempty"` + PrivateIpPrimaryIps []string `json:"PrivateIpPrimaryIps,omitempty"` + PrivateIpPrivateIps []string `json:"PrivateIpPrivateIps,omitempty"` + PrivateIps []string `json:"PrivateIps,omitempty"` + ProductCodes []string `json:"ProductCodes,omitempty"` + PublicIps []string `json:"PublicIps,omitempty"` + RamDiskIds []string `json:"RamDiskIds,omitempty"` + RootDeviceNames []string `json:"RootDeviceNames,omitempty"` + RootDeviceTypes []string `json:"RootDeviceTypes,omitempty"` + SecurityGroupIds []string `json:"SecurityGroupIds,omitempty"` + SecurityGroupNames []string `json:"SecurityGroupNames,omitempty"` + SpotVmRequestIds []string `json:"SpotVmRequestIds,omitempty"` + SpotVms []string `json:"SpotVms,omitempty"` + StateComments []string `json:"StateComments,omitempty"` + SubnetIds []string `json:"SubnetIds,omitempty"` + SubregionNames []string `json:"SubregionNames,omitempty"` + Systems []string `json:"Systems,omitempty"` + TagKeys []string `json:"TagKeys,omitempty"` + TagValues []string `json:"TagValues,omitempty"` + Tags []string `json:"Tags,omitempty"` + Tenancies []string `json:"Tenancies,omitempty"` + Tokens []string `json:"Tokens,omitempty"` + VirtualizationTypes []string `json:"VirtualizationTypes,omitempty"` + VmIds []string `json:"VmIds,omitempty"` + VmStates []string `json:"VmStates,omitempty"` + VmTypes []string `json:"VmTypes,omitempty"` + VmsSecurityGroupIds []string `json:"VmsSecurityGroupIds,omitempty"` + VmsSecurityGroupNames []string `json:"VmsSecurityGroupNames,omitempty"` +} + +// implements the service definition of FiltersVmsState +type FiltersVmsState struct { + MaintenanceEventCodes []string `json:"MaintenanceEventCodes,omitempty"` + MaintenanceEventDescriptions []string `json:"MaintenanceEventDescriptions,omitempty"` + MaintenanceEventsNotAfter []string `json:"MaintenanceEventsNotAfter,omitempty"` + MaintenanceEventsNotBefore []string `json:"MaintenanceEventsNotBefore,omitempty"` + SubregionNames []string `json:"SubregionNames,omitempty"` + VmIds []string `json:"VmIds,omitempty"` + VmStates []string `json:"VmStates,omitempty"` +} + +// implements the service definition of FiltersVolume +type FiltersVolume struct { + CreationDates []string `json:"CreationDates,omitempty"` + SnapshotIds []string `json:"SnapshotIds,omitempty"` + SubregionNames []string `json:"SubregionNames,omitempty"` + TagKeys []string `json:"TagKeys,omitempty"` + TagValues []string `json:"TagValues,omitempty"` + Tags []string `json:"Tags,omitempty"` + VolumeIds []string `json:"VolumeIds,omitempty"` + VolumeSizes []int64 `json:"VolumeSizes,omitempty"` + VolumeTypes []string `json:"VolumeTypes,omitempty"` +} + +// implements the service definition of FiltersVpnConnection +type FiltersVpnConnection struct { + ConnectionTypes []string `json:"ConnectionTypes,omitempty"` + NetToVirtualGatewayLinkNetIds []string `json:"NetToVirtualGatewayLinkNetIds,omitempty"` + NetToVirtualGatewayLinkStates []string `json:"NetToVirtualGatewayLinkStates,omitempty"` + States []string `json:"States,omitempty"` + TagKeys []string `json:"TagKeys,omitempty"` + TagValues []string `json:"TagValues,omitempty"` + Tags []string `json:"Tags,omitempty"` + VirtualGatewayIds []string `json:"VirtualGatewayIds,omitempty"` +} + +// implements the service definition of HealthCheck +type HealthCheck struct { + CheckInterval int64 `json:"CheckInterval,omitempty"` + HealthyThreshold int64 `json:"HealthyThreshold,omitempty"` + Path string `json:"Path,omitempty"` + Port int64 `json:"Port,omitempty"` + Protocol string `json:"Protocol,omitempty"` + Timeout int64 `json:"Timeout,omitempty"` + UnhealthyThreshold int64 `json:"UnhealthyThreshold,omitempty"` +} + +// implements the service definition of Image +type Image struct { + AccountAlias string `json:"AccountAlias,omitempty"` + AccountId string `json:"AccountId,omitempty"` + Architecture string `json:"Architecture,omitempty"` + BlockDeviceMappings []BlockDeviceMappingImage `json:"BlockDeviceMappings,omitempty"` + CreationDate string `json:"CreationDate,omitempty"` + Description string `json:"Description,omitempty"` + FileLocation string `json:"FileLocation,omitempty"` + ImageId string `json:"ImageId,omitempty"` + ImageName string `json:"ImageName,omitempty"` + ImageType string `json:"ImageType,omitempty"` + PermissionsToLaunch PermissionsOnResource `json:"PermissionsToLaunch,omitempty"` + ProductCodes []string `json:"ProductCodes,omitempty"` + RootDeviceName string `json:"RootDeviceName,omitempty"` + RootDeviceType string `json:"RootDeviceType,omitempty"` + State string `json:"State,omitempty"` + StateComment StateComment `json:"StateComment,omitempty"` + Tags []ResourceTag `json:"Tags,omitempty"` +} + +// implements the service definition of ImageExportTask +type ImageExportTask struct { + Comment string `json:"Comment,omitempty"` + ImageId string `json:"ImageId,omitempty"` + OsuExport OsuExport `json:"OsuExport,omitempty"` + Progress int64 `json:"Progress,omitempty"` + State string `json:"State,omitempty"` + TaskId string `json:"TaskId,omitempty"` +} + +// implements the service definition of InternetService +type InternetService struct { + InternetServiceId string `json:"InternetServiceId,omitempty"` + NetId string `json:"NetId,omitempty"` + State string `json:"State,omitempty"` + Tags []ResourceTag `json:"Tags,omitempty"` +} + +// implements the service definition of Item +type Item struct { + AccountId string `json:"AccountId,omitempty"` + Catalog []Catalog_0 `json:"Catalog,omitempty"` + ComsuptionValue int `json:"ComsuptionValue,omitempty"` + Entry string `json:"Entry,omitempty"` + FromDate string `json:"FromDate,omitempty"` + PayingAccountId string `json:"PayingAccountId,omitempty"` + Service string `json:"Service,omitempty"` + SubregionName string `json:"SubregionName,omitempty"` + ToDate string `json:"ToDate,omitempty"` + Type string `json:"Type,omitempty"` +} + +// implements the service definition of Keypair +type Keypair struct { + KeypairFingerprint string `json:"KeypairFingerprint,omitempty"` + KeypairName string `json:"KeypairName,omitempty"` +} + +// implements the service definition of KeypairCreated +type KeypairCreated struct { + KeypairFingerprint string `json:"KeypairFingerprint,omitempty"` + KeypairName string `json:"KeypairName,omitempty"` + PrivateKey string `json:"PrivateKey,omitempty"` +} + +// implements the service definition of LinkInternetServiceRequest +type LinkInternetServiceRequest struct { + DryRun bool `json:"DryRun,omitempty"` + InternetServiceId string `json:"InternetServiceId,omitempty"` + NetId string `json:"NetId,omitempty"` +} + +// implements the service definition of LinkInternetServiceResponse +type LinkInternetServiceResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of LinkNic +type LinkNic struct { + DeleteOnVmDeletion *bool `json:"DeleteOnVmDeletion,omitempty"` + DeviceNumber int64 `json:"DeviceNumber,omitempty"` + LinkNicId string `json:"LinkNicId,omitempty"` + State string `json:"State,omitempty"` + VmAccountId string `json:"VmAccountId,omitempty"` + VmId string `json:"VmId,omitempty"` +} + +// implements the service definition of LinkNicLight +type LinkNicLight struct { + DeleteOnVmDeletion *bool `json:"DeleteOnVmDeletion,omitempty"` + DeviceNumber int64 `json:"DeviceNumber,omitempty"` + LinkNicId string `json:"LinkNicId,omitempty"` + State string `json:"State,omitempty"` +} + +// implements the service definition of LinkNicRequest +type LinkNicRequest struct { + DeviceNumber int64 `json:"DeviceNumber,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + NicId string `json:"NicId,omitempty"` + VmId string `json:"VmId,omitempty"` +} + +// implements the service definition of LinkNicResponse +type LinkNicResponse struct { + LinkNicId string `json:"LinkNicId,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of LinkNicToUpdate +type LinkNicToUpdate struct { + DeleteOnVmDeletion *bool `json:"DeleteOnVmDeletion,omitempty"` + LinkNicId string `json:"LinkNicId,omitempty"` +} + +// implements the service definition of LinkPolicyRequest +type LinkPolicyRequest struct { + DryRun bool `json:"DryRun,omitempty"` + PolicyId string `json:"PolicyId,omitempty"` + UserGroupName string `json:"UserGroupName,omitempty"` + UserName string `json:"UserName,omitempty"` +} + +// implements the service definition of LinkPolicyResponse +type LinkPolicyResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of LinkPrivateIpsRequest +type LinkPrivateIpsRequest struct { + AllowRelink bool `json:"AllowRelink,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + NicId string `json:"NicId,omitempty"` + PrivateIps []string `json:"PrivateIps,omitempty"` + SecondaryPrivateIpCount int64 `json:"SecondaryPrivateIpCount,omitempty"` +} + +// implements the service definition of LinkPrivateIpsResponse +type LinkPrivateIpsResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of LinkPublicIp +type LinkPublicIp struct { + LinkPublicIpId string `json:"LinkPublicIpId,omitempty"` + PublicDnsName string `json:"PublicDnsName,omitempty"` + PublicIp string `json:"PublicIp,omitempty"` + PublicIpAccountId string `json:"PublicIpAccountId,omitempty"` + PublicIpId string `json:"PublicIpId,omitempty"` +} + +// implements the service definition of LinkPublicIpLightForVm +type LinkPublicIpLightForVm struct { + PublicDnsName string `json:"PublicDnsName,omitempty"` + PublicIp string `json:"PublicIp,omitempty"` + PublicIpAccountId string `json:"PublicIpAccountId,omitempty"` +} + +// implements the service definition of LinkPublicIpRequest +type LinkPublicIpRequest struct { + AllowRelink bool `json:"AllowRelink,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + NicId string `json:"NicId,omitempty"` + PrivateIp string `json:"PrivateIp,omitempty"` + PublicIp string `json:"PublicIp,omitempty"` + PublicIpId string `json:"PublicIpId,omitempty"` + VmId string `json:"VmId,omitempty"` +} + +// implements the service definition of LinkPublicIpResponse +type LinkPublicIpResponse struct { + LinkPublicIpId string `json:"LinkPublicIpId,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of LinkRouteTable +type LinkRouteTable struct { + LinkRouteTableId string `json:"LinkRouteTableId,omitempty"` + Main bool `json:"Main,omitempty"` + RouteTableId string `json:"RouteTableId,omitempty"` + SubnetId string `json:"SubnetId,omitempty"` +} + +// implements the service definition of LinkRouteTableRequest +type LinkRouteTableRequest struct { + DryRun bool `json:"DryRun,omitempty"` + RouteTableId string `json:"RouteTableId,omitempty"` + SubnetId string `json:"SubnetId,omitempty"` +} + +// implements the service definition of LinkRouteTableResponse +type LinkRouteTableResponse struct { + LinkRouteTableId string `json:"LinkRouteTableId,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of LinkVirtualGatewayRequest +type LinkVirtualGatewayRequest struct { + DryRun bool `json:"DryRun,omitempty"` + NetId string `json:"NetId,omitempty"` + VirtualGatewayId string `json:"VirtualGatewayId,omitempty"` +} + +// implements the service definition of LinkVirtualGatewayResponse +type LinkVirtualGatewayResponse struct { + NetToVirtualGatewayLink NetToVirtualGatewayLink `json:"NetToVirtualGatewayLink,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of LinkVolumeRequest +type LinkVolumeRequest struct { + DeviceName string `json:"DeviceName,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + VmId string `json:"VmId,omitempty"` + VolumeId string `json:"VolumeId,omitempty"` +} + +// implements the service definition of LinkVolumeResponse +type LinkVolumeResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of LinkedVolume +type LinkedVolume struct { + DeleteOnVmDeletion *bool `json:"DeleteOnVmDeletion,omitempty"` + DeviceName string `json:"DeviceName,omitempty"` + State string `json:"State,omitempty"` + VmId string `json:"VmId,omitempty"` + VolumeId string `json:"VolumeId,omitempty"` +} + +// implements the service definition of Listener +type Listener struct { + BackendPort int64 `json:"BackendPort,omitempty"` + BackendProtocol string `json:"BackendProtocol,omitempty"` + LoadBalancerPort int64 `json:"LoadBalancerPort,omitempty"` + LoadBalancerProtocol string `json:"LoadBalancerProtocol,omitempty"` + PolicyNames []string `json:"PolicyNames,omitempty"` + ServerCertificateId string `json:"ServerCertificateId,omitempty"` +} + +// implements the service definition of ListenerForCreation +type ListenerForCreation struct { + BackendPort int64 `json:"BackendPort,omitempty"` + BackendProtocol string `json:"BackendProtocol,omitempty"` + LoadBalancerPort int64 `json:"LoadBalancerPort,omitempty"` + LoadBalancerProtocol string `json:"LoadBalancerProtocol,omitempty"` + ServerCertificateId string `json:"ServerCertificateId,omitempty"` +} + +// implements the service definition of ListenerRule +type ListenerRule struct { + Action string `json:"Action,omitempty"` + HostNamePattern string `json:"HostNamePattern,omitempty"` + ListenerRuleId string `json:"ListenerRuleId,omitempty"` + ListenerRuleName string `json:"ListenerRuleName,omitempty"` + PathPattern string `json:"PathPattern,omitempty"` + Priority int64 `json:"Priority,omitempty"` +} + +// implements the service definition of ListenerRules +type ListenerRules struct { + ListenerId string `json:"ListenerId,omitempty"` + ListenerRule ListenerRule `json:"ListenerRule,omitempty"` + VmIds []string `json:"VmIds,omitempty"` +} + +// implements the service definition of LoadBalancer +type LoadBalancer struct { + AccessLog AccessLog `json:"AccessLog,omitempty"` + ApplicationStickyCookiePolicies []ApplicationStickyCookiePolicy `json:"ApplicationStickyCookiePolicies,omitempty"` + BackendVmsIds []string `json:"BackendVmsIds,omitempty"` + DnsName string `json:"DnsName,omitempty"` + HealthCheck HealthCheck `json:"HealthCheck,omitempty"` + Listeners []Listener `json:"Listeners,omitempty"` + LoadBalancerName string `json:"LoadBalancerName,omitempty"` + LoadBalancerStickyCookiePolicies []LoadBalancerStickyCookiePolicy `json:"LoadBalancerStickyCookiePolicies,omitempty"` + LoadBalancerType string `json:"LoadBalancerType,omitempty"` + NetId string `json:"NetId,omitempty"` + SecurityGroups []string `json:"SecurityGroups,omitempty"` + SourceSecurityGroup SourceSecurityGroup `json:"SourceSecurityGroup,omitempty"` + Subnets []string `json:"Subnets,omitempty"` + SubregionNames []string `json:"SubregionNames,omitempty"` + Tags []ResourceTag `json:"Tags,omitempty"` +} + +// implements the service definition of LoadBalancerLight +type LoadBalancerLight struct { + LoadBalancerName string `json:"LoadBalancerName,omitempty"` + LoadBalancerPort int64 `json:"LoadBalancerPort,omitempty"` +} + +// implements the service definition of LoadBalancerStickyCookiePolicy +type LoadBalancerStickyCookiePolicy struct { + PolicyName string `json:"PolicyName,omitempty"` +} + +// implements the service definition of Location +type Location struct { + Code string `json:"Code,omitempty"` + Name string `json:"Name,omitempty"` +} + +// implements the service definition of Log +type Log struct { + CallDuration int64 `json:"CallDuration,omitempty"` + QueryAccessKey string `json:"QueryAccessKey,omitempty"` + QueryApiName string `json:"QueryApiName,omitempty"` + QueryApiVersion string `json:"QueryApiVersion,omitempty"` + QueryCallName string `json:"QueryCallName,omitempty"` + QueryDate string `json:"QueryDate,omitempty"` + QueryIpAddress string `json:"QueryIpAddress,omitempty"` + QueryRaw string `json:"QueryRaw,omitempty"` + QuerySize int64 `json:"QuerySize,omitempty"` + QueryUserAgent string `json:"QueryUserAgent,omitempty"` + ResponseId string `json:"ResponseId,omitempty"` + ResponseSize int64 `json:"ResponseSize,omitempty"` + ResponseStatusCode int64 `json:"ResponseStatusCode,omitempty"` +} + +// implements the service definition of MaintenanceEvent +type MaintenanceEvent struct { + Code string `json:"Code,omitempty"` + Description string `json:"Description,omitempty"` + NotAfter string `json:"NotAfter,omitempty"` + NotBefore string `json:"NotBefore,omitempty"` +} + +// implements the service definition of NatService +type NatService struct { + NatServiceId string `json:"NatServiceId,omitempty"` + NetId string `json:"NetId,omitempty"` + PublicIps []PublicIpLight `json:"PublicIps,omitempty"` + State string `json:"State,omitempty"` + SubnetId string `json:"SubnetId,omitempty"` +} + +// implements the service definition of Net +type Net struct { + DhcpOptionsSetId string `json:"DhcpOptionsSetId,omitempty"` + IpRange string `json:"IpRange,omitempty"` + NetId string `json:"NetId,omitempty"` + State string `json:"State,omitempty"` + Tags []ResourceTag `json:"Tags,omitempty"` + Tenancy string `json:"Tenancy,omitempty"` +} + +// implements the service definition of NetAccessPoint +type NetAccessPoint struct { + NetAccessPointId string `json:"NetAccessPointId,omitempty"` + NetId string `json:"NetId,omitempty"` + PrefixListName string `json:"PrefixListName,omitempty"` + RouteTableIds []string `json:"RouteTableIds,omitempty"` + State string `json:"State,omitempty"` +} + +// implements the service definition of NetPeering +type NetPeering struct { + AccepterNet AccepterNet `json:"AccepterNet,omitempty"` + NetPeeringId string `json:"NetPeeringId,omitempty"` + SourceNet SourceNet `json:"SourceNet,omitempty"` + State NetPeeringState `json:"State,omitempty"` + Tags []ResourceTag `json:"Tags,omitempty"` +} + +// implements the service definition of NetPeeringState +type NetPeeringState struct { + Message string `json:"Message,omitempty"` + Name string `json:"Name,omitempty"` +} + +// implements the service definition of NetToVirtualGatewayLink +type NetToVirtualGatewayLink struct { + NetId string `json:"NetId,omitempty"` + State string `json:"State,omitempty"` +} + +// implements the service definition of Nic +type Nic struct { + AccountId string `json:"AccountId,omitempty"` + Description string `json:"Description,omitempty"` + IsSourceDestChecked bool `json:"IsSourceDestChecked,omitempty"` + LinkNic LinkNic `json:"LinkNic,omitempty"` + LinkPublicIp LinkPublicIp `json:"LinkPublicIp,omitempty"` + MacAddress string `json:"MacAddress,omitempty"` + NetId string `json:"NetId,omitempty"` + NicId string `json:"NicId,omitempty"` + PrivateDnsName string `json:"PrivateDnsName,omitempty"` + PrivateIps []PrivateIp `json:"PrivateIps,omitempty"` + SecurityGroups []SecurityGroupLight `json:"SecurityGroups,omitempty"` + State string `json:"State,omitempty"` + SubnetId string `json:"SubnetId,omitempty"` + SubregionName string `json:"SubregionName,omitempty"` + Tags []ResourceTag `json:"Tags,omitempty"` +} + +// implements the service definition of NicForVmCreation +type NicForVmCreation struct { + DeleteOnVmDeletion bool `json:"DeleteOnVmDeletion,omitempty"` + Description string `json:"Description,omitempty"` + DeviceNumber int64 `json:"DeviceNumber,omitempty"` + NicId string `json:"NicId,omitempty"` + PrivateIps []PrivateIpLight `json:"PrivateIps,omitempty"` + SecondaryPrivateIpCount int64 `json:"SecondaryPrivateIpCount,omitempty"` + SecurityGroupIds []string `json:"SecurityGroupIds,omitempty"` + SubnetId string `json:"SubnetId,omitempty"` +} + +// implements the service definition of NicLight +type NicLight struct { + AccountId string `json:"AccountId,omitempty"` + Description string `json:"Description,omitempty"` + IsSourceDestChecked bool `json:"IsSourceDestChecked,omitempty"` + LinkNic LinkNicLight `json:"LinkNic,omitempty"` + LinkPublicIp LinkPublicIpLightForVm `json:"LinkPublicIp,omitempty"` + MacAddress string `json:"MacAddress,omitempty"` + NetId string `json:"NetId,omitempty"` + NicId string `json:"NicId,omitempty"` + PrivateDnsName string `json:"PrivateDnsName,omitempty"` + PrivateIps []PrivateIpLightForVm `json:"PrivateIps,omitempty"` + SecurityGroups []SecurityGroupLight `json:"SecurityGroups,omitempty"` + State string `json:"State,omitempty"` + SubnetId string `json:"SubnetId,omitempty"` +} + +// implements the service definition of OsuApiKey +type OsuApiKey struct { + ApiKeyId string `json:"ApiKeyId,omitempty"` + SecretKey string `json:"SecretKey,omitempty"` +} + +// implements the service definition of OsuExport +type OsuExport struct { + DiskImageFormat string `json:"DiskImageFormat,omitempty"` + OsuApiKey OsuApiKey `json:"OsuApiKey,omitempty"` + OsuBucket string `json:"OsuBucket,omitempty"` + OsuManifestUrl string `json:"OsuManifestUrl,omitempty"` + OsuPrefix string `json:"OsuPrefix,omitempty"` +} + +// implements the service definition of PermissionsOnResource +type PermissionsOnResource struct { + AccountIds []string `json:"AccountIds,omitempty"` + GlobalPermission bool `json:"GlobalPermission,omitempty"` +} + +// implements the service definition of PermissionsOnResourceCreation +type PermissionsOnResourceCreation struct { + Additions PermissionsOnResource `json:"Additions,omitempty"` + Removals PermissionsOnResource `json:"Removals,omitempty"` +} + +// implements the service definition of Placement +type Placement struct { + SubregionName string `json:"SubregionName,omitempty"` + Tenancy string `json:"Tenancy,omitempty"` +} + +// implements the service definition of Policy +type Policy struct { + Description string `json:"Description,omitempty"` + IsLinkable bool `json:"IsLinkable,omitempty"` + Path string `json:"Path,omitempty"` + PolicyDefaultVersionId string `json:"PolicyDefaultVersionId,omitempty"` + PolicyId string `json:"PolicyId,omitempty"` + PolicyName string `json:"PolicyName,omitempty"` + ResourcesCount int64 `json:"ResourcesCount,omitempty"` +} + +// implements the service definition of PrefixLists +type PrefixLists struct { + IpRanges []string `json:"IpRanges,omitempty"` + PrefixListId string `json:"PrefixListId,omitempty"` + PrefixListName string `json:"PrefixListName,omitempty"` +} + +// implements the service definition of PricingDetail +type PricingDetail struct { + Count int64 `json:"Count,omitempty"` +} + +// implements the service definition of PrivateIp +type PrivateIp struct { + IsPrimary bool `json:"IsPrimary,omitempty"` + LinkPublicIp LinkPublicIp `json:"LinkPublicIp,omitempty"` + PrivateDnsName string `json:"PrivateDnsName,omitempty"` + PrivateIp string `json:"PrivateIp,omitempty"` +} + +// implements the service definition of PrivateIpLight +type PrivateIpLight struct { + IsPrimary bool `json:"IsPrimary,omitempty"` + PrivateIp string `json:"PrivateIp,omitempty"` +} + +// implements the service definition of PrivateIpLightForVm +type PrivateIpLightForVm struct { + IsPrimary bool `json:"IsPrimary,omitempty"` + LinkPublicIp LinkPublicIpLightForVm `json:"LinkPublicIp,omitempty"` + PrivateDnsName string `json:"PrivateDnsName,omitempty"` + PrivateIp string `json:"PrivateIp,omitempty"` +} + +// implements the service definition of ProductType +type ProductType struct { + Description string `json:"Description,omitempty"` + ProductTypeId string `json:"ProductTypeId,omitempty"` + Vendor string `json:"Vendor,omitempty"` +} + +// implements the service definition of PublicIp +type PublicIp struct { + LinkPublicIpId string `json:"LinkPublicIpId,omitempty"` + NicAccountId string `json:"NicAccountId,omitempty"` + NicId string `json:"NicId,omitempty"` + PrivateIp string `json:"PrivateIp,omitempty"` + PublicIp string `json:"PublicIp,omitempty"` + PublicIpId string `json:"PublicIpId,omitempty"` + VmId string `json:"VmId,omitempty"` +} + +// implements the service definition of PublicIpLight +type PublicIpLight struct { + PublicIp string `json:"PublicIp,omitempty"` + PublicIpId string `json:"PublicIpId,omitempty"` +} + +// implements the service definition of PurchaseReservedVmsOfferRequest +type PurchaseReservedVmsOfferRequest struct { + DryRun bool `json:"DryRun,omitempty"` + ReservedVmsOfferId string `json:"ReservedVmsOfferId,omitempty"` + VmCount int64 `json:"VmCount,omitempty"` +} + +// implements the service definition of PurchaseReservedVmsOfferResponse +type PurchaseReservedVmsOfferResponse struct { + ReservedVmsId string `json:"ReservedVmsId,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of Quota +type Quota struct { + AccountId string `json:"AccountId,omitempty"` + Description string `json:"Description,omitempty"` + MaxValue int64 `json:"MaxValue,omitempty"` + Name string `json:"Name,omitempty"` + QuotaCollection string `json:"QuotaCollection,omitempty"` + ShortDescription string `json:"ShortDescription,omitempty"` + UsedValue int64 `json:"UsedValue,omitempty"` +} + +// implements the service definition of QuotaTypes +type QuotaTypes struct { + QuotaType string `json:"QuotaType,omitempty"` + Quotas []Quota `json:"Quotas,omitempty"` +} + +// implements the service definition of ReadAccountConsumptionRequest +type ReadAccountConsumptionRequest struct { + DryRun bool `json:"DryRun,omitempty"` + FromDate string `json:"FromDate,omitempty"` + ToDate string `json:"ToDate,omitempty"` +} + +// implements the service definition of ReadAccountConsumptionResponse +type ReadAccountConsumptionResponse struct { + ConsumptionEntries ConsumptionEntries `json:"ConsumptionEntries,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadAccountRequest +type ReadAccountRequest struct { + DryRun bool `json:"DryRun,omitempty"` +} + +// implements the service definition of ReadAccountResponse +type ReadAccountResponse struct { + Account Account `json:"Account,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadAdminPasswordRequest +type ReadAdminPasswordRequest struct { + DryRun bool `json:"DryRun,omitempty"` + VmId string `json:"VmId,omitempty"` +} + +// implements the service definition of ReadAdminPasswordResponse +type ReadAdminPasswordResponse struct { + AdminPassword string `json:"AdminPassword,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + VmId string `json:"VmId,omitempty"` +} + +// implements the service definition of ReadApiKeysRequest +type ReadApiKeysRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Tags []ResourceTag `json:"Tags,omitempty"` + UserName string `json:"UserName,omitempty"` +} + +// implements the service definition of ReadApiKeysResponse +type ReadApiKeysResponse struct { + ApiKeys []ApiKey `json:"ApiKeys,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadApiLogsRequest +type ReadApiLogsRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters FiltersApiLog `json:"Filters,omitempty"` + With With `json:"With,omitempty"` +} + +// implements the service definition of ReadApiLogsResponse +type ReadApiLogsResponse struct { + Logs []Log `json:"Logs,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadBillableDigestRequest +type ReadBillableDigestRequest struct { + AccountId string `json:"AccountId,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + FromDate string `json:"FromDate,omitempty"` + InvoiceState string `json:"InvoiceState,omitempty"` + IsConsolidated bool `json:"IsConsolidated,omitempty"` + ToDate string `json:"ToDate,omitempty"` +} + +// implements the service definition of ReadBillableDigestResponse +type ReadBillableDigestResponse struct { + Items []Item `json:"Items,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadCatalogRequest +type ReadCatalogRequest struct { + DryRun bool `json:"DryRun,omitempty"` +} + +// implements the service definition of ReadCatalogResponse +type ReadCatalogResponse struct { + Catalog Catalog_1 `json:"Catalog,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadClientGatewaysRequest +type ReadClientGatewaysRequest struct { + ClientGatewayIds []string `json:"ClientGatewayIds,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + Filters []FiltersOldFormat `json:"Filters,omitempty"` +} + +// implements the service definition of ReadClientGatewaysResponse +type ReadClientGatewaysResponse struct { + ClientGateways []ClientGateway `json:"ClientGateways,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadConsoleOutputRequest +type ReadConsoleOutputRequest struct { + DryRun bool `json:"DryRun,omitempty"` + VmId string `json:"VmId,omitempty"` +} + +// implements the service definition of ReadConsoleOutputResponse +type ReadConsoleOutputResponse struct { + ConsoleOutput string `json:"ConsoleOutput,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + VmId string `json:"VmId,omitempty"` +} + +// implements the service definition of ReadDhcpOptionsRequest +type ReadDhcpOptionsRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters FiltersDhcpOptions `json:"Filters,omitempty"` +} + +// implements the service definition of ReadDhcpOptionsResponse +type ReadDhcpOptionsResponse struct { + DhcpOptionsSets []DhcpOptionsSet `json:"DhcpOptionsSets,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadDirectLinkInterfacesRequest +type ReadDirectLinkInterfacesRequest struct { + DirectLinkId string `json:"DirectLinkId,omitempty"` + DirectLinkInterfaceId string `json:"DirectLinkInterfaceId,omitempty"` + DryRun bool `json:"DryRun,omitempty"` +} + +// implements the service definition of ReadDirectLinkInterfacesResponse +type ReadDirectLinkInterfacesResponse struct { + DirectLinkInterfaces []DirectLinkInterfaces `json:"DirectLinkInterfaces,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadDirectLinksRequest +type ReadDirectLinksRequest struct { + DirectLinkId string `json:"DirectLinkId,omitempty"` + DryRun bool `json:"DryRun,omitempty"` +} + +// implements the service definition of ReadDirectLinksResponse +type ReadDirectLinksResponse struct { + DirectLinks []DirectLink `json:"DirectLinks,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadImageExportTasksRequest +type ReadImageExportTasksRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters FiltersExportTask `json:"Filters,omitempty"` +} + +// implements the service definition of ReadImageExportTasksResponse +type ReadImageExportTasksResponse struct { + ImageExportTasks []ImageExportTask `json:"ImageExportTasks,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadImagesRequest +type ReadImagesRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters FiltersImage `json:"Filters,omitempty"` +} + +// implements the service definition of ReadImagesResponse +type ReadImagesResponse struct { + Images []Image `json:"Images,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadInternetServicesRequest +type ReadInternetServicesRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters FiltersInternetService `json:"Filters,omitempty"` +} + +// implements the service definition of ReadInternetServicesResponse +type ReadInternetServicesResponse struct { + InternetServices []InternetService `json:"InternetServices,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadKeypairsRequest +type ReadKeypairsRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters FiltersKeypair `json:"Filters,omitempty"` +} + +// implements the service definition of ReadKeypairsResponse +type ReadKeypairsResponse struct { + Keypairs []Keypair `json:"Keypairs,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadListenerRulesRequest +type ReadListenerRulesRequest struct { + DryRun bool `json:"DryRun,omitempty"` + ListenerRuleNames []string `json:"ListenerRuleNames,omitempty"` +} + +// implements the service definition of ReadListenerRulesResponse +type ReadListenerRulesResponse struct { + ListenerRules []ListenerRules `json:"ListenerRules,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadLoadBalancersRequest +type ReadLoadBalancersRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters FiltersLoadBalancer `json:"Filters,omitempty"` +} + +// implements the service definition of ReadLoadBalancersResponse +type ReadLoadBalancersResponse struct { + LoadBalancers []LoadBalancer `json:"LoadBalancers,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadLocationsRequest +type ReadLocationsRequest struct { + DryRun bool `json:"DryRun,omitempty"` +} + +// implements the service definition of ReadLocationsResponse +type ReadLocationsResponse struct { + Locations []Location `json:"Locations,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadNatServicesRequest +type ReadNatServicesRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters FiltersNatService `json:"Filters,omitempty"` +} + +// implements the service definition of ReadNatServicesResponse +type ReadNatServicesResponse struct { + NatServices []NatService `json:"NatServices,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadNetAccessPointServicesRequest +type ReadNetAccessPointServicesRequest struct { + DryRun bool `json:"DryRun,omitempty"` +} + +// implements the service definition of ReadNetAccessPointServicesResponse +type ReadNetAccessPointServicesResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + ServiceNames []string `json:"ServiceNames,omitempty"` +} + +// implements the service definition of ReadNetAccessPointsRequest +type ReadNetAccessPointsRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters []FiltersOldFormat `json:"Filters,omitempty"` + NetAccessPointIds []string `json:"NetAccessPointIds,omitempty"` +} + +// implements the service definition of ReadNetAccessPointsResponse +type ReadNetAccessPointsResponse struct { + NetAccessPoints []NetAccessPoint `json:"NetAccessPoints,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadNetPeeringsRequest +type ReadNetPeeringsRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters FiltersNetPeering `json:"Filters,omitempty"` +} + +// implements the service definition of ReadNetPeeringsResponse +type ReadNetPeeringsResponse struct { + NetPeerings []NetPeering `json:"NetPeerings,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadNetsRequest +type ReadNetsRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters FiltersNet `json:"Filters,omitempty"` +} + +// implements the service definition of ReadNetsResponse +type ReadNetsResponse struct { + Nets []Net `json:"Nets,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadNicsRequest +type ReadNicsRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters FiltersNic `json:"Filters,omitempty"` +} + +// implements the service definition of ReadNicsResponse +type ReadNicsResponse struct { + Nics []Nic `json:"Nics,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadPoliciesRequest +type ReadPoliciesRequest struct { + DryRun bool `json:"DryRun,omitempty"` + IsLinked bool `json:"IsLinked,omitempty"` + Path string `json:"Path,omitempty"` + UserGroupName string `json:"UserGroupName,omitempty"` + UserName string `json:"UserName,omitempty"` +} + +// implements the service definition of ReadPoliciesResponse +type ReadPoliciesResponse struct { + Policies []Policy `json:"Policies,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadPrefixListsRequest +type ReadPrefixListsRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters []FiltersOldFormat `json:"Filters,omitempty"` + PrefixListIds []string `json:"PrefixListIds,omitempty"` +} + +// implements the service definition of ReadPrefixListsResponse +type ReadPrefixListsResponse struct { + PrefixLists []PrefixLists `json:"PrefixLists,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadProductTypesRequest +type ReadProductTypesRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters []FiltersOldFormat `json:"Filters,omitempty"` +} + +// implements the service definition of ReadProductTypesResponse +type ReadProductTypesResponse struct { + ProductTypes []ProductType `json:"ProductTypes,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadPublicCatalogRequest +type ReadPublicCatalogRequest struct { + DryRun bool `json:"DryRun,omitempty"` +} + +// implements the service definition of ReadPublicCatalogResponse +type ReadPublicCatalogResponse struct { + Catalog Catalog_1 `json:"Catalog,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadPublicIpRangesRequest +type ReadPublicIpRangesRequest struct { + DryRun bool `json:"DryRun,omitempty"` +} + +// implements the service definition of ReadPublicIpRangesResponse +type ReadPublicIpRangesResponse struct { + PublicIps []string `json:"PublicIps,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadPublicIpsRequest +type ReadPublicIpsRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters FiltersPublicIp `json:"Filters,omitempty"` +} + +// implements the service definition of ReadPublicIpsResponse +type ReadPublicIpsResponse struct { + PublicIps []PublicIp `json:"PublicIps,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadQuotasRequest +type ReadQuotasRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters []FiltersOldFormat `json:"Filters,omitempty"` + QuotaNames []string `json:"QuotaNames,omitempty"` +} + +// implements the service definition of ReadQuotasResponse +type ReadQuotasResponse struct { + QuotaTypes []QuotaTypes `json:"QuotaTypes,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadRegionConfigRequest +type ReadRegionConfigRequest struct { + DryRun bool `json:"DryRun,omitempty"` + FromDate string `json:"FromDate,omitempty"` +} + +// implements the service definition of ReadRegionConfigResponse +type ReadRegionConfigResponse struct { + RegionConfig RegionConfig `json:"RegionConfig,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadRegionsRequest +type ReadRegionsRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters []FiltersOldFormat `json:"Filters,omitempty"` + RegionNames []string `json:"RegionNames,omitempty"` +} + +// implements the service definition of ReadRegionsResponse +type ReadRegionsResponse struct { + Regions []Region `json:"Regions,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadReservedVmOffersRequest +type ReadReservedVmOffersRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters []FiltersOldFormat `json:"Filters,omitempty"` + OfferingType string `json:"OfferingType,omitempty"` + ProductType string `json:"ProductType,omitempty"` + ReservedVmsOfferIds []string `json:"ReservedVmsOfferIds,omitempty"` + SubregionName string `json:"SubregionName,omitempty"` + Tenancy string `json:"Tenancy,omitempty"` + VmType string `json:"VmType,omitempty"` +} + +// implements the service definition of ReadReservedVmOffersResponse +type ReadReservedVmOffersResponse struct { + ReservedVmsOffers []ReservedVmsOffer `json:"ReservedVmsOffers,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadReservedVmsRequest +type ReadReservedVmsRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters []FiltersOldFormat `json:"Filters,omitempty"` + OfferingType string `json:"OfferingType,omitempty"` + ReservedVmsIds []string `json:"ReservedVmsIds,omitempty"` + SubregionName string `json:"SubregionName,omitempty"` +} + +// implements the service definition of ReadReservedVmsResponse +type ReadReservedVmsResponse struct { + ReservedVms []ReservedVm `json:"ReservedVms,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadRouteTablesRequest +type ReadRouteTablesRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters FiltersRouteTable `json:"Filters,omitempty"` +} + +// implements the service definition of ReadRouteTablesResponse +type ReadRouteTablesResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + RouteTables []RouteTable `json:"RouteTables,omitempty"` +} + +// implements the service definition of ReadSecurityGroupsRequest +type ReadSecurityGroupsRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters FiltersSecurityGroup `json:"Filters,omitempty"` +} + +// implements the service definition of ReadSecurityGroupsResponse +type ReadSecurityGroupsResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + SecurityGroups []SecurityGroup `json:"SecurityGroups,omitempty"` +} + +// implements the service definition of ReadServerCertificatesRequest +type ReadServerCertificatesRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Path string `json:"Path,omitempty"` +} + +// implements the service definition of ReadServerCertificatesResponse +type ReadServerCertificatesResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + ServerCertificates []ServerCertificate `json:"ServerCertificates,omitempty"` +} + +// implements the service definition of ReadSnapshotExportTasksRequest +type ReadSnapshotExportTasksRequest struct { + DryRun bool `json:"DryRun,omitempty"` + TaskIds []string `json:"TaskIds,omitempty"` +} + +// implements the service definition of ReadSnapshotExportTasksResponse +type ReadSnapshotExportTasksResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + SnapshotExportTasks []SnapshotExportTask `json:"SnapshotExportTasks,omitempty"` +} + +// implements the service definition of ReadSnapshotsRequest +type ReadSnapshotsRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters FiltersSnapshot `json:"Filters,omitempty"` +} + +// implements the service definition of ReadSnapshotsResponse +type ReadSnapshotsResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + Snapshots []Snapshot `json:"Snapshots,omitempty"` +} + +// implements the service definition of ReadSubnetsRequest +type ReadSubnetsRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters FiltersSubnet `json:"Filters,omitempty"` +} + +// implements the service definition of ReadSubnetsResponse +type ReadSubnetsResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + Subnets []Subnet `json:"Subnets,omitempty"` +} + +// implements the service definition of ReadSubregionsRequest +type ReadSubregionsRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters []FiltersOldFormat `json:"Filters,omitempty"` + SubregionNames []string `json:"SubregionNames,omitempty"` +} + +// implements the service definition of ReadSubregionsResponse +type ReadSubregionsResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + Subregions []Subregion `json:"Subregions,omitempty"` +} + +// implements the service definition of ReadTagsRequest +type ReadTagsRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters FiltersTag `json:"Filters,omitempty"` +} + +// implements the service definition of ReadTagsResponse +type ReadTagsResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + Tags []Tag `json:"Tags,omitempty"` +} + +// implements the service definition of ReadUserGroupsRequest +type ReadUserGroupsRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters FiltersUserGroup `json:"Filters,omitempty"` +} + +// implements the service definition of ReadUserGroupsResponse +type ReadUserGroupsResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + UserGroups []UserGroup `json:"UserGroups,omitempty"` +} + +// implements the service definition of ReadUsersRequest +type ReadUsersRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Path string `json:"Path,omitempty"` +} + +// implements the service definition of ReadUsersResponse +type ReadUsersResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + Users []User `json:"Users,omitempty"` +} + +// implements the service definition of ReadVirtualGatewaysRequest +type ReadVirtualGatewaysRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters []FiltersOldFormat `json:"Filters,omitempty"` +} + +// implements the service definition of ReadVirtualGatewaysResponse +type ReadVirtualGatewaysResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + VirtualGateways []VirtualGateway `json:"VirtualGateways,omitempty"` +} + +// implements the service definition of ReadVmTypesRequest +type ReadVmTypesRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters []FiltersOldFormat `json:"Filters,omitempty"` +} + +// implements the service definition of ReadVmTypesResponse +type ReadVmTypesResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + VmTypes []VmType `json:"VmTypes,omitempty"` +} + +// implements the service definition of ReadVmsHealthRequest +type ReadVmsHealthRequest struct { + BackendVmsIds []string `json:"BackendVmsIds,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + LoadBalancerName string `json:"LoadBalancerName,omitempty"` +} + +// implements the service definition of ReadVmsHealthResponse +type ReadVmsHealthResponse struct { + BackendVmsHealth []BackendVmsHealth `json:"BackendVmsHealth,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReadVmsRequest +type ReadVmsRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters FiltersVm `json:"Filters,omitempty"` +} + +// implements the service definition of ReadVmsResponse +type ReadVmsResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + Vms []Vm `json:"Vms,omitempty"` +} + +// implements the service definition of ReadVmsStateRequest +type ReadVmsStateRequest struct { + AllVms bool `json:"AllVms,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + Filters FiltersVmsState `json:"Filters,omitempty"` +} + +// implements the service definition of ReadVmsStateResponse +type ReadVmsStateResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + VmStates []VmStates `json:"VmStates,omitempty"` +} + +// implements the service definition of ReadVolumesRequest +type ReadVolumesRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters FiltersVolume `json:"Filters,omitempty"` +} + +// implements the service definition of ReadVolumesResponse +type ReadVolumesResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + Volumes []Volume `json:"Volumes,omitempty"` +} + +// implements the service definition of ReadVpnConnectionsRequest +type ReadVpnConnectionsRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Filters FiltersVpnConnection `json:"Filters,omitempty"` + VpnConnectionIds []string `json:"VpnConnectionIds,omitempty"` +} + +// implements the service definition of ReadVpnConnectionsResponse +type ReadVpnConnectionsResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + VpnConnections []VpnConnection `json:"VpnConnections,omitempty"` +} + +// implements the service definition of RebootVmsRequest +type RebootVmsRequest struct { + DryRun bool `json:"DryRun,omitempty"` + VmIds []string `json:"VmIds,omitempty"` +} + +// implements the service definition of RebootVmsResponse +type RebootVmsResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of RecurringCharge +type RecurringCharge struct { + Frequency string `json:"Frequency,omitempty"` +} + +// implements the service definition of Region +type Region struct { + RegionEndpoint string `json:"RegionEndpoint,omitempty"` + RegionName string `json:"RegionName,omitempty"` +} + +// implements the service definition of RegionConfig +type RegionConfig struct { + FromDate string `json:"FromDate,omitempty"` + Regions []RegionDescription `json:"Regions,omitempty"` + TargetRegion TargetRegion `json:"TargetRegion,omitempty"` +} + +// implements the service definition of RegionDescription +type RegionDescription struct { + Attributes []Attribute `json:"Attributes,omitempty"` + Continent string `json:"Continent,omitempty"` + CurrencyCode string `json:"CurrencyCode,omitempty"` + Entity string `json:"Entity,omitempty"` + IsPublic bool `json:"IsPublic,omitempty"` + IsSynchronized bool `json:"IsSynchronized,omitempty"` + Permissions []RegionDescriptionPermission `json:"Permissions,omitempty"` + RegionDomain string `json:"RegionDomain,omitempty"` + RegionId string `json:"RegionId,omitempty"` + RegionInstance string `json:"RegionInstance,omitempty"` + RegionName string `json:"RegionName,omitempty"` + SerialFactor int64 `json:"SerialFactor,omitempty"` + Services []Service `json:"Services,omitempty"` + SubregionNames []string `json:"SubregionNames,omitempty"` +} + +// implements the service definition of RegionDescriptionPermission +type RegionDescriptionPermission struct { + Filter string `json:"Filter,omitempty"` + PermissionType string `json:"PermissionType,omitempty"` +} + +// implements the service definition of RegisterUserInUserGroupRequest +type RegisterUserInUserGroupRequest struct { + DryRun bool `json:"DryRun,omitempty"` + UserGroupName string `json:"UserGroupName,omitempty"` + UserName string `json:"UserName,omitempty"` +} + +// implements the service definition of RegisterUserInUserGroupResponse +type RegisterUserInUserGroupResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of RegisterVmsInLoadBalancerRequest +type RegisterVmsInLoadBalancerRequest struct { + BackendVmsIds []string `json:"BackendVmsIds,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + LoadBalancerName string `json:"LoadBalancerName,omitempty"` +} + +// implements the service definition of RegisterVmsInLoadBalancerResponse +type RegisterVmsInLoadBalancerResponse struct { + BackendVmsIds []string `json:"BackendVmsIds,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of RejectNetPeeringRequest +type RejectNetPeeringRequest struct { + DryRun bool `json:"DryRun,omitempty"` + NetPeeringId string `json:"NetPeeringId,omitempty"` +} + +// implements the service definition of RejectNetPeeringResponse +type RejectNetPeeringResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ReservedVm +type ReservedVm struct { + CurrencyCode string `json:"CurrencyCode,omitempty"` + OfferingType string `json:"OfferingType,omitempty"` + ProductType string `json:"ProductType,omitempty"` + RecurringCharges []RecurringCharge `json:"RecurringCharges,omitempty"` + ReservedVmsId string `json:"ReservedVmsId,omitempty"` + State string `json:"State,omitempty"` + SubregionName string `json:"SubregionName,omitempty"` + Tenancy string `json:"Tenancy,omitempty"` + VmCount int64 `json:"VmCount,omitempty"` + VmType string `json:"VmType,omitempty"` +} + +// implements the service definition of ReservedVmsOffer +type ReservedVmsOffer struct { + CurrencyCode string `json:"CurrencyCode,omitempty"` + Duration int64 `json:"Duration,omitempty"` + FixedPrice int `json:"FixedPrice,omitempty"` + OfferingType string `json:"OfferingType,omitempty"` + PricingDetails []PricingDetail `json:"PricingDetails,omitempty"` + ProductType string `json:"ProductType,omitempty"` + RecurringCharges []RecurringCharge `json:"RecurringCharges,omitempty"` + ReservedVmsOfferId string `json:"ReservedVmsOfferId,omitempty"` + SubregionName string `json:"SubregionName,omitempty"` + Tenancy string `json:"Tenancy,omitempty"` + UsagePrice int `json:"UsagePrice,omitempty"` + VmType string `json:"VmType,omitempty"` +} + +// implements the service definition of ResetAccountPasswordRequest +type ResetAccountPasswordRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Password string `json:"Password,omitempty"` + PasswordToken string `json:"PasswordToken,omitempty"` +} + +// implements the service definition of ResetAccountPasswordResponse +type ResetAccountPasswordResponse struct { + Email string `json:"Email,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ResourceTag +type ResourceTag struct { + Key string `json:"Key,omitempty"` + Value string `json:"Value,omitempty"` +} + +// implements the service definition of ResponseContext +type ResponseContext struct { + RequestId string `json:"RequestId,omitempty"` +} + +// implements the service definition of Route +type Route struct { + CreationMethod string `json:"CreationMethod,omitempty"` + DestinationIpRange string `json:"DestinationIpRange,omitempty"` + DestinationPrefixListId string `json:"DestinationPrefixListId,omitempty"` + GatewayId string `json:"GatewayId,omitempty"` + NatServiceId string `json:"NatServiceId,omitempty"` + NetPeeringId string `json:"NetPeeringId,omitempty"` + NicId string `json:"NicId,omitempty"` + State string `json:"State,omitempty"` + VmAccountId string `json:"VmAccountId,omitempty"` + VmId string `json:"VmId,omitempty"` +} + +// implements the service definition of RouteLight +type RouteLight struct { + DestinationIpRange string `json:"DestinationIpRange,omitempty"` + RouteType string `json:"RouteType,omitempty"` + State string `json:"State,omitempty"` +} + +// implements the service definition of RoutePropagatingVirtualGateway +type RoutePropagatingVirtualGateway struct { + VirtualGatewayId string `json:"VirtualGatewayId,omitempty"` +} + +// implements the service definition of RouteTable +type RouteTable struct { + LinkRouteTables []LinkRouteTable `json:"LinkRouteTables,omitempty"` + NetId string `json:"NetId,omitempty"` + RoutePropagatingVirtualGateways []RoutePropagatingVirtualGateway `json:"RoutePropagatingVirtualGateways,omitempty"` + RouteTableId string `json:"RouteTableId,omitempty"` + Routes []Route `json:"Routes,omitempty"` + Tags []ResourceTag `json:"Tags,omitempty"` +} + +// implements the service definition of SecurityGroup +type SecurityGroup struct { + AccountId string `json:"AccountId,omitempty"` + Description string `json:"Description,omitempty"` + InboundRules []SecurityGroupRule `json:"InboundRules,omitempty"` + NetId string `json:"NetId,omitempty"` + OutboundRules []SecurityGroupRule `json:"OutboundRules,omitempty"` + SecurityGroupId string `json:"SecurityGroupId,omitempty"` + SecurityGroupName string `json:"SecurityGroupName,omitempty"` + Tags []ResourceTag `json:"Tags,omitempty"` +} + +// implements the service definition of SecurityGroupLight +type SecurityGroupLight struct { + SecurityGroupId string `json:"SecurityGroupId,omitempty"` + SecurityGroupName string `json:"SecurityGroupName,omitempty"` +} + +// implements the service definition of SecurityGroupRule +type SecurityGroupRule struct { + FromPortRange int64 `json:"FromPortRange,omitempty"` + IpProtocol string `json:"IpProtocol,omitempty"` + IpRanges []string `json:"IpRanges,omitempty"` + PrefixListIds []string `json:"PrefixListIds,omitempty"` + SecurityGroupsMembers []SecurityGroupsMember `json:"SecurityGroupsMembers,omitempty"` + ToPortRange int64 `json:"ToPortRange,omitempty"` +} + +// implements the service definition of SecurityGroupsMember +type SecurityGroupsMember struct { + AccountId string `json:"AccountId,omitempty"` + SecurityGroupId string `json:"SecurityGroupId,omitempty"` + SecurityGroupName string `json:"SecurityGroupName,omitempty"` +} + +// implements the service definition of SendResetPasswordEmailRequest +type SendResetPasswordEmailRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Email string `json:"Email,omitempty"` +} + +// implements the service definition of SendResetPasswordEmailResponse +type SendResetPasswordEmailResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of ServerCertificate +type ServerCertificate struct { + Path string `json:"Path,omitempty"` + ServerCertificateId string `json:"ServerCertificateId,omitempty"` + ServerCertificateName string `json:"ServerCertificateName,omitempty"` +} + +// implements the service definition of Service +type Service struct { + Filters []FiltersServices `json:"Filters,omitempty"` + ServiceName string `json:"ServiceName,omitempty"` + ServiceType string `json:"ServiceType,omitempty"` +} + +// implements the service definition of Snapshot +type Snapshot struct { + AccountAlias string `json:"AccountAlias,omitempty"` + AccountId string `json:"AccountId,omitempty"` + Description string `json:"Description,omitempty"` + PermissionsToCreateVolume PermissionsOnResource `json:"PermissionsToCreateVolume,omitempty"` + Progress int64 `json:"Progress,omitempty"` + SnapshotId string `json:"SnapshotId,omitempty"` + State string `json:"State,omitempty"` + Tags []ResourceTag `json:"Tags,omitempty"` + VolumeId string `json:"VolumeId,omitempty"` + VolumeSize int64 `json:"VolumeSize,omitempty"` +} + +// implements the service definition of SnapshotExportTask +type SnapshotExportTask struct { + Comment string `json:"Comment,omitempty"` + OsuExport OsuExport `json:"OsuExport,omitempty"` + Progress int64 `json:"Progress,omitempty"` + SnapshotId string `json:"SnapshotId,omitempty"` + State string `json:"State,omitempty"` + TaskId string `json:"TaskId,omitempty"` +} + +// implements the service definition of SourceNet +type SourceNet struct { + AccountId string `json:"AccountId,omitempty"` + IpRange string `json:"IpRange,omitempty"` + NetId string `json:"NetId,omitempty"` +} + +// implements the service definition of SourceSecurityGroup +type SourceSecurityGroup struct { + SecurityGroupAccountId string `json:"SecurityGroupAccountId,omitempty"` + SecurityGroupName string `json:"SecurityGroupName,omitempty"` +} + +// implements the service definition of StartVmsRequest +type StartVmsRequest struct { + DryRun bool `json:"DryRun,omitempty"` + VmIds []string `json:"VmIds,omitempty"` +} + +// implements the service definition of StartVmsResponse +type StartVmsResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + Vms []VmState `json:"Vms,omitempty"` +} + +// implements the service definition of StateComment +type StateComment struct { + StateCode string `json:"StateCode,omitempty"` + StateMessage string `json:"StateMessage,omitempty"` +} + +// implements the service definition of StopVmsRequest +type StopVmsRequest struct { + DryRun bool `json:"DryRun,omitempty"` + ForceStop bool `json:"ForceStop,omitempty"` + VmIds []string `json:"VmIds,omitempty"` +} + +// implements the service definition of StopVmsResponse +type StopVmsResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + Vms []VmState `json:"Vms,omitempty"` +} + +// implements the service definition of Subnet +type Subnet struct { + AvailableIpsCount int64 `json:"AvailableIpsCount,omitempty"` + IpRange string `json:"IpRange,omitempty"` + NetId string `json:"NetId,omitempty"` + State string `json:"State,omitempty"` + SubnetId string `json:"SubnetId,omitempty"` + SubregionName string `json:"SubregionName,omitempty"` + Tags []ResourceTag `json:"Tags,omitempty"` +} + +// implements the service definition of Subregion +type Subregion struct { + RegionName string `json:"RegionName,omitempty"` + State string `json:"State,omitempty"` + SubregionName string `json:"SubregionName,omitempty"` +} + +// implements the service definition of Tag +type Tag struct { + Key string `json:"Key,omitempty"` + ResourceId string `json:"ResourceId,omitempty"` + ResourceType string `json:"ResourceType,omitempty"` + Value string `json:"Value,omitempty"` +} + +// implements the service definition of TargetRegion +type TargetRegion struct { + RegionDomain string `json:"RegionDomain,omitempty"` + RegionId string `json:"RegionId,omitempty"` + RegionName string `json:"RegionName,omitempty"` +} + +// implements the service definition of UnlinkInternetServiceRequest +type UnlinkInternetServiceRequest struct { + DryRun bool `json:"DryRun,omitempty"` + InternetServiceId string `json:"InternetServiceId,omitempty"` + NetId string `json:"NetId,omitempty"` +} + +// implements the service definition of UnlinkInternetServiceResponse +type UnlinkInternetServiceResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of UnlinkNicRequest +type UnlinkNicRequest struct { + DryRun bool `json:"DryRun,omitempty"` + LinkNicId string `json:"LinkNicId,omitempty"` +} + +// implements the service definition of UnlinkNicResponse +type UnlinkNicResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of UnlinkPolicyRequest +type UnlinkPolicyRequest struct { + DryRun bool `json:"DryRun,omitempty"` + PolicyId string `json:"PolicyId,omitempty"` + UserGroupName string `json:"UserGroupName,omitempty"` + UserName string `json:"UserName,omitempty"` +} + +// implements the service definition of UnlinkPolicyResponse +type UnlinkPolicyResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of UnlinkPrivateIpsRequest +type UnlinkPrivateIpsRequest struct { + DryRun bool `json:"DryRun,omitempty"` + NicId string `json:"NicId,omitempty"` + PrivateIps []string `json:"PrivateIps,omitempty"` +} + +// implements the service definition of UnlinkPrivateIpsResponse +type UnlinkPrivateIpsResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of UnlinkPublicIpRequest +type UnlinkPublicIpRequest struct { + DryRun bool `json:"DryRun,omitempty"` + LinkPublicIpId string `json:"LinkPublicIpId,omitempty"` + PublicIp string `json:"PublicIp,omitempty"` +} + +// implements the service definition of UnlinkPublicIpResponse +type UnlinkPublicIpResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of UnlinkRouteTableRequest +type UnlinkRouteTableRequest struct { + DryRun bool `json:"DryRun,omitempty"` + LinkRouteTableId string `json:"LinkRouteTableId,omitempty"` +} + +// implements the service definition of UnlinkRouteTableResponse +type UnlinkRouteTableResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of UnlinkVirtualGatewayRequest +type UnlinkVirtualGatewayRequest struct { + DryRun bool `json:"DryRun,omitempty"` + NetId string `json:"NetId,omitempty"` + VirtualGatewayId string `json:"VirtualGatewayId,omitempty"` +} + +// implements the service definition of UnlinkVirtualGatewayResponse +type UnlinkVirtualGatewayResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of UnlinkVolumeRequest +type UnlinkVolumeRequest struct { + DeviceName string `json:"DeviceName,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + ForceUnlink bool `json:"ForceUnlink,omitempty"` + VolumeId string `json:"VolumeId,omitempty"` +} + +// implements the service definition of UnlinkVolumeResponse +type UnlinkVolumeResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of UpdateAccountRequest +type UpdateAccountRequest struct { + City string `json:"City,omitempty"` + CompanyName string `json:"CompanyName,omitempty"` + Country string `json:"Country,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + Email string `json:"Email,omitempty"` + FirstName string `json:"FirstName,omitempty"` + JobTitle string `json:"JobTitle,omitempty"` + LastName string `json:"LastName,omitempty"` + Mobile string `json:"Mobile,omitempty"` + Password string `json:"Password,omitempty"` + Phone string `json:"Phone,omitempty"` + StateProvince string `json:"StateProvince,omitempty"` + VatNumber string `json:"VatNumber,omitempty"` + ZipCode string `json:"ZipCode,omitempty"` +} + +// implements the service definition of UpdateAccountResponse +type UpdateAccountResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of UpdateApiKeyRequest +type UpdateApiKeyRequest struct { + ApiKeyId string `json:"ApiKeyId,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + State string `json:"State,omitempty"` +} + +// implements the service definition of UpdateApiKeyResponse +type UpdateApiKeyResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of UpdateHealthCheckRequest +type UpdateHealthCheckRequest struct { + DryRun bool `json:"DryRun,omitempty"` + HealthCheck HealthCheck `json:"HealthCheck,omitempty"` + LoadBalancerName string `json:"LoadBalancerName,omitempty"` +} + +// implements the service definition of UpdateHealthCheckResponse +type UpdateHealthCheckResponse struct { + HealthCheck HealthCheck `json:"HealthCheck,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of UpdateImageRequest +type UpdateImageRequest struct { + DryRun bool `json:"DryRun,omitempty"` + ImageId string `json:"ImageId,omitempty"` + PermissionsToLaunch PermissionsOnResourceCreation `json:"PermissionsToLaunch,omitempty"` +} + +// implements the service definition of UpdateImageResponse +type UpdateImageResponse struct { + Image Image `json:"Image,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of UpdateKeypairRequest +type UpdateKeypairRequest struct { + DryRun bool `json:"DryRun,omitempty"` + KeypairName string `json:"KeypairName,omitempty"` + PublicKey string `json:"PublicKey,omitempty"` +} + +// implements the service definition of UpdateKeypairResponse +type UpdateKeypairResponse struct { + KeypairFingerprint string `json:"KeypairFingerprint,omitempty"` + KeypairName string `json:"KeypairName,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of UpdateListenerRuleRequest +type UpdateListenerRuleRequest struct { + Attribute string `json:"Attribute,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + ListenerRuleName string `json:"ListenerRuleName,omitempty"` + Value string `json:"Value,omitempty"` +} + +// implements the service definition of UpdateListenerRuleResponse +type UpdateListenerRuleResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of UpdateLoadBalancerRequest +type UpdateLoadBalancerRequest struct { + AccessLog AccessLog `json:"AccessLog,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + LoadBalancerName string `json:"LoadBalancerName,omitempty"` + LoadBalancerPort int64 `json:"LoadBalancerPort,omitempty"` + PolicyNames []string `json:"PolicyNames,omitempty"` + ServerCertificateId string `json:"ServerCertificateId,omitempty"` +} + +// implements the service definition of UpdateLoadBalancerResponse +type UpdateLoadBalancerResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of UpdateNetAccessPointRequest +type UpdateNetAccessPointRequest struct { + AddRouteTableIds []string `json:"AddRouteTableIds,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + NetAccessPointId string `json:"NetAccessPointId,omitempty"` + RemoveRouteTableIds []string `json:"RemoveRouteTableIds,omitempty"` +} + +// implements the service definition of UpdateNetAccessPointResponse +type UpdateNetAccessPointResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of UpdateNetRequest +type UpdateNetRequest struct { + DhcpOptionsSetId string `json:"DhcpOptionsSetId,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + NetId string `json:"NetId,omitempty"` +} + +// implements the service definition of UpdateNetResponse +type UpdateNetResponse struct { + Net Net `json:"Net,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of UpdateNicRequest +type UpdateNicRequest struct { + Description string `json:"Description,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + LinkNic LinkNicToUpdate `json:"LinkNic,omitempty"` + NicId string `json:"NicId,omitempty"` + SecurityGroupIds []string `json:"SecurityGroupIds,omitempty"` +} + +// implements the service definition of UpdateNicResponse +type UpdateNicResponse struct { + Nic Nic `json:"Nic,omitempty"` + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of UpdateRoutePropagationRequest +type UpdateRoutePropagationRequest struct { + DryRun bool `json:"DryRun,omitempty"` + Enable bool `json:"Enable,omitempty"` + RouteTableId string `json:"RouteTableId,omitempty"` + VirtualGatewayId string `json:"VirtualGatewayId,omitempty"` +} + +// implements the service definition of UpdateRoutePropagationResponse +type UpdateRoutePropagationResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + RouteTable RouteTable `json:"RouteTable,omitempty"` +} + +// implements the service definition of UpdateRouteRequest +type UpdateRouteRequest struct { + DestinationIpRange string `json:"DestinationIpRange,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + GatewayId string `json:"GatewayId,omitempty"` + NatServiceId string `json:"NatServiceId,omitempty"` + NetPeeringId string `json:"NetPeeringId,omitempty"` + NicId string `json:"NicId,omitempty"` + RouteTableId string `json:"RouteTableId,omitempty"` + VmId string `json:"VmId,omitempty"` +} + +// implements the service definition of UpdateRouteResponse +type UpdateRouteResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + Route Route `json:"Route,omitempty"` +} + +// implements the service definition of UpdateServerCertificateRequest +type UpdateServerCertificateRequest struct { + DryRun bool `json:"DryRun,omitempty"` + NewPath string `json:"NewPath,omitempty"` + NewServerCertificateName string `json:"NewServerCertificateName,omitempty"` + ServerCertificateName string `json:"ServerCertificateName,omitempty"` +} + +// implements the service definition of UpdateServerCertificateResponse +type UpdateServerCertificateResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of UpdateSnapshotRequest +type UpdateSnapshotRequest struct { + DryRun bool `json:"DryRun,omitempty"` + PermissionsToCreateVolume PermissionsOnResourceCreation `json:"PermissionsToCreateVolume,omitempty"` + SnapshotId string `json:"SnapshotId,omitempty"` +} + +// implements the service definition of UpdateSnapshotResponse +type UpdateSnapshotResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + Snapshot Snapshot `json:"Snapshot,omitempty"` +} + +// implements the service definition of UpdateUserGroupRequest +type UpdateUserGroupRequest struct { + DryRun bool `json:"DryRun,omitempty"` + NewPath string `json:"NewPath,omitempty"` + NewUserGroupName string `json:"NewUserGroupName,omitempty"` + UserGroupName string `json:"UserGroupName,omitempty"` +} + +// implements the service definition of UpdateUserGroupResponse +type UpdateUserGroupResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of UpdateUserRequest +type UpdateUserRequest struct { + DryRun bool `json:"DryRun,omitempty"` + NewPath string `json:"NewPath,omitempty"` + NewUserName string `json:"NewUserName,omitempty"` + UserName string `json:"UserName,omitempty"` +} + +// implements the service definition of UpdateUserResponse +type UpdateUserResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` +} + +// implements the service definition of UpdateVmRequest +type UpdateVmRequest struct { + BlockDeviceMappings []BlockDeviceMappingVmUpdate `json:"BlockDeviceMappings,omitempty"` + BsuOptimized bool `json:"BsuOptimized,omitempty"` + DeletionProtection bool `json:"DeletionProtection,omitempty"` + DryRun bool `json:"DryRun,omitempty"` + IsSourceDestChecked bool `json:"IsSourceDestChecked,omitempty"` + KeypairName string `json:"KeypairName,omitempty"` + SecurityGroupIds []string `json:"SecurityGroupIds,omitempty"` + UserData string `json:"UserData,omitempty"` + VmId string `json:"VmId,omitempty"` + VmInitiatedShutdownBehavior string `json:"VmInitiatedShutdownBehavior,omitempty"` + VmType string `json:"VmType,omitempty"` +} + +// implements the service definition of UpdateVmResponse +type UpdateVmResponse struct { + ResponseContext ResponseContext `json:"ResponseContext,omitempty"` + Vm Vm `json:"Vm,omitempty"` +} + +// implements the service definition of User +type User struct { + Path string `json:"Path,omitempty"` + UserId string `json:"UserId,omitempty"` + UserName string `json:"UserName,omitempty"` +} + +// implements the service definition of UserGroup +type UserGroup struct { + Path string `json:"Path,omitempty"` + UserGroupId string `json:"UserGroupId,omitempty"` + UserGroupName string `json:"UserGroupName,omitempty"` +} + +// implements the service definition of VirtualGateway +type VirtualGateway struct { + ConnectionType string `json:"ConnectionType,omitempty"` + NetToVirtualGatewayLinks []NetToVirtualGatewayLink `json:"NetToVirtualGatewayLinks,omitempty"` + State string `json:"State,omitempty"` + Tags []ResourceTag `json:"Tags,omitempty"` + VirtualGatewayId string `json:"VirtualGatewayId,omitempty"` +} + +// implements the service definition of Vm +type Vm struct { + Architecture string `json:"Architecture,omitempty"` + BlockDeviceMappings []BlockDeviceMappingCreated `json:"BlockDeviceMappings,omitempty"` + BsuOptimized bool `json:"BsuOptimized,omitempty"` + ClientToken string `json:"ClientToken,omitempty"` + DeletionProtection bool `json:"DeletionProtection,omitempty"` + Hypervisor string `json:"Hypervisor,omitempty"` + ImageId string `json:"ImageId,omitempty"` + IsSourceDestChecked bool `json:"IsSourceDestChecked,omitempty"` + KeypairName string `json:"KeypairName,omitempty"` + LaunchNumber int64 `json:"LaunchNumber,omitempty"` + NetId string `json:"NetId,omitempty"` + Nics []NicLight `json:"Nics,omitempty"` + OsFamily string `json:"OsFamily,omitempty"` + Placement Placement `json:"Placement,omitempty"` + PrivateDnsName string `json:"PrivateDnsName,omitempty"` + PrivateIp string `json:"PrivateIp,omitempty"` + ProductCodes []string `json:"ProductCodes,omitempty"` + PublicDnsName string `json:"PublicDnsName,omitempty"` + PublicIp string `json:"PublicIp,omitempty"` + ReservationId string `json:"ReservationId,omitempty"` + RootDeviceName string `json:"RootDeviceName,omitempty"` + RootDeviceType string `json:"RootDeviceType,omitempty"` + SecurityGroups []SecurityGroupLight `json:"SecurityGroups,omitempty"` + State string `json:"State,omitempty"` + StateReason string `json:"StateReason,omitempty"` + SubnetId string `json:"SubnetId,omitempty"` + Tags []ResourceTag `json:"Tags,omitempty"` + UserData string `json:"UserData,omitempty"` + VmId string `json:"VmId,omitempty"` + VmInitiatedShutdownBehavior string `json:"VmInitiatedShutdownBehavior,omitempty"` + VmType string `json:"VmType,omitempty"` +} + +// implements the service definition of VmState +type VmState struct { + CurrentState string `json:"CurrentState,omitempty"` + PreviousState string `json:"PreviousState,omitempty"` + VmId string `json:"VmId,omitempty"` +} + +// implements the service definition of VmStates +type VmStates struct { + MaintenanceEvents []MaintenanceEvent `json:"MaintenanceEvents,omitempty"` + SubregionName string `json:"SubregionName,omitempty"` + VmId string `json:"VmId,omitempty"` + VmState string `json:"VmState,omitempty"` +} + +// implements the service definition of VmType +type VmType struct { + IsBsuOptimized bool `json:"IsBsuOptimized,omitempty"` + MaxPrivateIps int64 `json:"MaxPrivateIps,omitempty"` + MemorySize int64 `json:"MemorySize,omitempty"` + StorageCount int64 `json:"StorageCount,omitempty"` + StorageSize int64 `json:"StorageSize,omitempty"` + VcoreCount int64 `json:"VcoreCount,omitempty"` + VmTypeName string `json:"VmTypeName,omitempty"` +} + +// implements the service definition of Volume +type Volume struct { + Iops int64 `json:"Iops,omitempty"` + LinkedVolumes []LinkedVolume `json:"LinkedVolumes,omitempty"` + Size int64 `json:"Size,omitempty"` + SnapshotId string `json:"SnapshotId,omitempty"` + State string `json:"State,omitempty"` + SubregionName string `json:"SubregionName,omitempty"` + Tags []ResourceTag `json:"Tags,omitempty"` + VolumeId string `json:"VolumeId,omitempty"` + VolumeType string `json:"VolumeType,omitempty"` +} + +// implements the service definition of VpnConnection +type VpnConnection struct { + ClientGatewayConfiguration string `json:"ClientGatewayConfiguration,omitempty"` + ClientGatewayId string `json:"ClientGatewayId,omitempty"` + ConnectionType string `json:"ConnectionType,omitempty"` + Routes []RouteLight `json:"Routes,omitempty"` + State string `json:"State,omitempty"` + StaticRoutesOnly bool `json:"StaticRoutesOnly,omitempty"` + Tags []ResourceTag `json:"Tags,omitempty"` + VirtualGatewayId string `json:"VirtualGatewayId,omitempty"` + VpnConnectionId string `json:"VpnConnectionId,omitempty"` +} + +// implements the service definition of With +type With struct { + CallDuration bool `json:"CallDuration,omitempty"` + QueryAccessKey bool `json:"QueryAccessKey,omitempty"` + QueryApiName bool `json:"QueryApiName,omitempty"` + QueryApiVersion bool `json:"QueryApiVersion,omitempty"` + QueryCallName bool `json:"QueryCallName,omitempty"` + QueryDate bool `json:"QueryDate,omitempty"` + QueryIpAddress bool `json:"QueryIpAddress,omitempty"` + QueryRaw bool `json:"QueryRaw,omitempty"` + QuerySize bool `json:"QuerySize,omitempty"` + QueryUserAgent bool `json:"QueryUserAgent,omitempty"` + ResponseId bool `json:"ResponseId,omitempty"` + ResponseSize bool `json:"ResponseSize,omitempty"` + ResponseStatusCode bool `json:"ResponseStatusCode,omitempty"` +} + +// POST_AcceptNetPeeringParameters holds parameters to POST_AcceptNetPeering +type POST_AcceptNetPeeringParameters struct { + Acceptnetpeeringrequest AcceptNetPeeringRequest `json:"acceptnetpeeringrequest,omitempty"` +} + +// POST_AcceptNetPeeringResponses holds responses of POST_AcceptNetPeering +type POST_AcceptNetPeeringResponses struct { + OK *AcceptNetPeeringResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code409 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_AuthenticateAccountParameters holds parameters to POST_AuthenticateAccount +type POST_AuthenticateAccountParameters struct { + Authenticateaccountrequest AuthenticateAccountRequest `json:"authenticateaccountrequest,omitempty"` +} + +// POST_AuthenticateAccountResponses holds responses of POST_AuthenticateAccount +type POST_AuthenticateAccountResponses struct { + OK *AuthenticateAccountResponse +} + +// POST_CheckSignatureParameters holds parameters to POST_CheckSignature +type POST_CheckSignatureParameters struct { + Checksignaturerequest CheckSignatureRequest `json:"checksignaturerequest,omitempty"` +} + +// POST_CheckSignatureResponses holds responses of POST_CheckSignature +type POST_CheckSignatureResponses struct { + OK *CheckSignatureResponse +} + +// POST_CopyAccountParameters holds parameters to POST_CopyAccount +type POST_CopyAccountParameters struct { + Copyaccountrequest CopyAccountRequest `json:"copyaccountrequest,omitempty"` +} + +// POST_CopyAccountResponses holds responses of POST_CopyAccount +type POST_CopyAccountResponses struct { + OK *CopyAccountResponse +} + +// POST_CreateAccountParameters holds parameters to POST_CreateAccount +type POST_CreateAccountParameters struct { + Createaccountrequest CreateAccountRequest `json:"createaccountrequest,omitempty"` +} + +// POST_CreateAccountResponses holds responses of POST_CreateAccount +type POST_CreateAccountResponses struct { + OK *CreateAccountResponse +} + +// POST_CreateApiKeyParameters holds parameters to POST_CreateApiKey +type POST_CreateApiKeyParameters struct { + Createapikeyrequest CreateApiKeyRequest `json:"createapikeyrequest,omitempty"` +} + +// POST_CreateApiKeyResponses holds responses of POST_CreateApiKey +type POST_CreateApiKeyResponses struct { + OK *CreateApiKeyResponse +} + +// POST_CreateClientGatewayParameters holds parameters to POST_CreateClientGateway +type POST_CreateClientGatewayParameters struct { + Createclientgatewayrequest CreateClientGatewayRequest `json:"createclientgatewayrequest,omitempty"` +} + +// POST_CreateClientGatewayResponses holds responses of POST_CreateClientGateway +type POST_CreateClientGatewayResponses struct { + OK *CreateClientGatewayResponse +} + +// POST_CreateDhcpOptionsParameters holds parameters to POST_CreateDhcpOptions +type POST_CreateDhcpOptionsParameters struct { + Createdhcpoptionsrequest CreateDhcpOptionsRequest `json:"createdhcpoptionsrequest,omitempty"` +} + +// POST_CreateDhcpOptionsResponses holds responses of POST_CreateDhcpOptions +type POST_CreateDhcpOptionsResponses struct { + OK *CreateDhcpOptionsResponse +} + +// POST_CreateDirectLinkParameters holds parameters to POST_CreateDirectLink +type POST_CreateDirectLinkParameters struct { + Createdirectlinkrequest CreateDirectLinkRequest `json:"createdirectlinkrequest,omitempty"` +} + +// POST_CreateDirectLinkResponses holds responses of POST_CreateDirectLink +type POST_CreateDirectLinkResponses struct { + OK *CreateDirectLinkResponse +} + +// POST_CreateDirectLinkInterfaceParameters holds parameters to POST_CreateDirectLinkInterface +type POST_CreateDirectLinkInterfaceParameters struct { + Createdirectlinkinterfacerequest CreateDirectLinkInterfaceRequest `json:"createdirectlinkinterfacerequest,omitempty"` +} + +// POST_CreateDirectLinkInterfaceResponses holds responses of POST_CreateDirectLinkInterface +type POST_CreateDirectLinkInterfaceResponses struct { + OK *CreateDirectLinkInterfaceResponse +} + +// POST_CreateImageParameters holds parameters to POST_CreateImage +type POST_CreateImageParameters struct { + Createimagerequest CreateImageRequest `json:"createimagerequest,omitempty"` +} + +// POST_CreateImageResponses holds responses of POST_CreateImage +type POST_CreateImageResponses struct { + OK *CreateImageResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_CreateImageExportTaskParameters holds parameters to POST_CreateImageExportTask +type POST_CreateImageExportTaskParameters struct { + Createimageexporttaskrequest CreateImageExportTaskRequest `json:"createimageexporttaskrequest,omitempty"` +} + +// POST_CreateImageExportTaskResponses holds responses of POST_CreateImageExportTask +type POST_CreateImageExportTaskResponses struct { + OK *CreateImageExportTaskResponse +} + +// POST_CreateInternetServiceParameters holds parameters to POST_CreateInternetService +type POST_CreateInternetServiceParameters struct { + Createinternetservicerequest CreateInternetServiceRequest `json:"createinternetservicerequest,omitempty"` +} + +// POST_CreateInternetServiceResponses holds responses of POST_CreateInternetService +type POST_CreateInternetServiceResponses struct { + OK *CreateInternetServiceResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_CreateKeypairParameters holds parameters to POST_CreateKeypair +type POST_CreateKeypairParameters struct { + Createkeypairrequest CreateKeypairRequest `json:"createkeypairrequest,omitempty"` +} + +// POST_CreateKeypairResponses holds responses of POST_CreateKeypair +type POST_CreateKeypairResponses struct { + OK *CreateKeypairResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code409 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_CreateListenerRuleParameters holds parameters to POST_CreateListenerRule +type POST_CreateListenerRuleParameters struct { + Createlistenerrulerequest CreateListenerRuleRequest `json:"createlistenerrulerequest,omitempty"` +} + +// POST_CreateListenerRuleResponses holds responses of POST_CreateListenerRule +type POST_CreateListenerRuleResponses struct { + OK *CreateListenerRuleResponse +} + +// POST_CreateLoadBalancerParameters holds parameters to POST_CreateLoadBalancer +type POST_CreateLoadBalancerParameters struct { + Createloadbalancerrequest CreateLoadBalancerRequest `json:"createloadbalancerrequest,omitempty"` +} + +// POST_CreateLoadBalancerResponses holds responses of POST_CreateLoadBalancer +type POST_CreateLoadBalancerResponses struct { + OK *CreateLoadBalancerResponse +} + +// POST_CreateLoadBalancerListenersParameters holds parameters to POST_CreateLoadBalancerListeners +type POST_CreateLoadBalancerListenersParameters struct { + Createloadbalancerlistenersrequest CreateLoadBalancerListenersRequest `json:"createloadbalancerlistenersrequest,omitempty"` +} + +// POST_CreateLoadBalancerListenersResponses holds responses of POST_CreateLoadBalancerListeners +type POST_CreateLoadBalancerListenersResponses struct { + OK *CreateLoadBalancerListenersResponse +} + +// POST_CreateLoadBalancerPolicyParameters holds parameters to POST_CreateLoadBalancerPolicy +type POST_CreateLoadBalancerPolicyParameters struct { + Createloadbalancerpolicyrequest CreateLoadBalancerPolicyRequest `json:"createloadbalancerpolicyrequest,omitempty"` +} + +// POST_CreateLoadBalancerPolicyResponses holds responses of POST_CreateLoadBalancerPolicy +type POST_CreateLoadBalancerPolicyResponses struct { + OK *CreateLoadBalancerPolicyResponse +} + +// POST_CreateNatServiceParameters holds parameters to POST_CreateNatService +type POST_CreateNatServiceParameters struct { + Createnatservicerequest CreateNatServiceRequest `json:"createnatservicerequest,omitempty"` +} + +// POST_CreateNatServiceResponses holds responses of POST_CreateNatService +type POST_CreateNatServiceResponses struct { + OK *CreateNatServiceResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_CreateNetParameters holds parameters to POST_CreateNet +type POST_CreateNetParameters struct { + Createnetrequest CreateNetRequest `json:"createnetrequest,omitempty"` +} + +// POST_CreateNetResponses holds responses of POST_CreateNet +type POST_CreateNetResponses struct { + OK *CreateNetResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code409 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_CreateNetAccessPointParameters holds parameters to POST_CreateNetAccessPoint +type POST_CreateNetAccessPointParameters struct { + Createnetaccesspointrequest CreateNetAccessPointRequest `json:"createnetaccesspointrequest,omitempty"` +} + +// POST_CreateNetAccessPointResponses holds responses of POST_CreateNetAccessPoint +type POST_CreateNetAccessPointResponses struct { + OK *CreateNetAccessPointResponse +} + +// POST_CreateNetPeeringParameters holds parameters to POST_CreateNetPeering +type POST_CreateNetPeeringParameters struct { + Createnetpeeringrequest CreateNetPeeringRequest `json:"createnetpeeringrequest,omitempty"` +} + +// POST_CreateNetPeeringResponses holds responses of POST_CreateNetPeering +type POST_CreateNetPeeringResponses struct { + OK *CreateNetPeeringResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_CreateNicParameters holds parameters to POST_CreateNic +type POST_CreateNicParameters struct { + Createnicrequest CreateNicRequest `json:"createnicrequest,omitempty"` +} + +// POST_CreateNicResponses holds responses of POST_CreateNic +type POST_CreateNicResponses struct { + OK *CreateNicResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_CreatePolicyParameters holds parameters to POST_CreatePolicy +type POST_CreatePolicyParameters struct { + Createpolicyrequest CreatePolicyRequest `json:"createpolicyrequest,omitempty"` +} + +// POST_CreatePolicyResponses holds responses of POST_CreatePolicy +type POST_CreatePolicyResponses struct { + OK *CreatePolicyResponse +} + +// POST_CreatePublicIpParameters holds parameters to POST_CreatePublicIp +type POST_CreatePublicIpParameters struct { + Createpubliciprequest CreatePublicIpRequest `json:"createpubliciprequest,omitempty"` +} + +// POST_CreatePublicIpResponses holds responses of POST_CreatePublicIp +type POST_CreatePublicIpResponses struct { + OK *CreatePublicIpResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_CreateRouteParameters holds parameters to POST_CreateRoute +type POST_CreateRouteParameters struct { + Createrouterequest CreateRouteRequest `json:"createrouterequest,omitempty"` +} + +// POST_CreateRouteResponses holds responses of POST_CreateRoute +type POST_CreateRouteResponses struct { + OK *CreateRouteResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_CreateRouteTableParameters holds parameters to POST_CreateRouteTable +type POST_CreateRouteTableParameters struct { + Createroutetablerequest CreateRouteTableRequest `json:"createroutetablerequest,omitempty"` +} + +// POST_CreateRouteTableResponses holds responses of POST_CreateRouteTable +type POST_CreateRouteTableResponses struct { + OK *CreateRouteTableResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_CreateSecurityGroupParameters holds parameters to POST_CreateSecurityGroup +type POST_CreateSecurityGroupParameters struct { + Createsecuritygrouprequest CreateSecurityGroupRequest `json:"createsecuritygrouprequest,omitempty"` +} + +// POST_CreateSecurityGroupResponses holds responses of POST_CreateSecurityGroup +type POST_CreateSecurityGroupResponses struct { + OK *CreateSecurityGroupResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_CreateSecurityGroupRuleParameters holds parameters to POST_CreateSecurityGroupRule +type POST_CreateSecurityGroupRuleParameters struct { + Createsecuritygrouprulerequest CreateSecurityGroupRuleRequest `json:"createsecuritygrouprulerequest,omitempty"` +} + +// POST_CreateSecurityGroupRuleResponses holds responses of POST_CreateSecurityGroupRule +type POST_CreateSecurityGroupRuleResponses struct { + OK *CreateSecurityGroupRuleResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_CreateServerCertificateParameters holds parameters to POST_CreateServerCertificate +type POST_CreateServerCertificateParameters struct { + Createservercertificaterequest CreateServerCertificateRequest `json:"createservercertificaterequest,omitempty"` +} + +// POST_CreateServerCertificateResponses holds responses of POST_CreateServerCertificate +type POST_CreateServerCertificateResponses struct { + OK *CreateServerCertificateResponse +} + +// POST_CreateSnapshotParameters holds parameters to POST_CreateSnapshot +type POST_CreateSnapshotParameters struct { + Createsnapshotrequest CreateSnapshotRequest `json:"createsnapshotrequest,omitempty"` +} + +// POST_CreateSnapshotResponses holds responses of POST_CreateSnapshot +type POST_CreateSnapshotResponses struct { + OK *CreateSnapshotResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_CreateSnapshotExportTaskParameters holds parameters to POST_CreateSnapshotExportTask +type POST_CreateSnapshotExportTaskParameters struct { + Createsnapshotexporttaskrequest CreateSnapshotExportTaskRequest `json:"createsnapshotexporttaskrequest,omitempty"` +} + +// POST_CreateSnapshotExportTaskResponses holds responses of POST_CreateSnapshotExportTask +type POST_CreateSnapshotExportTaskResponses struct { + OK *CreateSnapshotExportTaskResponse +} + +// POST_CreateSubnetParameters holds parameters to POST_CreateSubnet +type POST_CreateSubnetParameters struct { + Createsubnetrequest CreateSubnetRequest `json:"createsubnetrequest,omitempty"` +} + +// POST_CreateSubnetResponses holds responses of POST_CreateSubnet +type POST_CreateSubnetResponses struct { + OK *CreateSubnetResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code409 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_CreateTagsParameters holds parameters to POST_CreateTags +type POST_CreateTagsParameters struct { + Createtagsrequest CreateTagsRequest `json:"createtagsrequest,omitempty"` +} + +// POST_CreateTagsResponses holds responses of POST_CreateTags +type POST_CreateTagsResponses struct { + OK *CreateTagsResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_CreateUserParameters holds parameters to POST_CreateUser +type POST_CreateUserParameters struct { + Createuserrequest CreateUserRequest `json:"createuserrequest,omitempty"` +} + +// POST_CreateUserResponses holds responses of POST_CreateUser +type POST_CreateUserResponses struct { + OK *CreateUserResponse +} + +// POST_CreateUserGroupParameters holds parameters to POST_CreateUserGroup +type POST_CreateUserGroupParameters struct { + Createusergrouprequest CreateUserGroupRequest `json:"createusergrouprequest,omitempty"` +} + +// POST_CreateUserGroupResponses holds responses of POST_CreateUserGroup +type POST_CreateUserGroupResponses struct { + OK *CreateUserGroupResponse +} + +// POST_CreateVirtualGatewayParameters holds parameters to POST_CreateVirtualGateway +type POST_CreateVirtualGatewayParameters struct { + Createvirtualgatewayrequest CreateVirtualGatewayRequest `json:"createvirtualgatewayrequest,omitempty"` +} + +// POST_CreateVirtualGatewayResponses holds responses of POST_CreateVirtualGateway +type POST_CreateVirtualGatewayResponses struct { + OK *CreateVirtualGatewayResponse +} + +// POST_CreateVmsParameters holds parameters to POST_CreateVms +type POST_CreateVmsParameters struct { + Createvmsrequest CreateVmsRequest `json:"createvmsrequest,omitempty"` +} + +// POST_CreateVmsResponses holds responses of POST_CreateVms +type POST_CreateVmsResponses struct { + OK *CreateVmsResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_CreateVolumeParameters holds parameters to POST_CreateVolume +type POST_CreateVolumeParameters struct { + Createvolumerequest CreateVolumeRequest `json:"createvolumerequest,omitempty"` +} + +// POST_CreateVolumeResponses holds responses of POST_CreateVolume +type POST_CreateVolumeResponses struct { + OK *CreateVolumeResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_CreateVpnConnectionParameters holds parameters to POST_CreateVpnConnection +type POST_CreateVpnConnectionParameters struct { + Createvpnconnectionrequest CreateVpnConnectionRequest `json:"createvpnconnectionrequest,omitempty"` +} + +// POST_CreateVpnConnectionResponses holds responses of POST_CreateVpnConnection +type POST_CreateVpnConnectionResponses struct { + OK *CreateVpnConnectionResponse +} + +// POST_CreateVpnConnectionRouteParameters holds parameters to POST_CreateVpnConnectionRoute +type POST_CreateVpnConnectionRouteParameters struct { + Createvpnconnectionrouterequest CreateVpnConnectionRouteRequest `json:"createvpnconnectionrouterequest,omitempty"` +} + +// POST_CreateVpnConnectionRouteResponses holds responses of POST_CreateVpnConnectionRoute +type POST_CreateVpnConnectionRouteResponses struct { + OK *CreateVpnConnectionRouteResponse +} + +// POST_DeleteApiKeyParameters holds parameters to POST_DeleteApiKey +type POST_DeleteApiKeyParameters struct { + Deleteapikeyrequest DeleteApiKeyRequest `json:"deleteapikeyrequest,omitempty"` +} + +// POST_DeleteApiKeyResponses holds responses of POST_DeleteApiKey +type POST_DeleteApiKeyResponses struct { + OK *DeleteApiKeyResponse +} + +// POST_DeleteClientGatewayParameters holds parameters to POST_DeleteClientGateway +type POST_DeleteClientGatewayParameters struct { + Deleteclientgatewayrequest DeleteClientGatewayRequest `json:"deleteclientgatewayrequest,omitempty"` +} + +// POST_DeleteClientGatewayResponses holds responses of POST_DeleteClientGateway +type POST_DeleteClientGatewayResponses struct { + OK *DeleteClientGatewayResponse +} + +// POST_DeleteDhcpOptionsParameters holds parameters to POST_DeleteDhcpOptions +type POST_DeleteDhcpOptionsParameters struct { + Deletedhcpoptionsrequest DeleteDhcpOptionsRequest `json:"deletedhcpoptionsrequest,omitempty"` +} + +// POST_DeleteDhcpOptionsResponses holds responses of POST_DeleteDhcpOptions +type POST_DeleteDhcpOptionsResponses struct { + OK *DeleteDhcpOptionsResponse +} + +// POST_DeleteDirectLinkParameters holds parameters to POST_DeleteDirectLink +type POST_DeleteDirectLinkParameters struct { + Deletedirectlinkrequest DeleteDirectLinkRequest `json:"deletedirectlinkrequest,omitempty"` +} + +// POST_DeleteDirectLinkResponses holds responses of POST_DeleteDirectLink +type POST_DeleteDirectLinkResponses struct { + OK *DeleteDirectLinkResponse +} + +// POST_DeleteDirectLinkInterfaceParameters holds parameters to POST_DeleteDirectLinkInterface +type POST_DeleteDirectLinkInterfaceParameters struct { + Deletedirectlinkinterfacerequest DeleteDirectLinkInterfaceRequest `json:"deletedirectlinkinterfacerequest,omitempty"` +} + +// POST_DeleteDirectLinkInterfaceResponses holds responses of POST_DeleteDirectLinkInterface +type POST_DeleteDirectLinkInterfaceResponses struct { + OK *DeleteDirectLinkInterfaceResponse +} + +// POST_DeleteExportTaskParameters holds parameters to POST_DeleteExportTask +type POST_DeleteExportTaskParameters struct { + Deleteexporttaskrequest DeleteExportTaskRequest `json:"deleteexporttaskrequest,omitempty"` +} + +// POST_DeleteExportTaskResponses holds responses of POST_DeleteExportTask +type POST_DeleteExportTaskResponses struct { + OK *DeleteExportTaskResponse +} + +// POST_DeleteImageParameters holds parameters to POST_DeleteImage +type POST_DeleteImageParameters struct { + Deleteimagerequest DeleteImageRequest `json:"deleteimagerequest,omitempty"` +} + +// POST_DeleteImageResponses holds responses of POST_DeleteImage +type POST_DeleteImageResponses struct { + OK *DeleteImageResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_DeleteInternetServiceParameters holds parameters to POST_DeleteInternetService +type POST_DeleteInternetServiceParameters struct { + Deleteinternetservicerequest DeleteInternetServiceRequest `json:"deleteinternetservicerequest,omitempty"` +} + +// POST_DeleteInternetServiceResponses holds responses of POST_DeleteInternetService +type POST_DeleteInternetServiceResponses struct { + OK *DeleteInternetServiceResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_DeleteKeypairParameters holds parameters to POST_DeleteKeypair +type POST_DeleteKeypairParameters struct { + Deletekeypairrequest DeleteKeypairRequest `json:"deletekeypairrequest,omitempty"` +} + +// POST_DeleteKeypairResponses holds responses of POST_DeleteKeypair +type POST_DeleteKeypairResponses struct { + OK *DeleteKeypairResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_DeleteListenerRuleParameters holds parameters to POST_DeleteListenerRule +type POST_DeleteListenerRuleParameters struct { + Deletelistenerrulerequest DeleteListenerRuleRequest `json:"deletelistenerrulerequest,omitempty"` +} + +// POST_DeleteListenerRuleResponses holds responses of POST_DeleteListenerRule +type POST_DeleteListenerRuleResponses struct { + OK *DeleteListenerRuleResponse +} + +// POST_DeleteLoadBalancerParameters holds parameters to POST_DeleteLoadBalancer +type POST_DeleteLoadBalancerParameters struct { + Deleteloadbalancerrequest DeleteLoadBalancerRequest `json:"deleteloadbalancerrequest,omitempty"` +} + +// POST_DeleteLoadBalancerResponses holds responses of POST_DeleteLoadBalancer +type POST_DeleteLoadBalancerResponses struct { + OK *DeleteLoadBalancerResponse +} + +// POST_DeleteLoadBalancerListenersParameters holds parameters to POST_DeleteLoadBalancerListeners +type POST_DeleteLoadBalancerListenersParameters struct { + Deleteloadbalancerlistenersrequest DeleteLoadBalancerListenersRequest `json:"deleteloadbalancerlistenersrequest,omitempty"` +} + +// POST_DeleteLoadBalancerListenersResponses holds responses of POST_DeleteLoadBalancerListeners +type POST_DeleteLoadBalancerListenersResponses struct { + OK *DeleteLoadBalancerListenersResponse +} + +// POST_DeleteLoadBalancerPolicyParameters holds parameters to POST_DeleteLoadBalancerPolicy +type POST_DeleteLoadBalancerPolicyParameters struct { + Deleteloadbalancerpolicyrequest DeleteLoadBalancerPolicyRequest `json:"deleteloadbalancerpolicyrequest,omitempty"` +} + +// POST_DeleteLoadBalancerPolicyResponses holds responses of POST_DeleteLoadBalancerPolicy +type POST_DeleteLoadBalancerPolicyResponses struct { + OK *DeleteLoadBalancerPolicyResponse +} + +// POST_DeleteNatServiceParameters holds parameters to POST_DeleteNatService +type POST_DeleteNatServiceParameters struct { + Deletenatservicerequest DeleteNatServiceRequest `json:"deletenatservicerequest,omitempty"` +} + +// POST_DeleteNatServiceResponses holds responses of POST_DeleteNatService +type POST_DeleteNatServiceResponses struct { + OK *DeleteNatServiceResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_DeleteNetParameters holds parameters to POST_DeleteNet +type POST_DeleteNetParameters struct { + Deletenetrequest DeleteNetRequest `json:"deletenetrequest,omitempty"` +} + +// POST_DeleteNetResponses holds responses of POST_DeleteNet +type POST_DeleteNetResponses struct { + OK *DeleteNetResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_DeleteNetAccessPointsParameters holds parameters to POST_DeleteNetAccessPoints +type POST_DeleteNetAccessPointsParameters struct { + Deletenetaccesspointsrequest DeleteNetAccessPointsRequest `json:"deletenetaccesspointsrequest,omitempty"` +} + +// POST_DeleteNetAccessPointsResponses holds responses of POST_DeleteNetAccessPoints +type POST_DeleteNetAccessPointsResponses struct { + OK *DeleteNetAccessPointsResponse +} + +// POST_DeleteNetPeeringParameters holds parameters to POST_DeleteNetPeering +type POST_DeleteNetPeeringParameters struct { + Deletenetpeeringrequest DeleteNetPeeringRequest `json:"deletenetpeeringrequest,omitempty"` +} + +// POST_DeleteNetPeeringResponses holds responses of POST_DeleteNetPeering +type POST_DeleteNetPeeringResponses struct { + OK *DeleteNetPeeringResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code409 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_DeleteNicParameters holds parameters to POST_DeleteNic +type POST_DeleteNicParameters struct { + Deletenicrequest DeleteNicRequest `json:"deletenicrequest,omitempty"` +} + +// POST_DeleteNicResponses holds responses of POST_DeleteNic +type POST_DeleteNicResponses struct { + OK *DeleteNicResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_DeletePolicyParameters holds parameters to POST_DeletePolicy +type POST_DeletePolicyParameters struct { + Deletepolicyrequest DeletePolicyRequest `json:"deletepolicyrequest,omitempty"` +} + +// POST_DeletePolicyResponses holds responses of POST_DeletePolicy +type POST_DeletePolicyResponses struct { + OK *DeletePolicyResponse +} + +// POST_DeletePublicIpParameters holds parameters to POST_DeletePublicIp +type POST_DeletePublicIpParameters struct { + Deletepubliciprequest DeletePublicIpRequest `json:"deletepubliciprequest,omitempty"` +} + +// POST_DeletePublicIpResponses holds responses of POST_DeletePublicIp +type POST_DeletePublicIpResponses struct { + OK *DeletePublicIpResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_DeleteRouteParameters holds parameters to POST_DeleteRoute +type POST_DeleteRouteParameters struct { + Deleterouterequest DeleteRouteRequest `json:"deleterouterequest,omitempty"` +} + +// POST_DeleteRouteResponses holds responses of POST_DeleteRoute +type POST_DeleteRouteResponses struct { + OK *DeleteRouteResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_DeleteRouteTableParameters holds parameters to POST_DeleteRouteTable +type POST_DeleteRouteTableParameters struct { + Deleteroutetablerequest DeleteRouteTableRequest `json:"deleteroutetablerequest,omitempty"` +} + +// POST_DeleteRouteTableResponses holds responses of POST_DeleteRouteTable +type POST_DeleteRouteTableResponses struct { + OK *DeleteRouteTableResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_DeleteSecurityGroupParameters holds parameters to POST_DeleteSecurityGroup +type POST_DeleteSecurityGroupParameters struct { + Deletesecuritygrouprequest DeleteSecurityGroupRequest `json:"deletesecuritygrouprequest,omitempty"` +} + +// POST_DeleteSecurityGroupResponses holds responses of POST_DeleteSecurityGroup +type POST_DeleteSecurityGroupResponses struct { + OK *DeleteSecurityGroupResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_DeleteSecurityGroupRuleParameters holds parameters to POST_DeleteSecurityGroupRule +type POST_DeleteSecurityGroupRuleParameters struct { + Deletesecuritygrouprulerequest DeleteSecurityGroupRuleRequest `json:"deletesecuritygrouprulerequest,omitempty"` +} + +// POST_DeleteSecurityGroupRuleResponses holds responses of POST_DeleteSecurityGroupRule +type POST_DeleteSecurityGroupRuleResponses struct { + OK *DeleteSecurityGroupRuleResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_DeleteServerCertificateParameters holds parameters to POST_DeleteServerCertificate +type POST_DeleteServerCertificateParameters struct { + Deleteservercertificaterequest DeleteServerCertificateRequest `json:"deleteservercertificaterequest,omitempty"` +} + +// POST_DeleteServerCertificateResponses holds responses of POST_DeleteServerCertificate +type POST_DeleteServerCertificateResponses struct { + OK *DeleteServerCertificateResponse +} + +// POST_DeleteSnapshotParameters holds parameters to POST_DeleteSnapshot +type POST_DeleteSnapshotParameters struct { + Deletesnapshotrequest DeleteSnapshotRequest `json:"deletesnapshotrequest,omitempty"` +} + +// POST_DeleteSnapshotResponses holds responses of POST_DeleteSnapshot +type POST_DeleteSnapshotResponses struct { + OK *DeleteSnapshotResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_DeleteSubnetParameters holds parameters to POST_DeleteSubnet +type POST_DeleteSubnetParameters struct { + Deletesubnetrequest DeleteSubnetRequest `json:"deletesubnetrequest,omitempty"` +} + +// POST_DeleteSubnetResponses holds responses of POST_DeleteSubnet +type POST_DeleteSubnetResponses struct { + OK *DeleteSubnetResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_DeleteTagsParameters holds parameters to POST_DeleteTags +type POST_DeleteTagsParameters struct { + Deletetagsrequest DeleteTagsRequest `json:"deletetagsrequest,omitempty"` +} + +// POST_DeleteTagsResponses holds responses of POST_DeleteTags +type POST_DeleteTagsResponses struct { + OK *DeleteTagsResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_DeleteUserParameters holds parameters to POST_DeleteUser +type POST_DeleteUserParameters struct { + Deleteuserrequest DeleteUserRequest `json:"deleteuserrequest,omitempty"` +} + +// POST_DeleteUserResponses holds responses of POST_DeleteUser +type POST_DeleteUserResponses struct { + OK *DeleteUserResponse +} + +// POST_DeleteUserGroupParameters holds parameters to POST_DeleteUserGroup +type POST_DeleteUserGroupParameters struct { + Deleteusergrouprequest DeleteUserGroupRequest `json:"deleteusergrouprequest,omitempty"` +} + +// POST_DeleteUserGroupResponses holds responses of POST_DeleteUserGroup +type POST_DeleteUserGroupResponses struct { + OK *DeleteUserGroupResponse +} + +// POST_DeleteVirtualGatewayParameters holds parameters to POST_DeleteVirtualGateway +type POST_DeleteVirtualGatewayParameters struct { + Deletevirtualgatewayrequest DeleteVirtualGatewayRequest `json:"deletevirtualgatewayrequest,omitempty"` +} + +// POST_DeleteVirtualGatewayResponses holds responses of POST_DeleteVirtualGateway +type POST_DeleteVirtualGatewayResponses struct { + OK *DeleteVirtualGatewayResponse +} + +// POST_DeleteVmsParameters holds parameters to POST_DeleteVms +type POST_DeleteVmsParameters struct { + Deletevmsrequest DeleteVmsRequest `json:"deletevmsrequest,omitempty"` +} + +// POST_DeleteVmsResponses holds responses of POST_DeleteVms +type POST_DeleteVmsResponses struct { + OK *DeleteVmsResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_DeleteVolumeParameters holds parameters to POST_DeleteVolume +type POST_DeleteVolumeParameters struct { + Deletevolumerequest DeleteVolumeRequest `json:"deletevolumerequest,omitempty"` +} + +// POST_DeleteVolumeResponses holds responses of POST_DeleteVolume +type POST_DeleteVolumeResponses struct { + OK *DeleteVolumeResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_DeleteVpnConnectionParameters holds parameters to POST_DeleteVpnConnection +type POST_DeleteVpnConnectionParameters struct { + Deletevpnconnectionrequest DeleteVpnConnectionRequest `json:"deletevpnconnectionrequest,omitempty"` +} + +// POST_DeleteVpnConnectionResponses holds responses of POST_DeleteVpnConnection +type POST_DeleteVpnConnectionResponses struct { + OK *DeleteVpnConnectionResponse +} + +// POST_DeleteVpnConnectionRouteParameters holds parameters to POST_DeleteVpnConnectionRoute +type POST_DeleteVpnConnectionRouteParameters struct { + Deletevpnconnectionrouterequest DeleteVpnConnectionRouteRequest `json:"deletevpnconnectionrouterequest,omitempty"` +} + +// POST_DeleteVpnConnectionRouteResponses holds responses of POST_DeleteVpnConnectionRoute +type POST_DeleteVpnConnectionRouteResponses struct { + OK *DeleteVpnConnectionRouteResponse +} + +// POST_DeregisterUserInUserGroupParameters holds parameters to POST_DeregisterUserInUserGroup +type POST_DeregisterUserInUserGroupParameters struct { + Deregisteruserinusergrouprequest DeregisterUserInUserGroupRequest `json:"deregisteruserinusergrouprequest,omitempty"` +} + +// POST_DeregisterUserInUserGroupResponses holds responses of POST_DeregisterUserInUserGroup +type POST_DeregisterUserInUserGroupResponses struct { + OK *DeregisterUserInUserGroupResponse +} + +// POST_DeregisterVmsInLoadBalancerParameters holds parameters to POST_DeregisterVmsInLoadBalancer +type POST_DeregisterVmsInLoadBalancerParameters struct { + Deregistervmsinloadbalancerrequest DeregisterVmsInLoadBalancerRequest `json:"deregistervmsinloadbalancerrequest,omitempty"` +} + +// POST_DeregisterVmsInLoadBalancerResponses holds responses of POST_DeregisterVmsInLoadBalancer +type POST_DeregisterVmsInLoadBalancerResponses struct { + OK *DeregisterVmsInLoadBalancerResponse +} + +// POST_LinkInternetServiceParameters holds parameters to POST_LinkInternetService +type POST_LinkInternetServiceParameters struct { + Linkinternetservicerequest LinkInternetServiceRequest `json:"linkinternetservicerequest,omitempty"` +} + +// POST_LinkInternetServiceResponses holds responses of POST_LinkInternetService +type POST_LinkInternetServiceResponses struct { + OK *LinkInternetServiceResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_LinkNicParameters holds parameters to POST_LinkNic +type POST_LinkNicParameters struct { + Linknicrequest LinkNicRequest `json:"linknicrequest,omitempty"` +} + +// POST_LinkNicResponses holds responses of POST_LinkNic +type POST_LinkNicResponses struct { + OK *LinkNicResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_LinkPolicyParameters holds parameters to POST_LinkPolicy +type POST_LinkPolicyParameters struct { + Linkpolicyrequest LinkPolicyRequest `json:"linkpolicyrequest,omitempty"` +} + +// POST_LinkPolicyResponses holds responses of POST_LinkPolicy +type POST_LinkPolicyResponses struct { + OK *LinkPolicyResponse +} + +// POST_LinkPrivateIpsParameters holds parameters to POST_LinkPrivateIps +type POST_LinkPrivateIpsParameters struct { + Linkprivateipsrequest LinkPrivateIpsRequest `json:"linkprivateipsrequest,omitempty"` +} + +// POST_LinkPrivateIpsResponses holds responses of POST_LinkPrivateIps +type POST_LinkPrivateIpsResponses struct { + OK *LinkPrivateIpsResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_LinkPublicIpParameters holds parameters to POST_LinkPublicIp +type POST_LinkPublicIpParameters struct { + Linkpubliciprequest LinkPublicIpRequest `json:"linkpubliciprequest,omitempty"` +} + +// POST_LinkPublicIpResponses holds responses of POST_LinkPublicIp +type POST_LinkPublicIpResponses struct { + OK *LinkPublicIpResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_LinkRouteTableParameters holds parameters to POST_LinkRouteTable +type POST_LinkRouteTableParameters struct { + Linkroutetablerequest LinkRouteTableRequest `json:"linkroutetablerequest,omitempty"` +} + +// POST_LinkRouteTableResponses holds responses of POST_LinkRouteTable +type POST_LinkRouteTableResponses struct { + OK *LinkRouteTableResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_LinkVirtualGatewayParameters holds parameters to POST_LinkVirtualGateway +type POST_LinkVirtualGatewayParameters struct { + Linkvirtualgatewayrequest LinkVirtualGatewayRequest `json:"linkvirtualgatewayrequest,omitempty"` +} + +// POST_LinkVirtualGatewayResponses holds responses of POST_LinkVirtualGateway +type POST_LinkVirtualGatewayResponses struct { + OK *LinkVirtualGatewayResponse +} + +// POST_LinkVolumeParameters holds parameters to POST_LinkVolume +type POST_LinkVolumeParameters struct { + Linkvolumerequest LinkVolumeRequest `json:"linkvolumerequest,omitempty"` +} + +// POST_LinkVolumeResponses holds responses of POST_LinkVolume +type POST_LinkVolumeResponses struct { + OK *LinkVolumeResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_PurchaseReservedVmsOfferParameters holds parameters to POST_PurchaseReservedVmsOffer +type POST_PurchaseReservedVmsOfferParameters struct { + Purchasereservedvmsofferrequest PurchaseReservedVmsOfferRequest `json:"purchasereservedvmsofferrequest,omitempty"` +} + +// POST_PurchaseReservedVmsOfferResponses holds responses of POST_PurchaseReservedVmsOffer +type POST_PurchaseReservedVmsOfferResponses struct { + OK *PurchaseReservedVmsOfferResponse +} + +// POST_ReadAccountParameters holds parameters to POST_ReadAccount +type POST_ReadAccountParameters struct { + Readaccountrequest ReadAccountRequest `json:"readaccountrequest,omitempty"` +} + +// POST_ReadAccountResponses holds responses of POST_ReadAccount +type POST_ReadAccountResponses struct { + OK *ReadAccountResponse +} + +// POST_ReadAccountConsumptionParameters holds parameters to POST_ReadAccountConsumption +type POST_ReadAccountConsumptionParameters struct { + Readaccountconsumptionrequest ReadAccountConsumptionRequest `json:"readaccountconsumptionrequest,omitempty"` +} + +// POST_ReadAccountConsumptionResponses holds responses of POST_ReadAccountConsumption +type POST_ReadAccountConsumptionResponses struct { + OK *ReadAccountConsumptionResponse +} + +// POST_ReadAdminPasswordParameters holds parameters to POST_ReadAdminPassword +type POST_ReadAdminPasswordParameters struct { + Readadminpasswordrequest ReadAdminPasswordRequest `json:"readadminpasswordrequest,omitempty"` +} + +// POST_ReadAdminPasswordResponses holds responses of POST_ReadAdminPassword +type POST_ReadAdminPasswordResponses struct { + OK *ReadAdminPasswordResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_ReadApiKeysParameters holds parameters to POST_ReadApiKeys +type POST_ReadApiKeysParameters struct { + Readapikeysrequest ReadApiKeysRequest `json:"readapikeysrequest,omitempty"` +} + +// POST_ReadApiKeysResponses holds responses of POST_ReadApiKeys +type POST_ReadApiKeysResponses struct { + OK *ReadApiKeysResponse +} + +// POST_ReadApiLogsParameters holds parameters to POST_ReadApiLogs +type POST_ReadApiLogsParameters struct { + Readapilogsrequest ReadApiLogsRequest `json:"readapilogsrequest,omitempty"` +} + +// POST_ReadApiLogsResponses holds responses of POST_ReadApiLogs +type POST_ReadApiLogsResponses struct { + OK *ReadApiLogsResponse +} + +// POST_ReadBillableDigestParameters holds parameters to POST_ReadBillableDigest +type POST_ReadBillableDigestParameters struct { + Readbillabledigestrequest ReadBillableDigestRequest `json:"readbillabledigestrequest,omitempty"` +} + +// POST_ReadBillableDigestResponses holds responses of POST_ReadBillableDigest +type POST_ReadBillableDigestResponses struct { + OK *ReadBillableDigestResponse +} + +// POST_ReadCatalogParameters holds parameters to POST_ReadCatalog +type POST_ReadCatalogParameters struct { + Readcatalogrequest ReadCatalogRequest `json:"readcatalogrequest,omitempty"` +} + +// POST_ReadCatalogResponses holds responses of POST_ReadCatalog +type POST_ReadCatalogResponses struct { + OK *ReadCatalogResponse +} + +// POST_ReadClientGatewaysParameters holds parameters to POST_ReadClientGateways +type POST_ReadClientGatewaysParameters struct { + Readclientgatewaysrequest ReadClientGatewaysRequest `json:"readclientgatewaysrequest,omitempty"` +} + +// POST_ReadClientGatewaysResponses holds responses of POST_ReadClientGateways +type POST_ReadClientGatewaysResponses struct { + OK *ReadClientGatewaysResponse +} + +// POST_ReadConsoleOutputParameters holds parameters to POST_ReadConsoleOutput +type POST_ReadConsoleOutputParameters struct { + Readconsoleoutputrequest ReadConsoleOutputRequest `json:"readconsoleoutputrequest,omitempty"` +} + +// POST_ReadConsoleOutputResponses holds responses of POST_ReadConsoleOutput +type POST_ReadConsoleOutputResponses struct { + OK *ReadConsoleOutputResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_ReadDhcpOptionsParameters holds parameters to POST_ReadDhcpOptions +type POST_ReadDhcpOptionsParameters struct { + Readdhcpoptionsrequest ReadDhcpOptionsRequest `json:"readdhcpoptionsrequest,omitempty"` +} + +// POST_ReadDhcpOptionsResponses holds responses of POST_ReadDhcpOptions +type POST_ReadDhcpOptionsResponses struct { + OK *ReadDhcpOptionsResponse +} + +// POST_ReadDirectLinkInterfacesParameters holds parameters to POST_ReadDirectLinkInterfaces +type POST_ReadDirectLinkInterfacesParameters struct { + Readdirectlinkinterfacesrequest ReadDirectLinkInterfacesRequest `json:"readdirectlinkinterfacesrequest,omitempty"` +} + +// POST_ReadDirectLinkInterfacesResponses holds responses of POST_ReadDirectLinkInterfaces +type POST_ReadDirectLinkInterfacesResponses struct { + OK *ReadDirectLinkInterfacesResponse +} + +// POST_ReadDirectLinksParameters holds parameters to POST_ReadDirectLinks +type POST_ReadDirectLinksParameters struct { + Readdirectlinksrequest ReadDirectLinksRequest `json:"readdirectlinksrequest,omitempty"` +} + +// POST_ReadDirectLinksResponses holds responses of POST_ReadDirectLinks +type POST_ReadDirectLinksResponses struct { + OK *ReadDirectLinksResponse +} + +// POST_ReadImageExportTasksParameters holds parameters to POST_ReadImageExportTasks +type POST_ReadImageExportTasksParameters struct { + Readimageexporttasksrequest ReadImageExportTasksRequest `json:"readimageexporttasksrequest,omitempty"` +} + +// POST_ReadImageExportTasksResponses holds responses of POST_ReadImageExportTasks +type POST_ReadImageExportTasksResponses struct { + OK *ReadImageExportTasksResponse +} + +// POST_ReadImagesParameters holds parameters to POST_ReadImages +type POST_ReadImagesParameters struct { + Readimagesrequest ReadImagesRequest `json:"readimagesrequest,omitempty"` +} + +// POST_ReadImagesResponses holds responses of POST_ReadImages +type POST_ReadImagesResponses struct { + OK *ReadImagesResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_ReadInternetServicesParameters holds parameters to POST_ReadInternetServices +type POST_ReadInternetServicesParameters struct { + Readinternetservicesrequest ReadInternetServicesRequest `json:"readinternetservicesrequest,omitempty"` +} + +// POST_ReadInternetServicesResponses holds responses of POST_ReadInternetServices +type POST_ReadInternetServicesResponses struct { + OK *ReadInternetServicesResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_ReadKeypairsParameters holds parameters to POST_ReadKeypairs +type POST_ReadKeypairsParameters struct { + Readkeypairsrequest ReadKeypairsRequest `json:"readkeypairsrequest,omitempty"` +} + +// POST_ReadKeypairsResponses holds responses of POST_ReadKeypairs +type POST_ReadKeypairsResponses struct { + OK *ReadKeypairsResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_ReadListenerRulesParameters holds parameters to POST_ReadListenerRules +type POST_ReadListenerRulesParameters struct { + Readlistenerrulesrequest ReadListenerRulesRequest `json:"readlistenerrulesrequest,omitempty"` +} + +// POST_ReadListenerRulesResponses holds responses of POST_ReadListenerRules +type POST_ReadListenerRulesResponses struct { + OK *ReadListenerRulesResponse +} + +// POST_ReadLoadBalancersParameters holds parameters to POST_ReadLoadBalancers +type POST_ReadLoadBalancersParameters struct { + Readloadbalancersrequest ReadLoadBalancersRequest `json:"readloadbalancersrequest,omitempty"` +} + +// POST_ReadLoadBalancersResponses holds responses of POST_ReadLoadBalancers +type POST_ReadLoadBalancersResponses struct { + OK *ReadLoadBalancersResponse +} + +// POST_ReadLocationsParameters holds parameters to POST_ReadLocations +type POST_ReadLocationsParameters struct { + Readlocationsrequest ReadLocationsRequest `json:"readlocationsrequest,omitempty"` +} + +// POST_ReadLocationsResponses holds responses of POST_ReadLocations +type POST_ReadLocationsResponses struct { + OK *ReadLocationsResponse +} + +// POST_ReadNatServicesParameters holds parameters to POST_ReadNatServices +type POST_ReadNatServicesParameters struct { + Readnatservicesrequest ReadNatServicesRequest `json:"readnatservicesrequest,omitempty"` +} + +// POST_ReadNatServicesResponses holds responses of POST_ReadNatServices +type POST_ReadNatServicesResponses struct { + OK *ReadNatServicesResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_ReadNetAccessPointServicesParameters holds parameters to POST_ReadNetAccessPointServices +type POST_ReadNetAccessPointServicesParameters struct { + Readnetaccesspointservicesrequest ReadNetAccessPointServicesRequest `json:"readnetaccesspointservicesrequest,omitempty"` +} + +// POST_ReadNetAccessPointServicesResponses holds responses of POST_ReadNetAccessPointServices +type POST_ReadNetAccessPointServicesResponses struct { + OK *ReadNetAccessPointServicesResponse +} + +// POST_ReadNetAccessPointsParameters holds parameters to POST_ReadNetAccessPoints +type POST_ReadNetAccessPointsParameters struct { + Readnetaccesspointsrequest ReadNetAccessPointsRequest `json:"readnetaccesspointsrequest,omitempty"` +} + +// POST_ReadNetAccessPointsResponses holds responses of POST_ReadNetAccessPoints +type POST_ReadNetAccessPointsResponses struct { + OK *ReadNetAccessPointsResponse +} + +// POST_ReadNetPeeringsParameters holds parameters to POST_ReadNetPeerings +type POST_ReadNetPeeringsParameters struct { + Readnetpeeringsrequest ReadNetPeeringsRequest `json:"readnetpeeringsrequest,omitempty"` +} + +// POST_ReadNetPeeringsResponses holds responses of POST_ReadNetPeerings +type POST_ReadNetPeeringsResponses struct { + OK *ReadNetPeeringsResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_ReadNetsParameters holds parameters to POST_ReadNets +type POST_ReadNetsParameters struct { + Readnetsrequest ReadNetsRequest `json:"readnetsrequest,omitempty"` +} + +// POST_ReadNetsResponses holds responses of POST_ReadNets +type POST_ReadNetsResponses struct { + OK *ReadNetsResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_ReadNicsParameters holds parameters to POST_ReadNics +type POST_ReadNicsParameters struct { + Readnicsrequest ReadNicsRequest `json:"readnicsrequest,omitempty"` +} + +// POST_ReadNicsResponses holds responses of POST_ReadNics +type POST_ReadNicsResponses struct { + OK *ReadNicsResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_ReadPoliciesParameters holds parameters to POST_ReadPolicies +type POST_ReadPoliciesParameters struct { + Readpoliciesrequest ReadPoliciesRequest `json:"readpoliciesrequest,omitempty"` +} + +// POST_ReadPoliciesResponses holds responses of POST_ReadPolicies +type POST_ReadPoliciesResponses struct { + OK *ReadPoliciesResponse +} + +// POST_ReadPrefixListsParameters holds parameters to POST_ReadPrefixLists +type POST_ReadPrefixListsParameters struct { + Readprefixlistsrequest ReadPrefixListsRequest `json:"readprefixlistsrequest,omitempty"` +} + +// POST_ReadPrefixListsResponses holds responses of POST_ReadPrefixLists +type POST_ReadPrefixListsResponses struct { + OK *ReadPrefixListsResponse +} + +// POST_ReadProductTypesParameters holds parameters to POST_ReadProductTypes +type POST_ReadProductTypesParameters struct { + Readproducttypesrequest ReadProductTypesRequest `json:"readproducttypesrequest,omitempty"` +} + +// POST_ReadProductTypesResponses holds responses of POST_ReadProductTypes +type POST_ReadProductTypesResponses struct { + OK *ReadProductTypesResponse +} + +// POST_ReadPublicCatalogParameters holds parameters to POST_ReadPublicCatalog +type POST_ReadPublicCatalogParameters struct { + Readpubliccatalogrequest ReadPublicCatalogRequest `json:"readpubliccatalogrequest,omitempty"` +} + +// POST_ReadPublicCatalogResponses holds responses of POST_ReadPublicCatalog +type POST_ReadPublicCatalogResponses struct { + OK *ReadPublicCatalogResponse +} + +// POST_ReadPublicIpRangesParameters holds parameters to POST_ReadPublicIpRanges +type POST_ReadPublicIpRangesParameters struct { + Readpubliciprangesrequest ReadPublicIpRangesRequest `json:"readpubliciprangesrequest,omitempty"` +} + +// POST_ReadPublicIpRangesResponses holds responses of POST_ReadPublicIpRanges +type POST_ReadPublicIpRangesResponses struct { + OK *ReadPublicIpRangesResponse +} + +// POST_ReadPublicIpsParameters holds parameters to POST_ReadPublicIps +type POST_ReadPublicIpsParameters struct { + Readpublicipsrequest ReadPublicIpsRequest `json:"readpublicipsrequest,omitempty"` +} + +// POST_ReadPublicIpsResponses holds responses of POST_ReadPublicIps +type POST_ReadPublicIpsResponses struct { + OK *ReadPublicIpsResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_ReadQuotasParameters holds parameters to POST_ReadQuotas +type POST_ReadQuotasParameters struct { + Readquotasrequest ReadQuotasRequest `json:"readquotasrequest,omitempty"` +} + +// POST_ReadQuotasResponses holds responses of POST_ReadQuotas +type POST_ReadQuotasResponses struct { + OK *ReadQuotasResponse +} + +// POST_ReadRegionConfigParameters holds parameters to POST_ReadRegionConfig +type POST_ReadRegionConfigParameters struct { + Readregionconfigrequest ReadRegionConfigRequest `json:"readregionconfigrequest,omitempty"` +} + +// POST_ReadRegionConfigResponses holds responses of POST_ReadRegionConfig +type POST_ReadRegionConfigResponses struct { + OK *ReadRegionConfigResponse +} + +// POST_ReadRegionsParameters holds parameters to POST_ReadRegions +type POST_ReadRegionsParameters struct { + Readregionsrequest ReadRegionsRequest `json:"readregionsrequest,omitempty"` +} + +// POST_ReadRegionsResponses holds responses of POST_ReadRegions +type POST_ReadRegionsResponses struct { + OK *ReadRegionsResponse +} + +// POST_ReadReservedVmOffersParameters holds parameters to POST_ReadReservedVmOffers +type POST_ReadReservedVmOffersParameters struct { + Readreservedvmoffersrequest ReadReservedVmOffersRequest `json:"readreservedvmoffersrequest,omitempty"` +} + +// POST_ReadReservedVmOffersResponses holds responses of POST_ReadReservedVmOffers +type POST_ReadReservedVmOffersResponses struct { + OK *ReadReservedVmOffersResponse +} + +// POST_ReadReservedVmsParameters holds parameters to POST_ReadReservedVms +type POST_ReadReservedVmsParameters struct { + Readreservedvmsrequest ReadReservedVmsRequest `json:"readreservedvmsrequest,omitempty"` +} + +// POST_ReadReservedVmsResponses holds responses of POST_ReadReservedVms +type POST_ReadReservedVmsResponses struct { + OK *ReadReservedVmsResponse +} + +// POST_ReadRouteTablesParameters holds parameters to POST_ReadRouteTables +type POST_ReadRouteTablesParameters struct { + Readroutetablesrequest ReadRouteTablesRequest `json:"readroutetablesrequest,omitempty"` +} + +// POST_ReadRouteTablesResponses holds responses of POST_ReadRouteTables +type POST_ReadRouteTablesResponses struct { + OK *ReadRouteTablesResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_ReadSecurityGroupsParameters holds parameters to POST_ReadSecurityGroups +type POST_ReadSecurityGroupsParameters struct { + Readsecuritygroupsrequest ReadSecurityGroupsRequest `json:"readsecuritygroupsrequest,omitempty"` +} + +// POST_ReadSecurityGroupsResponses holds responses of POST_ReadSecurityGroups +type POST_ReadSecurityGroupsResponses struct { + OK *ReadSecurityGroupsResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_ReadServerCertificatesParameters holds parameters to POST_ReadServerCertificates +type POST_ReadServerCertificatesParameters struct { + Readservercertificatesrequest ReadServerCertificatesRequest `json:"readservercertificatesrequest,omitempty"` +} + +// POST_ReadServerCertificatesResponses holds responses of POST_ReadServerCertificates +type POST_ReadServerCertificatesResponses struct { + OK *ReadServerCertificatesResponse +} + +// POST_ReadSnapshotExportTasksParameters holds parameters to POST_ReadSnapshotExportTasks +type POST_ReadSnapshotExportTasksParameters struct { + Readsnapshotexporttasksrequest ReadSnapshotExportTasksRequest `json:"readsnapshotexporttasksrequest,omitempty"` +} + +// POST_ReadSnapshotExportTasksResponses holds responses of POST_ReadSnapshotExportTasks +type POST_ReadSnapshotExportTasksResponses struct { + OK *ReadSnapshotExportTasksResponse +} + +// POST_ReadSnapshotsParameters holds parameters to POST_ReadSnapshots +type POST_ReadSnapshotsParameters struct { + Readsnapshotsrequest ReadSnapshotsRequest `json:"readsnapshotsrequest,omitempty"` +} + +// POST_ReadSnapshotsResponses holds responses of POST_ReadSnapshots +type POST_ReadSnapshotsResponses struct { + OK *ReadSnapshotsResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_ReadSubnetsParameters holds parameters to POST_ReadSubnets +type POST_ReadSubnetsParameters struct { + Readsubnetsrequest ReadSubnetsRequest `json:"readsubnetsrequest,omitempty"` +} + +// POST_ReadSubnetsResponses holds responses of POST_ReadSubnets +type POST_ReadSubnetsResponses struct { + OK *ReadSubnetsResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_ReadSubregionsParameters holds parameters to POST_ReadSubregions +type POST_ReadSubregionsParameters struct { + Readsubregionsrequest ReadSubregionsRequest `json:"readsubregionsrequest,omitempty"` +} + +// POST_ReadSubregionsResponses holds responses of POST_ReadSubregions +type POST_ReadSubregionsResponses struct { + OK *ReadSubregionsResponse +} + +// POST_ReadTagsParameters holds parameters to POST_ReadTags +type POST_ReadTagsParameters struct { + Readtagsrequest ReadTagsRequest `json:"readtagsrequest,omitempty"` +} + +// POST_ReadTagsResponses holds responses of POST_ReadTags +type POST_ReadTagsResponses struct { + OK *ReadTagsResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_ReadUserGroupsParameters holds parameters to POST_ReadUserGroups +type POST_ReadUserGroupsParameters struct { + Readusergroupsrequest ReadUserGroupsRequest `json:"readusergroupsrequest,omitempty"` +} + +// POST_ReadUserGroupsResponses holds responses of POST_ReadUserGroups +type POST_ReadUserGroupsResponses struct { + OK *ReadUserGroupsResponse +} + +// POST_ReadUsersParameters holds parameters to POST_ReadUsers +type POST_ReadUsersParameters struct { + Readusersrequest ReadUsersRequest `json:"readusersrequest,omitempty"` +} + +// POST_ReadUsersResponses holds responses of POST_ReadUsers +type POST_ReadUsersResponses struct { + OK *ReadUsersResponse +} + +// POST_ReadVirtualGatewaysParameters holds parameters to POST_ReadVirtualGateways +type POST_ReadVirtualGatewaysParameters struct { + Readvirtualgatewaysrequest ReadVirtualGatewaysRequest `json:"readvirtualgatewaysrequest,omitempty"` +} + +// POST_ReadVirtualGatewaysResponses holds responses of POST_ReadVirtualGateways +type POST_ReadVirtualGatewaysResponses struct { + OK *ReadVirtualGatewaysResponse +} + +// POST_ReadVmTypesParameters holds parameters to POST_ReadVmTypes +type POST_ReadVmTypesParameters struct { + Readvmtypesrequest ReadVmTypesRequest `json:"readvmtypesrequest,omitempty"` +} + +// POST_ReadVmTypesResponses holds responses of POST_ReadVmTypes +type POST_ReadVmTypesResponses struct { + OK *ReadVmTypesResponse +} + +// POST_ReadVmsParameters holds parameters to POST_ReadVms +type POST_ReadVmsParameters struct { + Readvmsrequest ReadVmsRequest `json:"readvmsrequest,omitempty"` +} + +// POST_ReadVmsResponses holds responses of POST_ReadVms +type POST_ReadVmsResponses struct { + OK *ReadVmsResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_ReadVmsHealthParameters holds parameters to POST_ReadVmsHealth +type POST_ReadVmsHealthParameters struct { + Readvmshealthrequest ReadVmsHealthRequest `json:"readvmshealthrequest,omitempty"` +} + +// POST_ReadVmsHealthResponses holds responses of POST_ReadVmsHealth +type POST_ReadVmsHealthResponses struct { + OK *ReadVmsHealthResponse +} + +// POST_ReadVmsStateParameters holds parameters to POST_ReadVmsState +type POST_ReadVmsStateParameters struct { + Readvmsstaterequest ReadVmsStateRequest `json:"readvmsstaterequest,omitempty"` +} + +// POST_ReadVmsStateResponses holds responses of POST_ReadVmsState +type POST_ReadVmsStateResponses struct { + OK *ReadVmsStateResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_ReadVolumesParameters holds parameters to POST_ReadVolumes +type POST_ReadVolumesParameters struct { + Readvolumesrequest ReadVolumesRequest `json:"readvolumesrequest,omitempty"` +} + +// POST_ReadVolumesResponses holds responses of POST_ReadVolumes +type POST_ReadVolumesResponses struct { + OK *ReadVolumesResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_ReadVpnConnectionsParameters holds parameters to POST_ReadVpnConnections +type POST_ReadVpnConnectionsParameters struct { + Readvpnconnectionsrequest ReadVpnConnectionsRequest `json:"readvpnconnectionsrequest,omitempty"` +} + +// POST_ReadVpnConnectionsResponses holds responses of POST_ReadVpnConnections +type POST_ReadVpnConnectionsResponses struct { + OK *ReadVpnConnectionsResponse +} + +// POST_RebootVmsParameters holds parameters to POST_RebootVms +type POST_RebootVmsParameters struct { + Rebootvmsrequest RebootVmsRequest `json:"rebootvmsrequest,omitempty"` +} + +// POST_RebootVmsResponses holds responses of POST_RebootVms +type POST_RebootVmsResponses struct { + OK *RebootVmsResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_RegisterUserInUserGroupParameters holds parameters to POST_RegisterUserInUserGroup +type POST_RegisterUserInUserGroupParameters struct { + Registeruserinusergrouprequest RegisterUserInUserGroupRequest `json:"registeruserinusergrouprequest,omitempty"` +} + +// POST_RegisterUserInUserGroupResponses holds responses of POST_RegisterUserInUserGroup +type POST_RegisterUserInUserGroupResponses struct { + OK *RegisterUserInUserGroupResponse +} + +// POST_RegisterVmsInLoadBalancerParameters holds parameters to POST_RegisterVmsInLoadBalancer +type POST_RegisterVmsInLoadBalancerParameters struct { + Registervmsinloadbalancerrequest RegisterVmsInLoadBalancerRequest `json:"registervmsinloadbalancerrequest,omitempty"` +} + +// POST_RegisterVmsInLoadBalancerResponses holds responses of POST_RegisterVmsInLoadBalancer +type POST_RegisterVmsInLoadBalancerResponses struct { + OK *RegisterVmsInLoadBalancerResponse +} + +// POST_RejectNetPeeringParameters holds parameters to POST_RejectNetPeering +type POST_RejectNetPeeringParameters struct { + Rejectnetpeeringrequest RejectNetPeeringRequest `json:"rejectnetpeeringrequest,omitempty"` +} + +// POST_RejectNetPeeringResponses holds responses of POST_RejectNetPeering +type POST_RejectNetPeeringResponses struct { + OK *RejectNetPeeringResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code409 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_ResetAccountPasswordParameters holds parameters to POST_ResetAccountPassword +type POST_ResetAccountPasswordParameters struct { + Resetaccountpasswordrequest ResetAccountPasswordRequest `json:"resetaccountpasswordrequest,omitempty"` +} + +// POST_ResetAccountPasswordResponses holds responses of POST_ResetAccountPassword +type POST_ResetAccountPasswordResponses struct { + OK *ResetAccountPasswordResponse +} + +// POST_SendResetPasswordEmailParameters holds parameters to POST_SendResetPasswordEmail +type POST_SendResetPasswordEmailParameters struct { + Sendresetpasswordemailrequest SendResetPasswordEmailRequest `json:"sendresetpasswordemailrequest,omitempty"` +} + +// POST_SendResetPasswordEmailResponses holds responses of POST_SendResetPasswordEmail +type POST_SendResetPasswordEmailResponses struct { + OK *SendResetPasswordEmailResponse +} + +// POST_StartVmsParameters holds parameters to POST_StartVms +type POST_StartVmsParameters struct { + Startvmsrequest StartVmsRequest `json:"startvmsrequest,omitempty"` +} + +// POST_StartVmsResponses holds responses of POST_StartVms +type POST_StartVmsResponses struct { + OK *StartVmsResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_StopVmsParameters holds parameters to POST_StopVms +type POST_StopVmsParameters struct { + Stopvmsrequest StopVmsRequest `json:"stopvmsrequest,omitempty"` +} + +// POST_StopVmsResponses holds responses of POST_StopVms +type POST_StopVmsResponses struct { + OK *StopVmsResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_UnlinkInternetServiceParameters holds parameters to POST_UnlinkInternetService +type POST_UnlinkInternetServiceParameters struct { + Unlinkinternetservicerequest UnlinkInternetServiceRequest `json:"unlinkinternetservicerequest,omitempty"` +} + +// POST_UnlinkInternetServiceResponses holds responses of POST_UnlinkInternetService +type POST_UnlinkInternetServiceResponses struct { + OK *UnlinkInternetServiceResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_UnlinkNicParameters holds parameters to POST_UnlinkNic +type POST_UnlinkNicParameters struct { + Unlinknicrequest UnlinkNicRequest `json:"unlinknicrequest,omitempty"` +} + +// POST_UnlinkNicResponses holds responses of POST_UnlinkNic +type POST_UnlinkNicResponses struct { + OK *UnlinkNicResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_UnlinkPolicyParameters holds parameters to POST_UnlinkPolicy +type POST_UnlinkPolicyParameters struct { + Unlinkpolicyrequest UnlinkPolicyRequest `json:"unlinkpolicyrequest,omitempty"` +} + +// POST_UnlinkPolicyResponses holds responses of POST_UnlinkPolicy +type POST_UnlinkPolicyResponses struct { + OK *UnlinkPolicyResponse +} + +// POST_UnlinkPrivateIpsParameters holds parameters to POST_UnlinkPrivateIps +type POST_UnlinkPrivateIpsParameters struct { + Unlinkprivateipsrequest UnlinkPrivateIpsRequest `json:"unlinkprivateipsrequest,omitempty"` +} + +// POST_UnlinkPrivateIpsResponses holds responses of POST_UnlinkPrivateIps +type POST_UnlinkPrivateIpsResponses struct { + OK *UnlinkPrivateIpsResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_UnlinkPublicIpParameters holds parameters to POST_UnlinkPublicIp +type POST_UnlinkPublicIpParameters struct { + Unlinkpubliciprequest UnlinkPublicIpRequest `json:"unlinkpubliciprequest,omitempty"` +} + +// POST_UnlinkPublicIpResponses holds responses of POST_UnlinkPublicIp +type POST_UnlinkPublicIpResponses struct { + OK *UnlinkPublicIpResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_UnlinkRouteTableParameters holds parameters to POST_UnlinkRouteTable +type POST_UnlinkRouteTableParameters struct { + Unlinkroutetablerequest UnlinkRouteTableRequest `json:"unlinkroutetablerequest,omitempty"` +} + +// POST_UnlinkRouteTableResponses holds responses of POST_UnlinkRouteTable +type POST_UnlinkRouteTableResponses struct { + OK *UnlinkRouteTableResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_UnlinkVirtualGatewayParameters holds parameters to POST_UnlinkVirtualGateway +type POST_UnlinkVirtualGatewayParameters struct { + Unlinkvirtualgatewayrequest UnlinkVirtualGatewayRequest `json:"unlinkvirtualgatewayrequest,omitempty"` +} + +// POST_UnlinkVirtualGatewayResponses holds responses of POST_UnlinkVirtualGateway +type POST_UnlinkVirtualGatewayResponses struct { + OK *UnlinkVirtualGatewayResponse +} + +// POST_UnlinkVolumeParameters holds parameters to POST_UnlinkVolume +type POST_UnlinkVolumeParameters struct { + Unlinkvolumerequest UnlinkVolumeRequest `json:"unlinkvolumerequest,omitempty"` +} + +// POST_UnlinkVolumeResponses holds responses of POST_UnlinkVolume +type POST_UnlinkVolumeResponses struct { + OK *UnlinkVolumeResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_UpdateAccountParameters holds parameters to POST_UpdateAccount +type POST_UpdateAccountParameters struct { + Updateaccountrequest UpdateAccountRequest `json:"updateaccountrequest,omitempty"` +} + +// POST_UpdateAccountResponses holds responses of POST_UpdateAccount +type POST_UpdateAccountResponses struct { + OK *UpdateAccountResponse +} + +// POST_UpdateApiKeyParameters holds parameters to POST_UpdateApiKey +type POST_UpdateApiKeyParameters struct { + Updateapikeyrequest UpdateApiKeyRequest `json:"updateapikeyrequest,omitempty"` +} + +// POST_UpdateApiKeyResponses holds responses of POST_UpdateApiKey +type POST_UpdateApiKeyResponses struct { + OK *UpdateApiKeyResponse +} + +// POST_UpdateHealthCheckParameters holds parameters to POST_UpdateHealthCheck +type POST_UpdateHealthCheckParameters struct { + Updatehealthcheckrequest UpdateHealthCheckRequest `json:"updatehealthcheckrequest,omitempty"` +} + +// POST_UpdateHealthCheckResponses holds responses of POST_UpdateHealthCheck +type POST_UpdateHealthCheckResponses struct { + OK *UpdateHealthCheckResponse +} + +// POST_UpdateImageParameters holds parameters to POST_UpdateImage +type POST_UpdateImageParameters struct { + Updateimagerequest UpdateImageRequest `json:"updateimagerequest,omitempty"` +} + +// POST_UpdateImageResponses holds responses of POST_UpdateImage +type POST_UpdateImageResponses struct { + OK *UpdateImageResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_UpdateKeypairParameters holds parameters to POST_UpdateKeypair +type POST_UpdateKeypairParameters struct { + Updatekeypairrequest UpdateKeypairRequest `json:"updatekeypairrequest,omitempty"` +} + +// POST_UpdateKeypairResponses holds responses of POST_UpdateKeypair +type POST_UpdateKeypairResponses struct { + OK *UpdateKeypairResponse +} + +// POST_UpdateListenerRuleParameters holds parameters to POST_UpdateListenerRule +type POST_UpdateListenerRuleParameters struct { + Updatelistenerrulerequest UpdateListenerRuleRequest `json:"updatelistenerrulerequest,omitempty"` +} + +// POST_UpdateListenerRuleResponses holds responses of POST_UpdateListenerRule +type POST_UpdateListenerRuleResponses struct { + OK *UpdateListenerRuleResponse +} + +// POST_UpdateLoadBalancerParameters holds parameters to POST_UpdateLoadBalancer +type POST_UpdateLoadBalancerParameters struct { + Updateloadbalancerrequest UpdateLoadBalancerRequest `json:"updateloadbalancerrequest,omitempty"` +} + +// POST_UpdateLoadBalancerResponses holds responses of POST_UpdateLoadBalancer +type POST_UpdateLoadBalancerResponses struct { + OK *UpdateLoadBalancerResponse +} + +// POST_UpdateNetParameters holds parameters to POST_UpdateNet +type POST_UpdateNetParameters struct { + Updatenetrequest UpdateNetRequest `json:"updatenetrequest,omitempty"` +} + +// POST_UpdateNetResponses holds responses of POST_UpdateNet +type POST_UpdateNetResponses struct { + OK *UpdateNetResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_UpdateNetAccessPointParameters holds parameters to POST_UpdateNetAccessPoint +type POST_UpdateNetAccessPointParameters struct { + Updatenetaccesspointrequest UpdateNetAccessPointRequest `json:"updatenetaccesspointrequest,omitempty"` +} + +// POST_UpdateNetAccessPointResponses holds responses of POST_UpdateNetAccessPoint +type POST_UpdateNetAccessPointResponses struct { + OK *UpdateNetAccessPointResponse +} + +// POST_UpdateNicParameters holds parameters to POST_UpdateNic +type POST_UpdateNicParameters struct { + Updatenicrequest UpdateNicRequest `json:"updatenicrequest,omitempty"` +} + +// POST_UpdateNicResponses holds responses of POST_UpdateNic +type POST_UpdateNicResponses struct { + OK *UpdateNicResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_UpdateRouteParameters holds parameters to POST_UpdateRoute +type POST_UpdateRouteParameters struct { + Updaterouterequest UpdateRouteRequest `json:"updaterouterequest,omitempty"` +} + +// POST_UpdateRouteResponses holds responses of POST_UpdateRoute +type POST_UpdateRouteResponses struct { + OK *UpdateRouteResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_UpdateRoutePropagationParameters holds parameters to POST_UpdateRoutePropagation +type POST_UpdateRoutePropagationParameters struct { + Updateroutepropagationrequest UpdateRoutePropagationRequest `json:"updateroutepropagationrequest,omitempty"` +} + +// POST_UpdateRoutePropagationResponses holds responses of POST_UpdateRoutePropagation +type POST_UpdateRoutePropagationResponses struct { + OK *UpdateRoutePropagationResponse +} + +// POST_UpdateServerCertificateParameters holds parameters to POST_UpdateServerCertificate +type POST_UpdateServerCertificateParameters struct { + Updateservercertificaterequest UpdateServerCertificateRequest `json:"updateservercertificaterequest,omitempty"` +} + +// POST_UpdateServerCertificateResponses holds responses of POST_UpdateServerCertificate +type POST_UpdateServerCertificateResponses struct { + OK *UpdateServerCertificateResponse +} + +// POST_UpdateSnapshotParameters holds parameters to POST_UpdateSnapshot +type POST_UpdateSnapshotParameters struct { + Updatesnapshotrequest UpdateSnapshotRequest `json:"updatesnapshotrequest,omitempty"` +} + +// POST_UpdateSnapshotResponses holds responses of POST_UpdateSnapshot +type POST_UpdateSnapshotResponses struct { + OK *UpdateSnapshotResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} + +// POST_UpdateUserParameters holds parameters to POST_UpdateUser +type POST_UpdateUserParameters struct { + Updateuserrequest UpdateUserRequest `json:"updateuserrequest,omitempty"` +} + +// POST_UpdateUserResponses holds responses of POST_UpdateUser +type POST_UpdateUserResponses struct { + OK *UpdateUserResponse +} + +// POST_UpdateUserGroupParameters holds parameters to POST_UpdateUserGroup +type POST_UpdateUserGroupParameters struct { + Updateusergrouprequest UpdateUserGroupRequest `json:"updateusergrouprequest,omitempty"` +} + +// POST_UpdateUserGroupResponses holds responses of POST_UpdateUserGroup +type POST_UpdateUserGroupResponses struct { + OK *UpdateUserGroupResponse +} + +// POST_UpdateVmParameters holds parameters to POST_UpdateVm +type POST_UpdateVmParameters struct { + Updatevmrequest UpdateVmRequest `json:"updatevmrequest,omitempty"` +} + +// POST_UpdateVmResponses holds responses of POST_UpdateVm +type POST_UpdateVmResponses struct { + OK *UpdateVmResponse + Code400 *ErrorResponse + Code401 *ErrorResponse + Code500 *ErrorResponse +} diff --git a/vendor/github.com/outscale/osc-go/utils/utils.go b/vendor/github.com/outscale/osc-go/utils/utils.go new file mode 100644 index 000000000..5ecfb59be --- /dev/null +++ b/vendor/github.com/outscale/osc-go/utils/utils.go @@ -0,0 +1,27 @@ +package utils + +import ( + "fmt" + "log" + "net/http" + "net/http/httputil" +) + +// DebugRequest ... +func DebugRequest(req *http.Request) { + requestDump, err := httputil.DumpRequest(req, true) + if err != nil { + fmt.Println(err) + } + log.Printf("[DEBUG] Request\n%s", string(requestDump)) +} + +// DebugResponse ... +func DebugResponse(res *http.Response) { + responseDump, err := httputil.DumpResponse(res, true) + if err != nil { + fmt.Println(err) + } + + log.Printf("[DEBUG] Response\n%s", string(responseDump)) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 5885406ca..0c08958b2 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -376,6 +376,9 @@ github.com/olekukonko/tablewriter # github.com/oracle/oci-go-sdk v1.8.0 github.com/oracle/oci-go-sdk/common github.com/oracle/oci-go-sdk/core +# github.com/outscale/osc-go v0.0.1 +github.com/outscale/osc-go/oapi +github.com/outscale/osc-go/utils # github.com/packer-community/winrmcp v0.0.0-20180921204643-0fd363d6159a github.com/packer-community/winrmcp/winrmcp # github.com/pierrec/lz4 v2.0.5+incompatible From a3b0c28bb62b9bfb70ee2abd50ae49eea0e3c01b Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Thu, 21 Feb 2019 15:56:32 -0600 Subject: [PATCH 056/113] test: add acceptance basic test for outscale chroot builder --- builder/osc/chroot/builder_acc_test.go | 30 ++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 builder/osc/chroot/builder_acc_test.go diff --git a/builder/osc/chroot/builder_acc_test.go b/builder/osc/chroot/builder_acc_test.go new file mode 100644 index 000000000..0a65f74af --- /dev/null +++ b/builder/osc/chroot/builder_acc_test.go @@ -0,0 +1,30 @@ +package chroot + +import ( + "testing" + + builderT "github.com/hashicorp/packer/helper/builder/testing" +) + +func TestBuilderAcc_basic(t *testing.T) { + builderT.Test(t, builderT.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Builder: &Builder{}, + Template: testBuilderAccBasic, + }) +} + +func testAccPreCheck(t *testing.T) { +} + +const testBuilderAccBasic = ` +{ + "builders": [{ + "type": "test", + "region": "eu-west-2", + "source_omi": "ami-46260446", + "omi_name": "packer-test {{timestamp}}", + "omi_virtualization_type": "hvm" + }] +} +` From bc907f0fd07f3810553000c1f11163575436d3f8 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Thu, 21 Feb 2019 15:57:07 -0600 Subject: [PATCH 057/113] feature: add vm info step --- builder/osc/chroot/builder.go | 45 +++++++++++++++++++++ builder/osc/chroot/command.go | 15 +++++++ builder/osc/chroot/step_vm_info.go | 64 ++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+) create mode 100644 builder/osc/chroot/command.go create mode 100644 builder/osc/chroot/step_vm_info.go diff --git a/builder/osc/chroot/builder.go b/builder/osc/chroot/builder.go index 2feb8083e..12a83bc0c 100644 --- a/builder/osc/chroot/builder.go +++ b/builder/osc/chroot/builder.go @@ -5,8 +5,10 @@ package chroot import ( + "crypto/tls" "errors" "log" + "net/http" "runtime" osccommon "github.com/hashicorp/packer/builder/osc/common" @@ -15,6 +17,7 @@ import ( "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" + "github.com/outscale/osc-go/oapi" ) // The unique ID for this builder @@ -184,6 +187,48 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe if runtime.GOOS != "linux" { return nil, errors.New("The outscale-chroot builder only works on Linux environments.") } + + clientConfig, err := b.config.Config() + if err != nil { + return nil, err + } + + skipClient := &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }, + } + + oapiconn := oapi.NewClient(clientConfig, skipClient) + + wrappedCommand := func(command string) (string, error) { + ctx := b.config.ctx + ctx.Data = &wrappedCommandTemplate{Command: command} + return interpolate.Render(b.config.CommandWrapper, &ctx) + } + + // Setup the state bag and initial state for the steps + state := new(multistep.BasicStateBag) + state.Put("config", &b.config) + state.Put("oapi", oapiconn) + state.Put("clientConfig", clientConfig) + state.Put("hook", hook) + state.Put("ui", ui) + state.Put("wrappedCommand", CommandWrapper(wrappedCommand)) + + // Build the steps + steps := []multistep.Step{ + &osccommon.StepPreValidate{ + DestOmiName: b.config.OMIName, + ForceDeregister: b.config.OMIForceDeregister, + }, + &StepVmInfo{}, + } + + // Run! + b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) + b.runner.Run(state) + return nil, nil } diff --git a/builder/osc/chroot/command.go b/builder/osc/chroot/command.go new file mode 100644 index 000000000..0ca55be67 --- /dev/null +++ b/builder/osc/chroot/command.go @@ -0,0 +1,15 @@ +package chroot + +import ( + "os/exec" +) + +// CommandWrapper is a type that given a command, will possibly modify that +// command in-flight. This might return an error. +type CommandWrapper func(string) (string, error) + +// ShellCommand takes a command string and returns an *exec.Cmd to execute +// it within the context of a shell (/bin/sh). +func ShellCommand(command string) *exec.Cmd { + return exec.Command("/bin/sh", "-c", command) +} diff --git a/builder/osc/chroot/step_vm_info.go b/builder/osc/chroot/step_vm_info.go new file mode 100644 index 000000000..0104e2f48 --- /dev/null +++ b/builder/osc/chroot/step_vm_info.go @@ -0,0 +1,64 @@ +package chroot + +import ( + "context" + "fmt" + "log" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/outscale/osc-go/oapi" +) + +// StepVmInfo verifies that this builder is running on an Outscale vm. +type StepVmInfo struct{} + +func (s *StepVmInfo) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + oapiconn := state.Get("oapi").(*oapi.Client) + //session := state.Get("clientConfig").(*session.Session) + ui := state.Get("ui").(packer.Ui) + + // Get our own vm ID + ui.Say("Gathering information about this Outscale vm...") + + cmd := ShellCommand("curl http://169.254.169.254/latest/meta-data/instance-id") + + vmID, err := cmd.Output() + if err != nil { + err := fmt.Errorf( + "Error retrieving the ID of the vm Packer is running on.\n" + + "Please verify Packer is running on a proper Outscale vm.") + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + log.Printf("[Debug] VmID got: %s", string(vmID)) + + // Query the entire vm metadata + resp, err := oapiconn.POST_ReadVms(oapi.ReadVmsRequest{Filters: oapi.FiltersVm{ + VmIds: []string{string(vmID)}, + }}) + if err != nil { + err := fmt.Errorf("Error getting vm data: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + vmsResp := resp.OK + + if len(vmsResp.Vms) == 0 { + err := fmt.Errorf("Error getting vm data: no vm found.") + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + vm := vmsResp.Vms[0] + state.Put("vm", vm) + + return multistep.ActionContinue +} + +func (s *StepVmInfo) Cleanup(multistep.StateBag) {} From 66cf27fe316206a54a589c1271b87a967ebf2919 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Fri, 22 Feb 2019 09:50:46 -0600 Subject: [PATCH 058/113] feature: add step check root device step in chrrot builder --- builder/osc/chroot/builder.go | 13 ++++++++ builder/osc/chroot/step_check_root_device.go | 32 ++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 builder/osc/chroot/step_check_root_device.go diff --git a/builder/osc/chroot/builder.go b/builder/osc/chroot/builder.go index 12a83bc0c..6843ad179 100644 --- a/builder/osc/chroot/builder.go +++ b/builder/osc/chroot/builder.go @@ -225,6 +225,19 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &StepVmInfo{}, } + if !b.config.FromScratch { + steps = append(steps, + &osccommon.StepSourceOMIInfo{ + SourceOmi: b.config.SourceOMI, + EnableOMISriovNetSupport: b.config.OMISriovNetSupport, + EnableOMIENASupport: b.config.OMIENASupport, + OmiFilters: b.config.SourceOMIFilter, + OMIVirtType: b.config.OMIVirtType, + }, + &StepCheckRootDevice{}, + ) + } + // Run! b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) b.runner.Run(state) diff --git a/builder/osc/chroot/step_check_root_device.go b/builder/osc/chroot/step_check_root_device.go new file mode 100644 index 000000000..e251a1ff5 --- /dev/null +++ b/builder/osc/chroot/step_check_root_device.go @@ -0,0 +1,32 @@ +package chroot + +import ( + "context" + "fmt" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/outscale/osc-go/oapi" +) + +// StepCheckRootDevice makes sure the root device on the AMI is EBS-backed. +type StepCheckRootDevice struct{} + +func (s *StepCheckRootDevice) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + image := state.Get("source_image").(oapi.Image) + ui := state.Get("ui").(packer.Ui) + + ui.Say("Checking the root device on source AMI...") + + // It must be EBS-backed otherwise the build won't work + if image.RootDeviceType != "ebs" { + err := fmt.Errorf("The root device of the source AMI must be EBS-backed.") + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + return multistep.ActionContinue +} + +func (s *StepCheckRootDevice) Cleanup(multistep.StateBag) {} From bf2d66c4e6ccb80587657c3bbfb976f01fa0966a Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Fri, 22 Feb 2019 12:20:44 -0600 Subject: [PATCH 059/113] feature: add file lock step for chroot builder --- builder/osc/chroot/lockfile.go | 16 +++++++ builder/osc/chroot/lockfile_unix.go | 27 +++++++++++ builder/osc/chroot/step_flock.go | 74 +++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+) create mode 100644 builder/osc/chroot/lockfile.go create mode 100644 builder/osc/chroot/lockfile_unix.go create mode 100644 builder/osc/chroot/step_flock.go diff --git a/builder/osc/chroot/lockfile.go b/builder/osc/chroot/lockfile.go new file mode 100644 index 000000000..1ba13e04b --- /dev/null +++ b/builder/osc/chroot/lockfile.go @@ -0,0 +1,16 @@ +// +build windows + +package chroot + +import ( + "errors" + "os" +) + +func lockFile(*os.File) error { + return errors.New("not supported on Windows") +} + +func unlockFile(f *os.File) error { + return nil +} diff --git a/builder/osc/chroot/lockfile_unix.go b/builder/osc/chroot/lockfile_unix.go new file mode 100644 index 000000000..0d0f8c8f7 --- /dev/null +++ b/builder/osc/chroot/lockfile_unix.go @@ -0,0 +1,27 @@ +// +build !windows + +package chroot + +import ( + "os" + + "golang.org/x/sys/unix" +) + +// See: http://linux.die.net/include/sys/file.h +const LOCK_EX = 2 +const LOCK_NB = 4 +const LOCK_UN = 8 + +func lockFile(f *os.File) error { + err := unix.Flock(int(f.Fd()), LOCK_EX) + if err != nil { + return err + } + + return nil +} + +func unlockFile(f *os.File) error { + return unix.Flock(int(f.Fd()), LOCK_UN) +} diff --git a/builder/osc/chroot/step_flock.go b/builder/osc/chroot/step_flock.go new file mode 100644 index 000000000..2c81193da --- /dev/null +++ b/builder/osc/chroot/step_flock.go @@ -0,0 +1,74 @@ +package chroot + +import ( + "context" + "fmt" + "log" + "os" + "path/filepath" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" +) + +// StepFlock provisions the vm within a chroot. +// +// Produces: +// flock_cleanup Cleanup - To perform early cleanup +type StepFlock struct { + fh *os.File +} + +func (s *StepFlock) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + ui := state.Get("ui").(packer.Ui) + + lockfile := "/var/lock/packer-chroot/lock" + if err := os.MkdirAll(filepath.Dir(lockfile), 0755); err != nil { + err := fmt.Errorf("Error creating lock: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + log.Printf("Obtaining lock: %s", lockfile) + f, err := os.Create(lockfile) + if err != nil { + err := fmt.Errorf("Error creating lock: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + // LOCK! + if err := lockFile(f); err != nil { + err := fmt.Errorf("Error obtaining lock: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + // Set the file handle, we can't close it because we need to hold + // the lock. + s.fh = f + + state.Put("flock_cleanup", s) + return multistep.ActionContinue +} + +func (s *StepFlock) Cleanup(state multistep.StateBag) { + s.CleanupFunc(state) +} + +func (s *StepFlock) CleanupFunc(state multistep.StateBag) error { + if s.fh == nil { + return nil + } + + log.Printf("Unlocking: %s", s.fh.Name()) + if err := unlockFile(s.fh); err != nil { + return err + } + + s.fh = nil + return nil +} From b7f8c6ad9defd0ccf4292ff7ab5fafb7f7ca47a6 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Fri, 22 Feb 2019 13:45:00 -0600 Subject: [PATCH 060/113] feature: add prepare device for chroot builder --- builder/osc/chroot/builder.go | 10 ++++ builder/osc/chroot/device.go | 70 +++++++++++++++++++++++ builder/osc/chroot/step_prepare_device.go | 46 +++++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 builder/osc/chroot/device.go create mode 100644 builder/osc/chroot/step_prepare_device.go diff --git a/builder/osc/chroot/builder.go b/builder/osc/chroot/builder.go index 6843ad179..7c64edbc5 100644 --- a/builder/osc/chroot/builder.go +++ b/builder/osc/chroot/builder.go @@ -238,10 +238,20 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ) } + steps = append(steps, + &StepFlock{}, + &StepPrepareDevice{}, + ) + // Run! b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) b.runner.Run(state) + // If there was an error, return that + if rawErr, ok := state.GetOk("error"); ok { + return nil, rawErr.(error) + } + return nil, nil } diff --git a/builder/osc/chroot/device.go b/builder/osc/chroot/device.go new file mode 100644 index 000000000..4ae8bc789 --- /dev/null +++ b/builder/osc/chroot/device.go @@ -0,0 +1,70 @@ +package chroot + +import ( + "errors" + "fmt" + "os" + "path/filepath" + "strings" +) + +// AvailableDevice finds an available device and returns it. Note that +// you should externally hold a flock or something in order to guarantee +// that this device is available across processes. +func AvailableDevice() (string, error) { + prefix, err := devicePrefix() + if err != nil { + return "", err + } + + letters := "fghijklmnop" + for _, letter := range letters { + device := fmt.Sprintf("/dev/%s%c", prefix, letter) + + // If the block device itself, i.e. /dev/sf, exists, then we + // can't use any of the numbers either. + if _, err := os.Stat(device); err == nil { + continue + } + + // To be able to build both Paravirtual and HVM images, the unnumbered + // device and the first numbered one must be available. + // E.g. /dev/xvdf and /dev/xvdf1 + numbered_device := fmt.Sprintf("%s%d", device, 1) + if _, err := os.Stat(numbered_device); err != nil { + return device, nil + } + } + + return "", errors.New("available device could not be found") +} + +// devicePrefix returns the prefix ("sd" or "xvd" or so on) of the devices +// on the system. The "vd" prefix appears on outscale images. +func devicePrefix() (string, error) { + available := []string{"sd", "xvd", "vd"} + + f, err := os.Open("/sys/block") + if err != nil { + return "", err + } + defer f.Close() + + dirs, err := f.Readdirnames(-1) + if dirs != nil && len(dirs) > 0 { + for _, dir := range dirs { + dirBase := filepath.Base(dir) + for _, prefix := range available { + if strings.HasPrefix(dirBase, prefix) { + return prefix, nil + } + } + } + } + + if err != nil { + return "", err + } + + return "", errors.New("device prefix could not be detected") +} diff --git a/builder/osc/chroot/step_prepare_device.go b/builder/osc/chroot/step_prepare_device.go new file mode 100644 index 000000000..0939d33cd --- /dev/null +++ b/builder/osc/chroot/step_prepare_device.go @@ -0,0 +1,46 @@ +package chroot + +import ( + "context" + "fmt" + "log" + "os" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" +) + +// StepPrepareDevice finds an available device and sets it. +type StepPrepareDevice struct { +} + +func (s *StepPrepareDevice) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + config := state.Get("config").(*Config) + ui := state.Get("ui").(packer.Ui) + + device := config.DevicePath + if device == "" { + var err error + log.Println("Device path not specified, searching for available device...") + device, err = AvailableDevice() + if err != nil { + err := fmt.Errorf("Error finding available device: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + + if _, err := os.Stat(device); err == nil { + err := fmt.Errorf("Device is in use: %s", device) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + log.Printf("Device: %s", device) + state.Put("device", device) + return multistep.ActionContinue +} + +func (s *StepPrepareDevice) Cleanup(state multistep.StateBag) {} From b246bf732922347f2d5f532d593b50433a536890 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Sat, 23 Feb 2019 20:49:51 -0600 Subject: [PATCH 061/113] wip: add create_volume step in chroot builder --- builder/osc/chroot/builder.go | 6 + builder/osc/chroot/step_create_volume.go | 170 +++++++++++++++++++++++ builder/osc/common/state.go | 37 +++++ builder/osc/common/temp_const.go | 18 +++ 4 files changed, 231 insertions(+) create mode 100644 builder/osc/chroot/step_create_volume.go create mode 100644 builder/osc/common/temp_const.go diff --git a/builder/osc/chroot/builder.go b/builder/osc/chroot/builder.go index 7c64edbc5..9a3d1d54f 100644 --- a/builder/osc/chroot/builder.go +++ b/builder/osc/chroot/builder.go @@ -241,6 +241,12 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe steps = append(steps, &StepFlock{}, &StepPrepareDevice{}, + &StepCreateVolume{ + RootVolumeType: b.config.RootVolumeType, + RootVolumeSize: b.config.RootVolumeSize, + RootVolumeTags: b.config.RootVolumeTags, + Ctx: b.config.ctx, + }, ) // Run! diff --git a/builder/osc/chroot/step_create_volume.go b/builder/osc/chroot/step_create_volume.go new file mode 100644 index 000000000..3d7434f42 --- /dev/null +++ b/builder/osc/chroot/step_create_volume.go @@ -0,0 +1,170 @@ +package chroot + +import ( + "context" + "errors" + "fmt" + "log" + + osccommon "github.com/hashicorp/packer/builder/osc/common" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/hashicorp/packer/template/interpolate" + "github.com/outscale/osc-go/oapi" +) + +// StepCreateVolume creates a new volume from the snapshot of the root +// device of the OMI. +// +// Produces: +// volume_id string - The ID of the created volume +type StepCreateVolume struct { + volumeId string + RootVolumeSize int64 + RootVolumeType string + RootVolumeTags osccommon.TagMap + Ctx interpolate.Context +} + +func (s *StepCreateVolume) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + config := state.Get("config").(*Config) + oapiconn := state.Get("oapi").(*oapi.Client) + vm := state.Get("vm").(oapi.Vm) + ui := state.Get("ui").(packer.Ui) + + var err error + + //TODO: Add tags + // volTags, err := s.RootVolumeTags.OAPITags(s.Ctx, oapiconn.GetConfig().Region, state) + // if err != nil { + // err := fmt.Errorf("Error tagging volumes: %s", err) + // state.Put("error", err) + // ui.Error(err.Error()) + // return multistep.ActionHalt + // } + + // // Collect tags for tagging on resource creation + // var tagSpecs []oapi.ResourceTag + + // if len(volTags) > 0 { + // runVolTags := &oapi.Resou rceTag{ + // ResourceType: "volume", + // Tags: volTags, + // } + + // tagSpecs = append(tagSpecs, runVolTags) + // } + + var createVolume *oapi.CreateVolumeRequest + if config.FromScratch { + rootVolumeType := osccommon.VolumeTypeGp2 + if s.RootVolumeType == "io1" { + err := errors.New("Cannot use io1 volume when building from scratch") + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } else if s.RootVolumeType != "" { + rootVolumeType = s.RootVolumeType + } + createVolume = &oapi.CreateVolumeRequest{ + SubregionName: vm.Placement.SubregionName, + Size: s.RootVolumeSize, + VolumeType: rootVolumeType, + } + + } else { + // Determine the root device snapshot + image := state.Get("source_image").(oapi.Image) + log.Printf("Searching for root device of the image (%s)", image.RootDeviceName) + var rootDevice *oapi.BlockDeviceMappingImage + for _, device := range image.BlockDeviceMappings { + if device.DeviceName == image.RootDeviceName { + *rootDevice = device + break + } + } + + ui.Say("Creating the root volume...") + createVolume, err = s.buildCreateVolumeInput(vm.Placement.SubregionName, rootDevice) + if err != nil { + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + //TODO: ADD TAGS + // if len(tagSpecs) > 0 { + // createVolume.SetTagSpecifications(tagSpecs) + // volTags.Report(ui) + // } + log.Printf("Create args: %+v", createVolume) + + createVolumeResp, err := oapiconn.POST_CreateVolume(*createVolume) + if err != nil { + err := fmt.Errorf("Error creating root volume: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + // Set the volume ID so we remember to delete it later + s.volumeId = createVolumeResp.OK.Volume.VolumeId + log.Printf("Volume ID: %s", s.volumeId) + + // Wait for the volume to become ready + err = osccommon.WaitUntilVolumeAvailable(oapiconn, s.volumeId) + if err != nil { + err := fmt.Errorf("Error waiting for volume: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + state.Put("volume_id", s.volumeId) + return multistep.ActionContinue +} + +func (s *StepCreateVolume) Cleanup(state multistep.StateBag) { + if s.volumeId == "" { + return + } + + oapiconn := state.Get("oapi").(*oapi.Client) + ui := state.Get("ui").(packer.Ui) + + ui.Say("Deleting the created BSU volume...") + _, err := oapiconn.POST_DeleteVolume(oapi.DeleteVolumeRequest{VolumeId: s.volumeId}) + if err != nil { + ui.Error(fmt.Sprintf("Error deleting BSU volume: %s", err)) + } +} + +func (s *StepCreateVolume) buildCreateVolumeInput(suregionName string, rootDevice *oapi.BlockDeviceMappingImage) (*oapi.CreateVolumeRequest, error) { + if rootDevice == nil { + return nil, fmt.Errorf("Couldn't find root device!") + } + createVolumeInput := &oapi.CreateVolumeRequest{ + SubregionName: suregionName, + Size: rootDevice.Bsu.VolumeSize, + SnapshotId: rootDevice.Bsu.SnapshotId, + VolumeType: rootDevice.Bsu.VolumeType, + Iops: rootDevice.Bsu.Iops, + } + if s.RootVolumeSize > rootDevice.Bsu.VolumeSize { + createVolumeInput.Size = s.RootVolumeSize + } + + if s.RootVolumeType == "" || s.RootVolumeType == rootDevice.Bsu.VolumeType { + return createVolumeInput, nil + } + + if s.RootVolumeType == "io1" { + return nil, fmt.Errorf("Root volume type cannot be io1, because existing root volume type was %s", rootDevice.Bsu.VolumeType) + } + + createVolumeInput.VolumeType = s.RootVolumeType + // non io1 cannot set iops + createVolumeInput.Iops = 0 + + return createVolumeInput, nil +} diff --git a/builder/osc/common/state.go b/builder/osc/common/state.go index ed8941268..d0fd7a2db 100644 --- a/builder/osc/common/state.go +++ b/builder/osc/common/state.go @@ -48,6 +48,12 @@ func WaitUntilImageAvailable(conn *oapi.Client, imageID string) error { return <-errCh } +func WaitUntilVolumeAvailable(conn *oapi.Client, volumeID string) error { + errCh := make(chan error, 1) + go waitForState(errCh, "available", volumeWaitFunc(conn, volumeID)) + return <-errCh +} + func waitForState(errCh chan<- error, target string, refresh stateRefreshFunc) error { err := common.Retry(2, 2, 0, func(_ uint) (bool, error) { state, err := refresh() @@ -173,3 +179,34 @@ func securityGroupWaitFunc(conn *oapi.Client, id string) stateRefreshFunc { return "exists", nil } } + +func volumeWaitFunc(conn *oapi.Client, id string) stateRefreshFunc { + return func() (string, error) { + log.Printf("[Debug] Check if SvolumeG with id %s exists", id) + resp, err := conn.POST_ReadVolumes(oapi.ReadVolumesRequest{ + Filters: oapi.FiltersVolume{ + VolumeIds: []string{id}, + }, + }) + + log.Printf("[Debug] Read Response %+v", resp.OK) + + if err != nil { + return "", err + } + + if resp.OK == nil { + return "", fmt.Errorf("Volume with ID %s. Not Found", id) + } + + if len(resp.OK.Volumes) == 0 { + return "waiting", nil + } + + if resp.OK.Volumes[0].State == "error" { + return resp.OK.Volumes[0].State, fmt.Errorf("Volume (%s) creation is failed", id) + } + + return resp.OK.Volumes[0].State, nil + } +} diff --git a/builder/osc/common/temp_const.go b/builder/osc/common/temp_const.go new file mode 100644 index 000000000..d43e0276d --- /dev/null +++ b/builder/osc/common/temp_const.go @@ -0,0 +1,18 @@ +package common + +const ( + // VolumeTypeStandard is a VolumeType enum value + VolumeTypeStandard = "standard" + + // VolumeTypeIo1 is a VolumeType enum value + VolumeTypeIo1 = "io1" + + // VolumeTypeGp2 is a VolumeType enum value + VolumeTypeGp2 = "gp2" + + // VolumeTypeSc1 is a VolumeType enum value + VolumeTypeSc1 = "sc1" + + // VolumeTypeSt1 is a VolumeType enum value + VolumeTypeSt1 = "st1" +) From f1e5dafc7139b5c5bb653fe88126a6a671804de2 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Mon, 25 Feb 2019 12:02:51 -0600 Subject: [PATCH 062/113] fix: convert volume size to Gib before volume creation --- builder/osc/chroot/step_create_volume.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/builder/osc/chroot/step_create_volume.go b/builder/osc/chroot/step_create_volume.go index 3d7434f42..57ce2c43a 100644 --- a/builder/osc/chroot/step_create_volume.go +++ b/builder/osc/chroot/step_create_volume.go @@ -79,7 +79,7 @@ func (s *StepCreateVolume) Run(ctx context.Context, state multistep.StateBag) mu var rootDevice *oapi.BlockDeviceMappingImage for _, device := range image.BlockDeviceMappings { if device.DeviceName == image.RootDeviceName { - *rootDevice = device + rootDevice = &device break } } @@ -143,9 +143,12 @@ func (s *StepCreateVolume) buildCreateVolumeInput(suregionName string, rootDevic if rootDevice == nil { return nil, fmt.Errorf("Couldn't find root device!") } + + //FIX: Temporary fix + gibSize := rootDevice.Bsu.VolumeSize / (1024 * 1024 * 1024) createVolumeInput := &oapi.CreateVolumeRequest{ SubregionName: suregionName, - Size: rootDevice.Bsu.VolumeSize, + Size: gibSize, SnapshotId: rootDevice.Bsu.SnapshotId, VolumeType: rootDevice.Bsu.VolumeType, Iops: rootDevice.Bsu.Iops, From b3310f65a6c1645e37c19050398408b28d020bcf Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Mon, 25 Feb 2019 15:37:06 -0600 Subject: [PATCH 063/113] feature: add link volume step for chroot builder --- builder/osc/chroot/builder.go | 1 + builder/osc/chroot/step_link_volume.go | 97 ++++++++++++++++++++++++++ builder/osc/common/state.go | 74 ++++++++++++++++++++ 3 files changed, 172 insertions(+) create mode 100644 builder/osc/chroot/step_link_volume.go diff --git a/builder/osc/chroot/builder.go b/builder/osc/chroot/builder.go index 9a3d1d54f..6f545ee98 100644 --- a/builder/osc/chroot/builder.go +++ b/builder/osc/chroot/builder.go @@ -247,6 +247,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe RootVolumeTags: b.config.RootVolumeTags, Ctx: b.config.ctx, }, + &StepLinkVolume{}, ) // Run! diff --git a/builder/osc/chroot/step_link_volume.go b/builder/osc/chroot/step_link_volume.go new file mode 100644 index 000000000..09f00f03a --- /dev/null +++ b/builder/osc/chroot/step_link_volume.go @@ -0,0 +1,97 @@ +package chroot + +import ( + "context" + "fmt" + "strings" + + osccommon "github.com/hashicorp/packer/builder/osc/common" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/outscale/osc-go/oapi" +) + +// StepLinkVolume attaches the previously created volume to an +// available device location. +// +// Produces: +// device string - The location where the volume was attached. +// attach_cleanup CleanupFunc +type StepLinkVolume struct { + attached bool + volumeId string +} + +func (s *StepLinkVolume) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + oapiconn := state.Get("oapi").(*oapi.Client) + device := state.Get("device").(string) + vm := state.Get("vm").(oapi.Vm) + ui := state.Get("ui").(packer.Ui) + volumeId := state.Get("volume_id").(string) + + // For the API call, it expects "sd" prefixed devices. + //linkVolume := strings.Replace(device, "/xvd", "/sd", 1) + linkVolume := strings.Replace(device, "/vd", "/sd", 1) + + ui.Say(fmt.Sprintf("Attaching the root volume to %s", linkVolume)) + _, err := oapiconn.POST_LinkVolume(oapi.LinkVolumeRequest{ + VmId: vm.VmId, + VolumeId: volumeId, + DeviceName: linkVolume, + }) + + if err != nil { + err := fmt.Errorf("Error attaching volume: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + // Mark that we attached it so we can detach it later + s.attached = true + s.volumeId = volumeId + + // Wait for the volume to become attached + err = osccommon.WaitUntilVolumeIsLinked(oapiconn, s.volumeId) + if err != nil { + err := fmt.Errorf("Error waiting for volume: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + state.Put("attach_cleanup", s) + return multistep.ActionContinue +} + +func (s *StepLinkVolume) Cleanup(state multistep.StateBag) { + ui := state.Get("ui").(packer.Ui) + if err := s.CleanupFunc(state); err != nil { + ui.Error(err.Error()) + } +} + +func (s *StepLinkVolume) CleanupFunc(state multistep.StateBag) error { + if !s.attached { + return nil + } + + oapiconn := state.Get("oapi").(*oapi.Client) + ui := state.Get("ui").(packer.Ui) + + ui.Say("Detaching BSU volume...") + _, err := oapiconn.POST_UnlinkVolume(oapi.UnlinkVolumeRequest{VolumeId: s.volumeId}) + if err != nil { + return fmt.Errorf("Error detaching BSU volume: %s", err) + } + + s.attached = false + + // Wait for the volume to detach + err = osccommon.WaitUntilVolumeIsUnlinked(oapiconn, s.volumeId) + if err != nil { + return fmt.Errorf("Error waiting for volume: %s", err) + } + + return nil +} diff --git a/builder/osc/common/state.go b/builder/osc/common/state.go index d0fd7a2db..b211f882a 100644 --- a/builder/osc/common/state.go +++ b/builder/osc/common/state.go @@ -54,6 +54,18 @@ func WaitUntilVolumeAvailable(conn *oapi.Client, volumeID string) error { return <-errCh } +func WaitUntilVolumeIsLinked(conn *oapi.Client, volumeID string) error { + errCh := make(chan error, 1) + go waitForState(errCh, "attached", waitUntilVolumeLinkedStateFunc(conn, volumeID)) + return <-errCh +} + +func WaitUntilVolumeIsUnlinked(conn *oapi.Client, volumeID string) error { + errCh := make(chan error, 1) + go waitForState(errCh, "dettached", waitUntilVolumeUnLinkedStateFunc(conn, volumeID)) + return <-errCh +} + func waitForState(errCh chan<- error, target string, refresh stateRefreshFunc) error { err := common.Retry(2, 2, 0, func(_ uint) (bool, error) { state, err := refresh() @@ -95,6 +107,68 @@ func waitUntilVmStateFunc(conn *oapi.Client, id string) stateRefreshFunc { } } +func waitUntilVolumeLinkedStateFunc(conn *oapi.Client, id string) stateRefreshFunc { + return func() (string, error) { + log.Printf("[Debug] Check if volume with id %s exists", id) + resp, err := conn.POST_ReadVolumes(oapi.ReadVolumesRequest{ + Filters: oapi.FiltersVolume{ + VolumeIds: []string{id}, + }, + }) + + if err != nil { + return "", err + } + + if resp.OK == nil { + return "", fmt.Errorf("Vm with ID %s. Not Found", id) + } + + log.Printf("[Debug] Read Response %+v", resp.OK) + + if len(resp.OK.Volumes) == 0 { + return "pending", nil + } + + if len(resp.OK.Volumes[0].LinkedVolumes) == 0 { + return "pending", nil + } + + return resp.OK.Volumes[0].LinkedVolumes[0].State, nil + } +} + +func waitUntilVolumeUnLinkedStateFunc(conn *oapi.Client, id string) stateRefreshFunc { + return func() (string, error) { + log.Printf("[Debug] Check if volume with id %s exists", id) + resp, err := conn.POST_ReadVolumes(oapi.ReadVolumesRequest{ + Filters: oapi.FiltersVolume{ + VolumeIds: []string{id}, + }, + }) + + if err != nil { + return "", err + } + + if resp.OK == nil { + return "", fmt.Errorf("Vm with ID %s. Not Found", id) + } + + log.Printf("[Debug] Read Response %+v", resp.OK) + + if len(resp.OK.Volumes) == 0 { + return "pending", nil + } + + if len(resp.OK.Volumes[0].LinkedVolumes) == 0 { + return "dettached", nil + } + + return "failed", nil + } +} + func waitUntilSnapshotStateFunc(conn *oapi.Client, id string) stateRefreshFunc { return func() (string, error) { log.Printf("[Debug] Check if Snapshot with id %s exists", id) From 0f51ab5c084c36a915e0b19d8e52f0143b180215 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Mon, 25 Feb 2019 15:57:15 -0600 Subject: [PATCH 064/113] feature: add early unflock step for chroot builder --- builder/osc/chroot/builder.go | 1 + builder/osc/chroot/cleanup.go | 10 ++++++++ builder/osc/chroot/step_early_unflock.go | 30 ++++++++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 builder/osc/chroot/cleanup.go create mode 100644 builder/osc/chroot/step_early_unflock.go diff --git a/builder/osc/chroot/builder.go b/builder/osc/chroot/builder.go index 6f545ee98..b5bcb907e 100644 --- a/builder/osc/chroot/builder.go +++ b/builder/osc/chroot/builder.go @@ -248,6 +248,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Ctx: b.config.ctx, }, &StepLinkVolume{}, + &StepEarlyUnflock{}, ) // Run! diff --git a/builder/osc/chroot/cleanup.go b/builder/osc/chroot/cleanup.go new file mode 100644 index 000000000..0befac174 --- /dev/null +++ b/builder/osc/chroot/cleanup.go @@ -0,0 +1,10 @@ +package chroot + +import ( + "github.com/hashicorp/packer/helper/multistep" +) + +// Cleanup is an interface that some steps implement for early cleanup. +type Cleanup interface { + CleanupFunc(multistep.StateBag) error +} diff --git a/builder/osc/chroot/step_early_unflock.go b/builder/osc/chroot/step_early_unflock.go new file mode 100644 index 000000000..225e91fb9 --- /dev/null +++ b/builder/osc/chroot/step_early_unflock.go @@ -0,0 +1,30 @@ +package chroot + +import ( + "context" + "fmt" + "log" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" +) + +// StepEarlyUnflock unlocks the flock. +type StepEarlyUnflock struct{} + +func (s *StepEarlyUnflock) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + cleanup := state.Get("flock_cleanup").(Cleanup) + ui := state.Get("ui").(packer.Ui) + + log.Println("Unlocking file lock...") + if err := cleanup.CleanupFunc(state); err != nil { + err := fmt.Errorf("Error unlocking file lock: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + return multistep.ActionContinue +} + +func (s *StepEarlyUnflock) Cleanup(state multistep.StateBag) {} From 00ab0097de0db22521bed127708dc620a59784a5 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Mon, 25 Feb 2019 16:31:08 -0600 Subject: [PATCH 065/113] feature: add pre mount commands step for chroot builder --- builder/osc/chroot/builder.go | 3 ++ builder/osc/chroot/run_local_commands.go | 39 ++++++++++++++++++ builder/osc/chroot/step_pre_mount_commands.go | 41 +++++++++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 builder/osc/chroot/run_local_commands.go create mode 100644 builder/osc/chroot/step_pre_mount_commands.go diff --git a/builder/osc/chroot/builder.go b/builder/osc/chroot/builder.go index b5bcb907e..1b5019653 100644 --- a/builder/osc/chroot/builder.go +++ b/builder/osc/chroot/builder.go @@ -249,6 +249,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, &StepLinkVolume{}, &StepEarlyUnflock{}, + &StepPreMountCommands{ + Commands: b.config.PreMountCommands, + }, ) // Run! diff --git a/builder/osc/chroot/run_local_commands.go b/builder/osc/chroot/run_local_commands.go new file mode 100644 index 000000000..fc1c01e2b --- /dev/null +++ b/builder/osc/chroot/run_local_commands.go @@ -0,0 +1,39 @@ +package chroot + +import ( + "fmt" + + sl "github.com/hashicorp/packer/common/shell-local" + "github.com/hashicorp/packer/packer" + "github.com/hashicorp/packer/template/interpolate" +) + +func RunLocalCommands(commands []string, wrappedCommand CommandWrapper, ctx interpolate.Context, ui packer.Ui) error { + for _, rawCmd := range commands { + intCmd, err := interpolate.Render(rawCmd, &ctx) + if err != nil { + return fmt.Errorf("Error interpolating: %s", err) + } + + command, err := wrappedCommand(intCmd) + if err != nil { + return fmt.Errorf("Error wrapping command: %s", err) + } + + ui.Say(fmt.Sprintf("Executing command: %s", command)) + comm := &sl.Communicator{ + ExecuteCommand: []string{"sh", "-c", command}, + } + cmd := &packer.RemoteCmd{Command: command} + if err := cmd.StartWithUi(comm, ui); err != nil { + return fmt.Errorf("Error executing command: %s", err) + } + if cmd.ExitStatus != 0 { + return fmt.Errorf( + "Received non-zero exit code %d from command: %s", + cmd.ExitStatus, + command) + } + } + return nil +} diff --git a/builder/osc/chroot/step_pre_mount_commands.go b/builder/osc/chroot/step_pre_mount_commands.go new file mode 100644 index 000000000..ce3c26e02 --- /dev/null +++ b/builder/osc/chroot/step_pre_mount_commands.go @@ -0,0 +1,41 @@ +package chroot + +import ( + "context" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" +) + +type preMountCommandsData struct { + Device string +} + +// StepPreMountCommands sets up the a new block device when building from scratch +type StepPreMountCommands struct { + Commands []string +} + +func (s *StepPreMountCommands) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + config := state.Get("config").(*Config) + device := state.Get("device").(string) + ui := state.Get("ui").(packer.Ui) + wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) + + if len(s.Commands) == 0 { + return multistep.ActionContinue + } + + ctx := config.ctx + ctx.Data = &preMountCommandsData{Device: device} + + ui.Say("Running device setup commands...") + if err := RunLocalCommands(s.Commands, wrappedCommand, ctx, ui); err != nil { + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + return multistep.ActionContinue +} + +func (s *StepPreMountCommands) Cleanup(state multistep.StateBag) {} From 6e6bdc4f42b144a5e47494c8c52176bfccf5b97a Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Wed, 27 Feb 2019 15:26:51 -0600 Subject: [PATCH 066/113] feature: add mount device step in chroot builder --- builder/osc/chroot/builder.go | 4 + builder/osc/chroot/builder_acc_test.go | 13 +- builder/osc/chroot/device.go | 2 +- builder/osc/chroot/step_link_volume.go | 3 +- builder/osc/chroot/step_mount_device.go | 157 ++++++++++++++++++++++++ 5 files changed, 171 insertions(+), 8 deletions(-) create mode 100644 builder/osc/chroot/step_mount_device.go diff --git a/builder/osc/chroot/builder.go b/builder/osc/chroot/builder.go index 1b5019653..88d1ebfc9 100644 --- a/builder/osc/chroot/builder.go +++ b/builder/osc/chroot/builder.go @@ -252,6 +252,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &StepPreMountCommands{ Commands: b.config.PreMountCommands, }, + &StepMountDevice{ + MountOptions: b.config.MountOptions, + MountPartition: b.config.MountPartition, + }, ) // Run! diff --git a/builder/osc/chroot/builder_acc_test.go b/builder/osc/chroot/builder_acc_test.go index 0a65f74af..be28b3b76 100644 --- a/builder/osc/chroot/builder_acc_test.go +++ b/builder/osc/chroot/builder_acc_test.go @@ -8,9 +8,10 @@ import ( func TestBuilderAcc_basic(t *testing.T) { builderT.Test(t, builderT.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Builder: &Builder{}, - Template: testBuilderAccBasic, + PreCheck: func() { testAccPreCheck(t) }, + Builder: &Builder{}, + Template: testBuilderAccBasic, + SkipArtifactTeardown: true, }) } @@ -22,9 +23,11 @@ const testBuilderAccBasic = ` "builders": [{ "type": "test", "region": "eu-west-2", - "source_omi": "ami-46260446", + "source_omi": "ami-99466096", "omi_name": "packer-test {{timestamp}}", - "omi_virtualization_type": "hvm" + "omi_virtualization_type": "hvm", + "device_path": "/dev/xvdf", + "mount_partition": "0" }] } ` diff --git a/builder/osc/chroot/device.go b/builder/osc/chroot/device.go index 4ae8bc789..f703b78ea 100644 --- a/builder/osc/chroot/device.go +++ b/builder/osc/chroot/device.go @@ -42,7 +42,7 @@ func AvailableDevice() (string, error) { // devicePrefix returns the prefix ("sd" or "xvd" or so on) of the devices // on the system. The "vd" prefix appears on outscale images. func devicePrefix() (string, error) { - available := []string{"sd", "xvd", "vd"} + available := []string{"sd", "xvd"} f, err := os.Open("/sys/block") if err != nil { diff --git a/builder/osc/chroot/step_link_volume.go b/builder/osc/chroot/step_link_volume.go index 09f00f03a..8c5b6d941 100644 --- a/builder/osc/chroot/step_link_volume.go +++ b/builder/osc/chroot/step_link_volume.go @@ -30,8 +30,7 @@ func (s *StepLinkVolume) Run(ctx context.Context, state multistep.StateBag) mult volumeId := state.Get("volume_id").(string) // For the API call, it expects "sd" prefixed devices. - //linkVolume := strings.Replace(device, "/xvd", "/sd", 1) - linkVolume := strings.Replace(device, "/vd", "/sd", 1) + linkVolume := strings.Replace(device, "/xvd", "/sd", 1) ui.Say(fmt.Sprintf("Attaching the root volume to %s", linkVolume)) _, err := oapiconn.POST_LinkVolume(oapi.LinkVolumeRequest{ diff --git a/builder/osc/chroot/step_mount_device.go b/builder/osc/chroot/step_mount_device.go new file mode 100644 index 000000000..51a150e19 --- /dev/null +++ b/builder/osc/chroot/step_mount_device.go @@ -0,0 +1,157 @@ +package chroot + +import ( + "bytes" + "context" + "fmt" + "log" + "os" + "path/filepath" + "strings" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/hashicorp/packer/template/interpolate" +) + +type mountPathData struct { + Device string +} + +// StepMountDevice mounts the attached device. +// +// Produces: +// mount_path string - The location where the volume was mounted. +// mount_device_cleanup CleanupFunc - To perform early cleanup +type StepMountDevice struct { + MountOptions []string + MountPartition string + + mountPath string +} + +func (s *StepMountDevice) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + config := state.Get("config").(*Config) + ui := state.Get("ui").(packer.Ui) + device := state.Get("device").(string) + if config.NVMEDevicePath != "" { + // customizable device path for mounting NVME block devices on c5 and m5 HVM + device = config.NVMEDevicePath + } + wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) + + var virtualizationType string + if config.FromScratch { + virtualizationType = config.OMIVirtType + } else { + //image := state.Get("source_image").(oapi.Image) + + //Is always hvm + virtualizationType = "hvm" + log.Printf("Source image virtualization type is: %s", virtualizationType) + } + + ctx := config.ctx + + ctx.Data = &mountPathData{Device: filepath.Base(device)} + mountPath, err := interpolate.Render(config.MountPath, &ctx) + + if err != nil { + err := fmt.Errorf("Error preparing mount directory: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + mountPath, err = filepath.Abs(mountPath) + if err != nil { + err := fmt.Errorf("Error preparing mount directory: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + log.Printf("Mount path: %s", mountPath) + + if err := os.MkdirAll(mountPath, 0755); err != nil { + err := fmt.Errorf("Error creating mount directory: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + //TODO: Check the symlink created + deviceMount := device + + log.Printf("[DEBUG] s.MountPartition = %s", s.MountPartition) + + if virtualizationType == "hvm" && s.MountPartition != "0" { + deviceMount = fmt.Sprintf("%s%s", deviceMount, s.MountPartition) + } + state.Put("deviceMount", deviceMount) + + ui.Say("Mounting the root device...") + stderr := new(bytes.Buffer) + + // build mount options from mount_options config, useful for nouuid options + // or other specific device type settings for mount + opts := "" + if len(s.MountOptions) > 0 { + opts = "-o " + strings.Join(s.MountOptions, " -o ") + } + mountCommand, err := wrappedCommand( + fmt.Sprintf("mount %s %s %s", opts, deviceMount, mountPath)) + if err != nil { + err := fmt.Errorf("Error creating mount command: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + log.Printf("[DEBUG] (step mount) mount command is %s", mountCommand) + cmd := ShellCommand(mountCommand) + cmd.Stderr = stderr + if err := cmd.Run(); err != nil { + err := fmt.Errorf( + "Error mounting root volume: %s\nStderr: %s", err, stderr.String()) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + // Set the mount path so we remember to unmount it later + s.mountPath = mountPath + state.Put("mount_path", s.mountPath) + state.Put("mount_device_cleanup", s) + + return multistep.ActionContinue +} + +func (s *StepMountDevice) Cleanup(state multistep.StateBag) { + ui := state.Get("ui").(packer.Ui) + if err := s.CleanupFunc(state); err != nil { + ui.Error(err.Error()) + } +} + +func (s *StepMountDevice) CleanupFunc(state multistep.StateBag) error { + if s.mountPath == "" { + return nil + } + + ui := state.Get("ui").(packer.Ui) + wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) + + ui.Say("Unmounting the root device...") + unmountCommand, err := wrappedCommand(fmt.Sprintf("umount %s", s.mountPath)) + if err != nil { + return fmt.Errorf("Error creating unmount command: %s", err) + } + + cmd := ShellCommand(unmountCommand) + if err := cmd.Run(); err != nil { + return fmt.Errorf("Error unmounting root device: %s", err) + } + + s.mountPath = "" + return nil +} From b3d165e864f3e35092e0ca9d40c680871c6783a7 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Thu, 28 Feb 2019 09:52:44 -0600 Subject: [PATCH 067/113] feature: add post mount commands step in chroot builder --- builder/osc/chroot/builder.go | 3 ++ .../osc/chroot/step_post_mount_commands.go | 47 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 builder/osc/chroot/step_post_mount_commands.go diff --git a/builder/osc/chroot/builder.go b/builder/osc/chroot/builder.go index 88d1ebfc9..272a8449e 100644 --- a/builder/osc/chroot/builder.go +++ b/builder/osc/chroot/builder.go @@ -256,6 +256,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe MountOptions: b.config.MountOptions, MountPartition: b.config.MountPartition, }, + &StepPostMountCommands{ + Commands: b.config.PostMountCommands, + }, ) // Run! diff --git a/builder/osc/chroot/step_post_mount_commands.go b/builder/osc/chroot/step_post_mount_commands.go new file mode 100644 index 000000000..a00e8e1bf --- /dev/null +++ b/builder/osc/chroot/step_post_mount_commands.go @@ -0,0 +1,47 @@ +package chroot + +import ( + "context" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" +) + +type postMountCommandsData struct { + Device string + MountPath string +} + +// StepPostMountCommands allows running arbitrary commands after mounting the +// device, but prior to the bind mount and copy steps. +type StepPostMountCommands struct { + Commands []string +} + +func (s *StepPostMountCommands) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + config := state.Get("config").(*Config) + device := state.Get("device").(string) + mountPath := state.Get("mount_path").(string) + ui := state.Get("ui").(packer.Ui) + wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) + + if len(s.Commands) == 0 { + return multistep.ActionContinue + } + + ctx := config.ctx + ctx.Data = &postMountCommandsData{ + Device: device, + MountPath: mountPath, + } + + ui.Say("Running post-mount commands...") + if err := RunLocalCommands(s.Commands, wrappedCommand, ctx, ui); err != nil { + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + return multistep.ActionContinue +} + +func (s *StepPostMountCommands) Cleanup(state multistep.StateBag) {} From 07b158000375b32d0ffe888b513ffc413b374f59 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Thu, 28 Feb 2019 10:18:57 -0600 Subject: [PATCH 068/113] feature: add mount extra step in chroot builder --- builder/osc/chroot/builder.go | 1 + builder/osc/chroot/step_mount_extra.go | 137 +++++++++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 builder/osc/chroot/step_mount_extra.go diff --git a/builder/osc/chroot/builder.go b/builder/osc/chroot/builder.go index 272a8449e..b6c8e6258 100644 --- a/builder/osc/chroot/builder.go +++ b/builder/osc/chroot/builder.go @@ -259,6 +259,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &StepPostMountCommands{ Commands: b.config.PostMountCommands, }, + &StepMountExtra{}, ) // Run! diff --git a/builder/osc/chroot/step_mount_extra.go b/builder/osc/chroot/step_mount_extra.go new file mode 100644 index 000000000..ffd8ac027 --- /dev/null +++ b/builder/osc/chroot/step_mount_extra.go @@ -0,0 +1,137 @@ +package chroot + +import ( + "bytes" + "context" + "fmt" + "os" + "os/exec" + "syscall" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" +) + +// StepMountExtra mounts the attached device. +// +// Produces: +// mount_extra_cleanup CleanupFunc - To perform early cleanup +type StepMountExtra struct { + mounts []string +} + +func (s *StepMountExtra) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + config := state.Get("config").(*Config) + mountPath := state.Get("mount_path").(string) + ui := state.Get("ui").(packer.Ui) + wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) + + s.mounts = make([]string, 0, len(config.ChrootMounts)) + + ui.Say("Mounting additional paths within the chroot...") + for _, mountInfo := range config.ChrootMounts { + innerPath := mountPath + mountInfo[2] + + if err := os.MkdirAll(innerPath, 0755); err != nil { + err := fmt.Errorf("Error creating mount directory: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + flags := "-t " + mountInfo[0] + if mountInfo[0] == "bind" { + flags = "--bind" + } + + ui.Message(fmt.Sprintf("Mounting: %s", mountInfo[2])) + stderr := new(bytes.Buffer) + mountCommand, err := wrappedCommand(fmt.Sprintf( + "mount %s %s %s", + flags, + mountInfo[1], + innerPath)) + if err != nil { + err := fmt.Errorf("Error creating mount command: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + cmd := ShellCommand(mountCommand) + cmd.Stderr = stderr + if err := cmd.Run(); err != nil { + err := fmt.Errorf( + "Error mounting: %s\nStderr: %s", err, stderr.String()) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + s.mounts = append(s.mounts, innerPath) + } + + state.Put("mount_extra_cleanup", s) + return multistep.ActionContinue +} + +func (s *StepMountExtra) Cleanup(state multistep.StateBag) { + ui := state.Get("ui").(packer.Ui) + + if err := s.CleanupFunc(state); err != nil { + ui.Error(err.Error()) + return + } +} + +func (s *StepMountExtra) CleanupFunc(state multistep.StateBag) error { + if s.mounts == nil { + return nil + } + + wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) + for len(s.mounts) > 0 { + var path string + lastIndex := len(s.mounts) - 1 + path, s.mounts = s.mounts[lastIndex], s.mounts[:lastIndex] + + grepCommand, err := wrappedCommand(fmt.Sprintf("grep %s /proc/mounts", path)) + if err != nil { + return fmt.Errorf("Error creating grep command: %s", err) + } + + // Before attempting to unmount, + // check to see if path is already unmounted + stderr := new(bytes.Buffer) + cmd := ShellCommand(grepCommand) + cmd.Stderr = stderr + if err := cmd.Run(); err != nil { + if exitError, ok := err.(*exec.ExitError); ok { + if status, ok := exitError.Sys().(syscall.WaitStatus); ok { + exitStatus := status.ExitStatus() + if exitStatus == 1 { + // path has already been unmounted + // just skip this path + continue + } + } + } + } + + unmountCommand, err := wrappedCommand(fmt.Sprintf("umount %s", path)) + if err != nil { + return fmt.Errorf("Error creating unmount command: %s", err) + } + + stderr = new(bytes.Buffer) + cmd = ShellCommand(unmountCommand) + cmd.Stderr = stderr + if err := cmd.Run(); err != nil { + return fmt.Errorf( + "Error unmounting device: %s\nStderr: %s", err, stderr.String()) + } + } + + s.mounts = nil + return nil +} From 31367ff768ec0de2e02920bbe2e7d33fa3bfc830 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Thu, 28 Feb 2019 10:40:22 -0600 Subject: [PATCH 069/113] feature: add copy files step in chroot builder --- builder/osc/chroot/builder.go | 1 + builder/osc/chroot/step_copy_files.go | 91 +++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 builder/osc/chroot/step_copy_files.go diff --git a/builder/osc/chroot/builder.go b/builder/osc/chroot/builder.go index b6c8e6258..33bbf6872 100644 --- a/builder/osc/chroot/builder.go +++ b/builder/osc/chroot/builder.go @@ -260,6 +260,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Commands: b.config.PostMountCommands, }, &StepMountExtra{}, + &StepCopyFiles{}, ) // Run! diff --git a/builder/osc/chroot/step_copy_files.go b/builder/osc/chroot/step_copy_files.go new file mode 100644 index 000000000..a973a5d81 --- /dev/null +++ b/builder/osc/chroot/step_copy_files.go @@ -0,0 +1,91 @@ +package chroot + +import ( + "bytes" + "context" + "fmt" + "log" + "path/filepath" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" +) + +// StepCopyFiles copies some files from the host into the chroot environment. +// +// Produces: +// copy_files_cleanup CleanupFunc - A function to clean up the copied files +// early. +type StepCopyFiles struct { + files []string +} + +func (s *StepCopyFiles) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + config := state.Get("config").(*Config) + mountPath := state.Get("mount_path").(string) + ui := state.Get("ui").(packer.Ui) + wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) + stderr := new(bytes.Buffer) + + s.files = make([]string, 0, len(config.CopyFiles)) + if len(config.CopyFiles) > 0 { + ui.Say("Copying files from host to chroot...") + for _, path := range config.CopyFiles { + ui.Message(path) + chrootPath := filepath.Join(mountPath, path) + log.Printf("Copying '%s' to '%s'", path, chrootPath) + + cmdText, err := wrappedCommand(fmt.Sprintf("cp --remove-destination %s %s", path, chrootPath)) + if err != nil { + err := fmt.Errorf("Error building copy command: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + stderr.Reset() + cmd := ShellCommand(cmdText) + cmd.Stderr = stderr + if err := cmd.Run(); err != nil { + err := fmt.Errorf( + "Error copying file: %s\nnStderr: %s", err, stderr.String()) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + s.files = append(s.files, chrootPath) + } + } + + state.Put("copy_files_cleanup", s) + return multistep.ActionContinue +} + +func (s *StepCopyFiles) Cleanup(state multistep.StateBag) { + ui := state.Get("ui").(packer.Ui) + if err := s.CleanupFunc(state); err != nil { + ui.Error(err.Error()) + } +} + +func (s *StepCopyFiles) CleanupFunc(state multistep.StateBag) error { + wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) + if s.files != nil { + for _, file := range s.files { + log.Printf("Removing: %s", file) + localCmdText, err := wrappedCommand(fmt.Sprintf("rm -f %s", file)) + if err != nil { + return err + } + + localCmd := ShellCommand(localCmdText) + if err := localCmd.Run(); err != nil { + return err + } + } + } + + s.files = nil + return nil +} From 352972a33dd33017d4fce34828e2332616b2424c Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Thu, 28 Feb 2019 11:19:34 -0600 Subject: [PATCH 070/113] feature: add chroot provision step in chroot builder --- builder/osc/chroot/builder.go | 1 + builder/osc/chroot/communicator.go | 142 ++++++++++++++++++++ builder/osc/chroot/step_chroot_provision.go | 37 +++++ 3 files changed, 180 insertions(+) create mode 100644 builder/osc/chroot/communicator.go create mode 100644 builder/osc/chroot/step_chroot_provision.go diff --git a/builder/osc/chroot/builder.go b/builder/osc/chroot/builder.go index 33bbf6872..23ea5d64f 100644 --- a/builder/osc/chroot/builder.go +++ b/builder/osc/chroot/builder.go @@ -261,6 +261,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, &StepMountExtra{}, &StepCopyFiles{}, + &StepChrootProvision{}, ) // Run! diff --git a/builder/osc/chroot/communicator.go b/builder/osc/chroot/communicator.go new file mode 100644 index 000000000..5dd3d0719 --- /dev/null +++ b/builder/osc/chroot/communicator.go @@ -0,0 +1,142 @@ +package chroot + +import ( + "bytes" + "fmt" + "io" + "log" + "os" + "os/exec" + "path/filepath" + "strconv" + "strings" + "syscall" + + "github.com/hashicorp/packer/packer" + "github.com/hashicorp/packer/packer/tmp" +) + +// Communicator is a special communicator that works by executing +// commands locally but within a chroot. +type Communicator struct { + Chroot string + CmdWrapper CommandWrapper +} + +func (c *Communicator) Start(cmd *packer.RemoteCmd) error { + // need extra escapes for the command since we're wrapping it in quotes + cmd.Command = strconv.Quote(cmd.Command) + command, err := c.CmdWrapper( + fmt.Sprintf("chroot %s /bin/sh -c %s", c.Chroot, cmd.Command)) + if err != nil { + return err + } + + localCmd := ShellCommand(command) + localCmd.Stdin = cmd.Stdin + localCmd.Stdout = cmd.Stdout + localCmd.Stderr = cmd.Stderr + log.Printf("Executing: %s %#v", localCmd.Path, localCmd.Args) + if err := localCmd.Start(); err != nil { + return err + } + + go func() { + exitStatus := 0 + if err := localCmd.Wait(); err != nil { + if exitErr, ok := err.(*exec.ExitError); ok { + exitStatus = 1 + + // There is no process-independent way to get the REAL + // exit status so we just try to go deeper. + if status, ok := exitErr.Sys().(syscall.WaitStatus); ok { + exitStatus = status.ExitStatus() + } + } + } + + log.Printf( + "Chroot execution exited with '%d': '%s'", + exitStatus, cmd.Command) + cmd.SetExited(exitStatus) + }() + + return nil +} + +func (c *Communicator) Upload(dst string, r io.Reader, fi *os.FileInfo) error { + dst = filepath.Join(c.Chroot, dst) + log.Printf("Uploading to chroot dir: %s", dst) + tf, err := tmp.File("packer-amazon-chroot") + if err != nil { + return fmt.Errorf("Error preparing shell script: %s", err) + } + defer os.Remove(tf.Name()) + + if _, err := io.Copy(tf, r); err != nil { + return err + } + + cpCmd, err := c.CmdWrapper(fmt.Sprintf("cp %s %s", tf.Name(), dst)) + if err != nil { + return err + } + + return ShellCommand(cpCmd).Run() +} + +func (c *Communicator) UploadDir(dst string, src string, exclude []string) error { + // If src ends with a trailing "/", copy from "src/." so that + // directory contents (including hidden files) are copied, but the + // directory "src" is omitted. BSD does this automatically when + // the source contains a trailing slash, but linux does not. + if src[len(src)-1] == '/' { + src = src + "." + } + + // TODO: remove any file copied if it appears in `exclude` + chrootDest := filepath.Join(c.Chroot, dst) + + log.Printf("Uploading directory '%s' to '%s'", src, chrootDest) + cpCmd, err := c.CmdWrapper(fmt.Sprintf("cp -R '%s' %s", src, chrootDest)) + if err != nil { + return err + } + + var stderr bytes.Buffer + cmd := ShellCommand(cpCmd) + cmd.Env = append(cmd.Env, "LANG=C") + cmd.Env = append(cmd.Env, os.Environ()...) + cmd.Stderr = &stderr + err = cmd.Run() + if err == nil { + return err + } + + if strings.Contains(stderr.String(), "No such file") { + // This just means that the directory was empty. Just ignore it. + return nil + } + + return err +} + +func (c *Communicator) DownloadDir(src string, dst string, exclude []string) error { + return fmt.Errorf("DownloadDir is not implemented for amazon-chroot") +} + +func (c *Communicator) Download(src string, w io.Writer) error { + src = filepath.Join(c.Chroot, src) + log.Printf("Downloading from chroot dir: %s", src) + f, err := os.Open(src) + if err != nil { + return err + } + defer f.Close() + + if _, err := io.Copy(w, f); err != nil { + return err + } + + return nil +} diff --git a/builder/osc/chroot/step_chroot_provision.go b/builder/osc/chroot/step_chroot_provision.go new file mode 100644 index 000000000..be8667077 --- /dev/null +++ b/builder/osc/chroot/step_chroot_provision.go @@ -0,0 +1,37 @@ +package chroot + +import ( + "context" + "log" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" +) + +// StepChrootProvision provisions the instance within a chroot. +type StepChrootProvision struct { +} + +func (s *StepChrootProvision) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + hook := state.Get("hook").(packer.Hook) + mountPath := state.Get("mount_path").(string) + ui := state.Get("ui").(packer.Ui) + wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) + + // Create our communicator + comm := &Communicator{ + Chroot: mountPath, + CmdWrapper: wrappedCommand, + } + + // Provision + log.Println("Running the provision hook") + if err := hook.Run(packer.HookProvision, ui, comm, nil); err != nil { + state.Put("error", err) + return multistep.ActionHalt + } + + return multistep.ActionContinue +} + +func (s *StepChrootProvision) Cleanup(state multistep.StateBag) {} From 6843b64331da4bb4275f8e98d2231b4186925335 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Thu, 28 Feb 2019 15:42:04 -0600 Subject: [PATCH 071/113] feature: add eartly cleanup and snapshot steps in chroot builder --- builder/osc/chroot/builder.go | 2 + builder/osc/chroot/step_early_cleanup.go | 39 ++++++++++++ builder/osc/chroot/step_snapshot.go | 81 ++++++++++++++++++++++++ builder/osc/common/state.go | 37 +++++++++++ 4 files changed, 159 insertions(+) create mode 100644 builder/osc/chroot/step_early_cleanup.go create mode 100644 builder/osc/chroot/step_snapshot.go diff --git a/builder/osc/chroot/builder.go b/builder/osc/chroot/builder.go index 23ea5d64f..d4340ce44 100644 --- a/builder/osc/chroot/builder.go +++ b/builder/osc/chroot/builder.go @@ -262,6 +262,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &StepMountExtra{}, &StepCopyFiles{}, &StepChrootProvision{}, + &StepEarlyCleanup{}, + &StepSnapshot{}, ) // Run! diff --git a/builder/osc/chroot/step_early_cleanup.go b/builder/osc/chroot/step_early_cleanup.go new file mode 100644 index 000000000..34e7817df --- /dev/null +++ b/builder/osc/chroot/step_early_cleanup.go @@ -0,0 +1,39 @@ +package chroot + +import ( + "context" + "fmt" + "log" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" +) + +// StepEarlyCleanup performs some of the cleanup steps early in order to +// prepare for snapshotting and creating an AMI. +type StepEarlyCleanup struct{} + +func (s *StepEarlyCleanup) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + ui := state.Get("ui").(packer.Ui) + cleanupKeys := []string{ + "copy_files_cleanup", + "mount_extra_cleanup", + "mount_device_cleanup", + "attach_cleanup", + } + + for _, key := range cleanupKeys { + c := state.Get(key).(Cleanup) + log.Printf("Running cleanup func: %s", key) + if err := c.CleanupFunc(state); err != nil { + err := fmt.Errorf("Error cleaning up: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + + return multistep.ActionContinue +} + +func (s *StepEarlyCleanup) Cleanup(state multistep.StateBag) {} diff --git a/builder/osc/chroot/step_snapshot.go b/builder/osc/chroot/step_snapshot.go new file mode 100644 index 000000000..3df493728 --- /dev/null +++ b/builder/osc/chroot/step_snapshot.go @@ -0,0 +1,81 @@ +package chroot + +import ( + "context" + "fmt" + "time" + + osccommon "github.com/hashicorp/packer/builder/osc/common" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/outscale/osc-go/oapi" +) + +// StepSnapshot creates a snapshot of the created volume. +// +// Produces: +// snapshot_id string - ID of the created snapshot +type StepSnapshot struct { + snapshotId string +} + +func (s *StepSnapshot) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + oapiconn := state.Get("oapi").(*oapi.Client) + ui := state.Get("ui").(packer.Ui) + volumeId := state.Get("volume_id").(string) + + ui.Say("Creating snapshot...") + description := fmt.Sprintf("Packer: %s", time.Now().String()) + + createSnapResp, err := oapiconn.POST_CreateSnapshot(oapi.CreateSnapshotRequest{ + VolumeId: volumeId, + Description: description, + }) + if err != nil { + err := fmt.Errorf("Error creating snapshot: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + // Set the snapshot ID so we can delete it later + s.snapshotId = createSnapResp.OK.Snapshot.SnapshotId + ui.Message(fmt.Sprintf("Snapshot ID: %s", s.snapshotId)) + + // Wait for the snapshot to be ready + err = osccommon.WaitUntilSnapshotDone(oapiconn, s.snapshotId) + if err != nil { + err := fmt.Errorf("Error waiting for snapshot: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + state.Put("snapshot_id", s.snapshotId) + + snapshots := map[string][]string{ + oapiconn.GetConfig().Region: {s.snapshotId}, + } + state.Put("snapshots", snapshots) + + return multistep.ActionContinue +} + +func (s *StepSnapshot) Cleanup(state multistep.StateBag) { + if s.snapshotId == "" { + return + } + + _, cancelled := state.GetOk(multistep.StateCancelled) + _, halted := state.GetOk(multistep.StateHalted) + + if cancelled || halted { + oapiconn := state.Get("oapi").(*oapi.Client) + ui := state.Get("ui").(packer.Ui) + ui.Say("Removing snapshot since we cancelled or halted...") + _, err := oapiconn.POST_DeleteSnapshot(oapi.DeleteSnapshotRequest{SnapshotId: s.snapshotId}) + if err != nil { + ui.Error(fmt.Sprintf("Error: %s", err)) + } + } +} diff --git a/builder/osc/common/state.go b/builder/osc/common/state.go index b211f882a..2cc475123 100644 --- a/builder/osc/common/state.go +++ b/builder/osc/common/state.go @@ -66,6 +66,12 @@ func WaitUntilVolumeIsUnlinked(conn *oapi.Client, volumeID string) error { return <-errCh } +func WaitUntilSnapshotDone(conn *oapi.Client, snapshotID string) error { + errCh := make(chan error, 1) + go waitForState(errCh, "completed", waitUntilSnapshotDoneStateFunc(conn, snapshotID)) + return <-errCh +} + func waitForState(errCh chan<- error, target string, refresh stateRefreshFunc) error { err := common.Retry(2, 2, 0, func(_ uint) (bool, error) { state, err := refresh() @@ -254,6 +260,37 @@ func securityGroupWaitFunc(conn *oapi.Client, id string) stateRefreshFunc { } } +func waitUntilSnapshotDoneStateFunc(conn *oapi.Client, id string) stateRefreshFunc { + return func() (string, error) { + log.Printf("[Debug] Check if Snapshot with id %s exists", id) + resp, err := conn.POST_ReadSnapshots(oapi.ReadSnapshotsRequest{ + Filters: oapi.FiltersSnapshot{ + SnapshotIds: []string{id}, + }, + }) + + log.Printf("[Debug] Read Response %+v", resp.OK) + + if err != nil { + return "", err + } + + if resp.OK == nil { + return "", fmt.Errorf("Snapshot with ID %s. Not Found", id) + } + + if len(resp.OK.Snapshots) == 0 { + return "", fmt.Errorf("Snapshot with ID %s. Not Found", id) + } + + if resp.OK.Snapshots[0].State == "error" { + return resp.OK.Snapshots[0].State, fmt.Errorf("Snapshot (%s) creation is failed", id) + } + + return resp.OK.Snapshots[0].State, nil + } +} + func volumeWaitFunc(conn *oapi.Client, id string) stateRefreshFunc { return func() (string, error) { log.Printf("[Debug] Check if SvolumeG with id %s exists", id) From 70d2ff3d8a80df7507ee5cb07e9d2f6ae91bd289 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Mon, 4 Mar 2019 10:02:55 -0600 Subject: [PATCH 072/113] feature: add create omi step in chroot builder --- builder/osc/chroot/builder.go | 10 +++ builder/osc/chroot/step_create_omi.go | 112 ++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 builder/osc/chroot/step_create_omi.go diff --git a/builder/osc/chroot/builder.go b/builder/osc/chroot/builder.go index d4340ce44..2cf0e4ece 100644 --- a/builder/osc/chroot/builder.go +++ b/builder/osc/chroot/builder.go @@ -264,6 +264,16 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &StepChrootProvision{}, &StepEarlyCleanup{}, &StepSnapshot{}, + &osccommon.StepDeregisterOMI{ + AccessConfig: &b.config.AccessConfig, + ForceDeregister: b.config.OMIForceDeregister, + ForceDeleteSnapshot: b.config.OMIForceDeleteSnapshot, + OMIName: b.config.OMIName, + Regions: b.config.OMIRegions, + }, + &StepCreateOMI{ + RootVolumeSize: b.config.RootVolumeSize, + }, ) // Run! diff --git a/builder/osc/chroot/step_create_omi.go b/builder/osc/chroot/step_create_omi.go new file mode 100644 index 000000000..1dd69979c --- /dev/null +++ b/builder/osc/chroot/step_create_omi.go @@ -0,0 +1,112 @@ +package chroot + +import ( + "context" + "fmt" + + osccommon "github.com/hashicorp/packer/builder/osc/common" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/outscale/osc-go/oapi" +) + +// StepCreateOMI creates the OMI. +type StepCreateOMI struct { + RootVolumeSize int64 +} + +func (s *StepCreateOMI) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + config := state.Get("config").(*Config) + oapiconn := state.Get("oapi").(*oapi.Client) + snapshotId := state.Get("snapshot_id").(string) + ui := state.Get("ui").(packer.Ui) + + ui.Say("Creating the OMI...") + + var ( + registerOpts oapi.CreateImageRequest + mappings []oapi.BlockDeviceMappingImage + image oapi.Image + rootDeviceName string + ) + + if config.FromScratch { + mappings = config.OMIBlockDevices.BuildOMIDevices() + rootDeviceName = config.RootDeviceName + } else { + image = state.Get("source_image").(oapi.Image) + mappings = image.BlockDeviceMappings + rootDeviceName = image.RootDeviceName + } + + newMappings := make([]oapi.BlockDeviceMappingImage, len(mappings)) + for i, device := range mappings { + newDevice := device + + //FIX: Temporary fix + gibSize := newDevice.Bsu.VolumeSize / (1024 * 1024 * 1024) + newDevice.Bsu.VolumeSize = gibSize + + if newDevice.DeviceName == rootDeviceName { + if &newDevice.Bsu != nil { + newDevice.Bsu.SnapshotId = snapshotId + } else { + newDevice.Bsu = oapi.BsuToCreate{SnapshotId: snapshotId} + } + + if config.FromScratch || s.RootVolumeSize > newDevice.Bsu.VolumeSize { + newDevice.Bsu.VolumeSize = s.RootVolumeSize + } + } + + newMappings[i] = newDevice + } + + if config.FromScratch { + registerOpts = oapi.CreateImageRequest{ + ImageName: config.OMIName, + Architecture: "x86_64", + RootDeviceName: rootDeviceName, + BlockDeviceMappings: newMappings, + } + } else { + registerOpts = buildRegisterOpts(config, image, newMappings) + } + + registerResp, err := oapiconn.POST_CreateImage(registerOpts) + if err != nil { + state.Put("error", fmt.Errorf("Error registering OMI: %s", err)) + ui.Error(state.Get("error").(error).Error()) + return multistep.ActionHalt + } + + imageID := registerResp.OK.Image.ImageId + + // Set the OMI ID in the state + ui.Say(fmt.Sprintf("OMI: %s", imageID)) + omis := make(map[string]string) + omis[oapiconn.GetConfig().Region] = imageID + state.Put("omis", omis) + + ui.Say("Waiting for OMI to become ready...") + if err := osccommon.WaitUntilImageAvailable(oapiconn, imageID); err != nil { + err := fmt.Errorf("Error waiting for OMI: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + return multistep.ActionContinue +} + +func (s *StepCreateOMI) Cleanup(state multistep.StateBag) {} + +func buildRegisterOpts(config *Config, image oapi.Image, mappings []oapi.BlockDeviceMappingImage) oapi.CreateImageRequest { + registerOpts := oapi.CreateImageRequest{ + ImageName: config.OMIName, + Architecture: image.Architecture, + RootDeviceName: image.RootDeviceName, + BlockDeviceMappings: mappings, + } + return registerOpts +} From 9d6c4a8e5b9a6e9c3654eaaa90bb16bf6f51aced Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Tue, 5 Mar 2019 11:58:59 -0600 Subject: [PATCH 073/113] feature: add remaining steps and and create artifact in chroot builder --- builder/osc/chroot/builder.go | 24 +++++++++++++++++++- builder/osc/chroot/builder_acc_test.go | 12 ++++++++-- builder/osc/chroot/step_check_root_device.go | 8 +++---- builder/osc/common/step_create_tags.go | 4 ++-- 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/builder/osc/chroot/builder.go b/builder/osc/chroot/builder.go index 2cf0e4ece..f809ea219 100644 --- a/builder/osc/chroot/builder.go +++ b/builder/osc/chroot/builder.go @@ -274,6 +274,16 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &StepCreateOMI{ RootVolumeSize: b.config.RootVolumeSize, }, + &osccommon.StepUpdateOMIAttributes{ + AccountIds: b.config.OMIAccountIDs, + SnapshotAccountIds: b.config.SnapshotAccountIDs, + Ctx: b.config.ctx, + }, + &osccommon.StepCreateTags{ + Tags: b.config.OMITags, + SnapshotTags: b.config.SnapshotTags, + Ctx: b.config.ctx, + }, ) // Run! @@ -285,7 +295,19 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe return nil, rawErr.(error) } - return nil, nil + // If there are no OMIs, then just return + if _, ok := state.GetOk("omis"); !ok { + return nil, nil + } + + // Build the artifact and return it + artifact := &osccommon.Artifact{ + Omis: state.Get("omis").(map[string]string), + BuilderIdValue: BuilderId, + Config: clientConfig, + } + + return artifact, nil } func (b *Builder) Cancel() { diff --git a/builder/osc/chroot/builder_acc_test.go b/builder/osc/chroot/builder_acc_test.go index be28b3b76..df8256218 100644 --- a/builder/osc/chroot/builder_acc_test.go +++ b/builder/osc/chroot/builder_acc_test.go @@ -24,10 +24,18 @@ const testBuilderAccBasic = ` "type": "test", "region": "eu-west-2", "source_omi": "ami-99466096", - "omi_name": "packer-test {{timestamp}}", + "omi_name": "packer-test-{{timestamp}}", "omi_virtualization_type": "hvm", "device_path": "/dev/xvdf", "mount_partition": "0" - }] + }], + "provisioners": [ + { + "type": "shell", + "inline": [ + "echo Packer-test | tee /tmp/test.txt" + ] + } + ] } ` diff --git a/builder/osc/chroot/step_check_root_device.go b/builder/osc/chroot/step_check_root_device.go index e251a1ff5..da73cb5e0 100644 --- a/builder/osc/chroot/step_check_root_device.go +++ b/builder/osc/chroot/step_check_root_device.go @@ -9,18 +9,18 @@ import ( "github.com/outscale/osc-go/oapi" ) -// StepCheckRootDevice makes sure the root device on the AMI is EBS-backed. +// StepCheckRootDevice makes sure the root device on the OMI is BSU-backed. type StepCheckRootDevice struct{} func (s *StepCheckRootDevice) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { image := state.Get("source_image").(oapi.Image) ui := state.Get("ui").(packer.Ui) - ui.Say("Checking the root device on source AMI...") + ui.Say("Checking the root device on source OMI...") - // It must be EBS-backed otherwise the build won't work + // It must be BSU-backed otherwise the build won't work if image.RootDeviceType != "ebs" { - err := fmt.Errorf("The root device of the source AMI must be EBS-backed.") + err := fmt.Errorf("The root device of the source OMI must be BSU-backed.") state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt diff --git a/builder/osc/common/step_create_tags.go b/builder/osc/common/step_create_tags.go index e3cd317de..44bdcc78c 100644 --- a/builder/osc/common/step_create_tags.go +++ b/builder/osc/common/step_create_tags.go @@ -24,14 +24,14 @@ func (s *StepCreateTags) Run(_ context.Context, state multistep.StateBag) multis oapiconn := state.Get("oapi").(*oapi.Client) config := state.Get("clientConfig").(*oapi.Config) ui := state.Get("ui").(packer.Ui) - amis := state.Get("amis").(map[string]string) + omis := state.Get("omis").(map[string]string) if !s.Tags.IsSet() && !s.SnapshotTags.IsSet() { return multistep.ActionContinue } // Adds tags to OMIs and snapshots - for region, ami := range amis { + for region, ami := range omis { ui.Say(fmt.Sprintf("Adding tags to OMI (%s)...", ami)) newConfig := &oapi.Config{ From 987b4148e161c9e1313ec90ad2ae226fced5e122 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Tue, 5 Mar 2019 13:31:28 -0600 Subject: [PATCH 074/113] fix: remove pointer when gets vm from the state --- builder/osc/bsu/builder_acc_test.go | 4 ++-- builder/osc/bsu/step_create_omi.go | 2 +- builder/osc/common/step_cleanup_volumes.go | 6 +++--- builder/osc/common/step_stop_bsu_backed_vm.go | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/builder/osc/bsu/builder_acc_test.go b/builder/osc/bsu/builder_acc_test.go index 7a2de6611..f31f8c058 100644 --- a/builder/osc/bsu/builder_acc_test.go +++ b/builder/osc/bsu/builder_acc_test.go @@ -46,9 +46,9 @@ const testBuilderAccBasic = ` "builders": [{ "type": "test", "region": "eu-west-2", - "vm_type": "m3.medium", + "vm_type": "t2.micro", "source_omi": "ami-46260446", - "ssh_username": "ubuntu", + "ssh_username": "outscale", "omi_name": "packer-test {{timestamp}}" }] } diff --git a/builder/osc/bsu/step_create_omi.go b/builder/osc/bsu/step_create_omi.go index 8c6d73aa0..2ccd538e3 100644 --- a/builder/osc/bsu/step_create_omi.go +++ b/builder/osc/bsu/step_create_omi.go @@ -18,7 +18,7 @@ type stepCreateOMI struct { func (s *stepCreateOMI) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) oapiconn := state.Get("oapi").(*oapi.Client) - vm := state.Get("vm").(*oapi.Vm) + vm := state.Get("vm").(oapi.Vm) ui := state.Get("ui").(packer.Ui) // Create the image diff --git a/builder/osc/common/step_cleanup_volumes.go b/builder/osc/common/step_cleanup_volumes.go index e49afe91d..a65b1325d 100644 --- a/builder/osc/common/step_cleanup_volumes.go +++ b/builder/osc/common/step_cleanup_volumes.go @@ -25,12 +25,12 @@ func (s *StepCleanupVolumes) Run(_ context.Context, state multistep.StateBag) mu func (s *StepCleanupVolumes) Cleanup(state multistep.StateBag) { oapiconn := state.Get("oapi").(*oapi.Client) vmRaw := state.Get("vm") - var vm *oapi.Vm + var vm oapi.Vm if vmRaw != nil { - vm = vmRaw.(*oapi.Vm) + vm = vmRaw.(oapi.Vm) } ui := state.Get("ui").(packer.Ui) - if vm == nil { + if vm.VmId == "" { ui.Say("No volumes to clean up, skipping") return } diff --git a/builder/osc/common/step_stop_bsu_backed_vm.go b/builder/osc/common/step_stop_bsu_backed_vm.go index d3b987ac6..02076d35d 100644 --- a/builder/osc/common/step_stop_bsu_backed_vm.go +++ b/builder/osc/common/step_stop_bsu_backed_vm.go @@ -18,7 +18,7 @@ type StepStopBSUBackedVm struct { func (s *StepStopBSUBackedVm) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { oapiconn := state.Get("oapi").(*oapi.Client) - vm := state.Get("vm").(*oapi.Vm) + vm := state.Get("vm").(oapi.Vm) ui := state.Get("ui").(packer.Ui) // Skip when it is a spot vm From ff0336965ba5e8484be81e4e32bb362774767510 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Wed, 6 Mar 2019 14:03:56 -0600 Subject: [PATCH 075/113] feature: add create tags function --- builder/osc/common/tags.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/builder/osc/common/tags.go b/builder/osc/common/tags.go index 0f70bac4a..c42d48db7 100644 --- a/builder/osc/common/tags.go +++ b/builder/osc/common/tags.go @@ -43,3 +43,14 @@ func (t TagMap) OAPITags(ctx interpolate.Context, region string, state multistep } return oapiTags, nil } + +func CreateTags(conn *oapi.Client, resourceID string, ui packer.Ui, tags OAPITags) error { + tags.Report(ui) + + _, err := conn.POST_CreateTags(oapi.CreateTagsRequest{ + ResourceIds: []string{resourceID}, + Tags: tags, + }) + + return err +} From 8a6faf1ad31e6caf2b09ce3c7cae7e3fb3bf34a8 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Wed, 6 Mar 2019 14:04:25 -0600 Subject: [PATCH 076/113] feature: add create tags for vm and volume --- builder/osc/common/step_run_source_vm.go | 37 ++++++++++++++++++------ 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/builder/osc/common/step_run_source_vm.go b/builder/osc/common/step_run_source_vm.go index 38e175a0d..85e74e68c 100644 --- a/builder/osc/common/step_run_source_vm.go +++ b/builder/osc/common/step_run_source_vm.go @@ -98,13 +98,13 @@ func (s *StepRunSourceVm) Run(ctx context.Context, state multistep.StateBag) mul return multistep.ActionHalt } - // volTags, err := s.VolumeTags.OAPITags(s.Ctx, oapiconn.GetConfig().Region, state) - // if err != nil { - // err := fmt.Errorf("Error tagging volumes: %s", err) - // state.Put("error", err) - // ui.Error(err.Error()) - // return multistep.ActionHalt - // } + volTags, err := s.VolumeTags.OAPITags(s.Ctx, oapiconn.GetConfig().Region, state) + if err != nil { + err := fmt.Errorf("Error tagging volumes: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } subregion := state.Get("subregion_name").(string) runOpts := oapi.CreateVmsRequest{ @@ -125,7 +125,7 @@ func (s *StepRunSourceVm) Run(ctx context.Context, state multistep.StateBag) mul // } // Collect tags for tagging on resource creation - // var tagSpecs []oapi.ResourceTag + // var tagSpecs []oapi.ResourceTag // if len(oapiTags) > 0 { // runTags := &oapi.ResourceTag{ @@ -185,6 +185,7 @@ func (s *StepRunSourceVm) Run(ctx context.Context, state multistep.StateBag) mul return multistep.ActionHalt } vmId = runResp.OK.Vms[0].VmId + volumeId := runResp.OK.Vms[0].BlockDeviceMappings[0].Bsu.VolumeId // Set the vm ID so that the cleanup works properly s.vmId = vmId @@ -204,7 +205,25 @@ func (s *StepRunSourceVm) Run(ctx context.Context, state multistep.StateBag) mul return multistep.ActionHalt } - //TODO:Set Vm and Volume Tags, + //Set Vm tags and vollume tags + if len(oapiTags) > 0 { + if err := CreateTags(oapiconn, s.vmId, ui, oapiTags); err != nil { + err := fmt.Errorf("Error creating tags for vm (%s): %s", s.vmId, err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + + if len(volTags) > 0 { + if err := CreateTags(oapiconn, volumeId, ui, volTags); err != nil { + err := fmt.Errorf("Error creating tags for volume (%s): %s", volumeId, err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + //TODO: LinkPublicIp i resp, err := oapiconn.POST_ReadVms(request) From cf1fdfef00f2681d90e449cca20b874d9e6141fb Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Wed, 6 Mar 2019 14:05:03 -0600 Subject: [PATCH 077/113] fix: add missing keys when artifact is destroying --- builder/osc/common/artifact.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/builder/osc/common/artifact.go b/builder/osc/common/artifact.go index 6174ce4fa..3fe329891 100644 --- a/builder/osc/common/artifact.go +++ b/builder/osc/common/artifact.go @@ -71,12 +71,15 @@ func (a *Artifact) Destroy() error { newConfig := &oapi.Config{ UserAgent: a.Config.UserAgent, + AccessKey: a.Config.AccessKey, SecretKey: a.Config.SecretKey, Service: a.Config.Service, Region: region, //New region URL: a.Config.URL, } + log.Printf("[DEBUG] New Client config %+v", newConfig) + skipClient := &http.Client{ Transport: &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, From 571ef828e6c8515cd13ed1e9c0ea0330aae5c58c Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Wed, 6 Mar 2019 14:07:35 -0600 Subject: [PATCH 078/113] fix: remove pointer when vm is getting --- builder/osc/bsusurrogate/step_snapshop_volumes.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/osc/bsusurrogate/step_snapshop_volumes.go b/builder/osc/bsusurrogate/step_snapshop_volumes.go index 22f3c3f45..faf19b0a8 100644 --- a/builder/osc/bsusurrogate/step_snapshop_volumes.go +++ b/builder/osc/bsusurrogate/step_snapshop_volumes.go @@ -25,7 +25,7 @@ type StepSnapshotVolumes struct { func (s *StepSnapshotVolumes) snapshotVolume(ctx context.Context, deviceName string, state multistep.StateBag) error { oapiconn := state.Get("oapi").(*oapi.Client) ui := state.Get("ui").(packer.Ui) - vm := state.Get("vm").(*oapi.Vm) + vm := state.Get("vm").(oapi.Vm) var volumeId string for _, volume := range vm.BlockDeviceMappings { From 683431afa2ebd02dc178530dd503ca0e1f595458 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Wed, 6 Mar 2019 14:08:13 -0600 Subject: [PATCH 079/113] fix acceptance test configuration --- builder/osc/bsu/builder_acc_test.go | 14 ++++++-------- builder/osc/bsusurrogate/builder_acc_test.go | 16 +++++++++------- builder/osc/chroot/builder_acc_test.go | 12 ++---------- 3 files changed, 17 insertions(+), 25 deletions(-) diff --git a/builder/osc/bsu/builder_acc_test.go b/builder/osc/bsu/builder_acc_test.go index f31f8c058..2bce61683 100644 --- a/builder/osc/bsu/builder_acc_test.go +++ b/builder/osc/bsu/builder_acc_test.go @@ -1,7 +1,4 @@ -/* -Deregister the test image with -aws oapi deregister-image --image-id $(aws oapi describe-images --output text --filters "Name=name,Values=packer-test-packer-test-dereg" --query 'Images[*].{ID:ImageId}') -*/ +//TODO: explain how to delete the image. package bsu import ( @@ -16,9 +13,10 @@ import ( func TestBuilderAcc_basic(t *testing.T) { builderT.Test(t, builderT.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Builder: &Builder{}, - Template: testBuilderAccBasic, + PreCheck: func() { testAccPreCheck(t) }, + Builder: &Builder{}, + Template: testBuilderAccBasic, + SkipArtifactTeardown: true, }) } @@ -47,7 +45,7 @@ const testBuilderAccBasic = ` "type": "test", "region": "eu-west-2", "vm_type": "t2.micro", - "source_omi": "ami-46260446", + "source_omi": "ami-65efcc11", "ssh_username": "outscale", "omi_name": "packer-test {{timestamp}}" }] diff --git a/builder/osc/bsusurrogate/builder_acc_test.go b/builder/osc/bsusurrogate/builder_acc_test.go index 04b397f2a..0923d4865 100644 --- a/builder/osc/bsusurrogate/builder_acc_test.go +++ b/builder/osc/bsusurrogate/builder_acc_test.go @@ -12,9 +12,10 @@ import ( func TestBuilderAcc_basic(t *testing.T) { builderT.Test(t, builderT.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Builder: &Builder{}, - Template: testBuilderAccBasic, + PreCheck: func() { testAccPreCheck(t) }, + Builder: &Builder{}, + Template: testBuilderAccBasic, + SkipArtifactTeardown: true, }) } @@ -26,9 +27,9 @@ const testBuilderAccBasic = ` "builders": [{ "type": "test", "region": "eu-west-2", - "vm_type": "c4.large", - "source_omi": "ami-46260446", - "ssh_username": "ubuntu", + "vm_type": "t2.micro", + "source_omi": "ami-65efcc11", + "ssh_username": "outscale", "omi_name": "packer-test {{timestamp}}", "omi_virtualization_type": "hvm", "subregion_name": "eu-west-2a", @@ -38,7 +39,8 @@ const testBuilderAccBasic = ` "device_name" : "/dev/xvdf", "delete_on_vm_deletion" : false, "volume_size" : 10, - "iops": 300 + "iops": 300, + "no_device": 0 } ], "omi_root_device":{ diff --git a/builder/osc/chroot/builder_acc_test.go b/builder/osc/chroot/builder_acc_test.go index df8256218..cb2fdd108 100644 --- a/builder/osc/chroot/builder_acc_test.go +++ b/builder/osc/chroot/builder_acc_test.go @@ -23,19 +23,11 @@ const testBuilderAccBasic = ` "builders": [{ "type": "test", "region": "eu-west-2", - "source_omi": "ami-99466096", + "source_omi": "ami-65efcc11", "omi_name": "packer-test-{{timestamp}}", "omi_virtualization_type": "hvm", "device_path": "/dev/xvdf", "mount_partition": "0" - }], - "provisioners": [ - { - "type": "shell", - "inline": [ - "echo Packer-test | tee /tmp/test.txt" - ] - } - ] + }] } ` From db2832d80c83b39d35369be780a06f4670ffd0b2 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Wed, 6 Mar 2019 14:52:16 -0600 Subject: [PATCH 080/113] fix: change name of dirs --- builder/osc/chroot/communicator.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/osc/chroot/communicator.go b/builder/osc/chroot/communicator.go index 5dd3d0719..6efb6cb25 100644 --- a/builder/osc/chroot/communicator.go +++ b/builder/osc/chroot/communicator.go @@ -67,7 +67,7 @@ func (c *Communicator) Start(cmd *packer.RemoteCmd) error { func (c *Communicator) Upload(dst string, r io.Reader, fi *os.FileInfo) error { dst = filepath.Join(c.Chroot, dst) log.Printf("Uploading to chroot dir: %s", dst) - tf, err := tmp.File("packer-amazon-chroot") + tf, err := tmp.File("packer-outscale-chroot") if err != nil { return fmt.Errorf("Error preparing shell script: %s", err) } @@ -122,7 +122,7 @@ func (c *Communicator) UploadDir(dst string, src string, exclude []string) error } func (c *Communicator) DownloadDir(src string, dst string, exclude []string) error { - return fmt.Errorf("DownloadDir is not implemented for amazon-chroot") + return fmt.Errorf("DownloadDir is not implemented for outscale-chroot") } func (c *Communicator) Download(src string, w io.Writer) error { From 8b8eb70e192fe3984d872b25f17656be86bb95b2 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Wed, 6 Mar 2019 14:54:23 -0600 Subject: [PATCH 081/113] feature: add create tags to volume --- builder/osc/chroot/step_create_volume.go | 32 ++++++------------------ 1 file changed, 7 insertions(+), 25 deletions(-) diff --git a/builder/osc/chroot/step_create_volume.go b/builder/osc/chroot/step_create_volume.go index 57ce2c43a..6944ceef9 100644 --- a/builder/osc/chroot/step_create_volume.go +++ b/builder/osc/chroot/step_create_volume.go @@ -34,26 +34,7 @@ func (s *StepCreateVolume) Run(ctx context.Context, state multistep.StateBag) mu var err error - //TODO: Add tags - // volTags, err := s.RootVolumeTags.OAPITags(s.Ctx, oapiconn.GetConfig().Region, state) - // if err != nil { - // err := fmt.Errorf("Error tagging volumes: %s", err) - // state.Put("error", err) - // ui.Error(err.Error()) - // return multistep.ActionHalt - // } - - // // Collect tags for tagging on resource creation - // var tagSpecs []oapi.ResourceTag - - // if len(volTags) > 0 { - // runVolTags := &oapi.Resou rceTag{ - // ResourceType: "volume", - // Tags: volTags, - // } - - // tagSpecs = append(tagSpecs, runVolTags) - // } + volTags, err := s.RootVolumeTags.OAPITags(s.Ctx, oapiconn.GetConfig().Region, state) var createVolume *oapi.CreateVolumeRequest if config.FromScratch { @@ -92,11 +73,7 @@ func (s *StepCreateVolume) Run(ctx context.Context, state multistep.StateBag) mu return multistep.ActionHalt } } - //TODO: ADD TAGS - // if len(tagSpecs) > 0 { - // createVolume.SetTagSpecifications(tagSpecs) - // volTags.Report(ui) - // } + log.Printf("Create args: %+v", createVolume) createVolumeResp, err := oapiconn.POST_CreateVolume(*createVolume) @@ -111,6 +88,11 @@ func (s *StepCreateVolume) Run(ctx context.Context, state multistep.StateBag) mu s.volumeId = createVolumeResp.OK.Volume.VolumeId log.Printf("Volume ID: %s", s.volumeId) + //Create tags for volume + if len(volTags) > 0 { + osccommon.CreateTags(oapiconn, s.volumeId, ui, volTags) + } + // Wait for the volume to become ready err = osccommon.WaitUntilVolumeAvailable(oapiconn, s.volumeId) if err != nil { From c9b8bc6b5412b0a3ad08556e2a6fa655bb53efb7 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Wed, 6 Mar 2019 16:31:28 -0600 Subject: [PATCH 082/113] fix: typo in bsusurrogate acc test --- builder/osc/bsusurrogate/builder_acc_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/builder/osc/bsusurrogate/builder_acc_test.go b/builder/osc/bsusurrogate/builder_acc_test.go index 0923d4865..37fe057f4 100644 --- a/builder/osc/bsusurrogate/builder_acc_test.go +++ b/builder/osc/bsusurrogate/builder_acc_test.go @@ -39,8 +39,7 @@ const testBuilderAccBasic = ` "device_name" : "/dev/xvdf", "delete_on_vm_deletion" : false, "volume_size" : 10, - "iops": 300, - "no_device": 0 + "iops": 300 } ], "omi_root_device":{ From 80dadaf3f156af775cb406027379627c6c8afed7 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Thu, 7 Mar 2019 11:10:16 -0600 Subject: [PATCH 083/113] feature: add bsuvolume builder and acceptance test --- builder/osc/bsuvolume/artifact.go | 87 ++++++++ builder/osc/bsuvolume/block_device.go | 29 +++ builder/osc/bsuvolume/builder.go | 204 ++++++++++++++++++ builder/osc/bsuvolume/builder_acc_test.go | 86 ++++++++ builder/osc/bsuvolume/builder_test.go | 92 ++++++++ builder/osc/bsuvolume/step_tag_bsu_volumes.go | 81 +++++++ builder/osc/common/block_device.go | 12 +- command/plugin.go | 2 + 8 files changed, 588 insertions(+), 5 deletions(-) create mode 100644 builder/osc/bsuvolume/artifact.go create mode 100644 builder/osc/bsuvolume/block_device.go create mode 100644 builder/osc/bsuvolume/builder.go create mode 100644 builder/osc/bsuvolume/builder_acc_test.go create mode 100644 builder/osc/bsuvolume/builder_test.go create mode 100644 builder/osc/bsuvolume/step_tag_bsu_volumes.go diff --git a/builder/osc/bsuvolume/artifact.go b/builder/osc/bsuvolume/artifact.go new file mode 100644 index 000000000..61d92b6a2 --- /dev/null +++ b/builder/osc/bsuvolume/artifact.go @@ -0,0 +1,87 @@ +package bsuvolume + +import ( + "fmt" + "log" + "sort" + "strings" + + "github.com/hashicorp/packer/packer" + "github.com/outscale/osc-go/oapi" +) + +// map of region to list of volume IDs +type BsuVolumes map[string][]string + +// Artifact is an artifact implementation that contains built AMIs. +type Artifact struct { + // A map of regions to EBS Volume IDs. + Volumes BsuVolumes + + // BuilderId is the unique ID for the builder that created this AMI + BuilderIdValue string + + // Client connection for performing API stuff. + Conn *oapi.Client +} + +func (a *Artifact) BuilderId() string { + return a.BuilderIdValue +} + +func (*Artifact) Files() []string { + // We have no files + return nil +} + +// returns a sorted list of region:ID pairs +func (a *Artifact) idList() []string { + parts := make([]string, 0, len(a.Volumes)) + for region, volumeIDs := range a.Volumes { + for _, volumeID := range volumeIDs { + parts = append(parts, fmt.Sprintf("%s:%s", region, volumeID)) + } + } + + sort.Strings(parts) + return parts +} + +func (a *Artifact) Id() string { + return strings.Join(a.idList(), ",") +} + +func (a *Artifact) String() string { + return fmt.Sprintf("EBS Volumes were created:\n\n%s", strings.Join(a.idList(), "\n")) +} + +func (a *Artifact) State(name string) interface{} { + return nil +} + +func (a *Artifact) Destroy() error { + errors := make([]error, 0) + + for region, volumeIDs := range a.Volumes { + for _, volumeID := range volumeIDs { + log.Printf("Deregistering Volume ID (%s) from region (%s)", volumeID, region) + + input := oapi.DeleteVolumeRequest{ + VolumeId: volumeID, + } + if _, err := a.Conn.POST_DeleteVolume(input); err != nil { + errors = append(errors, err) + } + } + } + + if len(errors) > 0 { + if len(errors) == 1 { + return errors[0] + } else { + return &packer.MultiError{Errors: errors} + } + } + + return nil +} diff --git a/builder/osc/bsuvolume/block_device.go b/builder/osc/bsuvolume/block_device.go new file mode 100644 index 000000000..3217fef7f --- /dev/null +++ b/builder/osc/bsuvolume/block_device.go @@ -0,0 +1,29 @@ +package bsuvolume + +import ( + osccommon "github.com/hashicorp/packer/builder/osc/common" + "github.com/hashicorp/packer/template/interpolate" +) + +type BlockDevice struct { + osccommon.BlockDevice `mapstructure:"-,squash"` + Tags osccommon.TagMap `mapstructure:"tags"` +} + +func commonBlockDevices(mappings []BlockDevice, ctx *interpolate.Context) (osccommon.BlockDevices, error) { + result := make([]osccommon.BlockDevice, len(mappings)) + + for i, mapping := range mappings { + interpolateBlockDev, err := interpolate.RenderInterface(&mapping.BlockDevice, ctx) + if err != nil { + return osccommon.BlockDevices{}, err + } + result[i] = *interpolateBlockDev.(*osccommon.BlockDevice) + } + + return osccommon.BlockDevices{ + LaunchBlockDevices: osccommon.LaunchBlockDevices{ + LaunchMappings: result, + }, + }, nil +} diff --git a/builder/osc/bsuvolume/builder.go b/builder/osc/bsuvolume/builder.go new file mode 100644 index 000000000..363e50faf --- /dev/null +++ b/builder/osc/bsuvolume/builder.go @@ -0,0 +1,204 @@ +// The ebsvolume package contains a packer.Builder implementation that +// builds EBS volumes for Outscale using an ephemeral instance, +package bsuvolume + +import ( + "crypto/tls" + "fmt" + "log" + "net/http" + + osccommon "github.com/hashicorp/packer/builder/osc/common" + "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" + "github.com/outscale/osc-go/oapi" +) + +const BuilderId = "oapi.outscale.bsuvolume" + +type Config struct { + common.PackerConfig `mapstructure:",squash"` + osccommon.AccessConfig `mapstructure:",squash"` + osccommon.RunConfig `mapstructure:",squash"` + + VolumeMappings []BlockDevice `mapstructure:"ebs_volumes"` + + launchBlockDevices osccommon.BlockDevices + ctx interpolate.Context +} + +type Builder struct { + config Config + runner multistep.Runner +} + +type EngineVarsTemplate struct { + BuildRegion string + SourceOMI string +} + +func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { + b.config.ctx.Funcs = osccommon.TemplateFuncs + // Create passthrough for {{ .BuildRegion }} and {{ .SourceOMI }} variables + // so we can fill them in later + b.config.ctx.Data = &EngineVarsTemplate{ + BuildRegion: `{{ .BuildRegion }}`, + SourceOMI: `{{ .SourceOMI }} `, + } + err := config.Decode(&b.config, &config.DecodeOpts{ + Interpolate: true, + InterpolateContext: &b.config.ctx, + }, raws...) + if err != nil { + return nil, err + } + + // Accumulate any errors + var errs *packer.MultiError + errs = packer.MultiErrorAppend(errs, b.config.AccessConfig.Prepare(&b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare(&b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, b.config.launchBlockDevices.Prepare(&b.config.ctx)...) + + for _, d := range b.config.VolumeMappings { + if err := d.Prepare(&b.config.ctx); err != nil { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("OMIMapping: %s", err.Error())) + } + } + + b.config.launchBlockDevices, err = commonBlockDevices(b.config.VolumeMappings, &b.config.ctx) + if err != nil { + errs = packer.MultiErrorAppend(errs, err) + } + + if errs != nil && len(errs.Errors) > 0 { + return nil, errs + } + + packer.LogSecretFilter.Set(b.config.AccessKey, b.config.SecretKey, b.config.Token) + return nil, nil +} + +func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { + clientConfig, err := b.config.Config() + if err != nil { + return nil, err + } + + skipClient := &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }, + } + + oapiconn := oapi.NewClient(clientConfig, skipClient) + + // Setup the state bag and initial state for the steps + state := new(multistep.BasicStateBag) + state.Put("config", &b.config) + state.Put("oapi", oapiconn) + state.Put("hook", hook) + state.Put("ui", ui) + + log.Printf("[DEBUG] launch block devices %#v", b.config.launchBlockDevices) + + instanceStep := &osccommon.StepRunSourceVm{ + AssociatePublicIpAddress: b.config.AssociatePublicIpAddress, + BlockDevices: b.config.launchBlockDevices, + Comm: &b.config.RunConfig.Comm, + Ctx: b.config.ctx, + Debug: b.config.PackerDebug, + BsuOptimized: b.config.BsuOptimized, + EnableT2Unlimited: b.config.EnableT2Unlimited, + ExpectedRootDevice: "ebs", + IamVmProfile: b.config.IamVmProfile, + VmInitiatedShutdownBehavior: b.config.VmInitiatedShutdownBehavior, + VmType: b.config.VmType, + SourceOMI: b.config.SourceOmi, + Tags: b.config.RunTags, + UserData: b.config.UserData, + UserDataFile: b.config.UserDataFile, + } + + // Build the steps + steps := []multistep.Step{ + &osccommon.StepSourceOMIInfo{ + SourceOmi: b.config.SourceOmi, + OmiFilters: b.config.SourceOmiFilter, + }, + &osccommon.StepNetworkInfo{ + NetId: b.config.NetId, + NetFilter: b.config.NetFilter, + SecurityGroupIds: b.config.SecurityGroupIds, + SecurityGroupFilter: b.config.SecurityGroupFilter, + SubnetId: b.config.SubnetId, + SubnetFilter: b.config.SubnetFilter, + SubregionName: b.config.Subregion, + }, + &osccommon.StepKeyPair{ + Debug: b.config.PackerDebug, + Comm: &b.config.RunConfig.Comm, + DebugKeyPath: fmt.Sprintf("oapi_%s.pem", b.config.PackerBuildName), + }, + &osccommon.StepSecurityGroup{ + SecurityGroupFilter: b.config.SecurityGroupFilter, + SecurityGroupIds: b.config.SecurityGroupIds, + CommConfig: &b.config.RunConfig.Comm, + TemporarySGSourceCidr: b.config.TemporarySGSourceCidr, + }, + instanceStep, + &stepTagBSUVolumes{ + VolumeMapping: b.config.VolumeMappings, + Ctx: b.config.ctx, + }, + &osccommon.StepGetPassword{ + Debug: b.config.PackerDebug, + Comm: &b.config.RunConfig.Comm, + Timeout: b.config.WindowsPasswordTimeout, + BuildName: b.config.PackerBuildName, + }, + &communicator.StepConnect{ + Config: &b.config.RunConfig.Comm, + Host: osccommon.SSHHost( + oapiconn, + b.config.Comm.SSHInterface), + SSHConfig: b.config.RunConfig.Comm.SSHConfigFunc(), + }, + &common.StepProvision{}, + &common.StepCleanupTempKeys{ + Comm: &b.config.RunConfig.Comm, + }, + &osccommon.StepStopBSUBackedVm{ + Skip: b.config.IsSpotVm(), + DisableStopVm: b.config.DisableStopVm, + }, + } + + // Run! + b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) + b.runner.Run(state) + + // If there was an error, return that + if rawErr, ok := state.GetOk("error"); ok { + return nil, rawErr.(error) + } + + // Build the artifact and return it + artifact := &Artifact{ + Volumes: state.Get("bsuvolumes").(BsuVolumes), + BuilderIdValue: BuilderId, + Conn: oapiconn, + } + ui.Say(fmt.Sprintf("Created Volumes: %s", artifact)) + return artifact, nil +} + +func (b *Builder) Cancel() { + if b.runner != nil { + log.Println("Cancelling the step runner...") + b.runner.Cancel() + } +} diff --git a/builder/osc/bsuvolume/builder_acc_test.go b/builder/osc/bsuvolume/builder_acc_test.go new file mode 100644 index 000000000..ef4e46cde --- /dev/null +++ b/builder/osc/bsuvolume/builder_acc_test.go @@ -0,0 +1,86 @@ +//TODO: explain how to delete the image. +package bsuvolume + +import ( + "crypto/tls" + "net/http" + "testing" + + "github.com/hashicorp/packer/builder/osc/common" + builderT "github.com/hashicorp/packer/helper/builder/testing" + "github.com/outscale/osc-go/oapi" +) + +func TestBuilderAcc_basic(t *testing.T) { + builderT.Test(t, builderT.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Builder: &Builder{}, + Template: testBuilderAccBasic, + SkipArtifactTeardown: true, + }) +} + +func testAccPreCheck(t *testing.T) { +} + +func testOAPIConn() (*oapi.Client, error) { + access := &common.AccessConfig{RawRegion: "us-east-1"} + clientConfig, err := access.Config() + if err != nil { + return nil, err + } + + skipClient := &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }, + } + + return oapi.NewClient(clientConfig, skipClient), nil +} + +const testBuilderAccBasic = ` +{ + "builders": [ + { + "type": "test", + "region": "eu-west-2", + "vm_type": "t2.micro", + "source_omi": "ami-65efcc11", + "ssh_username": "outscale", + "ebs_volumes": [ + { + "volume_type": "gp2", + "device_name": "/dev/xvdf", + "delete_on_vm_deletion": false, + "tags": { + "zpool": "data", + "Name": "Data1" + }, + "volume_size": 10 + }, + { + "volume_type": "gp2", + "device_name": "/dev/xvdg", + "tags": { + "zpool": "data", + "Name": "Data2" + }, + "delete_on_vm_deletion": false, + "volume_size": 10 + }, + { + "volume_size": 10, + "tags": { + "Name": "Data3", + "zpool": "data" + }, + "delete_on_vm_deletion": false, + "device_name": "/dev/xvdh", + "volume_type": "gp2" + } + ] + } + ] +} +` diff --git a/builder/osc/bsuvolume/builder_test.go b/builder/osc/bsuvolume/builder_test.go new file mode 100644 index 000000000..956fba60f --- /dev/null +++ b/builder/osc/bsuvolume/builder_test.go @@ -0,0 +1,92 @@ +package bsuvolume + +import ( + "testing" + + "github.com/hashicorp/packer/packer" +) + +func testConfig() map[string]interface{} { + return map[string]interface{}{ + "access_key": "foo", + "secret_key": "bar", + "source_omi": "foo", + "vm_type": "foo", + "region": "us-east-1", + "ssh_username": "root", + } +} + +func TestBuilder_ImplementsBuilder(t *testing.T) { + var raw interface{} + raw = &Builder{} + if _, ok := raw.(packer.Builder); !ok { + t.Fatalf("Builder should be a builder") + } +} + +func TestBuilder_Prepare_BadType(t *testing.T) { + b := &Builder{} + c := map[string]interface{}{ + "access_key": []string{}, + } + + warnings, err := b.Prepare(c) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err == nil { + t.Fatalf("prepare should fail") + } +} + +func TestBuilderPrepare_InvalidKey(t *testing.T) { + var b Builder + config := testConfig() + + // Add a random key + config["i_should_not_be_valid"] = true + warnings, err := b.Prepare(config) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err == nil { + t.Fatal("should have error") + } +} + +func TestBuilderPrepare_InvalidShutdownBehavior(t *testing.T) { + var b Builder + config := testConfig() + + // Test good + config["shutdown_behavior"] = "terminate" + config["skip_region_validation"] = true + warnings, err := b.Prepare(config) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + // Test good + config["shutdown_behavior"] = "stop" + warnings, err = b.Prepare(config) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + // Test bad + config["shutdown_behavior"] = "foobar" + warnings, err = b.Prepare(config) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err == nil { + t.Fatal("should have error") + } +} diff --git a/builder/osc/bsuvolume/step_tag_bsu_volumes.go b/builder/osc/bsuvolume/step_tag_bsu_volumes.go new file mode 100644 index 000000000..c02f77112 --- /dev/null +++ b/builder/osc/bsuvolume/step_tag_bsu_volumes.go @@ -0,0 +1,81 @@ +package bsuvolume + +import ( + "context" + "fmt" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" + "github.com/hashicorp/packer/template/interpolate" + "github.com/outscale/osc-go/oapi" +) + +type stepTagBSUVolumes struct { + VolumeMapping []BlockDevice + Ctx interpolate.Context +} + +func (s *stepTagBSUVolumes) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + oapiconn := state.Get("oapi").(*oapi.Client) + vm := state.Get("vm").(oapi.Vm) + ui := state.Get("ui").(packer.Ui) + + volumes := make(BsuVolumes) + for _, instanceBlockDevices := range vm.BlockDeviceMappings { + for _, configVolumeMapping := range s.VolumeMapping { + if configVolumeMapping.DeviceName == instanceBlockDevices.DeviceName { + volumes[oapiconn.GetConfig().Region] = append( + volumes[oapiconn.GetConfig().Region], + instanceBlockDevices.Bsu.VolumeId) + } + } + } + state.Put("bsuvolumes", volumes) + + if len(s.VolumeMapping) > 0 { + ui.Say("Tagging BSU volumes...") + + toTag := map[string][]oapi.ResourceTag{} + for _, mapping := range s.VolumeMapping { + if len(mapping.Tags) == 0 { + ui.Say(fmt.Sprintf("No tags specified for volume on %s...", mapping.DeviceName)) + continue + } + + tags, err := mapping.Tags.OAPITags(s.Ctx, oapiconn.GetConfig().Region, state) + if err != nil { + err := fmt.Errorf("Error tagging device %s with %s", mapping.DeviceName, err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + tags.Report(ui) + + for _, v := range vm.BlockDeviceMappings { + if v.DeviceName == mapping.DeviceName { + toTag[v.Bsu.VolumeId] = tags + } + } + } + + for volumeId, tags := range toTag { + _, err := oapiconn.POST_CreateTags(oapi.CreateTagsRequest{ + ResourceIds: []string{volumeId}, + Tags: tags, + }) + if err != nil { + err := fmt.Errorf("Error tagging BSU Volume %s on %s: %s", volumeId, vm.VmId, err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + } + } + + return multistep.ActionContinue +} + +func (s *stepTagBSUVolumes) Cleanup(state multistep.StateBag) { + // No cleanup... +} diff --git a/builder/osc/common/block_device.go b/builder/osc/common/block_device.go index 420d112da..24da540ce 100644 --- a/builder/osc/common/block_device.go +++ b/builder/osc/common/block_device.go @@ -2,6 +2,7 @@ package common import ( "fmt" + "log" "strings" "github.com/hashicorp/packer/template/interpolate" @@ -50,9 +51,8 @@ func buildBlockDevices(b []BlockDevice) []*oapi.BlockDeviceMapping { mapping.VirtualDeviceName = blockDevice.VirtualName } } else { - bsu := oapi.Bsu{ - DeleteOnVmDeletion: blockDevice.DeleteOnVmDeletion, - } + bsu := oapi.Bsu{} + bsu.DeleteOnVmDeletion = &blockDevice.DeleteOnVmDeletion if blockDevice.VolumeType != "" { bsu.VolumeType = blockDevice.VolumeType @@ -97,7 +97,7 @@ func buildBlockDevicesImage(b []BlockDevice) []oapi.BlockDeviceMappingImage { } } else { bsu := oapi.BsuToCreate{ - DeleteOnVmDeletion: blockDevice.DeleteOnVmDeletion, + DeleteOnVmDeletion: &blockDevice.DeleteOnVmDeletion, } if blockDevice.VolumeType != "" { @@ -126,6 +126,8 @@ func buildBlockDevicesImage(b []BlockDevice) []oapi.BlockDeviceMappingImage { } func buildBlockDevicesVmCreation(b []BlockDevice) []oapi.BlockDeviceMappingVmCreation { + log.Printf("[DEBUG] Launch Block Device %#v", b) + var blockDevices []oapi.BlockDeviceMappingVmCreation for _, blockDevice := range b { @@ -141,7 +143,7 @@ func buildBlockDevicesVmCreation(b []BlockDevice) []oapi.BlockDeviceMappingVmCre } } else { bsu := oapi.BsuToCreate{ - DeleteOnVmDeletion: blockDevice.DeleteOnVmDeletion, + DeleteOnVmDeletion: &blockDevice.DeleteOnVmDeletion, } if blockDevice.VolumeType != "" { diff --git a/command/plugin.go b/command/plugin.go index cfe9c417d..9ebd2a046 100644 --- a/command/plugin.go +++ b/command/plugin.go @@ -40,6 +40,7 @@ import ( oracleocibuilder "github.com/hashicorp/packer/builder/oracle/oci" oscbsubuilder "github.com/hashicorp/packer/builder/osc/bsu" oscbsusurrogatebuilder "github.com/hashicorp/packer/builder/osc/bsusurrogate" + oscbsuvolumebuilder "github.com/hashicorp/packer/builder/osc/bsuvolume" oscchrootbuilder "github.com/hashicorp/packer/builder/osc/chroot" parallelsisobuilder "github.com/hashicorp/packer/builder/parallels/iso" parallelspvmbuilder "github.com/hashicorp/packer/builder/parallels/pvm" @@ -126,6 +127,7 @@ var Builders = map[string]packer.Builder{ "oracle-oci": new(oracleocibuilder.Builder), "osc-bsu": new(oscbsubuilder.Builder), "osc-bsusurrogate": new(oscbsusurrogatebuilder.Builder), + "osc-bsuvolume": new(oscbsuvolumebuilder.Builder), "osc-chroot": new(oscchrootbuilder.Builder), "parallels-iso": new(parallelsisobuilder.Builder), "parallels-pvm": new(parallelspvmbuilder.Builder), From 27528aeb686913ab1254ce6a1a462eb0afe701cf Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Thu, 7 Mar 2019 12:33:48 -0600 Subject: [PATCH 084/113] test: fix test error in block_device --- builder/osc/common/block_device.go | 7 ++-- builder/osc/common/block_device_test.go | 47 +++++++++++++------------ 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/builder/osc/common/block_device.go b/builder/osc/common/block_device.go index 24da540ce..3f6abdd85 100644 --- a/builder/osc/common/block_device.go +++ b/builder/osc/common/block_device.go @@ -5,6 +5,7 @@ import ( "log" "strings" + "github.com/aws/aws-sdk-go/aws" "github.com/hashicorp/packer/template/interpolate" "github.com/outscale/osc-go/oapi" ) @@ -52,7 +53,7 @@ func buildBlockDevices(b []BlockDevice) []*oapi.BlockDeviceMapping { } } else { bsu := oapi.Bsu{} - bsu.DeleteOnVmDeletion = &blockDevice.DeleteOnVmDeletion + bsu.DeleteOnVmDeletion = aws.Bool(blockDevice.DeleteOnVmDeletion) if blockDevice.VolumeType != "" { bsu.VolumeType = blockDevice.VolumeType @@ -97,7 +98,7 @@ func buildBlockDevicesImage(b []BlockDevice) []oapi.BlockDeviceMappingImage { } } else { bsu := oapi.BsuToCreate{ - DeleteOnVmDeletion: &blockDevice.DeleteOnVmDeletion, + DeleteOnVmDeletion: aws.Bool(blockDevice.DeleteOnVmDeletion), } if blockDevice.VolumeType != "" { @@ -143,7 +144,7 @@ func buildBlockDevicesVmCreation(b []BlockDevice) []oapi.BlockDeviceMappingVmCre } } else { bsu := oapi.BsuToCreate{ - DeleteOnVmDeletion: &blockDevice.DeleteOnVmDeletion, + DeleteOnVmDeletion: aws.Bool(blockDevice.DeleteOnVmDeletion), } if blockDevice.VolumeType != "" { diff --git a/builder/osc/common/block_device_test.go b/builder/osc/common/block_device_test.go index 144b91f31..c047e3167 100644 --- a/builder/osc/common/block_device_test.go +++ b/builder/osc/common/block_device_test.go @@ -8,6 +8,12 @@ import ( ) func TestBlockDevice_LaunchDevices(t *testing.T) { + tr := new(bool) + f := new(bool) + + *tr = true + *f = false + cases := []struct { Config *BlockDevice Result oapi.BlockDeviceMappingVmCreation @@ -27,7 +33,7 @@ func TestBlockDevice_LaunchDevices(t *testing.T) { SnapshotId: "snap-1234", VolumeType: "standard", VolumeSize: 8, - DeleteOnVmDeletion: true, + DeleteOnVmDeletion: tr, }, }, }, @@ -41,7 +47,7 @@ func TestBlockDevice_LaunchDevices(t *testing.T) { DeviceName: "/dev/sdb", Bsu: oapi.BsuToCreate{ VolumeSize: 8, - DeleteOnVmDeletion: false, + DeleteOnVmDeletion: f, }, }, }, @@ -59,7 +65,7 @@ func TestBlockDevice_LaunchDevices(t *testing.T) { Bsu: oapi.BsuToCreate{ VolumeType: "io1", VolumeSize: 8, - DeleteOnVmDeletion: true, + DeleteOnVmDeletion: tr, Iops: 1000, }, }, @@ -77,7 +83,7 @@ func TestBlockDevice_LaunchDevices(t *testing.T) { Bsu: oapi.BsuToCreate{ VolumeType: "gp2", VolumeSize: 8, - DeleteOnVmDeletion: true, + DeleteOnVmDeletion: tr, }, }, }, @@ -94,7 +100,7 @@ func TestBlockDevice_LaunchDevices(t *testing.T) { Bsu: oapi.BsuToCreate{ VolumeType: "gp2", VolumeSize: 8, - DeleteOnVmDeletion: true, + DeleteOnVmDeletion: tr, }, }, }, @@ -109,7 +115,7 @@ func TestBlockDevice_LaunchDevices(t *testing.T) { DeviceName: "/dev/sdb", Bsu: oapi.BsuToCreate{ VolumeType: "standard", - DeleteOnVmDeletion: true, + DeleteOnVmDeletion: tr, }, }, }, @@ -154,6 +160,12 @@ func TestBlockDevice_LaunchDevices(t *testing.T) { } func TestBlockDevice_OMI(t *testing.T) { + tr := new(bool) + f := new(bool) + + *tr = true + *f = false + cases := []struct { Config *BlockDevice Result oapi.BlockDeviceMappingImage @@ -173,7 +185,7 @@ func TestBlockDevice_OMI(t *testing.T) { SnapshotId: "snap-1234", VolumeType: "standard", VolumeSize: 8, - DeleteOnVmDeletion: true, + DeleteOnVmDeletion: tr, }, }, }, @@ -187,7 +199,7 @@ func TestBlockDevice_OMI(t *testing.T) { DeviceName: "/dev/sdb", Bsu: oapi.BsuToCreate{ VolumeSize: 8, - DeleteOnVmDeletion: false, + DeleteOnVmDeletion: f, }, }, }, @@ -205,7 +217,7 @@ func TestBlockDevice_OMI(t *testing.T) { Bsu: oapi.BsuToCreate{ VolumeType: "io1", VolumeSize: 8, - DeleteOnVmDeletion: true, + DeleteOnVmDeletion: tr, Iops: 1000, }, }, @@ -223,7 +235,7 @@ func TestBlockDevice_OMI(t *testing.T) { Bsu: oapi.BsuToCreate{ VolumeType: "gp2", VolumeSize: 8, - DeleteOnVmDeletion: true, + DeleteOnVmDeletion: tr, }, }, }, @@ -240,7 +252,7 @@ func TestBlockDevice_OMI(t *testing.T) { Bsu: oapi.BsuToCreate{ VolumeType: "gp2", VolumeSize: 8, - DeleteOnVmDeletion: true, + DeleteOnVmDeletion: tr, }, }, }, @@ -255,7 +267,7 @@ func TestBlockDevice_OMI(t *testing.T) { DeviceName: "/dev/sdb", Bsu: oapi.BsuToCreate{ VolumeType: "standard", - DeleteOnVmDeletion: true, + DeleteOnVmDeletion: tr, }, }, }, @@ -270,15 +282,6 @@ func TestBlockDevice_OMI(t *testing.T) { VirtualDeviceName: "ephemeral0", }, }, - { - Config: &BlockDevice{ - DeviceName: "/dev/sdb", - }, - - Result: oapi.BlockDeviceMappingImage{ - DeviceName: "/dev/sdb", - }, - }, } for _, tc := range cases { @@ -290,7 +293,7 @@ func TestBlockDevice_OMI(t *testing.T) { omiResults := omiBlockDevices.BuildOMIDevices() if !reflect.DeepEqual(expected, omiResults) { - t.Fatalf("Bad block device, \nexpected: %#v\n\ngot: %#v", + t.Fatalf("Bad block device, \nexpected: %+#v\n\ngot: %+#v", expected, omiResults) } } From 810e30e8e14f42cd64145246b0b4a0bc25b71a68 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Tue, 12 Mar 2019 12:49:46 -0600 Subject: [PATCH 085/113] refactor: fix symlink issue on ubuntu --- builder/osc/chroot/builder_acc_test.go | 4 +--- builder/osc/chroot/device.go | 6 +++++- builder/osc/chroot/step_link_volume.go | 4 ++-- builder/osc/chroot/step_mount_device.go | 17 ++++++++++++++--- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/builder/osc/chroot/builder_acc_test.go b/builder/osc/chroot/builder_acc_test.go index cb2fdd108..f194dd49c 100644 --- a/builder/osc/chroot/builder_acc_test.go +++ b/builder/osc/chroot/builder_acc_test.go @@ -25,9 +25,7 @@ const testBuilderAccBasic = ` "region": "eu-west-2", "source_omi": "ami-65efcc11", "omi_name": "packer-test-{{timestamp}}", - "omi_virtualization_type": "hvm", - "device_path": "/dev/xvdf", - "mount_partition": "0" + "omi_virtualization_type": "hvm" }] } ` diff --git a/builder/osc/chroot/device.go b/builder/osc/chroot/device.go index f703b78ea..7f9aec94d 100644 --- a/builder/osc/chroot/device.go +++ b/builder/osc/chroot/device.go @@ -42,7 +42,7 @@ func AvailableDevice() (string, error) { // devicePrefix returns the prefix ("sd" or "xvd" or so on) of the devices // on the system. The "vd" prefix appears on outscale images. func devicePrefix() (string, error) { - available := []string{"sd", "xvd"} + available := []string{"sd", "xvd", "vd"} f, err := os.Open("/sys/block") if err != nil { @@ -56,6 +56,10 @@ func devicePrefix() (string, error) { dirBase := filepath.Base(dir) for _, prefix := range available { if strings.HasPrefix(dirBase, prefix) { + //for outscale. + if prefix != "xvd" { + prefix = "xvd" + } return prefix, nil } } diff --git a/builder/osc/chroot/step_link_volume.go b/builder/osc/chroot/step_link_volume.go index 8c5b6d941..f30b7803c 100644 --- a/builder/osc/chroot/step_link_volume.go +++ b/builder/osc/chroot/step_link_volume.go @@ -3,7 +3,6 @@ package chroot import ( "context" "fmt" - "strings" osccommon "github.com/hashicorp/packer/builder/osc/common" "github.com/hashicorp/packer/helper/multistep" @@ -30,7 +29,8 @@ func (s *StepLinkVolume) Run(ctx context.Context, state multistep.StateBag) mult volumeId := state.Get("volume_id").(string) // For the API call, it expects "sd" prefixed devices. - linkVolume := strings.Replace(device, "/xvd", "/sd", 1) + //linkVolume := strings.Replace(device, "/xvd", "/sd", 1) + linkVolume := device ui.Say(fmt.Sprintf("Attaching the root volume to %s", linkVolume)) _, err := oapiconn.POST_LinkVolume(oapi.LinkVolumeRequest{ diff --git a/builder/osc/chroot/step_mount_device.go b/builder/osc/chroot/step_mount_device.go index 51a150e19..0b564e14e 100644 --- a/builder/osc/chroot/step_mount_device.go +++ b/builder/osc/chroot/step_mount_device.go @@ -80,8 +80,19 @@ func (s *StepMountDevice) Run(_ context.Context, state multistep.StateBag) multi return multistep.ActionHalt } - //TODO: Check the symlink created - deviceMount := device + //Check the symbolic link for the device to get the real device name + cmd := ShellCommand(fmt.Sprintf("lsblk -no pkname $(readlink -f %s)", device)) + + realDeviceName, err := cmd.Output() + if err != nil { + err := fmt.Errorf( + "Error retrieving the symlink of the device %s.\n", device) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + deviceMount := fmt.Sprintf("/dev/%s", strings.Replace(string(realDeviceName), "\n", "", -1)) log.Printf("[DEBUG] s.MountPartition = %s", s.MountPartition) @@ -108,7 +119,7 @@ func (s *StepMountDevice) Run(_ context.Context, state multistep.StateBag) multi return multistep.ActionHalt } log.Printf("[DEBUG] (step mount) mount command is %s", mountCommand) - cmd := ShellCommand(mountCommand) + cmd = ShellCommand(mountCommand) cmd.Stderr = stderr if err := cmd.Run(); err != nil { err := fmt.Errorf( From 35c7c6163ce74ea4c3901c95f94da5b629c5df17 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Wed, 13 Mar 2019 16:12:06 -0600 Subject: [PATCH 086/113] refactor: remove unnecessary fields and add default values --- builder/osc/common/access_config.go | 15 +++++++++------ builder/osc/common/build_filters.go | 18 +++++++++--------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/builder/osc/common/access_config.go b/builder/osc/common/access_config.go index 485811beb..667c85028 100644 --- a/builder/osc/common/access_config.go +++ b/builder/osc/common/access_config.go @@ -14,8 +14,7 @@ import ( // AccessConfig is for common configuration related to AWS access type AccessConfig struct { AccessKey string `mapstructure:"access_key"` - CustomEndpoint string `mapstructure:"custom_endpoint"` - DecodeAuthZMessages bool `mapstructure:"decode_authorization_messages"` + CustomEndpointOAPI string `mapstructure:"custom_endpoint_oapi"` InsecureSkipTLSVerify bool `mapstructure:"insecure_skip_tls_verify"` MFACode string `mapstructure:"mfa_code"` ProfileName string `mapstructure:"profile"` @@ -50,15 +49,19 @@ func (c *AccessConfig) Config() (*oapi.Config, error) { c.RawRegion = os.Getenv("OUTSCALE_REGION") } - if c.CustomEndpoint == "" { - c.CustomEndpoint = os.Getenv("OUTSCALE_OAPI_URL") + if c.CustomEndpointOAPI == "" { + c.CustomEndpointOAPI = os.Getenv("OUTSCALE_OAPI_URL") + } + + if c.CustomEndpointOAPI == "" { + c.CustomEndpointOAPI = "outscale.com/oapi/latest" } config := &oapi.Config{ AccessKey: c.AccessKey, SecretKey: c.SecretKey, Region: c.RawRegion, - URL: c.CustomEndpoint, + URL: c.CustomEndpointOAPI, Service: "api", } @@ -77,7 +80,7 @@ func (c *AccessConfig) NewOAPIConnection() (oapi.OAPIClient, error) { skipClient := &http.Client{ Transport: &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + TLSClientConfig: &tls.Config{InsecureSkipVerify: c.InsecureSkipTLSVerify}, }, } diff --git a/builder/osc/common/build_filters.go b/builder/osc/common/build_filters.go index bec8a8fd1..fe88ed09f 100644 --- a/builder/osc/common/build_filters.go +++ b/builder/osc/common/build_filters.go @@ -65,27 +65,27 @@ func buildOMIFilters(input map[string]string) oapi.FiltersImage { filterValue := []string{v} switch name := k; name { - case "account-aliases": + case "account-alias": filters.AccountAliases = filterValue - case "account-ids": + case "account-id": filters.AccountIds = filterValue - case "architectures": + case "architecture": filters.Architectures = filterValue - case "image-ids": + case "image-id": filters.ImageIds = filterValue - case "image-names": + case "image-name": filters.ImageNames = filterValue - case "image-types": + case "image-type": filters.ImageTypes = filterValue - case "virtualization-types": + case "virtualization-type": filters.VirtualizationTypes = filterValue - case "root-device-types": + case "root-device-type": filters.RootDeviceTypes = filterValue case "block-device-mapping-volume-type": filters.BlockDeviceMappingVolumeType = filterValue //Some params are missing. default: - log.Printf("[Debug] Unknown Filter Name: %s.", name) + log.Printf("[WARN] Unknown Filter Name: %s.", name) } } return filters From 6b3da118fb21b11f0ae884e6a6ddeb71af191d70 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Wed, 13 Mar 2019 16:17:33 -0600 Subject: [PATCH 087/113] website: add outscale bsu builder webite documentation --- website/source/docs/builders/osc-bsu.html.md | 355 ++++++++++++++++++ website/source/docs/builders/outscale.html.md | 91 +++++ website/source/layouts/docs.erb | 8 + 3 files changed, 454 insertions(+) create mode 100644 website/source/docs/builders/osc-bsu.html.md create mode 100644 website/source/docs/builders/outscale.html.md diff --git a/website/source/docs/builders/osc-bsu.html.md b/website/source/docs/builders/osc-bsu.html.md new file mode 100644 index 000000000..e0321110e --- /dev/null +++ b/website/source/docs/builders/osc-bsu.html.md @@ -0,0 +1,355 @@ +--- +description: | + The osc-bsu Packer builder is able to create Outscale OMIs backed by BSU volumes for use in Outscale. For more information on the difference between + BSU-backed VMs and VM-store backed VMs, see the storage for + the root device section in the Outscale documentation. +layout: docs +page_title: 'Outscale BSU - Builders' +sidebar_current: 'docs-builders-osc-bsubacked' +--- + +# OMI Builder (BSU backed) + +Type: `osc-bsu` + +The `osc-bsu` Packer builder is able to create Outscale OMIs backed by BSU +volumes for use in [Flexible Compute Unit](https://wiki.outscale.net/pages/viewpage.action?pageId=43060893). For more information on +the difference between BSU-backed VMs and VM-store backed +VMs, see the ["storage for the root device" section in the Outscale +documentation](https://wiki.outscale.net/display/EN/Defining+Block+Device+Mappings). + +This builder builds an OMI by launching an Outscale VM from a source OMI, +provisioning that running machine, and then creating an OMI from that machine. +This is all done in your own Outscale account. The builder will create temporary +keypairs, security group rules, etc. that provide it temporary access to the +VM while the image is being created. This simplifies configuration quite +a bit. + +The builder does *not* manage OMIs. Once it creates an OMI and stores it in +your account, it is up to you to use, delete, etc. the OMI. + +-> **Note:** Temporary resources are, by default, all created with the +prefix `packer`. This can be useful if you want to restrict the security groups +and key pairs Packer is able to operate on. + +## Configuration Reference + +There are many configuration options available for the builder. They are +segmented below into two categories: required and optional parameters. Within +each category, the available configuration keys are alphabetized. + +In addition to the options listed here, a +[communicator](../templates/communicator.html) can be configured for this +builder. + +### Required: + +- `access_key` (string) - The access key used to communicate with OUTSCALE. [Learn how to set this](outscale.html#authentication) + +- `omi_name` (string) - The name of the resulting OMIS that will appear when managing OMIs in the Outscale console or via APIs. This must be unique. To help make this unique, use a function like `timestamp` (see [template engine](../templates/engine.html) for more info). + +- `vm_type` (string) - The Outscale VM type to use while building the OMI, such as `t2.small`. + +- `region` (string) - The name of the region, such as `us-east-1`, in which to launch the Outscale VM to create the OMI. + +- `secret_key` (string) - The secret key used to communicate with Outscale. [Learn how to set this](outscale.html#authentication) + +- `source_omi` (string) - The initial OMI used as a base for the newly created machine. `source_omi_filter` may be used instead to populate this automatically. + +### Optional: + +- `omi_block_device_mappings` (array of block device mappings) - Add one or more [block device mappings](https://wiki.outscale.net/display/EN/Defining+Block+Device+Mappings) to the OMI. These will be attached when booting a new VM from your OMI. To add a block device during the Packer build see `launch_block_device_mappings` below. Your options here may vary depending on the type of VM you use. The block device mappings allow for the following configuration: + + - `delete_on_vm_deletion` (boolean) - Indicates whether the BSU volume is deleted on VM termination. Default `false`. **NOTE**: If this value is not explicitly set to `true` and volumes are not cleaned up by an alternative method, additional volumes will accumulate after every build. + + - `device_name` (string) - The device name exposed to the VM (for example, `/dev/sdh` or `xvdh`). Required for every device in the block device mapping. + + - `iops` (number) - The number of I/O operations per second (IOPS) that the volume supports. See the documentation on + [IOPs](https://wiki.outscale.net/display/EN/About+Volumes#AboutVolumes-VolumeTypesVolumeTypesandIOPS) + for more information + + - `no_device` (boolean) - Suppresses the specified device included in the + block device mapping of the OMI + + - `snapshot_id` (string) - The ID of the snapshot + + - `virtual_name` (string) - The virtual device name. See the documentation on [Block Device Mapping](https://wiki.outscale.net/display/EN/Defining+Block+Device+Mappings) for more information + + - `volume_size` (number) - The size of the volume, in GiB. Required if not specifying a `snapshot_id` + + - `volume_type` (string) - The volume type. `gp2` for General Purpose (SSD) volumes, `io1` for Provisioned IOPS (SSD) volumes, and `standard` for Magnetic volumes + +- `omi_description` (string) - The description to set for the resulting OMI(s). By default this description is empty. This is a [template engine](../templates/engine.html), see [Build template + data](#build-template-data) for more information. + +- `omi_account_ids` (array of strings) - A list of account IDs that have access to launch the resulting OMI(s). By default no additional users other than the user creating the OMIS has permissions to launch it. + +- `omi_virtualization_type` (string) - The type of virtualization for the OMI you are building. This option must match the supported virtualization type of `source_omi`. Can be `paravirtual` or `hvm`. + +- `associate_public_ip_address` (boolean) - If using a non-default Net, public IP addresses are not provided by default. If this is toggled, your new VM will get a Public IP. + +- `subregion_name` (string) - Destination subregion to launch VM in. Leave this empty to allow Outscale to auto-assign. + +- `custom_endpoint_oapi` (string) - This option is useful if you use a cloud + provider whose API is compatible with Outscale OAPI. Specify another endpoint + like this `outscale.com/oapi/latest`. + +- `disable_stop_vm` (boolean) - Packer normally stops the build + VM after all provisioners have run. For Windows VMs, it is + sometimes desirable to [run Sysprep](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-vista/cc721940(v=ws.10)) which will stop the VM for you. If this is set to `true`, Packer + *will not* stop the VM but will assume that you will send the stop + signal yourself through your final provisioner. You can do this with a + [windows-shell provisioner](https://www.packer.io/docs/provisioners/windows-shell.html). + + Note that Packer will still wait for the VM to be stopped, and + failing to send the stop signal yourself, when you have set this flag to + `true`, will cause a timeout. + +- `bsu_optimized` (boolean) - If true, the VM is created with optimized BSU I/O. + +- `force_delete_snapshot` (boolean) - Force Packer to delete snapshots + associated with OMIs, which have been deregistered by `force_deregister`. + Default `false`. + +- `force_deregister` (boolean) - Force Packer to first deregister an existing + OMIS if one with the same name already exists. Default `false`. + +- `insecure_skip_tls_verify` (boolean) - This allows skipping TLS + verification of the OAPI endpoint. The default is `false`. + +- `launch_block_device_mappings` (array of block device mappings) - Add one + or more block devices before the Packer build starts. If you add VM + store volumes or BSU volumes in addition to the root device volume, the + created OMIS will contain block device mapping information for those + volumes. Outscale creates snapshots of the source VM's root volume and + any other BSU volumes described here. When you launch an VM from this + new OMI, the VM automatically launches with these additional volumes, + and will restore them from snapshots taken from the source VM. + +- `run_tags` (object of key/value strings) - Tags to apply to the VM + that is *launched* to create the OMI. These tags are *not* applied to the + resulting OMIS unless they're duplicated in `tags`. This is a [template + engine](../templates/engine.html), see [Build template + data](#build-template-data) for more information. + +- `run_volume_tags` (object of key/value strings) - Tags to apply to the + volumes that are *launched* to create the OMI. These tags are *not* applied + to the resulting OMIS unless they're duplicated in `tags`. This is a + [template engine](../templates/engine.html), see [Build template + data](#build-template-data) for more information. + +- `security_group_id` (string) - The ID (*not* the name) of the security + group to assign to the VM. By default this is not set and Packer will + automatically create a new temporary security group to allow SSH access. + Note that if this is specified, you must be sure the security group allows + access to the `ssh_port` given below. + +- `security_group_ids` (array of strings) - A list of security groups as + described above. Note that if this is specified, you must omit the + `security_group_id`. + +- `shutdown_behavior` (string) - Automatically terminate VMs on + shutdown in case Packer exits ungracefully. Possible values are "stop" and + "terminate", default is `stop`. + +- `skip_region_validation` (boolean) - Set to true if you want to skip + validation of the region configuration option. Default `false`. + +- `snapshot_groups` (array of strings) - A list of groups that have access to + create volumes from the snapshot(s). By default no groups have permission + to create volumes from the snapshot(s). `all` will make the snapshot + publicly accessible. + +- `snapshot_users` (array of strings) - A list of account IDs that have + access to create volumes from the snapshot(s). By default no additional + users other than the user creating the OMIS has permissions to create + volumes from the backing snapshot(s). + +- `snapshot_tags` (object of key/value strings) - Tags to apply to snapshot. + They will override OMIS tags if already applied to snapshot. This is a + [template engine](../templates/engine.html), see [Build template + data](#build-template-data) for more information. + +- `source_omi_filter` (object) - Filters used to populate the `source_ami` field. + - `filters` (map of strings) - filters used to select a `source_omi`. + - `owners` (array of strings) - Filters the images by their owner. You may specify one or more Outscale account IDs, "self" (which will use the account whose credentials you are using to run Packer). This option is required for security reasons. + + Example: + + ``` json + { + "source_omi_filter": { + "filters": { + "virtualization-type": "hvm", + "image-name": "ubuntu/images/*ubuntu-xenial-16.04-amd64-server-*", + "root-device-type": "ebs" + }, + "owners": ["099720109477"], + } + } + ``` + + This selects an Ubuntu 16.04 HVM BSU OMIS from Canonical. NOTE: + This will fail unless *exactly* one OMIS is returned. In the above example, + `most_recent` will cause this to succeed by selecting the newest image. + +- `ssh_keypair_name` (string) - If specified, this is the key that will be used for SSH with the machine. The key must match a key pair name loaded up into Outscale. By default, this is blank, and Packer will generate a temporary keypair unless [`ssh_password`](../templates/communicator.html#ssh_password) is used. [`ssh_private_key_file`](../templates/communicator.html#ssh_private_key_file) or `ssh_agent_auth` must be specified when `ssh_keypair_name` is utilized. + +- `ssh_agent_auth` (boolean) - If true, the local SSH agent will be used to authenticate connections to the source VM. No temporary keypair will be created, and the values of `ssh_password` and `ssh_private_key_file` will be ignored. To use this option with a key pair already configured in the source OMI, leave the `ssh_keypair_name` blank. To associate an existing key pair in Outscale with the source VM, set the `ssh_keypair_name` field to the name of the key pair. + +- `ssh_interface` (string) - One of `public_ip`, `private_ip`, `public_dns`, or `private_dns`. If set, either the public IP address, private IP address, public DNS name or private DNS name will used as the host for SSH. The default behaviour if inside a Net is to use the public IP address if available, otherwise the private IP address will be used. If not in a Net the public DNS name will be used. Also works for WinRM. + + Where Packer is configured for an outbound proxy but WinRM traffic should be direct, `ssh_interface` must be set to `private_dns` and `.compute.internal` included in the `NO_PROXY` environment variable. + +- `subnet_id` (string) - If using Net, the ID of the subnet, such as `subnet-12345def`, where Packer will launch the VM. This field is required if you are using an non-default Net. + +- `tags` (object of key/value strings) - Tags applied to the OMIS and relevant snapshots. This is a [template engine](../templates/engine.html), see [Build template data](#build-template-data) for more information. + +- `temporary_key_pair_name` (string) - The name of the temporary key pair to generate. By default, Packer generates a name that looks like `packer_`, where <UUID> is a 36 character unique identifier. + +- `temporary_security_group_source_cidr` (string) - An IPv4 CIDR block to be authorized access to the VM, when packer is creating a temporary security group. The default is `0.0.0.0/0` (i.e., allow any IPv4 source). This is only used when `security_group_id` or `security_group_ids` is not specified. + +- `user_data` (string) - User data to apply when launching the VM. Note that you need to be careful about escaping characters due to the templates being JSON. It is often more convenient to use `user_data_file`, instead. Packer will not automatically wait for a user script to finish before shutting down the VM this must be handled in a provisioner. + +- `user_data_file` (string) - Path to a file that will be used for the user data when launching the VM. + +- `net_id` (string) - If launching into a Net subnet, Packer needs the Net ID in order to create a temporary security group within the Net. Requires `subnet_id` to be set. If this field is left blank, Packer will try to get the Net ID from the `subnet_id`. + +- `net_filter` (object) - Filters used to populate the net_id` field. + Example: + + ``` json + { + "net_filter": { + "filters": { + "is-default": "false", + "ip-range": "/24" + } + } + } + ``` + + This selects the Net with a IPv4 CIDR block of `/24`. NOTE: This will fail unless *exactly* one Net is returned. + + - `filters` (map of strings) - filters used to select a `vpc_id`. NOTE: This will fail unless *exactly* one Net is returned. + + `net_id` take precedence over this. + +- `windows_password_timeout` (string) - The timeout for waiting for a Windows password for Windows VMs. Defaults to 20 minutes. Example value: `10m` + +## Basic Example + +Here is a basic example. You will need to provide access keys, and may need to change the OMIS IDs according to what images exist at the time the template is run: + +```json +{ + "variables": { + "access_key": "{{env `OUTSCALE_ACCESSKEYID`}}", + "secret_key": "{{env `OUTSCALE_SECRETKEYID`}}" + }, + "builders": [ + { + "type": "osc-bsu", + "access_key": "{{user `access_key`}}", + "secret_key": "{{user `secret_key`}}", + "region": "us-east-1", + "source_omi": "ami-abcfd0283", + "vm_type": "t2.micro", + "ssh_username": "outscale", + "ami_name": "packer_osc {{timestamp}}" + } + ] +} +``` + +-> **Note:** Packer can also read the access key and secret access key from +environmental variables. See the configuration reference in the section above +for more information on what environmental variables Packer will look for. + +Further information on locating OMIS IDs and their relationship to VM +types and regions can be found in the Outscale Documentation [reference](https://wiki.outscale.net/display/EN/Official+OMIs+Reference). + +## Accessing the Instance to Debug + +If you need to access the VM to debug for some reason, run the builder +with the `-debug` flag. In debug mode, the Outscale builder will save the private key in the current directory and will output the DNS or IP information as well. +You can use this information to access the VM as it is running. + +## OMIS Block Device Mappings Example + +Here is an example using the optional OMIS block device mappings. Our +configuration of `launch_block_device_mappings` will expand the root volume +(`/dev/sda`) to 40gb during the build (up from the default of 8gb). With +`ami_block_device_mappings` Outscale will attach additional volumes `/dev/sdb` and +`/dev/sdc` when we boot a new VM of our OMI. + +``` json +{ + "type": "osc-bsu", + "access_key": "YOUR KEY HERE", + "secret_key": "YOUR SECRET KEY HERE", + "region": "us-east-1", + "source_ami": "ami-fce3c696", + "VM_type": "t2.micro", + "ssh_username": "ubuntu", + "ami_name": "packer-quick-start {{timestamp}}", + "launch_block_device_mappings": [ + { + "device_name": "/dev/sda1", + "volume_size": 40, + "volume_type": "gp2", + "delete_on_vm_deletion": true + } + ], + "omi_block_device_mappings": [ + { + "device_name": "/dev/sdb", + "virtual_name": "ephemeral0" + }, + { + "device_name": "/dev/sdc", + "virtual_name": "ephemeral1" + } + ] +} +``` + +## Build template data + +In configuration directives marked as a template engine above, the following variables are available: + +- `BuildRegion` - The region (for example `eu-west-2`) where Packer is building the OMI. +- `SourceOMI` - The source OMIS ID (for example ami-a2412fcd`) used to build the OMI. +- `SourceOMIName` - The source OMIS Name (for example `ubutu-390`) used to build the OMI. +- `SourceOMITags` - The source OMIS Tags, as a `map[string]string` object. + +## Tag Example + +Here is an example using the optional OMIS tags. This will add the tags `OS_Version` and `Release` to the finished OMI. As before, you will need to provide your access keys, and may need to change the source OMIS ID based on what images exist when this template is run: + +``` json +{ + "type": "osc-bsu", + "access_key": "YOUR KEY HERE", + "secret_key": "YOUR SECRET KEY HERE", + "region": "us-east-1", + "source_ami": "ami-fce3c696", + "VM_type": "t2.micro", + "ssh_username": "ubuntu", + "ami_name": "packer-quick-start {{timestamp}}", + "tags": { + "OS_Version": "Ubuntu", + "Release": "Latest", + "Base_OMI_Name": "{{ .SourceOMIName }}", + "Extra": "{{ .SourceOMITags.TagName }}" + } +} +``` + +-> **Note:** Packer uses pre-built OMIs as the source for building images. +These source OMIs may include volumes that are not flagged to be destroyed on +termination of the VM building the new image. Packer will attempt to +clean up all residual volumes that are not designated by the user to remain +after termination. If you need to preserve those source volumes, you can +overwrite the termination setting by specifying `delete_on_vm_deletion=false` +in the `launch_block_device_mappings` block for the device. diff --git a/website/source/docs/builders/outscale.html.md b/website/source/docs/builders/outscale.html.md new file mode 100644 index 000000000..b33380921 --- /dev/null +++ b/website/source/docs/builders/outscale.html.md @@ -0,0 +1,91 @@ +--- +description: | + Packer is able to create Outscale Machine Images (OMIs). To achieve this, Packer comes with + multiple builders depending on the strategy you want to use to build the OMI. +layout: docs +page_title: 'Outscale OMI - Builders' +sidebar_current: 'docs-builders-outscale' +--- + +# Outscale OMI Builder + +Packer is able to create Outscale OMIs. To achieve this, Packer comes with +multiple builders depending on the strategy you want to use to build the OMI. +Packer supports the following builders at the moment: + +- [osc-bsu](/docs/builders/osc-bsu.html) - Create BSU-backed OMIs by + launching a source OMI and re-packaging it into a new OMI after + provisioning. If in doubt, use this builder, which is the easiest to get + started with. + +- [osc-chroot](/docs/builders/osc-chroot.html) - Create EBS-backed OMIs + from an existing OUTSCALE VM by mounting the root device and using a + [Chroot](https://en.wikipedia.org/wiki/Chroot) environment to provision + that device. This is an **advanced builder and should not be used by + newcomers**. However, it is also the fastest way to build an EBS-backed OMI + since no new OUTSCALE VM needs to be launched. + +- [osc-bsusurrogate](/docs/builders/osc-bsusurrogate.html) - Create BSU-backed OMIs from scratch. Works similarly to the `chroot` builder but does + not require running in Outscale VM. This is an **advanced builder and should not be + used by newcomers**. + +-> **Don't know which builder to use?** If in doubt, use the [osc-bsu +builder](/docs/builders/osc-bsu.html). It is much easier to use and Outscale generally recommends BSU-backed images nowadays. + +# Outscale BSU Volume Builder + +Packer is able to create Outscale BSU Volumes which are preinitialized with a filesystem and data. + +- [osc-bsuvolume](/docs/builders/osc-bsuvolume.html) - Create EBS volumes by launching a source OMI with block devices mapped. Provision the VM, then destroy it, retaining the EBS volumes. + +## Authentication + +The OUTSCALE provider offers a flexible means of providing credentials for authentication. The following methods are supported, in this order, and explained below: + +- Static credentials +- Environment variables +- Shared credentials file +- Outscale Role + +### Static Credentials + +Static credentials can be provided in the form of an access key id and secret. +These look like: + +``` json +{ + "access_key": "AKIAIOSFODNN7EXAMPLE", + "secret_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "region": "us-east-1", + "type": "osc-bsu", + "oapi_custom_endpoint": "outscale.com/oapi/latest" +} +``` + +### Environment variables + +You can provide your credentials via the `OUTSCALE_ACCESSKEYID` and +`OUTSCALE_SECRETKEYID`, environment variables, representing your Outscale Access +Key and Outscale Secret Key, respectively. The `OUTSCALE_REGION` and +`OUTSCALE_OAPI_URL` environment variables are also used, if applicable: + +Usage: + + $ export OUTSCALE_ACCESSKEYID="anaccesskey" + $ export OUTSCALE_SECRETKEYID="asecretkey" + $ export OUTSCALE_REGION="eu-west-2" + $ packer build packer.json + +### Checking that system time is current + +Outscale uses the current time as part of the [request signing +process](http://docs.aws.osc.com/general/latest/gr/sigv4_signing.html). If +your system clock is too skewed from the current time, your requests might +fail. If that's the case, you might see an error like this: + + ==> osc-bsu: Error querying OMI: AuthFailure: OUTSCALE was not able to validate the provided access credentials + +If you suspect your system's date is wrong, you can compare it against +. On Linux/OS X, you can run the `date` command to get +the current time. If you're on Linux, you can try setting the time with ntp by +running `sudo ntpd -q`. diff --git a/website/source/layouts/docs.erb b/website/source/layouts/docs.erb index 0f2665f56..13588449b 100644 --- a/website/source/layouts/docs.erb +++ b/website/source/layouts/docs.erb @@ -151,6 +151,14 @@ + > + Outscale + + > Parallels - > + > Outscale > From 0fe997184378a3ecccec04236ead017010d0c297 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Thu, 14 Mar 2019 14:20:01 -0600 Subject: [PATCH 089/113] website: add outscale chroot website documentation --- website/source/docs/builders/osc-bsu.html.md | 2 +- .../source/docs/builders/osc-chroot.html.md | 383 ++++++++++++++++++ website/source/layouts/docs.erb | 3 + 3 files changed, 387 insertions(+), 1 deletion(-) create mode 100644 website/source/docs/builders/osc-chroot.html.md diff --git a/website/source/docs/builders/osc-bsu.html.md b/website/source/docs/builders/osc-bsu.html.md index ea63d5905..402035111 100644 --- a/website/source/docs/builders/osc-bsu.html.md +++ b/website/source/docs/builders/osc-bsu.html.md @@ -170,7 +170,7 @@ builder. [template engine](../templates/engine.html), see [Build template data](#build-template-data) for more information. -- `source_omi_filter` (object) - Filters used to populate the `source_ami` field. +- `source_omi_filter` (object) - Filters used to populate the `source_omi` field. - `filters` (map of strings) - filters used to select a `source_omi`. - `owners` (array of strings) - Filters the images by their owner. You may specify one or more Outscale account IDs, "self" (which will use the account whose credentials you are using to run Packer). This option is required for security reasons. diff --git a/website/source/docs/builders/osc-chroot.html.md b/website/source/docs/builders/osc-chroot.html.md new file mode 100644 index 000000000..31e1ced2b --- /dev/null +++ b/website/source/docs/builders/osc-chroot.html.md @@ -0,0 +1,383 @@ +--- +description: | + The amazon-chroot Packer builder is able to create Outscale OMIs backed by an BSU + volume as the root device. For more information on the difference between + instance storage and BSU-backed instances, storage for the root device section + in the Outscale documentation. +layout: docs +page_title: 'Outscale chroot - Builders' +sidebar_current: 'docs-builders-osc-chroot' +--- + +# OMI Builder (chroot) + +Type: `osc-chroot` + +The `osc-chroot` Packer builder is able to create Outscale Machine Images (OMIs) backed by an +BSU volume as the root device. For more information on the difference between +instance storage and BSU-backed instances, see the ["storage for the root +device" section in the Outscale +documentation](https://wiki.outscale.net/display/EN/Home). + +The difference between this builder and the `osc-bsu` builder is that this +builder is able to build an BSU-backed OMI without launching a new Outscale +VM. This can dramatically speed up OMI builds for organizations who need +the extra fast build. + +~> **This is an advanced builder** If you're just getting started with +Packer, we recommend starting with the [osc-bsu +builder](/docs/builders/osc-bsu.html), which is much easier to use. + +The builder does *not* manage OMIs. Once it creates an OMI and stores it in +your account, it is up to you to use, delete, etc., the OMI. + +## How Does it Work? + +This builder works by creating a new BSU volume from an existing source OMI and +attaching it into an already-running Outscale VM. Once attached, a +[chroot](https://en.wikipedia.org/wiki/Chroot) is used to provision the system +within that volume. After provisioning, the volume is detached, snapshotted, +and an OMI is made. + +Using this process, minutes can be shaved off the OMI creation process because +a new Outscale VM doesn't need to be launched. + +There are some restrictions, however. The host Outscale instance where the volume is +attached to must be a similar system (generally the same OS version, kernel +versions, etc.) as the OMI being built. Additionally, this process is much more +expensive because the Outscale VM must be kept running persistently in order +to build OMIs, whereas the other OMI builders start VMs on-demand to +build OMIs as needed. + +## Configuration Reference + +There are many configuration options available for the builder. They are +segmented below into two categories: required and optional parameters. Within +each category, the available configuration keys are alphabetized. + +### Required: + +- `access_key` (string) - The access key used to communicate with OUTSCALE. [Learn how to set this](outscale.html#authentication) + +- `omi_name` (string) - The name of the resulting OMIS that will appear when managing OMIs in the Outscale console or via APIs. This must be unique. To help make this unique, use a function like `timestamp` (see [template engine](../templates/engine.html) for more info). + +- `secret_key` (string) - The secret key used to communicate with Outscale. [Learn how to set this](outscale.html#authentication) + +- `source_omi` (string) - The initial OMI used as a base for the newly created machine. `source_omi_filter` may be used instead to populate this automatically. + +### Optional: + +- `omi_description` (string) - The description to set for the resulting OMI(s). + By default this description is empty. This is a [template engine](../templates/engine.html), + see [Build template data](#build-template-data) for more information. + +- `omi_account_ids` (array of strings) - A list of account IDs that have access to launch the resulting OMI(s). By default no additional users other than the user creating the OMIS has permissions to launch it. + +- `omi_virtualization_type` (string) - The type of virtualization for the OMI you are building. This option must match the supported virtualization type of `source_omi`. Can be `paravirtual` or `hvm`. + +- `chroot_mounts` (array of array of strings) - This is a list of devices to + mount into the chroot environment. This configuration parameter requires + some additional documentation which is in the [Chroot + Mounts](#chroot-mounts) section. Please read that section for more + information on how to use this. + +- `command_wrapper` (string) - How to run shell commands. This defaults to + `{{.Command}}`. This may be useful to set if you want to set environmental + variables or perhaps run it with `sudo` or so on. This is a configuration + template where the `.Command` variable is replaced with the command to be + run. Defaults to `{{.Command}}`. + +- `copy_files` (array of strings) - Paths to files on the running Outscale + VM that will be copied into the chroot environment prior to + provisioning. Defaults to `/etc/resolv.conf` so that DNS lookups work. Pass + an empty list to skip copying `/etc/resolv.conf`. You may need to do this + if you're building an image that uses systemd. + +- `custom_endpoint_oapi` (string) - This option is useful if you use a cloud + provider whose API is compatible with Outscale OAPI. Specify another endpoint + like this `outscale.com/oapi/latest`. + +- `device_path` (string) - The path to the device where the root volume of + the source OMI will be attached. This defaults to "" (empty string), which + forces Packer to find an open device automatically. + +- `force_deregister` (boolean) - Force Packer to first deregister an existing + OMIS if one with the same name already exists. Default `false`. + +- `force_delete_snapshot` (boolean) - Force Packer to delete snapshots + associated with OMIs, which have been deregistered by `force_deregister`. + Default `false`. + +- `insecure_skip_tls_verify` (boolean) - This allows skipping TLS + verification of the OAPI endpoint. The default is `false`. + +- `from_scratch` (boolean) - Build a new volume instead of starting from an + existing OMI root volume snapshot. Default `false`. If `true`, `source_omi` + is no longer used and the following options become required: + `omi_virtualization_type`, `pre_mount_commands` and `root_volume_size`. The + below options are also required in this mode only: + +- `omi_block_device_mappings` (array of block device mappings) - Add one or more [block device mappings](https://wiki.outscale.net/display/EN/Defining+Block+Device+Mappings) to the OMI. These will be attached when booting a new VM from your OMI. To add a block device during the Packer build see `launch_block_device_mappings` below. Your options here may vary depending on the type of VM you use. The block device mappings allow for the following configuration: + + - `delete_on_vm_deletion` (boolean) - Indicates whether the BSU volume is deleted on VM termination. Default `false`. **NOTE**: If this value is not explicitly set to `true` and volumes are not cleaned up by an alternative method, additional volumes will accumulate after every build. + + - `device_name` (string) - The device name exposed to the VM (for example, `/dev/sdh` or `xvdh`). Required for every device in the block device mapping. + + - `iops` (number) - The number of I/O operations per second (IOPS) that the volume supports. See the documentation on + [IOPs](https://wiki.outscale.net/display/EN/About+Volumes#AboutVolumes-VolumeTypesVolumeTypesandIOPS) + for more information + + - `no_device` (boolean) - Suppresses the specified device included in the + block device mapping of the OMI + + - `snapshot_id` (string) - The ID of the snapshot + + - `virtual_name` (string) - The virtual device name. See the documentation on [Block Device Mapping](https://wiki.outscale.net/display/EN/Defining+Block+Device+Mappings) for more information + + - `volume_size` (number) - The size of the volume, in GiB. Required if not specifying a `snapshot_id` + + - `volume_type` (string) - The volume type. `gp2` for General Purpose (SSD) volumes, `io1` for Provisioned IOPS (SSD) volumes, and `standard` for Magnetic volumes + +- `root_device_name` (string) - The root device name. For example, `xvda`. + +- `mount_path` (string) - The path where the volume will be mounted. This is + where the chroot environment will be. This defaults to + `/mnt/packer-amazon-chroot-volumes/{{.Device}}`. This is a configuration + template where the `.Device` variable is replaced with the name of the + device where the volume is attached. + +- `mount_partition` (string) - The partition number containing the / + partition. By default this is the first partition of the volume, (for + example, `xvdf1`) but you can designate the entire block device by setting + `"mount_partition": "0"` in your config, which will mount `xvdf` instead. + +- `mount_options` (array of strings) - Options to supply the `mount` command + when mounting devices. Each option will be prefixed with `-o` and supplied + to the `mount` command ran by Packer. Because this command is ran in a + shell, user discretion is advised. See [this manual page for the mount + command](http://linuxcommand.org/man_pages/mount8.html) for valid file + system specific options. + +- `nvme_device_path` (string) - When we call the mount command (by default + `mount -o device dir`), the string provided in `nvme_mount_path` will + replace `device` in that command. When this option is not set, `device` in + that command will be something like `/dev/sdf1`, mirroring the attached + device name. This assumption works for most instances but will fail with c5 + and m5 instances. In order to use the chroot builder with c5 and m5 + instances, you must manually set `nvme_device_path` and `device_path`. + +- `pre_mount_commands` (array of strings) - A series of commands to execute + after attaching the root volume and before mounting the chroot. This is not + required unless using `from_scratch`. If so, this should include any + partitioning and filesystem creation commands. The path to the device is + provided by `{{.Device}}`. + +- `post_mount_commands` (array of strings) - As `pre_mount_commands`, but the + commands are executed after mounting the root device and before the extra + mount and copy steps. The device and mount path are provided by + `{{.Device}}` and `{{.MountPath}}`. + +- `root_volume_size` (number) - The size of the root volume in GB for the + chroot environment and the resulting OMI. Default size is the snapshot size + of the `source_omi` unless `from_scratch` is `true`, in which case this + field must be defined. + +- `root_volume_type` (string) - The type of BSU volume for the chroot + environment and resulting OMI. The default value is the type of the + `source_omi`, unless `from_scratch` is `true`, in which case the default + value is `gp2`. You can only specify `io1` if building based on top of a + `source_omi` which is also `io1`. + +- `root_volume_tags` (object of key/value strings) - Tags to apply to the + volumes that are *launched*. This is a [template + engine](/docs/templates/engine.html), see [Build template + data](#build-template-data) for more information. + +- `skip_region_validation` (boolean) - Set to true if you want to skip + validation of the region configuration option. Default `false`. + +- `snapshot_tags` (object of key/value strings) - Tags to apply to snapshot. + They will override OMI tags if already applied to snapshot. This is a + [template engine](/docs/templates/engine.html), see [Build template + data](#build-template-data) for more information. + +- `snapshot_groups` (array of strings) - A list of groups that have access to + create volumes from the snapshot(s). By default no groups have permission + to create volumes from the snapshot(s). `all` will make the snapshot + publicly accessible. + +- `snapshot_users` (array of strings) - A list of account IDs that have + access to create volumes from the snapshot(s). By default no additional + users other than the user creating the OMIS has permissions to create + volumes from the backing snapshot(s). + +- `source_omi_filter` (object) - Filters used to populate the `source_omi` field. + - `filters` (map of strings) - filters used to select a `source_omi`. + - `owners` (array of strings) - Filters the images by their owner. You may specify one or more Outscale account IDs, "self" (which will use the account whose credentials you are using to run Packer). This option is required for security reasons. + + Example: + + ``` json + { + "source_omi_filter": { + "filters": { + "virtualization-type": "hvm", + "image-name": "ubuntu/images/*ubuntu-xenial-16.04-amd64-server-*", + "root-device-type": "ebs" + }, + "owners": ["099720109477"], + } + } + ``` + + This selects an Ubuntu 16.04 HVM BSU OMIS from Canonical. NOTE: + This will fail unless *exactly* one OMIS is returned. In the above example, + `most_recent` will cause this to succeed by selecting the newest image. + + You may set this in place of `source_omi` or in conjunction with it. If you + set this in conjunction with `source_omi`, the `source_omi` will be added + to the filter. The provided `source_omi` must meet all of the filtering + criteria provided in `source_omi_filter`; this pins the OMI returned by the + filter, but will cause Packer to fail if the `source_omi` does not exist. + +- `tags` (object of key/value strings) - Tags applied to the OMI. This is a + [template engine](/docs/templates/engine.html), see [Build template + data](#build-template-data) for more information. + +## Basic Example + +Here is a basic example. It is completely valid except for the access keys: + +``` json +{ + "type": "osc-chroot", + "access_key": "YOUR KEY HERE", + "secret_key": "YOUR SECRET KEY HERE", + "source_omi": "ami-3e158364", + "omi_name": "packer-outscale-chroot {{timestamp}}" +} +``` + +## Chroot Mounts + +The `chroot_mounts` configuration can be used to mount specific devices within +the chroot. By default, the following additional mounts are added into the +chroot by Packer: + +- `/proc` (proc) +- `/sys` (sysfs) +- `/dev` (bind to real `/dev`) +- `/dev/pts` (devpts) +- `/proc/sys/fs/binfmt_misc` (binfmt\_misc) + +These default mounts are usually good enough for anyone and are sane defaults. +However, if you want to change or add the mount points, you may using the +`chroot_mounts` configuration. Here is an example configuration which only +mounts `/proc` and `/dev`: + +``` json +{ + "chroot_mounts": [ + ["proc", "proc", "/proc"], + ["bind", "/dev", "/dev"] + ] +} +``` + +`chroot_mounts` is a list of a 3-tuples of strings. The three components of the +3-tuple, in order, are: + +- The filesystem type. If this is "bind", then Packer will properly bind the + filesystem to another mount point. + +- The source device. + +- The mount directory. + +## Parallelism + +A quick note on parallelism: it is perfectly safe to run multiple *separate* +Packer processes with the `osc-chroot` builder on the same Outscale VM. In +fact, this is recommended as a way to push the most performance out of your OMI +builds. + +Packer properly obtains a process lock for the parallelism-sensitive parts of +its internals such as finding an available device. + +## Gotchas + +### Unmounting the Filesystem + +One of the difficulties with using the chroot builder is that your provisioning +scripts must not leave any processes running or packer will be unable to +unmount the filesystem. + +For debian based distributions you can setup a +[policy-rc.d](http://people.debian.org/~hmh/invokerc.d-policyrc.d-specification.txt) +file which will prevent packages installed by your provisioners from starting +services: + +``` json +{ + "type": "shell", + "inline": [ + "echo '#!/bin/sh' > /usr/sbin/policy-rc.d", + "echo 'exit 101' >> /usr/sbin/policy-rc.d", + "chmod a+x /usr/sbin/policy-rc.d" + ] +}, + +// ... + +{ + "type": "shell", + "inline": [ + "rm -f /usr/sbin/policy-rc.d" + ] +} +``` + +### Ansible provisioner + +Running ansible against `osc-chroot` requires changing the Ansible connection +to chroot and running Ansible as root/sudo. + +## Building From Scratch + +This example demonstrates the essentials of building an image from scratch. A +15G gp2 (SSD) device is created (overriding the default of standard/magnetic). +The device setup commands partition the device with one partition for use as an +HVM image and format it ext4. This builder block should be followed by +provisioning commands to install the os and bootloader. + +``` json +{ + "type": "osc-chroot", + "ami_name": "packer-from-scratch {{timestamp}}", + "from_scratch": true, + "ami_virtualization_type": "hvm", + "pre_mount_commands": [ + "parted {{.Device}} mklabel msdos mkpart primary 1M 100% set 1 boot on print", + "mkfs.ext4 {{.Device}}1" + ], + "root_volume_size": 15, + "root_device_name": "xvdf", + "ami_block_device_mappings": [ + { + "device_name": "xvdf", + "delete_on_termination": true, + "volume_type": "gp2" + } + ] +} +``` + +## Build template data + +In configuration directives marked as a template engine above, the following +variables are available: + +- `BuildRegion` - The region (for example `eu-west-2`) where Packer is building the OMI. +- `SourceOMI` - The source OMIS ID (for example `ami-a2412fcd`) used to build the OMI. +- `SourceOMIName` - The source OMIS Name (for example `ubuntu-390`) used to build the OMI. +- `SourceOMITags` - The source OMIS Tags, as a `map[string]string` object diff --git a/website/source/layouts/docs.erb b/website/source/layouts/docs.erb index 3fe54d771..34f14a03a 100644 --- a/website/source/layouts/docs.erb +++ b/website/source/layouts/docs.erb @@ -154,6 +154,9 @@ > Outscale > From 5535dfa03d2f4fd21bbd146c788c4dd98df4a468 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Tue, 2 Apr 2019 16:33:29 -0600 Subject: [PATCH 091/113] chore: go modules integration --- common/bootcommand/boot_command.go | 521 +++-------------------------- go.mod | 2 + go.sum | 2 + 3 files changed, 57 insertions(+), 468 deletions(-) diff --git a/common/bootcommand/boot_command.go b/common/bootcommand/boot_command.go index 1447a4337..fc1f75631 100644 --- a/common/bootcommand/boot_command.go +++ b/common/bootcommand/boot_command.go @@ -1,5 +1,3 @@ -// Code generated by pigeon; DO NOT EDIT. - package bootcommand import ( @@ -8,9 +6,7 @@ import ( "fmt" "io" "io/ioutil" - "math" "os" - "sort" "strconv" "strings" "time" @@ -791,85 +787,18 @@ var ( // errNoRule is returned when the grammar to parse has no rule. errNoRule = errors.New("grammar has no rule") - // errInvalidEntrypoint is returned when the specified entrypoint rule - // does not exit. - errInvalidEntrypoint = errors.New("invalid entrypoint") - // errInvalidEncoding is returned when the source is not properly // utf8-encoded. errInvalidEncoding = errors.New("invalid encoding") - // errMaxExprCnt is used to signal that the maximum number of - // expressions have been parsed. - errMaxExprCnt = errors.New("max number of expresssions parsed") + // errNoMatch is returned if no match could be found. + errNoMatch = errors.New("no match found") ) // Option is a function that can set an option on the parser. It returns // the previous setting as an Option. type Option func(*parser) Option -// MaxExpressions creates an Option to stop parsing after the provided -// number of expressions have been parsed, if the value is 0 then the parser will -// parse for as many steps as needed (possibly an infinite number). -// -// The default for maxExprCnt is 0. -func MaxExpressions(maxExprCnt uint64) Option { - return func(p *parser) Option { - oldMaxExprCnt := p.maxExprCnt - p.maxExprCnt = maxExprCnt - return MaxExpressions(oldMaxExprCnt) - } -} - -// Entrypoint creates an Option to set the rule name to use as entrypoint. -// The rule name must have been specified in the -alternate-entrypoints -// if generating the parser with the -optimize-grammar flag, otherwise -// it may have been optimized out. Passing an empty string sets the -// entrypoint to the first rule in the grammar. -// -// The default is to start parsing at the first rule in the grammar. -func Entrypoint(ruleName string) Option { - return func(p *parser) Option { - oldEntrypoint := p.entrypoint - p.entrypoint = ruleName - if ruleName == "" { - p.entrypoint = g.rules[0].name - } - return Entrypoint(oldEntrypoint) - } -} - -// Statistics adds a user provided Stats struct to the parser to allow -// the user to process the results after the parsing has finished. -// Also the key for the "no match" counter is set. -// -// Example usage: -// -// input := "input" -// stats := Stats{} -// _, err := Parse("input-file", []byte(input), Statistics(&stats, "no match")) -// if err != nil { -// log.Panicln(err) -// } -// b, err := json.MarshalIndent(stats.ChoiceAltCnt, "", " ") -// if err != nil { -// log.Panicln(err) -// } -// fmt.Println(string(b)) -// -func Statistics(stats *Stats, choiceNoMatch string) Option { - return func(p *parser) Option { - oldStats := p.Stats - p.Stats = stats - oldChoiceNoMatch := p.choiceNoMatch - p.choiceNoMatch = choiceNoMatch - if p.Stats.ChoiceAltCnt == nil { - p.Stats.ChoiceAltCnt = make(map[string]map[string]int) - } - return Statistics(oldStats, oldChoiceNoMatch) - } -} - // Debug creates an Option to set the debug flag to b. When set to true, // debugging information is printed to stdout while parsing. // @@ -896,20 +825,6 @@ func Memoize(b bool) Option { } } -// AllowInvalidUTF8 creates an Option to allow invalid UTF-8 bytes. -// Every invalid UTF-8 byte is treated as a utf8.RuneError (U+FFFD) -// by character class matchers and is matched by the any matcher. -// The returned matched value, c.text and c.offset are NOT affected. -// -// The default is false. -func AllowInvalidUTF8(b bool) Option { - return func(p *parser) Option { - old := p.allowInvalidUTF8 - p.allowInvalidUTF8 = b - return AllowInvalidUTF8(old) - } -} - // Recover creates an Option to set the recover flag to b. When set to // true, this causes the parser to recover from panics and convert it // to an error. Setting it to false can be useful while debugging to @@ -924,37 +839,13 @@ func Recover(b bool) Option { } } -// GlobalStore creates an Option to set a key to a certain value in -// the globalStore. -func GlobalStore(key string, value interface{}) Option { - return func(p *parser) Option { - old := p.cur.globalStore[key] - p.cur.globalStore[key] = value - return GlobalStore(key, old) - } -} - -// InitState creates an Option to set a key to a certain value in -// the global "state" store. -func InitState(key string, value interface{}) Option { - return func(p *parser) Option { - old := p.cur.state[key] - p.cur.state[key] = value - return InitState(key, old) - } -} - // ParseFile parses the file identified by filename. -func ParseFile(filename string, opts ...Option) (i interface{}, err error) { +func ParseFile(filename string, opts ...Option) (interface{}, error) { f, err := os.Open(filename) if err != nil { return nil, err } - defer func() { - if closeErr := f.Close(); closeErr != nil { - err = closeErr - } - }() + defer f.Close() return ParseReader(filename, f, opts...) } @@ -995,22 +886,8 @@ type savepoint struct { type current struct { pos position // start position of the match text []byte // raw text of the match - - // state is a store for arbitrary key,value pairs that the user wants to be - // tied to the backtracking of the parser. - // This is always rolled back if a parsing rule fails. - state storeDict - - // globalStore is a general store for the user to store arbitrary key-value - // pairs that they need to manage and that they do not want tied to the - // backtracking of the parser. This is only modified by the user and never - // rolled back by the parser. It is always up to the user to keep this in a - // consistent state. - globalStore storeDict } -type storeDict map[string]interface{} - // the AST types... type grammar struct { @@ -1036,23 +913,11 @@ type actionExpr struct { run func(*parser) (interface{}, error) } -type recoveryExpr struct { - pos position - expr interface{} - recoverExpr interface{} - failureLabel []string -} - type seqExpr struct { pos position exprs []interface{} } -type throwExpr struct { - pos position - label string -} - type labeledExpr struct { pos position label string @@ -1075,11 +940,6 @@ type ruleRefExpr struct { name string } -type stateCodeExpr struct { - pos position - run func(*parser) error -} - type andCodeExpr struct { pos position run func(*parser) (bool, error) @@ -1097,14 +957,13 @@ type litMatcher struct { } type charClassMatcher struct { - pos position - val string - basicLatinChars [128]bool - chars []rune - ranges []rune - classes []*unicode.RangeTable - ignoreCase bool - inverted bool + pos position + val string + chars []rune + ranges []rune + classes []*unicode.RangeTable + ignoreCase bool + inverted bool } type anyMatcher position @@ -1158,10 +1017,9 @@ func (e errList) Error() string { // parserError wraps an error with a prefix indicating the rule in which // the error occurred. The original error is stored in the Inner field. type parserError struct { - Inner error - pos position - prefix string - expected []string + Inner error + pos position + prefix string } // Error returns the error message. @@ -1171,32 +1029,14 @@ func (p *parserError) Error() string { // newParser creates a parser with the specified input source and options. func newParser(filename string, b []byte, opts ...Option) *parser { - stats := Stats{ - ChoiceAltCnt: make(map[string]map[string]int), - } - p := &parser{ filename: filename, errs: new(errList), data: b, pt: savepoint{position: position{line: 1}}, recover: true, - cur: current{ - state: make(storeDict), - globalStore: make(storeDict), - }, - maxFailPos: position{col: 1, line: 1}, - maxFailExpected: make([]string, 0, 20), - Stats: &stats, - // start rule is rule [0] unless an alternate entrypoint is specified - entrypoint: g.rules[0].name, } p.setOptions(opts) - - if p.maxExprCnt == 0 { - p.maxExprCnt = math.MaxUint64 - } - return p } @@ -1213,30 +1053,6 @@ type resultTuple struct { end savepoint } -const choiceNoMatch = -1 - -// Stats stores some statistics, gathered during parsing -type Stats struct { - // ExprCnt counts the number of expressions processed during parsing - // This value is compared to the maximum number of expressions allowed - // (set by the MaxExpressions option). - ExprCnt uint64 - - // ChoiceAltCnt is used to count for each ordered choice expression, - // which alternative is used how may times. - // These numbers allow to optimize the order of the ordered choice expression - // to increase the performance of the parser - // - // The outer key of ChoiceAltCnt is composed of the name of the rule as well - // as the line and the column of the ordered choice. - // The inner key of ChoiceAltCnt is the number (one-based) of the matching alternative. - // For each alternative the number of matches are counted. If an ordered choice does not - // match, a special counter is incremented. The name of this counter is set with - // the parser option Statistics. - // For an alternative to be included in ChoiceAltCnt, it has to match at least once. - ChoiceAltCnt map[string]map[string]int -} - type parser struct { filename string pt savepoint @@ -1245,9 +1061,9 @@ type parser struct { data []byte errs *errList - depth int recover bool debug bool + depth int memoize bool // memoization table for the packrat algorithm: @@ -1261,23 +1077,8 @@ type parser struct { // rule stack, allows identification of the current rule in errors rstack []*rule - // parse fail - maxFailPos position - maxFailExpected []string - maxFailInvertExpected bool - - // max number of expressions to be parsed - maxExprCnt uint64 - // entrypoint for the parser - entrypoint string - - allowInvalidUTF8 bool - - *Stats - - choiceNoMatch string - // recovery expression stack, keeps track of the currently available recovery expression, these are traversed in reverse - recoveryStack []map[string]interface{} + // stats + exprCnt int } // push a variable set on the vstack. @@ -1312,31 +1113,6 @@ func (p *parser) popV() { p.vstack = p.vstack[:len(p.vstack)-1] } -// push a recovery expression with its labels to the recoveryStack -func (p *parser) pushRecovery(labels []string, expr interface{}) { - if cap(p.recoveryStack) == len(p.recoveryStack) { - // create new empty slot in the stack - p.recoveryStack = append(p.recoveryStack, nil) - } else { - // slice to 1 more - p.recoveryStack = p.recoveryStack[:len(p.recoveryStack)+1] - } - - m := make(map[string]interface{}, len(labels)) - for _, fl := range labels { - m[fl] = expr - } - p.recoveryStack[len(p.recoveryStack)-1] = m -} - -// pop a recovery expression from the recoveryStack -func (p *parser) popRecovery() { - // GC that map - p.recoveryStack[len(p.recoveryStack)-1] = nil - - p.recoveryStack = p.recoveryStack[:len(p.recoveryStack)-1] -} - func (p *parser) print(prefix, s string) string { if !p.debug { return s @@ -1358,10 +1134,10 @@ func (p *parser) out(s string) string { } func (p *parser) addErr(err error) { - p.addErrAt(err, p.pt.position, []string{}) + p.addErrAt(err, p.pt.position) } -func (p *parser) addErrAt(err error, pos position, expected []string) { +func (p *parser) addErrAt(err error, pos position) { var buf bytes.Buffer if p.filename != "" { buf.WriteString(p.filename) @@ -1381,29 +1157,10 @@ func (p *parser) addErrAt(err error, pos position, expected []string) { buf.WriteString("rule " + rule.name) } } - pe := &parserError{Inner: err, pos: pos, prefix: buf.String(), expected: expected} + pe := &parserError{Inner: err, pos: pos, prefix: buf.String()} p.errs.add(pe) } -func (p *parser) failAt(fail bool, pos position, want string) { - // process fail if parsing fails and not inverted or parsing succeeds and invert is set - if fail == p.maxFailInvertExpected { - if pos.offset < p.maxFailPos.offset { - return - } - - if pos.offset > p.maxFailPos.offset { - p.maxFailPos = pos - p.maxFailExpected = p.maxFailExpected[:0] - } - - if p.maxFailInvertExpected { - want = "!" + want - } - p.maxFailExpected = append(p.maxFailExpected, want) - } -} - // read advances the parser to the next rune. func (p *parser) read() { p.pt.offset += p.pt.w @@ -1416,8 +1173,8 @@ func (p *parser) read() { p.pt.col = 0 } - if rn == utf8.RuneError && n == 1 { // see utf8.DecodeRune - if !p.allowInvalidUTF8 { + if rn == utf8.RuneError { + if n == 1 { p.addErr(errInvalidEncoding) } } @@ -1434,43 +1191,6 @@ func (p *parser) restore(pt savepoint) { p.pt = pt } -// Cloner is implemented by any value that has a Clone method, which returns a -// copy of the value. This is mainly used for types which are not passed by -// value (e.g map, slice, chan) or structs that contain such types. -// -// This is used in conjunction with the global state feature to create proper -// copies of the state to allow the parser to properly restore the state in -// the case of backtracking. -type Cloner interface { - Clone() interface{} -} - -// clone and return parser current state. -func (p *parser) cloneState() storeDict { - if p.debug { - defer p.out(p.in("cloneState")) - } - - state := make(storeDict, len(p.cur.state)) - for k, v := range p.cur.state { - if c, ok := v.(Cloner); ok { - state[k] = c.Clone() - } else { - state[k] = v - } - } - return state -} - -// restore parser current state to the state storeDict. -// every restoreState should applied only one time for every cloned state -func (p *parser) restoreState(state storeDict) { - if p.debug { - defer p.out(p.in("restoreState")) - } - p.cur.state = state -} - // get the slice of bytes from the savepoint start to the current position. func (p *parser) sliceFrom(start savepoint) []byte { return p.data[start.position.offset:p.pt.position.offset] @@ -1536,54 +1256,19 @@ func (p *parser) parse(g *grammar) (val interface{}, err error) { }() } - startRule, ok := p.rules[p.entrypoint] - if !ok { - p.addErr(errInvalidEntrypoint) - return nil, p.errs.err() - } - + // start rule is rule [0] p.read() // advance to first rune - val, ok = p.parseRule(startRule) + val, ok := p.parseRule(g.rules[0]) if !ok { if len(*p.errs) == 0 { - // If parsing fails, but no errors have been recorded, the expected values - // for the farthest parser position are returned as error. - maxFailExpectedMap := make(map[string]struct{}, len(p.maxFailExpected)) - for _, v := range p.maxFailExpected { - maxFailExpectedMap[v] = struct{}{} - } - expected := make([]string, 0, len(maxFailExpectedMap)) - eof := false - if _, ok := maxFailExpectedMap["!."]; ok { - delete(maxFailExpectedMap, "!.") - eof = true - } - for k := range maxFailExpectedMap { - expected = append(expected, k) - } - sort.Strings(expected) - if eof { - expected = append(expected, "EOF") - } - p.addErrAt(errors.New("no match found, expected: "+listJoin(expected, ", ", "or")), p.maxFailPos, expected) + // make sure this doesn't go out silently + p.addErr(errNoMatch) } - return nil, p.errs.err() } return val, p.errs.err() } -func listJoin(list []string, sep string, lastSep string) string { - switch len(list) { - case 0: - return "" - case 1: - return list[0] - default: - return fmt.Sprintf("%s %s %s", strings.Join(list[:len(list)-1], sep), lastSep, list[len(list)-1]) - } -} - func (p *parser) parseRule(rule *rule) (interface{}, bool) { if p.debug { defer p.out(p.in("parseRule " + rule.name)) @@ -1615,6 +1300,7 @@ func (p *parser) parseRule(rule *rule) (interface{}, bool) { func (p *parser) parseExpr(expr interface{}) (interface{}, bool) { var pt savepoint + var ok bool if p.memoize { res, ok := p.getMemoized(expr) @@ -1625,13 +1311,8 @@ func (p *parser) parseExpr(expr interface{}) (interface{}, bool) { pt = p.pt } - p.ExprCnt++ - if p.ExprCnt > p.maxExprCnt { - panic(errMaxExprCnt) - } - + p.exprCnt++ var val interface{} - var ok bool switch expr := expr.(type) { case *actionExpr: val, ok = p.parseActionExpr(expr) @@ -1655,16 +1336,10 @@ func (p *parser) parseExpr(expr interface{}) (interface{}, bool) { val, ok = p.parseNotExpr(expr) case *oneOrMoreExpr: val, ok = p.parseOneOrMoreExpr(expr) - case *recoveryExpr: - val, ok = p.parseRecoveryExpr(expr) case *ruleRefExpr: val, ok = p.parseRuleRefExpr(expr) case *seqExpr: val, ok = p.parseSeqExpr(expr) - case *stateCodeExpr: - val, ok = p.parseStateCodeExpr(expr) - case *throwExpr: - val, ok = p.parseThrowExpr(expr) case *zeroOrMoreExpr: val, ok = p.parseZeroOrMoreExpr(expr) case *zeroOrOneExpr: @@ -1688,13 +1363,10 @@ func (p *parser) parseActionExpr(act *actionExpr) (interface{}, bool) { if ok { p.cur.pos = start.position p.cur.text = p.sliceFrom(start) - state := p.cloneState() actVal, err := act.run(p) if err != nil { - p.addErrAt(err, start.position, []string{}) + p.addErrAt(err, start.position) } - p.restoreState(state) - val = actVal } if ok && p.debug { @@ -1708,14 +1380,10 @@ func (p *parser) parseAndCodeExpr(and *andCodeExpr) (interface{}, bool) { defer p.out(p.in("parseAndCodeExpr")) } - state := p.cloneState() - ok, err := and.run(p) if err != nil { p.addErr(err) } - p.restoreState(state) - return nil, ok } @@ -1725,13 +1393,10 @@ func (p *parser) parseAndExpr(and *andExpr) (interface{}, bool) { } pt := p.pt - state := p.cloneState() p.pushV() _, ok := p.parseExpr(and.expr) p.popV() - p.restoreState(state) p.restore(pt) - return nil, ok } @@ -1740,15 +1405,12 @@ func (p *parser) parseAnyMatcher(any *anyMatcher) (interface{}, bool) { defer p.out(p.in("parseAnyMatcher")) } - if p.pt.rn == utf8.RuneError && p.pt.w == 0 { - // EOF - see utf8.DecodeRune - p.failAt(false, p.pt.position, ".") - return nil, false + if p.pt.rn != utf8.RuneError { + start := p.pt + p.read() + return p.sliceFrom(start), true } - start := p.pt - p.read() - p.failAt(true, start.position, ".") - return p.sliceFrom(start), true + return nil, false } func (p *parser) parseCharClassMatcher(chr *charClassMatcher) (interface{}, bool) { @@ -1757,14 +1419,11 @@ func (p *parser) parseCharClassMatcher(chr *charClassMatcher) (interface{}, bool } cur := p.pt.rn - start := p.pt - // can't match EOF - if cur == utf8.RuneError && p.pt.w == 0 { // see utf8.DecodeRune - p.failAt(false, start.position, chr.val) + if cur == utf8.RuneError { return nil, false } - + start := p.pt if chr.ignoreCase { cur = unicode.ToLower(cur) } @@ -1773,11 +1432,9 @@ func (p *parser) parseCharClassMatcher(chr *charClassMatcher) (interface{}, bool for _, rn := range chr.chars { if rn == cur { if chr.inverted { - p.failAt(false, start.position, chr.val) return nil, false } p.read() - p.failAt(true, start.position, chr.val) return p.sliceFrom(start), true } } @@ -1786,11 +1443,9 @@ func (p *parser) parseCharClassMatcher(chr *charClassMatcher) (interface{}, bool for i := 0; i < len(chr.ranges); i += 2 { if cur >= chr.ranges[i] && cur <= chr.ranges[i+1] { if chr.inverted { - p.failAt(false, start.position, chr.val) return nil, false } p.read() - p.failAt(true, start.position, chr.val) return p.sliceFrom(start), true } } @@ -1799,60 +1454,33 @@ func (p *parser) parseCharClassMatcher(chr *charClassMatcher) (interface{}, bool for _, cl := range chr.classes { if unicode.Is(cl, cur) { if chr.inverted { - p.failAt(false, start.position, chr.val) return nil, false } p.read() - p.failAt(true, start.position, chr.val) return p.sliceFrom(start), true } } if chr.inverted { p.read() - p.failAt(true, start.position, chr.val) return p.sliceFrom(start), true } - p.failAt(false, start.position, chr.val) return nil, false } -func (p *parser) incChoiceAltCnt(ch *choiceExpr, altI int) { - choiceIdent := fmt.Sprintf("%s %d:%d", p.rstack[len(p.rstack)-1].name, ch.pos.line, ch.pos.col) - m := p.ChoiceAltCnt[choiceIdent] - if m == nil { - m = make(map[string]int) - p.ChoiceAltCnt[choiceIdent] = m - } - // We increment altI by 1, so the keys do not start at 0 - alt := strconv.Itoa(altI + 1) - if altI == choiceNoMatch { - alt = p.choiceNoMatch - } - m[alt]++ -} - func (p *parser) parseChoiceExpr(ch *choiceExpr) (interface{}, bool) { if p.debug { defer p.out(p.in("parseChoiceExpr")) } - for altI, alt := range ch.alternatives { - // dummy assignment to prevent compile error if optimized - _ = altI - - state := p.cloneState() - + for _, alt := range ch.alternatives { p.pushV() val, ok := p.parseExpr(alt) p.popV() if ok { - p.incChoiceAltCnt(ch, altI) return val, ok } - p.restoreState(state) } - p.incChoiceAltCnt(ch, choiceNoMatch) return nil, false } @@ -1876,11 +1504,6 @@ func (p *parser) parseLitMatcher(lit *litMatcher) (interface{}, bool) { defer p.out(p.in("parseLitMatcher")) } - ignoreCase := "" - if lit.ignoreCase { - ignoreCase = "i" - } - val := fmt.Sprintf("%q%s", lit.val, ignoreCase) start := p.pt for _, want := range lit.val { cur := p.pt.rn @@ -1888,13 +1511,11 @@ func (p *parser) parseLitMatcher(lit *litMatcher) (interface{}, bool) { cur = unicode.ToLower(cur) } if cur != want { - p.failAt(false, start.position, val) p.restore(start) return nil, false } p.read() } - p.failAt(true, start.position, val) return p.sliceFrom(start), true } @@ -1903,14 +1524,10 @@ func (p *parser) parseNotCodeExpr(not *notCodeExpr) (interface{}, bool) { defer p.out(p.in("parseNotCodeExpr")) } - state := p.cloneState() - ok, err := not.run(p) if err != nil { p.addErr(err) } - p.restoreState(state) - return nil, !ok } @@ -1920,15 +1537,10 @@ func (p *parser) parseNotExpr(not *notExpr) (interface{}, bool) { } pt := p.pt - state := p.cloneState() p.pushV() - p.maxFailInvertExpected = !p.maxFailInvertExpected _, ok := p.parseExpr(not.expr) - p.maxFailInvertExpected = !p.maxFailInvertExpected p.popV() - p.restoreState(state) p.restore(pt) - return nil, !ok } @@ -1954,18 +1566,6 @@ func (p *parser) parseOneOrMoreExpr(expr *oneOrMoreExpr) (interface{}, bool) { } } -func (p *parser) parseRecoveryExpr(recover *recoveryExpr) (interface{}, bool) { - if p.debug { - defer p.out(p.in("parseRecoveryExpr (" + strings.Join(recover.failureLabel, ",") + ")")) - } - - p.pushRecovery(recover.failureLabel, recover.recoverExpr) - val, ok := p.parseExpr(recover.expr) - p.popRecovery() - - return val, ok -} - func (p *parser) parseRuleRefExpr(ref *ruleRefExpr) (interface{}, bool) { if p.debug { defer p.out(p.in("parseRuleRefExpr " + ref.name)) @@ -1988,14 +1588,12 @@ func (p *parser) parseSeqExpr(seq *seqExpr) (interface{}, bool) { defer p.out(p.in("parseSeqExpr")) } - vals := make([]interface{}, 0, len(seq.exprs)) + var vals []interface{} pt := p.pt - state := p.cloneState() for _, expr := range seq.exprs { val, ok := p.parseExpr(expr) if !ok { - p.restoreState(state) p.restore(pt) return nil, false } @@ -2004,34 +1602,6 @@ func (p *parser) parseSeqExpr(seq *seqExpr) (interface{}, bool) { return vals, true } -func (p *parser) parseStateCodeExpr(state *stateCodeExpr) (interface{}, bool) { - if p.debug { - defer p.out(p.in("parseStateCodeExpr")) - } - - err := state.run(p) - if err != nil { - p.addErr(err) - } - return nil, true -} - -func (p *parser) parseThrowExpr(expr *throwExpr) (interface{}, bool) { - if p.debug { - defer p.out(p.in("parseThrowExpr")) - } - - for i := len(p.recoveryStack) - 1; i >= 0; i-- { - if recoverExpr, ok := p.recoveryStack[i][expr.label]; ok { - if val, ok := p.parseExpr(recoverExpr); ok { - return val, ok - } - } - } - - return nil, false -} - func (p *parser) parseZeroOrMoreExpr(expr *zeroOrMoreExpr) (interface{}, bool) { if p.debug { defer p.out(p.in("parseZeroOrMoreExpr")) @@ -2061,3 +1631,18 @@ func (p *parser) parseZeroOrOneExpr(expr *zeroOrOneExpr) (interface{}, bool) { // whether it matched or not, consider it a match return val, true } + +func rangeTable(class string) *unicode.RangeTable { + if rt, ok := unicode.Categories[class]; ok { + return rt + } + if rt, ok := unicode.Properties[class]; ok { + return rt + } + if rt, ok := unicode.Scripts[class]; ok { + return rt + } + + // cannot happen + panic(fmt.Sprintf("invalid Unicode class: %s", class)) +} diff --git a/go.mod b/go.mod index 661ece0da..20054550f 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/Azure/azure-sdk-for-go v30.0.0+incompatible github.com/Azure/go-autorest v12.0.0+incompatible github.com/Azure/go-ntlmssp v0.0.0-20180810175552-4a21cbd618b4 // indirect + github.com/Bowery/prompt v0.0.0-20180817134258-8a1d5376df1c // indirect github.com/ChrisTrenkamp/goxpath v0.0.0-20170625215350-4fe035839290 github.com/NaverCloudPlatform/ncloud-sdk-go v0.0.0-20180110055012-c2e73f942591 github.com/Telmate/proxmox-api-go v0.0.0-20190614181158-26cd147831a4 @@ -63,6 +64,7 @@ require ( github.com/joyent/triton-go v0.0.0-20180116165742-545edbe0d564 github.com/json-iterator/go v1.1.6 // indirect github.com/jtolds/gls v4.2.1+incompatible // indirect + github.com/kardianos/govendor v1.0.9 // indirect github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1 github.com/klauspost/compress v0.0.0-20160131094358-f86d2e6d8a77 // indirect github.com/klauspost/cpuid v0.0.0-20160106104451-349c67577817 // indirect diff --git a/go.sum b/go.sum index 88c1c04b9..2e93bff22 100644 --- a/go.sum +++ b/go.sum @@ -26,6 +26,7 @@ github.com/Azure/go-autorest/tracing v0.1.0 h1:TRBxC5Pj/fIuh4Qob0ZpkggbfT8RC0Sub github.com/Azure/go-autorest/tracing v0.1.0/go.mod h1:ROEEAFwXycQw7Sn3DXNtEedEvdeRAgDr0izn4z5Ij88= github.com/Azure/go-ntlmssp v0.0.0-20180810175552-4a21cbd618b4 h1:pSm8mp0T2OH2CPmPDPtwHPr3VAQaOwVF/JbllOPP4xA= github.com/Azure/go-ntlmssp v0.0.0-20180810175552-4a21cbd618b4/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= +github.com/Bowery/prompt v0.0.0-20180817134258-8a1d5376df1c/go.mod h1:4/6eNcqZ09BZ9wLK3tZOjBA1nDj+B0728nlX5YRlSmQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/ChrisTrenkamp/goxpath v0.0.0-20170625215350-4fe035839290 h1:K9I21XUHNbYD3GNMmJBN0UKJCpdP+glftwNZ7Bo8kqY= github.com/ChrisTrenkamp/goxpath v0.0.0-20170625215350-4fe035839290/go.mod h1:nuWgzSkT5PnyOd+272uUmV0dnAnAn42Mk7PiQC5VzN4= @@ -249,6 +250,7 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kardianos/govendor v1.0.9/go.mod h1:yvmR6q9ZZ7nSF5Wvh40v0wfP+3TwwL8zYQp+itoZSVM= github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1 h1:PJPDf8OUfOK1bb/NeTKd4f1QXZItOX389VN3B6qC8ro= github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= From 4b52816935474dae614e4eed89edfbb8752e69c4 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Wed, 3 Apr 2019 13:30:52 -0600 Subject: [PATCH 092/113] fix: go modules conflicts --- builder/amazon/ebssurrogate/builder.go | 2 +- builder/osc/bsu/builder.go | 2 +- builder/osc/bsusurrogate/builder.go | 2 +- builder/osc/bsuvolume/builder.go | 2 +- builder/osc/chroot/builder.go | 2 +- builder/osc/chroot/step_create_volume.go | 6 ++++++ 6 files changed, 11 insertions(+), 5 deletions(-) diff --git a/builder/amazon/ebssurrogate/builder.go b/builder/amazon/ebssurrogate/builder.go index ad5126cc0..0c1219063 100644 --- a/builder/amazon/ebssurrogate/builder.go +++ b/builder/amazon/ebssurrogate/builder.go @@ -218,7 +218,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack &awscommon.StepKeyPair{ Debug: b.config.PackerDebug, Comm: &b.config.RunConfig.Comm, - DebugKeyPath: fmt.Sprintf("ec2_%s", b.config.PackerBuildName), + DebugKeyPath: fmt.Sprintf("ec2_%s.pem", b.config.PackerBuildName), }, &awscommon.StepSecurityGroup{ SecurityGroupFilter: b.config.SecurityGroupFilter, diff --git a/builder/osc/bsu/builder.go b/builder/osc/bsu/builder.go index f0d804d37..0c51768f3 100644 --- a/builder/osc/bsu/builder.go +++ b/builder/osc/bsu/builder.go @@ -80,7 +80,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { return nil, nil } -func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { +func (b *Builder) Run(ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { clientConfig, err := b.config.Config() if err != nil { return nil, err diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index 1649fcede..bc6822b60 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -106,7 +106,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { } -func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { +func (b *Builder) Run(ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { clientConfig, err := b.config.Config() if err != nil { return nil, err diff --git a/builder/osc/bsuvolume/builder.go b/builder/osc/bsuvolume/builder.go index 363e50faf..07e8b1441 100644 --- a/builder/osc/bsuvolume/builder.go +++ b/builder/osc/bsuvolume/builder.go @@ -82,7 +82,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { return nil, nil } -func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { +func (b *Builder) Run(ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { clientConfig, err := b.config.Config() if err != nil { return nil, err diff --git a/builder/osc/chroot/builder.go b/builder/osc/chroot/builder.go index f809ea219..c5bcf950d 100644 --- a/builder/osc/chroot/builder.go +++ b/builder/osc/chroot/builder.go @@ -183,7 +183,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { return warns, nil } -func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { +func (b *Builder) Run(ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { if runtime.GOOS != "linux" { return nil, errors.New("The outscale-chroot builder only works on Linux environments.") } diff --git a/builder/osc/chroot/step_create_volume.go b/builder/osc/chroot/step_create_volume.go index 6944ceef9..7cc9d022f 100644 --- a/builder/osc/chroot/step_create_volume.go +++ b/builder/osc/chroot/step_create_volume.go @@ -36,6 +36,12 @@ func (s *StepCreateVolume) Run(ctx context.Context, state multistep.StateBag) mu volTags, err := s.RootVolumeTags.OAPITags(s.Ctx, oapiconn.GetConfig().Region, state) + if err != nil { + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + var createVolume *oapi.CreateVolumeRequest if config.FromScratch { rootVolumeType := osccommon.VolumeTypeGp2 From 1811b3af521518c70d87cdb6e521a422f66fcf30 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Fri, 5 Apr 2019 14:36:53 -0600 Subject: [PATCH 093/113] chore: remove unused buildBlockDevice function --- builder/osc/common/block_device.go | 47 ------------------------------ 1 file changed, 47 deletions(-) diff --git a/builder/osc/common/block_device.go b/builder/osc/common/block_device.go index 3f6abdd85..ca6b2fbf6 100644 --- a/builder/osc/common/block_device.go +++ b/builder/osc/common/block_device.go @@ -37,53 +37,6 @@ type LaunchBlockDevices struct { LaunchMappings []BlockDevice `mapstructure:"launch_block_device_mappings"` } -func buildBlockDevices(b []BlockDevice) []*oapi.BlockDeviceMapping { - var blockDevices []*oapi.BlockDeviceMapping - - for _, blockDevice := range b { - mapping := &oapi.BlockDeviceMapping{ - DeviceName: blockDevice.DeviceName, - } - - if blockDevice.NoDevice { - mapping.NoDevice = "" - } else if blockDevice.VirtualName != "" { - if strings.HasPrefix(blockDevice.VirtualName, "ephemeral") { - mapping.VirtualDeviceName = blockDevice.VirtualName - } - } else { - bsu := oapi.Bsu{} - bsu.DeleteOnVmDeletion = aws.Bool(blockDevice.DeleteOnVmDeletion) - - if blockDevice.VolumeType != "" { - bsu.VolumeType = blockDevice.VolumeType - } - - if blockDevice.VolumeSize > 0 { - bsu.VolumeSize = blockDevice.VolumeSize - } - - // IOPS is only valid for io1 type - if blockDevice.VolumeType == "io1" { - bsu.Iops = blockDevice.IOPS - } - - if blockDevice.SnapshotId != "" { - bsu.SnapshotId = blockDevice.SnapshotId - } - - //missing - //BlockDevice Encrypted - //KmsKeyId - - mapping.Bsu = bsu - } - - blockDevices = append(blockDevices, mapping) - } - return blockDevices -} - func buildBlockDevicesImage(b []BlockDevice) []oapi.BlockDeviceMappingImage { var blockDevices []oapi.BlockDeviceMappingImage From d2dec2f01489e2fcb05afc3b1948cc76e8782c24 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Fri, 5 Apr 2019 14:38:08 -0600 Subject: [PATCH 094/113] chore: add removed comment in boot_command --- common/bootcommand/boot_command.go | 1 + 1 file changed, 1 insertion(+) diff --git a/common/bootcommand/boot_command.go b/common/bootcommand/boot_command.go index fc1f75631..ff4e6ebde 100644 --- a/common/bootcommand/boot_command.go +++ b/common/bootcommand/boot_command.go @@ -1,3 +1,4 @@ +// Code generated by pigeon; DO NOT EDIT. package bootcommand import ( From 04534d87acacfe1cda018e3734d6d3c29c5287ae Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Fri, 5 Apr 2019 14:39:00 -0600 Subject: [PATCH 095/113] chore: change templateCleanOMIName to templateCleanResourceName function : --- builder/osc/common/omi_config.go | 2 +- builder/osc/common/template_funcs.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/builder/osc/common/omi_config.go b/builder/osc/common/omi_config.go index 684f6fca4..5e7b520fd 100644 --- a/builder/osc/common/omi_config.go +++ b/builder/osc/common/omi_config.go @@ -50,7 +50,7 @@ func (c *OMIConfig) Prepare(accessConfig *AccessConfig, ctx *interpolate.Context errs = append(errs, fmt.Errorf("omi_name must be between 3 and 128 characters long")) } - if c.OMIName != templateCleanOMIName(c.OMIName) { + if c.OMIName != templateCleanResourceName(c.OMIName) { errs = append(errs, fmt.Errorf("OMIName should only contain "+ "alphanumeric characters, parentheses (()), square brackets ([]), spaces "+ "( ), periods (.), slashes (/), dashes (-), single quotes ('), at-signs "+ diff --git a/builder/osc/common/template_funcs.go b/builder/osc/common/template_funcs.go index 1b574f75b..78680c5c1 100644 --- a/builder/osc/common/template_funcs.go +++ b/builder/osc/common/template_funcs.go @@ -18,7 +18,7 @@ func isalphanumeric(b byte) bool { return false } -func templateCleanOMIName(s string) string { +func templateCleanResourceName(s string) string { allowed := []byte{'(', ')', '[', ']', ' ', '.', '/', '-', '\'', '@', '_'} b := []byte(s) newb := make([]byte, len(b)) @@ -33,5 +33,5 @@ func templateCleanOMIName(s string) string { } var TemplateFuncs = template.FuncMap{ - "clean_omi_name": templateCleanOMIName, + "clean_resource_name": templateCleanResourceName, } From 590bef0969e12dc449181279de6af094105b90d7 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Fri, 5 Apr 2019 14:43:51 -0600 Subject: [PATCH 096/113] chore: fix bad comments --- builder/osc/bsu/builder.go | 2 +- builder/osc/common/step_cleanup_volumes.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/osc/bsu/builder.go b/builder/osc/bsu/builder.go index 0c51768f3..c04e451c2 100644 --- a/builder/osc/bsu/builder.go +++ b/builder/osc/bsu/builder.go @@ -1,4 +1,4 @@ -// The amazonebs package contains a packer.Builder implementation that +// The bsu package contains a packer.Builder implementation that // builds OMIs for Outscale OAPI. // // In general, there are two types of OMIs that can be created: ebs-backed or diff --git a/builder/osc/common/step_cleanup_volumes.go b/builder/osc/common/step_cleanup_volumes.go index a65b1325d..79d3e123f 100644 --- a/builder/osc/common/step_cleanup_volumes.go +++ b/builder/osc/common/step_cleanup_volumes.go @@ -75,7 +75,7 @@ func (s *StepCleanupVolumes) Cleanup(state multistep.StateBag) { } // Filter out any devices created as part of the launch mappings, since - // we'll let amazon follow the `delete_on_termination` setting. + // we'll let outscale follow the `delete_on_vm_deletion` setting. for _, b := range s.BlockDevices.LaunchMappings { for volKey, volName := range volList { if volName == b.DeviceName { From f28c3877e3b087d321f2924c6b504ec1093dc29b Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Fri, 5 Apr 2019 16:06:17 -0600 Subject: [PATCH 097/113] refactor: remove unused attributes --- builder/osc/bsu/builder.go | 12 +++--------- builder/osc/bsusurrogate/builder.go | 20 +++----------------- builder/osc/chroot/builder.go | 8 +++----- builder/osc/common/omi_config.go | 2 -- builder/osc/common/step_source_omi_info.go | 8 +++----- 5 files changed, 12 insertions(+), 38 deletions(-) diff --git a/builder/osc/bsu/builder.go b/builder/osc/bsu/builder.go index c04e451c2..5c5a2fc20 100644 --- a/builder/osc/bsu/builder.go +++ b/builder/osc/bsu/builder.go @@ -108,11 +108,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { ForceDeregister: b.config.OMIForceDeregister, }, &osccommon.StepSourceOMIInfo{ - SourceOmi: b.config.SourceOmi, - EnableOMISriovNetSupport: b.config.OMISriovNetSupport, - EnableOMIENASupport: b.config.OMIENASupport, - OmiFilters: b.config.SourceOmiFilter, - OMIVirtType: b.config.OMIVirtType, //TODO: Remove if it is not used + SourceOmi: b.config.SourceOmi, + OmiFilters: b.config.SourceOmiFilter, + OMIVirtType: b.config.OMIVirtType, //TODO: Remove if it is not used }, &osccommon.StepNetworkInfo{ NetId: b.config.NetId, @@ -177,10 +175,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { Skip: false, DisableStopVm: b.config.DisableStopVm, }, - &osccommon.StepUpdateBSUBackedVm{ - EnableAMISriovNetSupport: b.config.OMISriovNetSupport, - EnableAMIENASupport: b.config.OMIENASupport, - }, &osccommon.StepDeregisterOMI{ AccessConfig: &b.config.AccessConfig, ForceDeregister: b.config.OMIForceDeregister, diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index bc6822b60..52b32130d 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -89,14 +89,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { errs = packer.MultiErrorAppend(errs, fmt.Errorf("no volume with name '%s' is found", b.config.RootDevice.SourceDeviceName)) } - //TODO: Chek if this is necessary - if b.config.IsSpotVm() && ((b.config.OMIENASupport != nil && *b.config.OMIENASupport) || b.config.OMISriovNetSupport) { - errs = packer.MultiErrorAppend(errs, - fmt.Errorf("Spot instances do not support modification, which is required "+ - "when either `ena_support` or `sriov_support` are set. Please ensure "+ - "you use an OMI that already has either SR-IOV or ENA enabled.")) - } - if errs != nil && len(errs.Errors) > 0 { return nil, errs } @@ -139,11 +131,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { ForceDeregister: b.config.OMIForceDeregister, }, &osccommon.StepSourceOMIInfo{ - SourceOmi: b.config.SourceOmi, - EnableOMISriovNetSupport: b.config.OMISriovNetSupport, - EnableOMIENASupport: b.config.OMIENASupport, - OmiFilters: b.config.SourceOmiFilter, - OMIVirtType: b.config.OMIVirtType, //TODO: Remove if it is not used + SourceOmi: b.config.SourceOmi, + OmiFilters: b.config.SourceOmiFilter, + OMIVirtType: b.config.OMIVirtType, //TODO: Remove if it is not used }, &osccommon.StepNetworkInfo{ NetId: b.config.NetId, @@ -208,10 +198,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { Skip: false, DisableStopVm: b.config.DisableStopVm, }, - &osccommon.StepUpdateBSUBackedVm{ - EnableAMISriovNetSupport: b.config.OMISriovNetSupport, - EnableAMIENASupport: b.config.OMIENASupport, - }, &StepSnapshotVolumes{ LaunchDevices: launchDevices, }, diff --git a/builder/osc/chroot/builder.go b/builder/osc/chroot/builder.go index c5bcf950d..8606bf0b8 100644 --- a/builder/osc/chroot/builder.go +++ b/builder/osc/chroot/builder.go @@ -228,11 +228,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { if !b.config.FromScratch { steps = append(steps, &osccommon.StepSourceOMIInfo{ - SourceOmi: b.config.SourceOMI, - EnableOMISriovNetSupport: b.config.OMISriovNetSupport, - EnableOMIENASupport: b.config.OMIENASupport, - OmiFilters: b.config.SourceOMIFilter, - OMIVirtType: b.config.OMIVirtType, + SourceOmi: b.config.SourceOMI, + OmiFilters: b.config.SourceOMIFilter, + OMIVirtType: b.config.OMIVirtType, }, &StepCheckRootDevice{}, ) diff --git a/builder/osc/common/omi_config.go b/builder/osc/common/omi_config.go index 5e7b520fd..6ac8711b0 100644 --- a/builder/osc/common/omi_config.go +++ b/builder/osc/common/omi_config.go @@ -19,8 +19,6 @@ type OMIConfig struct { OMIRegions []string `mapstructure:"omi_regions"` OMISkipRegionValidation bool `mapstructure:"skip_region_validation"` OMITags TagMap `mapstructure:"tags"` - OMIENASupport *bool `mapstructure:"ena_support"` - OMISriovNetSupport bool `mapstructure:"sriov_support"` OMIForceDeregister bool `mapstructure:"force_deregister"` OMIForceDeleteSnapshot bool `mapstructure:"force_delete_snapshot"` SnapshotTags TagMap `mapstructure:"snapshot_tags"` diff --git a/builder/osc/common/step_source_omi_info.go b/builder/osc/common/step_source_omi_info.go index f602b5cc7..19ec926cc 100644 --- a/builder/osc/common/step_source_omi_info.go +++ b/builder/osc/common/step_source_omi_info.go @@ -18,11 +18,9 @@ import ( // Produces: // source_image *oapi.Image - the source OMI info type StepSourceOMIInfo struct { - SourceOmi string - EnableOMISriovNetSupport bool - EnableOMIENASupport *bool - OMIVirtType string - OmiFilters OmiFilterOptions + SourceOmi string + OMIVirtType string + OmiFilters OmiFilterOptions } type imageSort []oapi.Image From 17ee7b81633d1657d10461580f1098713cecd621 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Fri, 12 Apr 2019 11:44:25 -0500 Subject: [PATCH 098/113] fix: add missing secret key in http client configuration --- builder/osc/common/step_update_omi.go | 1 + 1 file changed, 1 insertion(+) diff --git a/builder/osc/common/step_update_omi.go b/builder/osc/common/step_update_omi.go index e49068b7f..65dfdaf9e 100644 --- a/builder/osc/common/step_update_omi.go +++ b/builder/osc/common/step_update_omi.go @@ -59,6 +59,7 @@ func (s *StepUpdateOMIAttributes) Run(_ context.Context, state multistep.StateBa ui.Say(fmt.Sprintf("Updating attributes on OMI (%s)...", omi)) newConfig := &oapi.Config{ UserAgent: config.UserAgent, + AccessKey: config.AccessKey, SecretKey: config.SecretKey, Service: config.Service, Region: region, //New region From a28ea324a004b2f34836a22e9caef2584ff4895c Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Fri, 12 Apr 2019 12:02:52 -0500 Subject: [PATCH 099/113] website: fix some naming mistakes on the example configurations --- website/source/docs/builders/osc-bsu.html.md | 14 +++++------ .../docs/builders/osc-bsusurrogate.html.md | 25 +++++++++---------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/website/source/docs/builders/osc-bsu.html.md b/website/source/docs/builders/osc-bsu.html.md index 5ea166305..bdccee342 100644 --- a/website/source/docs/builders/osc-bsu.html.md +++ b/website/source/docs/builders/osc-bsu.html.md @@ -256,7 +256,7 @@ Here is a basic example. You will need to provide access keys, and may need to c "source_omi": "ami-abcfd0283", "vm_type": "t2.micro", "ssh_username": "outscale", - "ami_name": "packer_osc {{timestamp}}" + "omi_name": "packer_osc {{timestamp}}" } ] } @@ -289,10 +289,10 @@ configuration of `launch_block_device_mappings` will expand the root volume "access_key": "YOUR KEY HERE", "secret_key": "YOUR SECRET KEY HERE", "region": "us-east-1", - "source_ami": "ami-fce3c696", - "VM_type": "t2.micro", + "source_omi": "ami-fce3c696", + "vm_type": "t2.micro", "ssh_username": "ubuntu", - "ami_name": "packer-quick-start {{timestamp}}", + "omi_name": "packer-quick-start {{timestamp}}", "launch_block_device_mappings": [ { "device_name": "/dev/sda1", @@ -333,10 +333,10 @@ Here is an example using the optional OMIS tags. This will add the tags `OS_Vers "access_key": "YOUR KEY HERE", "secret_key": "YOUR SECRET KEY HERE", "region": "us-east-1", - "source_ami": "ami-fce3c696", - "VM_type": "t2.micro", + "source_omi": "ami-fce3c696", + "vm_type": "t2.micro", "ssh_username": "ubuntu", - "ami_name": "packer-quick-start {{timestamp}}", + "omi_name": "packer-quick-start {{timestamp}}", "tags": { "OS_Version": "Ubuntu", "Release": "Latest", diff --git a/website/source/docs/builders/osc-bsusurrogate.html.md b/website/source/docs/builders/osc-bsusurrogate.html.md index 865968f81..e98fe0d35 100644 --- a/website/source/docs/builders/osc-bsusurrogate.html.md +++ b/website/source/docs/builders/osc-bsusurrogate.html.md @@ -1,7 +1,7 @@ --- description: | The osc-bsusurrogate Packer builder is like the chroot builder, but does not - require running inside an Outscale instance. + require running inside an Outscale virtual machine. layout: docs page_title: 'Outacale BSU Surrogate - Builders' sidebar_current: 'docs-builders-osc-bsusurrogate' @@ -12,7 +12,7 @@ sidebar_current: 'docs-builders-osc-bsusurrogate' Type: `osc-bsusurrogate` The `osc-bsusurrogate` Packer builder is able to create Outscale OMIs by -running a source instance with an attached volume, provisioning the attached +running a source virtual machine with an attached volume, provisioning the attached volume in such a way that it can be used as the root volume for the OMI, and then snapshotting and creating the OMI from that volume. @@ -21,7 +21,7 @@ example FreeBSD or Ubuntu using ZFS as the root file system. This is all done in your own Outscale account. This builder will create temporary key pairs, security group rules, etc., that provide it temporary access to the -instance while the image is being created. +virtual machine while the image is being created. ## Configuration Reference @@ -52,7 +52,7 @@ builder. `omi_block_device_mapping`, except with an additional field: - `source_device_name` (string) - The device name of the block device on - the source instance to be used as the root device for the OMI. This + the source virtual machine to be used as the root device for the OMI. This must correspond to a block device in `launch_block_device_mapping`. ### Optional: @@ -169,7 +169,7 @@ builder. [template engine](../templates/engine.html), see [Build template data](#build-template-data) for more information. -- `source_omi_filter` (object) - Filters used to populate the `source_ami` field. +- `source_omi_filter` (object) - Filters used to populate the `source_omi` field. - `filters` (map of strings) - filters used to select a `source_omi`. - `owners` (array of strings) - Filters the images by their owner. You may specify one or more Outscale account IDs, "self" (which will use the account whose credentials you are using to run Packer). This option is required for security reasons. @@ -180,7 +180,7 @@ builder. "source_omi_filter": { "filters": { "virtualization-type": "hvm", - "image-name": "ubuntu/images/*ubuntu-xenial-16.04-amd64-server-*", + "image-name": "image-name", "root-device-type": "ebs" }, "owners": ["099720109477"], @@ -245,8 +245,8 @@ builder. "access_key" : "YOUR KEY HERE", "region" : "eu-west-2", "ssh_username" : "outscale", - "instance_type" : "t2.medium", - "source_ami" : "ami-bcfc34e0", + "vm_type" : "t2.medium", + "source_omi" : "ami-bcfc34e0", "subregion_name": "eu-west-2a", "launch_block_device_mappings" : [ { @@ -274,13 +274,12 @@ for more information on what environmental variables Packer will look for. Further information on locating OMIS IDs and their relationship to VM types and regions can be found in the Outscale Documentation [reference](https://wiki.outscale.net/display/EN/Official+OMIs+Reference). +## Accessing the Virtual Machine to Debug -## Accessing the Instance to Debug - -If you need to access the instance to debug for some reason, run this builder +If you need to access the virtual machine to debug for some reason, run this builder with the `-debug` flag. In debug mode, the Outscale builder will save the private key in the current directory and will output the DNS or IP information as well. -You can use this information to access the instance as it is running. +You can use this information to access the virtual machine as it is running. ## Build template data @@ -293,6 +292,6 @@ In configuration directives marked as a template engine above, the following var -> **Note:** Packer uses pre-built OMIs as the source for building images. These source OMIs may include volumes that are not flagged to be destroyed on -termination of the instance building the new image. In addition to those +termination of the virtual machine building the new image. In addition to those volumes created by this builder, any volumes inn the source OMI which are not marked for deletion on termination will remain in your account. From 653bf242111ba6ba3538077881e4365c250a6baa Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Fri, 12 Apr 2019 15:03:15 -0500 Subject: [PATCH 100/113] website: add block_device attributes documentation in bsusurrogate --- .../source/docs/builders/osc-bsusurrogate.html.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/website/source/docs/builders/osc-bsusurrogate.html.md b/website/source/docs/builders/osc-bsusurrogate.html.md index e98fe0d35..b9d6a7a2f 100644 --- a/website/source/docs/builders/osc-bsusurrogate.html.md +++ b/website/source/docs/builders/osc-bsusurrogate.html.md @@ -125,6 +125,18 @@ builder. new OMI, the VM automatically launches with these additional volumes, and will restore them from snapshots taken from the source VM. + - `delete_on_vm_deletion` (boolean) - Indicates whether the BSU volume is deleted on VM termination. Default `false`. **NOTE**: If this value is not explicitly set to `true` and volumes are not cleaned up by an alternative method, additional volumes will accumulate after every build. + + - `device_name` (string) - The device name exposed to the VM (for example, `/dev/sdh` or `xvdh`). Required for every device in the block device mapping. + + - `iops` (number) - The number of I/O operations per second (IOPS) that the volume supports. See the documentation on + [IOPs](https://wiki.outscale.net/display/EN/About+Volumes#AboutVolumes-VolumeTypesVolumeTypesandIOPS) + for more information. + + - `volume_size` (number) - The size of the volume, in GiB. Required if not specifying a `snapshot_id` + + - `volume_type` (string) - The volume type. `gp2` for General Purpose (SSD) volumes, `io1` for Provisioned IOPS (SSD) volumes, and `standard` for Magnetic volumes + - `run_tags` (object of key/value strings) - Tags to apply to the VM that is *launched* to create the OMI. These tags are *not* applied to the resulting OMIS unless they're duplicated in `tags`. This is a [template From 68208064368aabaed7b747827419479c863c2091 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Mon, 15 Apr 2019 13:58:02 -0500 Subject: [PATCH 101/113] refactor: add err check in create tags --- builder/osc/chroot/step_create_volume.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/builder/osc/chroot/step_create_volume.go b/builder/osc/chroot/step_create_volume.go index 7cc9d022f..9e1853d3e 100644 --- a/builder/osc/chroot/step_create_volume.go +++ b/builder/osc/chroot/step_create_volume.go @@ -96,7 +96,12 @@ func (s *StepCreateVolume) Run(ctx context.Context, state multistep.StateBag) mu //Create tags for volume if len(volTags) > 0 { - osccommon.CreateTags(oapiconn, s.volumeId, ui, volTags) + if err := osccommon.CreateTags(oapiconn, s.volumeId, ui, volTags); err != nil { + err := fmt.Errorf("Error creating tags for volume: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } } // Wait for the volume to become ready From 488535118dfc01473e5f236f3d1d017dc3a40b6d Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Mon, 15 Apr 2019 14:02:18 -0500 Subject: [PATCH 102/113] refactor: change validation when bsu is set --- builder/osc/chroot/step_create_omi.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/osc/chroot/step_create_omi.go b/builder/osc/chroot/step_create_omi.go index 1dd69979c..6d594d74d 100644 --- a/builder/osc/chroot/step_create_omi.go +++ b/builder/osc/chroot/step_create_omi.go @@ -48,7 +48,7 @@ func (s *StepCreateOMI) Run(ctx context.Context, state multistep.StateBag) multi newDevice.Bsu.VolumeSize = gibSize if newDevice.DeviceName == rootDeviceName { - if &newDevice.Bsu != nil { + if newDevice.Bsu != (oapi.BsuToCreate{}) { newDevice.Bsu.SnapshotId = snapshotId } else { newDevice.Bsu = oapi.BsuToCreate{SnapshotId: snapshotId} From ed2d2b90581da15d7836118ef8a2dbb18fc0a1e8 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Mon, 15 Apr 2019 14:04:34 -0500 Subject: [PATCH 103/113] refactor: clean duplicate files with aws chroot builder --- builder/osc/chroot/builder.go | 17 +- builder/osc/chroot/cleanup.go | 10 - builder/osc/chroot/device.go | 2 +- builder/osc/chroot/lockfile.go | 16 - builder/osc/chroot/lockfile_unix.go | 27 - builder/osc/chroot/run_local_commands.go | 39 -- builder/osc/chroot/step_chroot_provision.go | 37 -- builder/osc/chroot/step_copy_files.go | 91 --- builder/osc/chroot/step_early_cleanup.go | 39 -- builder/osc/chroot/step_early_unflock.go | 30 - builder/osc/chroot/step_flock.go | 74 --- builder/osc/chroot/step_mount_extra.go | 137 ----- .../osc/chroot/step_post_mount_commands.go | 47 -- builder/osc/chroot/step_pre_mount_commands.go | 41 -- common/bootcommand/boot_command.go | 520 ++++++++++++++++-- 15 files changed, 477 insertions(+), 650 deletions(-) delete mode 100644 builder/osc/chroot/cleanup.go delete mode 100644 builder/osc/chroot/lockfile.go delete mode 100644 builder/osc/chroot/lockfile_unix.go delete mode 100644 builder/osc/chroot/run_local_commands.go delete mode 100644 builder/osc/chroot/step_chroot_provision.go delete mode 100644 builder/osc/chroot/step_copy_files.go delete mode 100644 builder/osc/chroot/step_early_cleanup.go delete mode 100644 builder/osc/chroot/step_early_unflock.go delete mode 100644 builder/osc/chroot/step_flock.go delete mode 100644 builder/osc/chroot/step_mount_extra.go delete mode 100644 builder/osc/chroot/step_post_mount_commands.go delete mode 100644 builder/osc/chroot/step_pre_mount_commands.go diff --git a/builder/osc/chroot/builder.go b/builder/osc/chroot/builder.go index 8606bf0b8..0f3edeb6f 100644 --- a/builder/osc/chroot/builder.go +++ b/builder/osc/chroot/builder.go @@ -11,6 +11,7 @@ import ( "net/http" "runtime" + awschroot "github.com/hashicorp/packer/builder/amazon/chroot" osccommon "github.com/hashicorp/packer/builder/osc/common" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/config" @@ -237,7 +238,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { } steps = append(steps, - &StepFlock{}, + &awschroot.StepFlock{}, &StepPrepareDevice{}, &StepCreateVolume{ RootVolumeType: b.config.RootVolumeType, @@ -246,21 +247,21 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { Ctx: b.config.ctx, }, &StepLinkVolume{}, - &StepEarlyUnflock{}, - &StepPreMountCommands{ + &awschroot.StepEarlyUnflock{}, + &awschroot.StepPreMountCommands{ Commands: b.config.PreMountCommands, }, &StepMountDevice{ MountOptions: b.config.MountOptions, MountPartition: b.config.MountPartition, }, - &StepPostMountCommands{ + &awschroot.StepPostMountCommands{ Commands: b.config.PostMountCommands, }, - &StepMountExtra{}, - &StepCopyFiles{}, - &StepChrootProvision{}, - &StepEarlyCleanup{}, + &awschroot.StepMountExtra{}, + &awschroot.StepCopyFiles{}, + &awschroot.StepChrootProvision{}, + &awschroot.StepEarlyCleanup{}, &StepSnapshot{}, &osccommon.StepDeregisterOMI{ AccessConfig: &b.config.AccessConfig, diff --git a/builder/osc/chroot/cleanup.go b/builder/osc/chroot/cleanup.go deleted file mode 100644 index 0befac174..000000000 --- a/builder/osc/chroot/cleanup.go +++ /dev/null @@ -1,10 +0,0 @@ -package chroot - -import ( - "github.com/hashicorp/packer/helper/multistep" -) - -// Cleanup is an interface that some steps implement for early cleanup. -type Cleanup interface { - CleanupFunc(multistep.StateBag) error -} diff --git a/builder/osc/chroot/device.go b/builder/osc/chroot/device.go index 7f9aec94d..f6fec3d1f 100644 --- a/builder/osc/chroot/device.go +++ b/builder/osc/chroot/device.go @@ -51,7 +51,7 @@ func devicePrefix() (string, error) { defer f.Close() dirs, err := f.Readdirnames(-1) - if dirs != nil && len(dirs) > 0 { + if len(dirs) > 0 { for _, dir := range dirs { dirBase := filepath.Base(dir) for _, prefix := range available { diff --git a/builder/osc/chroot/lockfile.go b/builder/osc/chroot/lockfile.go deleted file mode 100644 index 1ba13e04b..000000000 --- a/builder/osc/chroot/lockfile.go +++ /dev/null @@ -1,16 +0,0 @@ -// +build windows - -package chroot - -import ( - "errors" - "os" -) - -func lockFile(*os.File) error { - return errors.New("not supported on Windows") -} - -func unlockFile(f *os.File) error { - return nil -} diff --git a/builder/osc/chroot/lockfile_unix.go b/builder/osc/chroot/lockfile_unix.go deleted file mode 100644 index 0d0f8c8f7..000000000 --- a/builder/osc/chroot/lockfile_unix.go +++ /dev/null @@ -1,27 +0,0 @@ -// +build !windows - -package chroot - -import ( - "os" - - "golang.org/x/sys/unix" -) - -// See: http://linux.die.net/include/sys/file.h -const LOCK_EX = 2 -const LOCK_NB = 4 -const LOCK_UN = 8 - -func lockFile(f *os.File) error { - err := unix.Flock(int(f.Fd()), LOCK_EX) - if err != nil { - return err - } - - return nil -} - -func unlockFile(f *os.File) error { - return unix.Flock(int(f.Fd()), LOCK_UN) -} diff --git a/builder/osc/chroot/run_local_commands.go b/builder/osc/chroot/run_local_commands.go deleted file mode 100644 index fc1c01e2b..000000000 --- a/builder/osc/chroot/run_local_commands.go +++ /dev/null @@ -1,39 +0,0 @@ -package chroot - -import ( - "fmt" - - sl "github.com/hashicorp/packer/common/shell-local" - "github.com/hashicorp/packer/packer" - "github.com/hashicorp/packer/template/interpolate" -) - -func RunLocalCommands(commands []string, wrappedCommand CommandWrapper, ctx interpolate.Context, ui packer.Ui) error { - for _, rawCmd := range commands { - intCmd, err := interpolate.Render(rawCmd, &ctx) - if err != nil { - return fmt.Errorf("Error interpolating: %s", err) - } - - command, err := wrappedCommand(intCmd) - if err != nil { - return fmt.Errorf("Error wrapping command: %s", err) - } - - ui.Say(fmt.Sprintf("Executing command: %s", command)) - comm := &sl.Communicator{ - ExecuteCommand: []string{"sh", "-c", command}, - } - cmd := &packer.RemoteCmd{Command: command} - if err := cmd.StartWithUi(comm, ui); err != nil { - return fmt.Errorf("Error executing command: %s", err) - } - if cmd.ExitStatus != 0 { - return fmt.Errorf( - "Received non-zero exit code %d from command: %s", - cmd.ExitStatus, - command) - } - } - return nil -} diff --git a/builder/osc/chroot/step_chroot_provision.go b/builder/osc/chroot/step_chroot_provision.go deleted file mode 100644 index be8667077..000000000 --- a/builder/osc/chroot/step_chroot_provision.go +++ /dev/null @@ -1,37 +0,0 @@ -package chroot - -import ( - "context" - "log" - - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" -) - -// StepChrootProvision provisions the instance within a chroot. -type StepChrootProvision struct { -} - -func (s *StepChrootProvision) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { - hook := state.Get("hook").(packer.Hook) - mountPath := state.Get("mount_path").(string) - ui := state.Get("ui").(packer.Ui) - wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) - - // Create our communicator - comm := &Communicator{ - Chroot: mountPath, - CmdWrapper: wrappedCommand, - } - - // Provision - log.Println("Running the provision hook") - if err := hook.Run(packer.HookProvision, ui, comm, nil); err != nil { - state.Put("error", err) - return multistep.ActionHalt - } - - return multistep.ActionContinue -} - -func (s *StepChrootProvision) Cleanup(state multistep.StateBag) {} diff --git a/builder/osc/chroot/step_copy_files.go b/builder/osc/chroot/step_copy_files.go deleted file mode 100644 index a973a5d81..000000000 --- a/builder/osc/chroot/step_copy_files.go +++ /dev/null @@ -1,91 +0,0 @@ -package chroot - -import ( - "bytes" - "context" - "fmt" - "log" - "path/filepath" - - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" -) - -// StepCopyFiles copies some files from the host into the chroot environment. -// -// Produces: -// copy_files_cleanup CleanupFunc - A function to clean up the copied files -// early. -type StepCopyFiles struct { - files []string -} - -func (s *StepCopyFiles) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { - config := state.Get("config").(*Config) - mountPath := state.Get("mount_path").(string) - ui := state.Get("ui").(packer.Ui) - wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) - stderr := new(bytes.Buffer) - - s.files = make([]string, 0, len(config.CopyFiles)) - if len(config.CopyFiles) > 0 { - ui.Say("Copying files from host to chroot...") - for _, path := range config.CopyFiles { - ui.Message(path) - chrootPath := filepath.Join(mountPath, path) - log.Printf("Copying '%s' to '%s'", path, chrootPath) - - cmdText, err := wrappedCommand(fmt.Sprintf("cp --remove-destination %s %s", path, chrootPath)) - if err != nil { - err := fmt.Errorf("Error building copy command: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - - stderr.Reset() - cmd := ShellCommand(cmdText) - cmd.Stderr = stderr - if err := cmd.Run(); err != nil { - err := fmt.Errorf( - "Error copying file: %s\nnStderr: %s", err, stderr.String()) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - - s.files = append(s.files, chrootPath) - } - } - - state.Put("copy_files_cleanup", s) - return multistep.ActionContinue -} - -func (s *StepCopyFiles) Cleanup(state multistep.StateBag) { - ui := state.Get("ui").(packer.Ui) - if err := s.CleanupFunc(state); err != nil { - ui.Error(err.Error()) - } -} - -func (s *StepCopyFiles) CleanupFunc(state multistep.StateBag) error { - wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) - if s.files != nil { - for _, file := range s.files { - log.Printf("Removing: %s", file) - localCmdText, err := wrappedCommand(fmt.Sprintf("rm -f %s", file)) - if err != nil { - return err - } - - localCmd := ShellCommand(localCmdText) - if err := localCmd.Run(); err != nil { - return err - } - } - } - - s.files = nil - return nil -} diff --git a/builder/osc/chroot/step_early_cleanup.go b/builder/osc/chroot/step_early_cleanup.go deleted file mode 100644 index 34e7817df..000000000 --- a/builder/osc/chroot/step_early_cleanup.go +++ /dev/null @@ -1,39 +0,0 @@ -package chroot - -import ( - "context" - "fmt" - "log" - - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" -) - -// StepEarlyCleanup performs some of the cleanup steps early in order to -// prepare for snapshotting and creating an AMI. -type StepEarlyCleanup struct{} - -func (s *StepEarlyCleanup) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { - ui := state.Get("ui").(packer.Ui) - cleanupKeys := []string{ - "copy_files_cleanup", - "mount_extra_cleanup", - "mount_device_cleanup", - "attach_cleanup", - } - - for _, key := range cleanupKeys { - c := state.Get(key).(Cleanup) - log.Printf("Running cleanup func: %s", key) - if err := c.CleanupFunc(state); err != nil { - err := fmt.Errorf("Error cleaning up: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - } - - return multistep.ActionContinue -} - -func (s *StepEarlyCleanup) Cleanup(state multistep.StateBag) {} diff --git a/builder/osc/chroot/step_early_unflock.go b/builder/osc/chroot/step_early_unflock.go deleted file mode 100644 index 225e91fb9..000000000 --- a/builder/osc/chroot/step_early_unflock.go +++ /dev/null @@ -1,30 +0,0 @@ -package chroot - -import ( - "context" - "fmt" - "log" - - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" -) - -// StepEarlyUnflock unlocks the flock. -type StepEarlyUnflock struct{} - -func (s *StepEarlyUnflock) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { - cleanup := state.Get("flock_cleanup").(Cleanup) - ui := state.Get("ui").(packer.Ui) - - log.Println("Unlocking file lock...") - if err := cleanup.CleanupFunc(state); err != nil { - err := fmt.Errorf("Error unlocking file lock: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - - return multistep.ActionContinue -} - -func (s *StepEarlyUnflock) Cleanup(state multistep.StateBag) {} diff --git a/builder/osc/chroot/step_flock.go b/builder/osc/chroot/step_flock.go deleted file mode 100644 index 2c81193da..000000000 --- a/builder/osc/chroot/step_flock.go +++ /dev/null @@ -1,74 +0,0 @@ -package chroot - -import ( - "context" - "fmt" - "log" - "os" - "path/filepath" - - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" -) - -// StepFlock provisions the vm within a chroot. -// -// Produces: -// flock_cleanup Cleanup - To perform early cleanup -type StepFlock struct { - fh *os.File -} - -func (s *StepFlock) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { - ui := state.Get("ui").(packer.Ui) - - lockfile := "/var/lock/packer-chroot/lock" - if err := os.MkdirAll(filepath.Dir(lockfile), 0755); err != nil { - err := fmt.Errorf("Error creating lock: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - - log.Printf("Obtaining lock: %s", lockfile) - f, err := os.Create(lockfile) - if err != nil { - err := fmt.Errorf("Error creating lock: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - - // LOCK! - if err := lockFile(f); err != nil { - err := fmt.Errorf("Error obtaining lock: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - - // Set the file handle, we can't close it because we need to hold - // the lock. - s.fh = f - - state.Put("flock_cleanup", s) - return multistep.ActionContinue -} - -func (s *StepFlock) Cleanup(state multistep.StateBag) { - s.CleanupFunc(state) -} - -func (s *StepFlock) CleanupFunc(state multistep.StateBag) error { - if s.fh == nil { - return nil - } - - log.Printf("Unlocking: %s", s.fh.Name()) - if err := unlockFile(s.fh); err != nil { - return err - } - - s.fh = nil - return nil -} diff --git a/builder/osc/chroot/step_mount_extra.go b/builder/osc/chroot/step_mount_extra.go deleted file mode 100644 index ffd8ac027..000000000 --- a/builder/osc/chroot/step_mount_extra.go +++ /dev/null @@ -1,137 +0,0 @@ -package chroot - -import ( - "bytes" - "context" - "fmt" - "os" - "os/exec" - "syscall" - - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" -) - -// StepMountExtra mounts the attached device. -// -// Produces: -// mount_extra_cleanup CleanupFunc - To perform early cleanup -type StepMountExtra struct { - mounts []string -} - -func (s *StepMountExtra) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { - config := state.Get("config").(*Config) - mountPath := state.Get("mount_path").(string) - ui := state.Get("ui").(packer.Ui) - wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) - - s.mounts = make([]string, 0, len(config.ChrootMounts)) - - ui.Say("Mounting additional paths within the chroot...") - for _, mountInfo := range config.ChrootMounts { - innerPath := mountPath + mountInfo[2] - - if err := os.MkdirAll(innerPath, 0755); err != nil { - err := fmt.Errorf("Error creating mount directory: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - - flags := "-t " + mountInfo[0] - if mountInfo[0] == "bind" { - flags = "--bind" - } - - ui.Message(fmt.Sprintf("Mounting: %s", mountInfo[2])) - stderr := new(bytes.Buffer) - mountCommand, err := wrappedCommand(fmt.Sprintf( - "mount %s %s %s", - flags, - mountInfo[1], - innerPath)) - if err != nil { - err := fmt.Errorf("Error creating mount command: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - - cmd := ShellCommand(mountCommand) - cmd.Stderr = stderr - if err := cmd.Run(); err != nil { - err := fmt.Errorf( - "Error mounting: %s\nStderr: %s", err, stderr.String()) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - - s.mounts = append(s.mounts, innerPath) - } - - state.Put("mount_extra_cleanup", s) - return multistep.ActionContinue -} - -func (s *StepMountExtra) Cleanup(state multistep.StateBag) { - ui := state.Get("ui").(packer.Ui) - - if err := s.CleanupFunc(state); err != nil { - ui.Error(err.Error()) - return - } -} - -func (s *StepMountExtra) CleanupFunc(state multistep.StateBag) error { - if s.mounts == nil { - return nil - } - - wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) - for len(s.mounts) > 0 { - var path string - lastIndex := len(s.mounts) - 1 - path, s.mounts = s.mounts[lastIndex], s.mounts[:lastIndex] - - grepCommand, err := wrappedCommand(fmt.Sprintf("grep %s /proc/mounts", path)) - if err != nil { - return fmt.Errorf("Error creating grep command: %s", err) - } - - // Before attempting to unmount, - // check to see if path is already unmounted - stderr := new(bytes.Buffer) - cmd := ShellCommand(grepCommand) - cmd.Stderr = stderr - if err := cmd.Run(); err != nil { - if exitError, ok := err.(*exec.ExitError); ok { - if status, ok := exitError.Sys().(syscall.WaitStatus); ok { - exitStatus := status.ExitStatus() - if exitStatus == 1 { - // path has already been unmounted - // just skip this path - continue - } - } - } - } - - unmountCommand, err := wrappedCommand(fmt.Sprintf("umount %s", path)) - if err != nil { - return fmt.Errorf("Error creating unmount command: %s", err) - } - - stderr = new(bytes.Buffer) - cmd = ShellCommand(unmountCommand) - cmd.Stderr = stderr - if err := cmd.Run(); err != nil { - return fmt.Errorf( - "Error unmounting device: %s\nStderr: %s", err, stderr.String()) - } - } - - s.mounts = nil - return nil -} diff --git a/builder/osc/chroot/step_post_mount_commands.go b/builder/osc/chroot/step_post_mount_commands.go deleted file mode 100644 index a00e8e1bf..000000000 --- a/builder/osc/chroot/step_post_mount_commands.go +++ /dev/null @@ -1,47 +0,0 @@ -package chroot - -import ( - "context" - - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" -) - -type postMountCommandsData struct { - Device string - MountPath string -} - -// StepPostMountCommands allows running arbitrary commands after mounting the -// device, but prior to the bind mount and copy steps. -type StepPostMountCommands struct { - Commands []string -} - -func (s *StepPostMountCommands) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { - config := state.Get("config").(*Config) - device := state.Get("device").(string) - mountPath := state.Get("mount_path").(string) - ui := state.Get("ui").(packer.Ui) - wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) - - if len(s.Commands) == 0 { - return multistep.ActionContinue - } - - ctx := config.ctx - ctx.Data = &postMountCommandsData{ - Device: device, - MountPath: mountPath, - } - - ui.Say("Running post-mount commands...") - if err := RunLocalCommands(s.Commands, wrappedCommand, ctx, ui); err != nil { - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - return multistep.ActionContinue -} - -func (s *StepPostMountCommands) Cleanup(state multistep.StateBag) {} diff --git a/builder/osc/chroot/step_pre_mount_commands.go b/builder/osc/chroot/step_pre_mount_commands.go deleted file mode 100644 index ce3c26e02..000000000 --- a/builder/osc/chroot/step_pre_mount_commands.go +++ /dev/null @@ -1,41 +0,0 @@ -package chroot - -import ( - "context" - - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" -) - -type preMountCommandsData struct { - Device string -} - -// StepPreMountCommands sets up the a new block device when building from scratch -type StepPreMountCommands struct { - Commands []string -} - -func (s *StepPreMountCommands) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { - config := state.Get("config").(*Config) - device := state.Get("device").(string) - ui := state.Get("ui").(packer.Ui) - wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) - - if len(s.Commands) == 0 { - return multistep.ActionContinue - } - - ctx := config.ctx - ctx.Data = &preMountCommandsData{Device: device} - - ui.Say("Running device setup commands...") - if err := RunLocalCommands(s.Commands, wrappedCommand, ctx, ui); err != nil { - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - return multistep.ActionContinue -} - -func (s *StepPreMountCommands) Cleanup(state multistep.StateBag) {} diff --git a/common/bootcommand/boot_command.go b/common/bootcommand/boot_command.go index ff4e6ebde..1447a4337 100644 --- a/common/bootcommand/boot_command.go +++ b/common/bootcommand/boot_command.go @@ -1,4 +1,5 @@ // Code generated by pigeon; DO NOT EDIT. + package bootcommand import ( @@ -7,7 +8,9 @@ import ( "fmt" "io" "io/ioutil" + "math" "os" + "sort" "strconv" "strings" "time" @@ -788,18 +791,85 @@ var ( // errNoRule is returned when the grammar to parse has no rule. errNoRule = errors.New("grammar has no rule") + // errInvalidEntrypoint is returned when the specified entrypoint rule + // does not exit. + errInvalidEntrypoint = errors.New("invalid entrypoint") + // errInvalidEncoding is returned when the source is not properly // utf8-encoded. errInvalidEncoding = errors.New("invalid encoding") - // errNoMatch is returned if no match could be found. - errNoMatch = errors.New("no match found") + // errMaxExprCnt is used to signal that the maximum number of + // expressions have been parsed. + errMaxExprCnt = errors.New("max number of expresssions parsed") ) // Option is a function that can set an option on the parser. It returns // the previous setting as an Option. type Option func(*parser) Option +// MaxExpressions creates an Option to stop parsing after the provided +// number of expressions have been parsed, if the value is 0 then the parser will +// parse for as many steps as needed (possibly an infinite number). +// +// The default for maxExprCnt is 0. +func MaxExpressions(maxExprCnt uint64) Option { + return func(p *parser) Option { + oldMaxExprCnt := p.maxExprCnt + p.maxExprCnt = maxExprCnt + return MaxExpressions(oldMaxExprCnt) + } +} + +// Entrypoint creates an Option to set the rule name to use as entrypoint. +// The rule name must have been specified in the -alternate-entrypoints +// if generating the parser with the -optimize-grammar flag, otherwise +// it may have been optimized out. Passing an empty string sets the +// entrypoint to the first rule in the grammar. +// +// The default is to start parsing at the first rule in the grammar. +func Entrypoint(ruleName string) Option { + return func(p *parser) Option { + oldEntrypoint := p.entrypoint + p.entrypoint = ruleName + if ruleName == "" { + p.entrypoint = g.rules[0].name + } + return Entrypoint(oldEntrypoint) + } +} + +// Statistics adds a user provided Stats struct to the parser to allow +// the user to process the results after the parsing has finished. +// Also the key for the "no match" counter is set. +// +// Example usage: +// +// input := "input" +// stats := Stats{} +// _, err := Parse("input-file", []byte(input), Statistics(&stats, "no match")) +// if err != nil { +// log.Panicln(err) +// } +// b, err := json.MarshalIndent(stats.ChoiceAltCnt, "", " ") +// if err != nil { +// log.Panicln(err) +// } +// fmt.Println(string(b)) +// +func Statistics(stats *Stats, choiceNoMatch string) Option { + return func(p *parser) Option { + oldStats := p.Stats + p.Stats = stats + oldChoiceNoMatch := p.choiceNoMatch + p.choiceNoMatch = choiceNoMatch + if p.Stats.ChoiceAltCnt == nil { + p.Stats.ChoiceAltCnt = make(map[string]map[string]int) + } + return Statistics(oldStats, oldChoiceNoMatch) + } +} + // Debug creates an Option to set the debug flag to b. When set to true, // debugging information is printed to stdout while parsing. // @@ -826,6 +896,20 @@ func Memoize(b bool) Option { } } +// AllowInvalidUTF8 creates an Option to allow invalid UTF-8 bytes. +// Every invalid UTF-8 byte is treated as a utf8.RuneError (U+FFFD) +// by character class matchers and is matched by the any matcher. +// The returned matched value, c.text and c.offset are NOT affected. +// +// The default is false. +func AllowInvalidUTF8(b bool) Option { + return func(p *parser) Option { + old := p.allowInvalidUTF8 + p.allowInvalidUTF8 = b + return AllowInvalidUTF8(old) + } +} + // Recover creates an Option to set the recover flag to b. When set to // true, this causes the parser to recover from panics and convert it // to an error. Setting it to false can be useful while debugging to @@ -840,13 +924,37 @@ func Recover(b bool) Option { } } +// GlobalStore creates an Option to set a key to a certain value in +// the globalStore. +func GlobalStore(key string, value interface{}) Option { + return func(p *parser) Option { + old := p.cur.globalStore[key] + p.cur.globalStore[key] = value + return GlobalStore(key, old) + } +} + +// InitState creates an Option to set a key to a certain value in +// the global "state" store. +func InitState(key string, value interface{}) Option { + return func(p *parser) Option { + old := p.cur.state[key] + p.cur.state[key] = value + return InitState(key, old) + } +} + // ParseFile parses the file identified by filename. -func ParseFile(filename string, opts ...Option) (interface{}, error) { +func ParseFile(filename string, opts ...Option) (i interface{}, err error) { f, err := os.Open(filename) if err != nil { return nil, err } - defer f.Close() + defer func() { + if closeErr := f.Close(); closeErr != nil { + err = closeErr + } + }() return ParseReader(filename, f, opts...) } @@ -887,8 +995,22 @@ type savepoint struct { type current struct { pos position // start position of the match text []byte // raw text of the match + + // state is a store for arbitrary key,value pairs that the user wants to be + // tied to the backtracking of the parser. + // This is always rolled back if a parsing rule fails. + state storeDict + + // globalStore is a general store for the user to store arbitrary key-value + // pairs that they need to manage and that they do not want tied to the + // backtracking of the parser. This is only modified by the user and never + // rolled back by the parser. It is always up to the user to keep this in a + // consistent state. + globalStore storeDict } +type storeDict map[string]interface{} + // the AST types... type grammar struct { @@ -914,11 +1036,23 @@ type actionExpr struct { run func(*parser) (interface{}, error) } +type recoveryExpr struct { + pos position + expr interface{} + recoverExpr interface{} + failureLabel []string +} + type seqExpr struct { pos position exprs []interface{} } +type throwExpr struct { + pos position + label string +} + type labeledExpr struct { pos position label string @@ -941,6 +1075,11 @@ type ruleRefExpr struct { name string } +type stateCodeExpr struct { + pos position + run func(*parser) error +} + type andCodeExpr struct { pos position run func(*parser) (bool, error) @@ -958,13 +1097,14 @@ type litMatcher struct { } type charClassMatcher struct { - pos position - val string - chars []rune - ranges []rune - classes []*unicode.RangeTable - ignoreCase bool - inverted bool + pos position + val string + basicLatinChars [128]bool + chars []rune + ranges []rune + classes []*unicode.RangeTable + ignoreCase bool + inverted bool } type anyMatcher position @@ -1018,9 +1158,10 @@ func (e errList) Error() string { // parserError wraps an error with a prefix indicating the rule in which // the error occurred. The original error is stored in the Inner field. type parserError struct { - Inner error - pos position - prefix string + Inner error + pos position + prefix string + expected []string } // Error returns the error message. @@ -1030,14 +1171,32 @@ func (p *parserError) Error() string { // newParser creates a parser with the specified input source and options. func newParser(filename string, b []byte, opts ...Option) *parser { + stats := Stats{ + ChoiceAltCnt: make(map[string]map[string]int), + } + p := &parser{ filename: filename, errs: new(errList), data: b, pt: savepoint{position: position{line: 1}}, recover: true, + cur: current{ + state: make(storeDict), + globalStore: make(storeDict), + }, + maxFailPos: position{col: 1, line: 1}, + maxFailExpected: make([]string, 0, 20), + Stats: &stats, + // start rule is rule [0] unless an alternate entrypoint is specified + entrypoint: g.rules[0].name, } p.setOptions(opts) + + if p.maxExprCnt == 0 { + p.maxExprCnt = math.MaxUint64 + } + return p } @@ -1054,6 +1213,30 @@ type resultTuple struct { end savepoint } +const choiceNoMatch = -1 + +// Stats stores some statistics, gathered during parsing +type Stats struct { + // ExprCnt counts the number of expressions processed during parsing + // This value is compared to the maximum number of expressions allowed + // (set by the MaxExpressions option). + ExprCnt uint64 + + // ChoiceAltCnt is used to count for each ordered choice expression, + // which alternative is used how may times. + // These numbers allow to optimize the order of the ordered choice expression + // to increase the performance of the parser + // + // The outer key of ChoiceAltCnt is composed of the name of the rule as well + // as the line and the column of the ordered choice. + // The inner key of ChoiceAltCnt is the number (one-based) of the matching alternative. + // For each alternative the number of matches are counted. If an ordered choice does not + // match, a special counter is incremented. The name of this counter is set with + // the parser option Statistics. + // For an alternative to be included in ChoiceAltCnt, it has to match at least once. + ChoiceAltCnt map[string]map[string]int +} + type parser struct { filename string pt savepoint @@ -1062,9 +1245,9 @@ type parser struct { data []byte errs *errList + depth int recover bool debug bool - depth int memoize bool // memoization table for the packrat algorithm: @@ -1078,8 +1261,23 @@ type parser struct { // rule stack, allows identification of the current rule in errors rstack []*rule - // stats - exprCnt int + // parse fail + maxFailPos position + maxFailExpected []string + maxFailInvertExpected bool + + // max number of expressions to be parsed + maxExprCnt uint64 + // entrypoint for the parser + entrypoint string + + allowInvalidUTF8 bool + + *Stats + + choiceNoMatch string + // recovery expression stack, keeps track of the currently available recovery expression, these are traversed in reverse + recoveryStack []map[string]interface{} } // push a variable set on the vstack. @@ -1114,6 +1312,31 @@ func (p *parser) popV() { p.vstack = p.vstack[:len(p.vstack)-1] } +// push a recovery expression with its labels to the recoveryStack +func (p *parser) pushRecovery(labels []string, expr interface{}) { + if cap(p.recoveryStack) == len(p.recoveryStack) { + // create new empty slot in the stack + p.recoveryStack = append(p.recoveryStack, nil) + } else { + // slice to 1 more + p.recoveryStack = p.recoveryStack[:len(p.recoveryStack)+1] + } + + m := make(map[string]interface{}, len(labels)) + for _, fl := range labels { + m[fl] = expr + } + p.recoveryStack[len(p.recoveryStack)-1] = m +} + +// pop a recovery expression from the recoveryStack +func (p *parser) popRecovery() { + // GC that map + p.recoveryStack[len(p.recoveryStack)-1] = nil + + p.recoveryStack = p.recoveryStack[:len(p.recoveryStack)-1] +} + func (p *parser) print(prefix, s string) string { if !p.debug { return s @@ -1135,10 +1358,10 @@ func (p *parser) out(s string) string { } func (p *parser) addErr(err error) { - p.addErrAt(err, p.pt.position) + p.addErrAt(err, p.pt.position, []string{}) } -func (p *parser) addErrAt(err error, pos position) { +func (p *parser) addErrAt(err error, pos position, expected []string) { var buf bytes.Buffer if p.filename != "" { buf.WriteString(p.filename) @@ -1158,10 +1381,29 @@ func (p *parser) addErrAt(err error, pos position) { buf.WriteString("rule " + rule.name) } } - pe := &parserError{Inner: err, pos: pos, prefix: buf.String()} + pe := &parserError{Inner: err, pos: pos, prefix: buf.String(), expected: expected} p.errs.add(pe) } +func (p *parser) failAt(fail bool, pos position, want string) { + // process fail if parsing fails and not inverted or parsing succeeds and invert is set + if fail == p.maxFailInvertExpected { + if pos.offset < p.maxFailPos.offset { + return + } + + if pos.offset > p.maxFailPos.offset { + p.maxFailPos = pos + p.maxFailExpected = p.maxFailExpected[:0] + } + + if p.maxFailInvertExpected { + want = "!" + want + } + p.maxFailExpected = append(p.maxFailExpected, want) + } +} + // read advances the parser to the next rune. func (p *parser) read() { p.pt.offset += p.pt.w @@ -1174,8 +1416,8 @@ func (p *parser) read() { p.pt.col = 0 } - if rn == utf8.RuneError { - if n == 1 { + if rn == utf8.RuneError && n == 1 { // see utf8.DecodeRune + if !p.allowInvalidUTF8 { p.addErr(errInvalidEncoding) } } @@ -1192,6 +1434,43 @@ func (p *parser) restore(pt savepoint) { p.pt = pt } +// Cloner is implemented by any value that has a Clone method, which returns a +// copy of the value. This is mainly used for types which are not passed by +// value (e.g map, slice, chan) or structs that contain such types. +// +// This is used in conjunction with the global state feature to create proper +// copies of the state to allow the parser to properly restore the state in +// the case of backtracking. +type Cloner interface { + Clone() interface{} +} + +// clone and return parser current state. +func (p *parser) cloneState() storeDict { + if p.debug { + defer p.out(p.in("cloneState")) + } + + state := make(storeDict, len(p.cur.state)) + for k, v := range p.cur.state { + if c, ok := v.(Cloner); ok { + state[k] = c.Clone() + } else { + state[k] = v + } + } + return state +} + +// restore parser current state to the state storeDict. +// every restoreState should applied only one time for every cloned state +func (p *parser) restoreState(state storeDict) { + if p.debug { + defer p.out(p.in("restoreState")) + } + p.cur.state = state +} + // get the slice of bytes from the savepoint start to the current position. func (p *parser) sliceFrom(start savepoint) []byte { return p.data[start.position.offset:p.pt.position.offset] @@ -1257,19 +1536,54 @@ func (p *parser) parse(g *grammar) (val interface{}, err error) { }() } - // start rule is rule [0] + startRule, ok := p.rules[p.entrypoint] + if !ok { + p.addErr(errInvalidEntrypoint) + return nil, p.errs.err() + } + p.read() // advance to first rune - val, ok := p.parseRule(g.rules[0]) + val, ok = p.parseRule(startRule) if !ok { if len(*p.errs) == 0 { - // make sure this doesn't go out silently - p.addErr(errNoMatch) + // If parsing fails, but no errors have been recorded, the expected values + // for the farthest parser position are returned as error. + maxFailExpectedMap := make(map[string]struct{}, len(p.maxFailExpected)) + for _, v := range p.maxFailExpected { + maxFailExpectedMap[v] = struct{}{} + } + expected := make([]string, 0, len(maxFailExpectedMap)) + eof := false + if _, ok := maxFailExpectedMap["!."]; ok { + delete(maxFailExpectedMap, "!.") + eof = true + } + for k := range maxFailExpectedMap { + expected = append(expected, k) + } + sort.Strings(expected) + if eof { + expected = append(expected, "EOF") + } + p.addErrAt(errors.New("no match found, expected: "+listJoin(expected, ", ", "or")), p.maxFailPos, expected) } + return nil, p.errs.err() } return val, p.errs.err() } +func listJoin(list []string, sep string, lastSep string) string { + switch len(list) { + case 0: + return "" + case 1: + return list[0] + default: + return fmt.Sprintf("%s %s %s", strings.Join(list[:len(list)-1], sep), lastSep, list[len(list)-1]) + } +} + func (p *parser) parseRule(rule *rule) (interface{}, bool) { if p.debug { defer p.out(p.in("parseRule " + rule.name)) @@ -1301,7 +1615,6 @@ func (p *parser) parseRule(rule *rule) (interface{}, bool) { func (p *parser) parseExpr(expr interface{}) (interface{}, bool) { var pt savepoint - var ok bool if p.memoize { res, ok := p.getMemoized(expr) @@ -1312,8 +1625,13 @@ func (p *parser) parseExpr(expr interface{}) (interface{}, bool) { pt = p.pt } - p.exprCnt++ + p.ExprCnt++ + if p.ExprCnt > p.maxExprCnt { + panic(errMaxExprCnt) + } + var val interface{} + var ok bool switch expr := expr.(type) { case *actionExpr: val, ok = p.parseActionExpr(expr) @@ -1337,10 +1655,16 @@ func (p *parser) parseExpr(expr interface{}) (interface{}, bool) { val, ok = p.parseNotExpr(expr) case *oneOrMoreExpr: val, ok = p.parseOneOrMoreExpr(expr) + case *recoveryExpr: + val, ok = p.parseRecoveryExpr(expr) case *ruleRefExpr: val, ok = p.parseRuleRefExpr(expr) case *seqExpr: val, ok = p.parseSeqExpr(expr) + case *stateCodeExpr: + val, ok = p.parseStateCodeExpr(expr) + case *throwExpr: + val, ok = p.parseThrowExpr(expr) case *zeroOrMoreExpr: val, ok = p.parseZeroOrMoreExpr(expr) case *zeroOrOneExpr: @@ -1364,10 +1688,13 @@ func (p *parser) parseActionExpr(act *actionExpr) (interface{}, bool) { if ok { p.cur.pos = start.position p.cur.text = p.sliceFrom(start) + state := p.cloneState() actVal, err := act.run(p) if err != nil { - p.addErrAt(err, start.position) + p.addErrAt(err, start.position, []string{}) } + p.restoreState(state) + val = actVal } if ok && p.debug { @@ -1381,10 +1708,14 @@ func (p *parser) parseAndCodeExpr(and *andCodeExpr) (interface{}, bool) { defer p.out(p.in("parseAndCodeExpr")) } + state := p.cloneState() + ok, err := and.run(p) if err != nil { p.addErr(err) } + p.restoreState(state) + return nil, ok } @@ -1394,10 +1725,13 @@ func (p *parser) parseAndExpr(and *andExpr) (interface{}, bool) { } pt := p.pt + state := p.cloneState() p.pushV() _, ok := p.parseExpr(and.expr) p.popV() + p.restoreState(state) p.restore(pt) + return nil, ok } @@ -1406,12 +1740,15 @@ func (p *parser) parseAnyMatcher(any *anyMatcher) (interface{}, bool) { defer p.out(p.in("parseAnyMatcher")) } - if p.pt.rn != utf8.RuneError { - start := p.pt - p.read() - return p.sliceFrom(start), true + if p.pt.rn == utf8.RuneError && p.pt.w == 0 { + // EOF - see utf8.DecodeRune + p.failAt(false, p.pt.position, ".") + return nil, false } - return nil, false + start := p.pt + p.read() + p.failAt(true, start.position, ".") + return p.sliceFrom(start), true } func (p *parser) parseCharClassMatcher(chr *charClassMatcher) (interface{}, bool) { @@ -1420,11 +1757,14 @@ func (p *parser) parseCharClassMatcher(chr *charClassMatcher) (interface{}, bool } cur := p.pt.rn + start := p.pt + // can't match EOF - if cur == utf8.RuneError { + if cur == utf8.RuneError && p.pt.w == 0 { // see utf8.DecodeRune + p.failAt(false, start.position, chr.val) return nil, false } - start := p.pt + if chr.ignoreCase { cur = unicode.ToLower(cur) } @@ -1433,9 +1773,11 @@ func (p *parser) parseCharClassMatcher(chr *charClassMatcher) (interface{}, bool for _, rn := range chr.chars { if rn == cur { if chr.inverted { + p.failAt(false, start.position, chr.val) return nil, false } p.read() + p.failAt(true, start.position, chr.val) return p.sliceFrom(start), true } } @@ -1444,9 +1786,11 @@ func (p *parser) parseCharClassMatcher(chr *charClassMatcher) (interface{}, bool for i := 0; i < len(chr.ranges); i += 2 { if cur >= chr.ranges[i] && cur <= chr.ranges[i+1] { if chr.inverted { + p.failAt(false, start.position, chr.val) return nil, false } p.read() + p.failAt(true, start.position, chr.val) return p.sliceFrom(start), true } } @@ -1455,33 +1799,60 @@ func (p *parser) parseCharClassMatcher(chr *charClassMatcher) (interface{}, bool for _, cl := range chr.classes { if unicode.Is(cl, cur) { if chr.inverted { + p.failAt(false, start.position, chr.val) return nil, false } p.read() + p.failAt(true, start.position, chr.val) return p.sliceFrom(start), true } } if chr.inverted { p.read() + p.failAt(true, start.position, chr.val) return p.sliceFrom(start), true } + p.failAt(false, start.position, chr.val) return nil, false } +func (p *parser) incChoiceAltCnt(ch *choiceExpr, altI int) { + choiceIdent := fmt.Sprintf("%s %d:%d", p.rstack[len(p.rstack)-1].name, ch.pos.line, ch.pos.col) + m := p.ChoiceAltCnt[choiceIdent] + if m == nil { + m = make(map[string]int) + p.ChoiceAltCnt[choiceIdent] = m + } + // We increment altI by 1, so the keys do not start at 0 + alt := strconv.Itoa(altI + 1) + if altI == choiceNoMatch { + alt = p.choiceNoMatch + } + m[alt]++ +} + func (p *parser) parseChoiceExpr(ch *choiceExpr) (interface{}, bool) { if p.debug { defer p.out(p.in("parseChoiceExpr")) } - for _, alt := range ch.alternatives { + for altI, alt := range ch.alternatives { + // dummy assignment to prevent compile error if optimized + _ = altI + + state := p.cloneState() + p.pushV() val, ok := p.parseExpr(alt) p.popV() if ok { + p.incChoiceAltCnt(ch, altI) return val, ok } + p.restoreState(state) } + p.incChoiceAltCnt(ch, choiceNoMatch) return nil, false } @@ -1505,6 +1876,11 @@ func (p *parser) parseLitMatcher(lit *litMatcher) (interface{}, bool) { defer p.out(p.in("parseLitMatcher")) } + ignoreCase := "" + if lit.ignoreCase { + ignoreCase = "i" + } + val := fmt.Sprintf("%q%s", lit.val, ignoreCase) start := p.pt for _, want := range lit.val { cur := p.pt.rn @@ -1512,11 +1888,13 @@ func (p *parser) parseLitMatcher(lit *litMatcher) (interface{}, bool) { cur = unicode.ToLower(cur) } if cur != want { + p.failAt(false, start.position, val) p.restore(start) return nil, false } p.read() } + p.failAt(true, start.position, val) return p.sliceFrom(start), true } @@ -1525,10 +1903,14 @@ func (p *parser) parseNotCodeExpr(not *notCodeExpr) (interface{}, bool) { defer p.out(p.in("parseNotCodeExpr")) } + state := p.cloneState() + ok, err := not.run(p) if err != nil { p.addErr(err) } + p.restoreState(state) + return nil, !ok } @@ -1538,10 +1920,15 @@ func (p *parser) parseNotExpr(not *notExpr) (interface{}, bool) { } pt := p.pt + state := p.cloneState() p.pushV() + p.maxFailInvertExpected = !p.maxFailInvertExpected _, ok := p.parseExpr(not.expr) + p.maxFailInvertExpected = !p.maxFailInvertExpected p.popV() + p.restoreState(state) p.restore(pt) + return nil, !ok } @@ -1567,6 +1954,18 @@ func (p *parser) parseOneOrMoreExpr(expr *oneOrMoreExpr) (interface{}, bool) { } } +func (p *parser) parseRecoveryExpr(recover *recoveryExpr) (interface{}, bool) { + if p.debug { + defer p.out(p.in("parseRecoveryExpr (" + strings.Join(recover.failureLabel, ",") + ")")) + } + + p.pushRecovery(recover.failureLabel, recover.recoverExpr) + val, ok := p.parseExpr(recover.expr) + p.popRecovery() + + return val, ok +} + func (p *parser) parseRuleRefExpr(ref *ruleRefExpr) (interface{}, bool) { if p.debug { defer p.out(p.in("parseRuleRefExpr " + ref.name)) @@ -1589,12 +1988,14 @@ func (p *parser) parseSeqExpr(seq *seqExpr) (interface{}, bool) { defer p.out(p.in("parseSeqExpr")) } - var vals []interface{} + vals := make([]interface{}, 0, len(seq.exprs)) pt := p.pt + state := p.cloneState() for _, expr := range seq.exprs { val, ok := p.parseExpr(expr) if !ok { + p.restoreState(state) p.restore(pt) return nil, false } @@ -1603,6 +2004,34 @@ func (p *parser) parseSeqExpr(seq *seqExpr) (interface{}, bool) { return vals, true } +func (p *parser) parseStateCodeExpr(state *stateCodeExpr) (interface{}, bool) { + if p.debug { + defer p.out(p.in("parseStateCodeExpr")) + } + + err := state.run(p) + if err != nil { + p.addErr(err) + } + return nil, true +} + +func (p *parser) parseThrowExpr(expr *throwExpr) (interface{}, bool) { + if p.debug { + defer p.out(p.in("parseThrowExpr")) + } + + for i := len(p.recoveryStack) - 1; i >= 0; i-- { + if recoverExpr, ok := p.recoveryStack[i][expr.label]; ok { + if val, ok := p.parseExpr(recoverExpr); ok { + return val, ok + } + } + } + + return nil, false +} + func (p *parser) parseZeroOrMoreExpr(expr *zeroOrMoreExpr) (interface{}, bool) { if p.debug { defer p.out(p.in("parseZeroOrMoreExpr")) @@ -1632,18 +2061,3 @@ func (p *parser) parseZeroOrOneExpr(expr *zeroOrOneExpr) (interface{}, bool) { // whether it matched or not, consider it a match return val, true } - -func rangeTable(class string) *unicode.RangeTable { - if rt, ok := unicode.Categories[class]; ok { - return rt - } - if rt, ok := unicode.Properties[class]; ok { - return rt - } - if rt, ok := unicode.Scripts[class]; ok { - return rt - } - - // cannot happen - panic(fmt.Sprintf("invalid Unicode class: %s", class)) -} From 2337703be65d1ea3d78a01f25fcdcf5c7ee1880b Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Thu, 18 Apr 2019 09:41:04 -0500 Subject: [PATCH 104/113] fix: add missing secret key in http client configuration --- builder/osc/common/step_update_omi.go | 1 + 1 file changed, 1 insertion(+) diff --git a/builder/osc/common/step_update_omi.go b/builder/osc/common/step_update_omi.go index 65dfdaf9e..d6126148b 100644 --- a/builder/osc/common/step_update_omi.go +++ b/builder/osc/common/step_update_omi.go @@ -91,6 +91,7 @@ func (s *StepUpdateOMIAttributes) Run(_ context.Context, state multistep.StateBa ui.Say(fmt.Sprintf("Updating attributes on snapshot (%s)...", snapshot)) newConfig := &oapi.Config{ UserAgent: config.UserAgent, + AccessKey: config.AccessKey, SecretKey: config.SecretKey, Service: config.Service, Region: region, //New region From dc0db4b32277c3eaf47b57222c39d358e7ef8443 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Wed, 1 May 2019 14:10:15 -0500 Subject: [PATCH 105/113] fix: change osc builder to be passed a context for cancellation and remove conflicts --- builder/osc/bsu/builder.go | 15 ++---- builder/osc/bsusurrogate/builder.go | 15 ++---- builder/osc/bsuvolume/builder.go | 12 ++--- builder/osc/chroot/builder.go | 13 ++--- go.mod | 15 ++---- go.sum | 77 ++--------------------------- 6 files changed, 23 insertions(+), 124 deletions(-) diff --git a/builder/osc/bsu/builder.go b/builder/osc/bsu/builder.go index 5c5a2fc20..2f4ff61d5 100644 --- a/builder/osc/bsu/builder.go +++ b/builder/osc/bsu/builder.go @@ -1,4 +1,4 @@ -// The bsu package contains a packer.Builder implementation that +// Package bsu contains a packer.Builder implementation that // builds OMIs for Outscale OAPI. // // In general, there are two types of OMIs that can be created: ebs-backed or @@ -6,9 +6,9 @@ package bsu import ( + "context" "crypto/tls" "fmt" - "log" "net/http" osccommon "github.com/hashicorp/packer/builder/osc/common" @@ -80,7 +80,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { return nil, nil } -func (b *Builder) Run(ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { +func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { clientConfig, err := b.config.Config() if err != nil { return nil, err @@ -196,7 +196,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { } b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) - b.runner.Run(state) + b.runner.Run(ctx, state) // If there was an error, return that if rawErr, ok := state.GetOk("error"); ok { @@ -217,10 +217,3 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { return nil, nil } - -func (b *Builder) Cancel() { - if b.runner != nil { - log.Println("Cancelling the step runner...") - b.runner.Cancel() - } -} diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index 52b32130d..3cefe9a16 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -1,12 +1,12 @@ -// The bsusurrogate package contains a packer.Builder implementation that +// Package bsusurrogate contains a packer.Builder implementation that // builds a new EBS-backed OMI using an ephemeral instance. package bsusurrogate import ( + "context" "crypto/tls" "errors" "fmt" - "log" "net/http" osccommon "github.com/hashicorp/packer/builder/osc/common" @@ -98,7 +98,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { } -func (b *Builder) Run(ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { +func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { clientConfig, err := b.config.Config() if err != nil { return nil, err @@ -226,7 +226,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { } b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) - b.runner.Run(state) + b.runner.Run(ctx, state) // If there was an error, return that if rawErr, ok := state.GetOk("error"); ok { @@ -247,10 +247,3 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { return nil, nil } - -func (b *Builder) Cancel() { - if b.runner != nil { - log.Println("Cancelling the step runner...") - b.runner.Cancel() - } -} diff --git a/builder/osc/bsuvolume/builder.go b/builder/osc/bsuvolume/builder.go index 07e8b1441..348e9d66a 100644 --- a/builder/osc/bsuvolume/builder.go +++ b/builder/osc/bsuvolume/builder.go @@ -3,6 +3,7 @@ package bsuvolume import ( + "context" "crypto/tls" "fmt" "log" @@ -82,7 +83,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { return nil, nil } -func (b *Builder) Run(ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { +func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { clientConfig, err := b.config.Config() if err != nil { return nil, err @@ -179,7 +180,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { // Run! b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) - b.runner.Run(state) + b.runner.Run(ctx, state) // If there was an error, return that if rawErr, ok := state.GetOk("error"); ok { @@ -195,10 +196,3 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { ui.Say(fmt.Sprintf("Created Volumes: %s", artifact)) return artifact, nil } - -func (b *Builder) Cancel() { - if b.runner != nil { - log.Println("Cancelling the step runner...") - b.runner.Cancel() - } -} diff --git a/builder/osc/chroot/builder.go b/builder/osc/chroot/builder.go index 0f3edeb6f..18eb84f6f 100644 --- a/builder/osc/chroot/builder.go +++ b/builder/osc/chroot/builder.go @@ -5,9 +5,9 @@ package chroot import ( + "context" "crypto/tls" "errors" - "log" "net/http" "runtime" @@ -184,7 +184,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { return warns, nil } -func (b *Builder) Run(ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { +func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { if runtime.GOOS != "linux" { return nil, errors.New("The outscale-chroot builder only works on Linux environments.") } @@ -287,7 +287,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { // Run! b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) - b.runner.Run(state) + b.runner.Run(ctx, state) // If there was an error, return that if rawErr, ok := state.GetOk("error"); ok { @@ -308,10 +308,3 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { return artifact, nil } - -func (b *Builder) Cancel() { - if b.runner != nil { - log.Println("Cancelling the step runner...") - b.runner.Cancel() - } -} diff --git a/go.mod b/go.mod index 20054550f..7e1f8e65e 100644 --- a/go.mod +++ b/go.mod @@ -6,25 +6,24 @@ require ( github.com/Azure/azure-sdk-for-go v30.0.0+incompatible github.com/Azure/go-autorest v12.0.0+incompatible github.com/Azure/go-ntlmssp v0.0.0-20180810175552-4a21cbd618b4 // indirect - github.com/Bowery/prompt v0.0.0-20180817134258-8a1d5376df1c // indirect github.com/ChrisTrenkamp/goxpath v0.0.0-20170625215350-4fe035839290 github.com/NaverCloudPlatform/ncloud-sdk-go v0.0.0-20180110055012-c2e73f942591 github.com/Telmate/proxmox-api-go v0.0.0-20190614181158-26cd147831a4 github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af // indirect github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190418113227-25233c783f4e github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20170113022742-e6dbea820a9f - github.com/alvaroloes/enumer v1.1.2 // indirect github.com/antchfx/xpath v0.0.0-20170728053731-b5c552e1acbd // indirect github.com/antchfx/xquery v0.0.0-20170730121040-eb8c3c172607 // indirect github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6 // indirect - github.com/apache/thrift v0.12.0 // indirect github.com/approvals/go-approval-tests v0.0.0-20160714161514-ad96e53bea43 github.com/armon/go-radix v1.0.0 // indirect github.com/aws/aws-sdk-go v1.16.24 github.com/biogo/hts v0.0.0-20160420073057-50da7d4131a3 github.com/c2h5oh/datasize v0.0.0-20171227191756-4eba002a5eae github.com/cheggaaa/pb v1.0.27 + github.com/chzyer/logex v1.1.10 // indirect github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e + github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 // indirect github.com/creack/goselect v0.1.0 // indirect github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/digitalocean/go-libvirt v0.0.0-20190626172931-4d226dd6c437 // indirect @@ -37,6 +36,7 @@ require ( github.com/exoscale/egoscale v0.18.1 github.com/go-ini/ini v1.25.4 github.com/gofrs/flock v0.7.1 + github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db // indirect github.com/google/go-cmp v0.2.0 github.com/google/shlex v0.0.0-20150127133951-6f45313302b9 github.com/google/uuid v1.0.0 @@ -64,7 +64,6 @@ require ( github.com/joyent/triton-go v0.0.0-20180116165742-545edbe0d564 github.com/json-iterator/go v1.1.6 // indirect github.com/jtolds/gls v4.2.1+incompatible // indirect - github.com/kardianos/govendor v1.0.9 // indirect github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1 github.com/klauspost/compress v0.0.0-20160131094358-f86d2e6d8a77 // indirect github.com/klauspost/cpuid v0.0.0-20160106104451-349c67577817 // indirect @@ -73,7 +72,6 @@ require ( github.com/kr/fs v0.0.0-20131111012553-2788f0dbd169 // indirect github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 // indirect github.com/linode/linodego v0.7.1 - github.com/marstr/guid v0.0.0-20170427235115-8bdf7d1a087c // indirect github.com/masterzen/azure-sdk-for-go v0.0.0-20161014135628-ee4f0065d00c // indirect github.com/masterzen/simplexml v0.0.0-20190410153822-31eea3082786 // indirect github.com/masterzen/winrm v0.0.0-20180224160350-7e40f93ae939 @@ -83,13 +81,11 @@ require ( github.com/mitchellh/go-fs v0.0.0-20180402234041-7b48fa161ea7 github.com/mitchellh/go-homedir v1.0.0 github.com/mitchellh/go-vnc v0.0.0-20150629162542-723ed9867aed - github.com/mitchellh/gox v1.0.1 // indirect github.com/mitchellh/iochan v1.0.0 github.com/mitchellh/mapstructure v0.0.0-20180111000720-b4575eea38cc github.com/mitchellh/panicwrap v0.0.0-20170106182340-fce601fe5557 github.com/mitchellh/prefixedio v0.0.0-20151214002211-6e6954073784 github.com/mitchellh/reflectwalk v1.0.0 - github.com/mna/pigeon v1.0.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.1 // indirect github.com/moul/anonuuid v0.0.0-20160222162117-609b752a95ef // indirect @@ -97,7 +93,8 @@ require ( github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 // indirect github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect github.com/olekukonko/tablewriter v0.0.0-20180105111133-96aac992fc8b - github.com/openzipkin/zipkin-go v0.1.6 // indirect + github.com/onsi/ginkgo v1.7.0 // indirect + github.com/onsi/gomega v1.4.3 // indirect github.com/oracle/oci-go-sdk v1.8.0 github.com/outscale/osc-go v0.0.1 github.com/packer-community/winrmcp v0.0.0-20180921204643-0fd363d6159a @@ -106,7 +103,6 @@ require ( github.com/pkg/sftp v0.0.0-20160118190721-e84cc8c755ca github.com/posener/complete v1.1.1 github.com/profitbricks/profitbricks-sdk-go v4.0.2+incompatible - github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829 // indirect github.com/renstrom/fuzzysearch v0.0.0-20160331204855-2d205ac6ec17 // indirect github.com/rwtodd/Go.Sed v0.0.0-20170507045331-d6d5d585814e github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735 // indirect @@ -129,7 +125,6 @@ require ( golang.org/x/sync v0.0.0-20190423024810-112230192c58 golang.org/x/sys v0.0.0-20190425145619-16072639606e golang.org/x/text v0.3.1 // indirect - golang.org/x/tools v0.0.0-20190619215442-4adf7a708c2d // indirect google.golang.org/api v0.4.0 google.golang.org/grpc v1.20.1 gopkg.in/h2non/gock.v1 v1.0.12 // indirect diff --git a/go.sum b/go.sum index 2e93bff22..0532bded3 100644 --- a/go.sum +++ b/go.sum @@ -3,8 +3,6 @@ cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.36.0 h1:+aCSj7tOo2LODWVEuZDZeGCckdt6MlSF+X/rB3wUiS8= cloud.google.com/go v0.36.0/go.mod h1:RUoy9p/M4ge0HzT8L+SDZ8jg+Q6fth0CiBuhFJpSV40= -contrib.go.opencensus.io/exporter/ocagent v0.4.12 h1:jGFvw3l57ViIVEPKKEUXPcLYIXJmQxLUh6ey1eJhwyc= -contrib.go.opencensus.io/exporter/ocagent v0.4.12/go.mod h1:450APlNTSR6FrvC3CTRqYosuDstRB9un7SOx2k/9ckA= contrib.go.opencensus.io/exporter/ocagent v0.5.0 h1:TKXjQSRS0/cCDrP7KvkgU6SmILtF/yV2TOs/02K/WZQ= contrib.go.opencensus.io/exporter/ocagent v0.5.0/go.mod h1:ImxhfLRpxoYiSq891pBrLVhN+qmP8BTVvdH2YLs7Gl0= dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= @@ -14,40 +12,25 @@ dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= github.com/1and1/oneandone-cloudserver-sdk-go v1.0.1 h1:RMTyvS5bjvSWiUcfqfr/E2pxHEMrALvU+E12n6biymg= github.com/1and1/oneandone-cloudserver-sdk-go v1.0.1/go.mod h1:61apmbkVJH4kg+38ftT+/l0XxdUCVnHggqcOTqZRSEE= -github.com/Azure/azure-sdk-for-go v27.3.0+incompatible h1:i+ROfG3CsZUPoVAnhK06T3R6PmBzKB9ds+lHBpN7Mzo= -github.com/Azure/azure-sdk-for-go v27.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v30.0.0+incompatible h1:6o1Yzl7wTBYg+xw0pY4qnalaPmEQolubEEdepo1/kmI= github.com/Azure/azure-sdk-for-go v30.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/go-autorest v10.12.0+incompatible h1:6YphwUK+oXbzvCc1fd5VrnxCekwzDkpA7gUEbci2MvI= -github.com/Azure/go-autorest v10.12.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest v12.0.0+incompatible h1:N+VqClcomLGD/sHb3smbSYYtNMgKpVV3Cd5r5i8z6bQ= github.com/Azure/go-autorest v12.0.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/tracing v0.1.0 h1:TRBxC5Pj/fIuh4Qob0ZpkggbfT8RC0SubHbpV3p4/Vc= -github.com/Azure/go-autorest/tracing v0.1.0/go.mod h1:ROEEAFwXycQw7Sn3DXNtEedEvdeRAgDr0izn4z5Ij88= github.com/Azure/go-ntlmssp v0.0.0-20180810175552-4a21cbd618b4 h1:pSm8mp0T2OH2CPmPDPtwHPr3VAQaOwVF/JbllOPP4xA= github.com/Azure/go-ntlmssp v0.0.0-20180810175552-4a21cbd618b4/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= -github.com/Bowery/prompt v0.0.0-20180817134258-8a1d5376df1c/go.mod h1:4/6eNcqZ09BZ9wLK3tZOjBA1nDj+B0728nlX5YRlSmQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/ChrisTrenkamp/goxpath v0.0.0-20170625215350-4fe035839290 h1:K9I21XUHNbYD3GNMmJBN0UKJCpdP+glftwNZ7Bo8kqY= github.com/ChrisTrenkamp/goxpath v0.0.0-20170625215350-4fe035839290/go.mod h1:nuWgzSkT5PnyOd+272uUmV0dnAnAn42Mk7PiQC5VzN4= github.com/NaverCloudPlatform/ncloud-sdk-go v0.0.0-20180110055012-c2e73f942591 h1:/P9HCl71+Eh6vDbKNyRu+rpIIR70UCZWNOGexVV3e6k= github.com/NaverCloudPlatform/ncloud-sdk-go v0.0.0-20180110055012-c2e73f942591/go.mod h1:EHGzQGbwozJBj/4qj3WGrTJ0FqjgOTOxLQ0VNWvPn08= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/Telmate/proxmox-api-go v0.0.0-20190410200643-f08824d5082d h1:igrCnHheXb+lZ1bW9Ths8JZZIjh9D4Vi/49JqiHE+cI= -github.com/Telmate/proxmox-api-go v0.0.0-20190410200643-f08824d5082d/go.mod h1:OGWyIMJ87/k/GCz8CGiWB2HOXsOVDM6Lpe/nFPkC4IQ= github.com/Telmate/proxmox-api-go v0.0.0-20190614181158-26cd147831a4 h1:o//09WenT9BNcQypCYfOBfRe5gtLUvUfTPq0xQqPMEI= github.com/Telmate/proxmox-api-go v0.0.0-20190614181158-26cd147831a4/go.mod h1:OGWyIMJ87/k/GCz8CGiWB2HOXsOVDM6Lpe/nFPkC4IQ= github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af h1:DBNMBMuMiWYu0b+8KMJuWmfCkcxl09JwdlqwDZZ6U14= github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af/go.mod h1:5Jv4cbFiHJMsVxt52+i0Ha45fjshj6wxYr1r19tB9bw= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190418113227-25233c783f4e h1:/8wOj52pewmIX/8d5eVO3t7Rr3astkBI/ruyg4WNqRo= github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190418113227-25233c783f4e/go.mod h1:T9M45xf79ahXVelWoOBmH0y4aC1t5kXO5BxwyakgIGA= github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20170113022742-e6dbea820a9f h1:jI4DIE5Vf4oRaHfthB0oRhU+yuYuoOTurDzwAlskP00= github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20170113022742-e6dbea820a9f/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= -github.com/alvaroloes/enumer v1.1.2 h1:5khqHB33TZy1GWCO/lZwcroBFh7u+0j40T83VUbfAMY= -github.com/alvaroloes/enumer v1.1.2/go.mod h1:FxrjvuXoDAx9isTJrv4c+T410zFi0DtXIT0m65DJ+Wo= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antchfx/xpath v0.0.0-20170728053731-b5c552e1acbd h1:S3Fr6QnkpW9VRjiEY4psQHhhbbahASuNVj52YIce7lI= github.com/antchfx/xpath v0.0.0-20170728053731-b5c552e1acbd/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByNYhvtNk= @@ -55,7 +38,6 @@ github.com/antchfx/xquery v0.0.0-20170730121040-eb8c3c172607 h1:BFFG6KP8ASFBg2pt github.com/antchfx/xquery v0.0.0-20170730121040-eb8c3c172607/go.mod h1:LzD22aAzDP8/dyiCKFp31He4m2GPjl0AFyzDtZzUu9M= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6 h1:uZuxRZCz65cG1o6K/xUqImNcYKtmk9ylqaH0itMSvzA= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/approvals/go-approval-tests v0.0.0-20160714161514-ad96e53bea43 h1:ePCAQPf5tUc5IMcUvu6euhSGna7jzs7eiXtJXHig6Zc= github.com/approvals/go-approval-tests v0.0.0-20160714161514-ad96e53bea43/go.mod h1:S6puKjZ9ZeqUPBv2hEBnMZGcM2J6mOsDRQcmxkMAND0= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= @@ -82,8 +64,12 @@ github.com/census-instrumentation/opencensus-proto v0.2.0 h1:LzQXZOgg4CQfE6bFvXG github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cheggaaa/pb v1.0.27 h1:wIkZHkNfC7R6GI5w7l/PdAdzXzlrbcI3p8OAlnkTsnc= github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= +github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/creack/goselect v0.1.0 h1:4QiXIhcpSQF50XGaBsFzesjwX/1qOY5bOveQPmN9CXY= @@ -109,9 +95,6 @@ github.com/dylanmei/iso8601 v0.1.0 h1:812NGQDBcqquTfH5Yeo7lwR0nzx/cKdsmf3qMjPURU github.com/dylanmei/iso8601 v0.1.0/go.mod h1:w9KhXSgIyROl1DefbMYIE7UVSIvELTbMrCfx+QkYnoQ= github.com/dylanmei/winrmtest v0.0.0-20170819153634-c2fbb09e6c08 h1:0bp6/GrNOrTDtSXe9YYGCwf8jp5Fb/b+4a6MTRm4qzY= github.com/dylanmei/winrmtest v0.0.0-20170819153634-c2fbb09e6c08/go.mod h1:VBVDFSBXCIW8JaHQpI8lldSKfYaLMzP9oyq6IJ4fhzY= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/exoscale/egoscale v0.18.1 h1:1FNZVk8jHUx0AvWhOZxLEDNlacTU0chMXUUNkm9EZaI= github.com/exoscale/egoscale v0.18.1/go.mod h1:Z7OOdzzTOz1Q1PjQXumlz9Wn/CddH0zSYdCF3rnBKXE= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= @@ -124,15 +107,11 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-ini/ini v1.25.4 h1:Mujh4R/dH6YL8bxuISne3xX2+qcQ9p0IxKAP6ExWoUo= github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gofrs/flock v0.7.1 h1:DP+LD/t0njgoPBvT5MJLeliUIVQR03hiKR6vezdwHlc= github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= @@ -169,8 +148,6 @@ github.com/gophercloud/utils v0.0.0-20190124192022-a5c25e7a53a6/go.mod h1:wjDF8z github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v0.0.0-20170319172727-a91eba7f9777 h1:JIM+OacoOJRU30xpjMf8sulYqjr0ViA3WDrTX6j/yDI= github.com/gorilla/websocket v0.0.0-20170319172727-a91eba7f9777/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= @@ -185,12 +162,6 @@ github.com/hashicorp/go-checkpoint v0.0.0-20171009173528-1545e56e46de h1:XDCSyth github.com/hashicorp/go-checkpoint v0.0.0-20171009173528-1545e56e46de/go.mod h1:xIwEieBHERyEvaeKF/TcHh1Hu+lxPM+n2vT1+g9I4m4= github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-getter v1.2.0 h1:E05bVPilzyh2yXgT6srn7WEkfMZaH+LuX9tDJw/4kaE= -github.com/hashicorp/go-getter v1.2.0/go.mod h1:/O1k/AizTN0QmfEKknCYGvICeyKUDqCYA8vvWtGWDeQ= -github.com/hashicorp/go-getter v1.3.1-0.20190627194702-0c4919d4eb92 h1:Tck3az71eOyEcxueXyZfM4YO5oy2Hq8AbTpvc9HrQN0= -github.com/hashicorp/go-getter v1.3.1-0.20190627194702-0c4919d4eb92/go.mod h1:/O1k/AizTN0QmfEKknCYGvICeyKUDqCYA8vvWtGWDeQ= -github.com/hashicorp/go-getter v1.3.1-0.20190627194820-3fc511e2f341 h1:v+hsBJMakfQLeYkPuv/Y/T86jKvDQrOU1TyzximcF2Y= -github.com/hashicorp/go-getter v1.3.1-0.20190627194820-3fc511e2f341/go.mod h1:/O1k/AizTN0QmfEKknCYGvICeyKUDqCYA8vvWtGWDeQ= github.com/hashicorp/go-getter v1.3.1-0.20190627223108-da0323b9545e h1:6krcdHPiS+aIP9XKzJzSahfjD7jG7Z+4+opm0z39V1M= github.com/hashicorp/go-getter v1.3.1-0.20190627223108-da0323b9545e/go.mod h1:/O1k/AizTN0QmfEKknCYGvICeyKUDqCYA8vvWtGWDeQ= github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= @@ -213,7 +184,6 @@ github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdv github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.1.0 h1:bPIoEKD27tNdebFGGxxYwcL4nepeY4j1QP23PFRGzg0= github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E= @@ -249,8 +219,6 @@ github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwK github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/kardianos/govendor v1.0.9/go.mod h1:yvmR6q9ZZ7nSF5Wvh40v0wfP+3TwwL8zYQp+itoZSVM= github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1 h1:PJPDf8OUfOK1bb/NeTKd4f1QXZItOX389VN3B6qC8ro= github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -266,7 +234,6 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGi github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.0.0-20131111012553-2788f0dbd169 h1:YUrU1/jxRqnt0PSrKj1Uj/wEjk/fjnE80QFfi2Zlj7Q= github.com/kr/fs v0.0.0-20131111012553-2788f0dbd169/go.mod h1:glhvuHOU9Hy7/8PwwdtnarXqLagOX0b/TbZx2zLMqEg= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -277,8 +244,6 @@ github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3v github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/linode/linodego v0.7.1 h1:4WZmMpSA2NRwlPZcc0+4Gyn7rr99Evk9bnr0B3gXRKE= github.com/linode/linodego v0.7.1/go.mod h1:ga11n3ivecUrPCHN0rANxKmfWBJVkOXfLMZinAbj2sY= -github.com/marstr/guid v0.0.0-20170427235115-8bdf7d1a087c h1:N7uWGS2fTwH/4BwxbHiJZNAFTSJ5yPU0emHsQWvkxEY= -github.com/marstr/guid v0.0.0-20170427235115-8bdf7d1a087c/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= github.com/masterzen/azure-sdk-for-go v0.0.0-20161014135628-ee4f0065d00c h1:FMUOnVGy8nWk1cvlMCAoftRItQGMxI0vzJ3dQjeZTCE= github.com/masterzen/azure-sdk-for-go v0.0.0-20161014135628-ee4f0065d00c/go.mod h1:mf8fjOu33zCqxUjuiU3I8S1lJMyEAlH+0F2+M5xl3hE= github.com/masterzen/simplexml v0.0.0-20190410153822-31eea3082786 h1:2ZKn+w/BJeL43sCxI2jhPLRv73oVVOjEKZjKkflyqxg= @@ -310,8 +275,6 @@ github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eI github.com/mitchellh/go-vnc v0.0.0-20150629162542-723ed9867aed h1:FI2NIv6fpef6BQl2u3IZX/Cj20tfypRF4yd+uaHOMtI= github.com/mitchellh/go-vnc v0.0.0-20150629162542-723ed9867aed/go.mod h1:3rdaFaCv4AyBgu5ALFM0+tSuHrBh6v692nyQe3ikrq0= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/gox v1.0.1 h1:x0jD3dcHk9a9xPSDN6YEL4xL6Qz0dvNYm8yZqui5chI= -github.com/mitchellh/gox v1.0.1/go.mod h1:ED6BioOGXMswlXa2zxfh/xdd5QhwYliBFn9V18Ap4z4= github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= @@ -323,8 +286,6 @@ github.com/mitchellh/prefixedio v0.0.0-20151214002211-6e6954073784 h1:+DAetXqxv/ github.com/mitchellh/prefixedio v0.0.0-20151214002211-6e6954073784/go.mod h1:kB1naBgV9ORnkiTVeyJOI1DavaJkG4oNIq0Af6ZVKUo= github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/mna/pigeon v1.0.0 h1:n46IoStjdzjaXuyBH53j9HZ8CVqGWpC7P5/v8dP4qEY= -github.com/mna/pigeon v1.0.0/go.mod h1:Iym28+kJVnC1hfQvv5MUtI6AiFFzvQjHcvI4RFTG/04= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= @@ -333,7 +294,6 @@ github.com/moul/anonuuid v0.0.0-20160222162117-609b752a95ef h1:E/seV1Rtsnr2juBw1 github.com/moul/anonuuid v0.0.0-20160222162117-609b752a95ef/go.mod h1:LgKrp0Iss/BVwquptq4eIe6HPr0s3t1WHT5x0qOh14U= github.com/moul/gotty-client v0.0.0-20180327180212-b26a57ebc215 h1:y6FZWUBBt1iPmJyGbGza3ncvVBMKzgd32oFChRZR7Do= github.com/moul/gotty-client v0.0.0-20180327180212-b26a57ebc215/go.mod h1:CxM/JGtpRrEPve5H04IhxJrGhxgwxMc6jSP2T4YD60w= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= @@ -348,7 +308,6 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/oracle/oci-go-sdk v1.8.0 h1:4SO45bKV0I3/Mn1os3ANDZmV0eSE5z5CLdSUIkxtyzs= github.com/oracle/oci-go-sdk v1.8.0/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= github.com/outscale/osc-go v0.0.1 h1:hvBtORyu7sWSKW1norGlfIP8C7c2aegI2Vkq75SRPCE= @@ -357,8 +316,6 @@ github.com/packer-community/winrmcp v0.0.0-20180921204643-0fd363d6159a h1:A3QMut github.com/packer-community/winrmcp v0.0.0-20180921204643-0fd363d6159a/go.mod h1:f6Izs6JvFTdnRbziASagjZ2vmf55NSIkC/weStxCHqk= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pascaldekloe/name v0.0.0-20180628100202-0fd16699aae1 h1:/I3lTljEEDNYLho3/FUB7iD/oc2cEFgVmbHzV+O0PtU= -github.com/pascaldekloe/name v0.0.0-20180628100202-0fd16699aae1/go.mod h1:eD5JxqMiuNYyFNmyY9rkJ/slN8y59oEu4Ei7F8OoKWQ= github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= @@ -372,16 +329,9 @@ github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndr github.com/profitbricks/profitbricks-sdk-go v4.0.2+incompatible h1:ZoVHH6voxW9Onzo6z2yLtocVoN6mBocyDoqoyAMHokE= github.com/profitbricks/profitbricks-sdk-go v4.0.2+incompatible/go.mod h1:T3/WrziK7fYH3C8ilAFAHe99R452/IzIG3YYkqaOFeQ= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/renstrom/fuzzysearch v0.0.0-20160331204855-2d205ac6ec17 h1:4qPms2txLWMLXKzqlnYSulKRS4cS9aYgPtAEpUelQok= github.com/renstrom/fuzzysearch v0.0.0-20160331204855-2d205ac6ec17/go.mod h1:SAEjPB4voP88qmWJXI7mA5m15uNlEnuHLx4Eu2mPGpQ= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= @@ -420,8 +370,6 @@ github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1l github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= -github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.3.0 h1:hI/7Q+DtNZ2kINb6qt/lS+IyXnHQe9e90POfeewL/ME= github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= @@ -456,10 +404,6 @@ github.com/yandex-cloud/go-sdk v0.0.0-20190402114215-3fc1d6947035 h1:2ZLZeg6xp+k github.com/yandex-cloud/go-sdk v0.0.0-20190402114215-3fc1d6947035/go.mod h1:Eml0jFLU4VVHgIN8zPHMuNwZXVzUMILyO6lQZSfz854= go.opencensus.io v0.18.0 h1:Mk5rgZcggtbvtAun5aJzAtjKKN/t0R3jJPlWILlv938= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= -go.opencensus.io v0.20.1 h1:pMEjRZ1M4ebWGikflH7nQpV6+Zr88KBMA2XJD3sbijw= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2 h1:NAfh7zF0/3/HqtMvJNZ/RFrSlCE6ZTlHmKfhL/Dm1Jk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0 h1:mU6zScU4U1YAFPHEHYk+3JC4SY7JxgkqS10ZOSyksNg= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= @@ -489,7 +433,6 @@ golang.org/x/net v0.0.0-20181201002055-351d144fa1fc h1:a3CU5tJYVj92DY2LaA1kUkrsq golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd h1:HuTn7WObtcDo9uEEU7rEqL0jYthdXAmZ6PP+meazmaU= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= @@ -521,8 +464,6 @@ golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5 h1:x6r4Jo0KNzOOzYd8lbcRsqjuq golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181213200352-4d1cda033e06/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -546,17 +487,10 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524210228-3d17549cdc6b/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190530184349-ce1a3806b557 h1:WFdP1eIY3AwGUPgVua5UIX4C7BzCIK8TOwm6RA+0vAQ= -golang.org/x/tools v0.0.0-20190530184349-ce1a3806b557/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190619215442-4adf7a708c2d h1:LQ06Vbju+Kwbcd94hb+6CgDsWoj/e7GOLPcYzHrG+iI= -golang.org/x/tools v0.0.0-20190619215442-4adf7a708c2d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0 h1:K6z2u68e86TPdSdefXdzvXgR1zEMa+459vBSfWYAZkI= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= -google.golang.org/api v0.3.1 h1:oJra/lMfmtm13/rgY/8i3MzjFWYXvQIAKjQ3HqofMk8= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0 h1:KKgc1aqhV8wDPbDzlDtpvyjZFY3vjz85FP7p4wcQUyI= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= @@ -577,11 +511,8 @@ google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9M google.golang.org/grpc v1.17.0 h1:TRJYBgMclJvGYn2rIMjj+h9KtMt5r1Ij7ODVRIZkwhk= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.19.1 h1:TrBcJ1yqAl1G++wO39nD/qtgpsW9/1+QGrluyMGEYgM= -google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= From 03f8b2ceb596c376246efc801fe90bda1e730c0a Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Wed, 1 May 2019 16:10:35 -0500 Subject: [PATCH 106/113] fix: change GlobalPermission to false in order to prevent public image creation --- builder/osc/common/step_update_omi.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/osc/common/step_update_omi.go b/builder/osc/common/step_update_omi.go index d6126148b..41ce69a89 100644 --- a/builder/osc/common/step_update_omi.go +++ b/builder/osc/common/step_update_omi.go @@ -40,7 +40,7 @@ func (s *StepUpdateOMIAttributes) Run(_ context.Context, state multistep.StateBa PermissionsToCreateVolume: oapi.PermissionsOnResourceCreation{ Additions: oapi.PermissionsOnResource{ AccountIds: s.AccountIds, - GlobalPermission: true, + GlobalPermission: false, }, }, } @@ -49,7 +49,7 @@ func (s *StepUpdateOMIAttributes) Run(_ context.Context, state multistep.StateBa PermissionsToLaunch: oapi.PermissionsOnResourceCreation{ Additions: oapi.PermissionsOnResource{ AccountIds: s.AccountIds, - GlobalPermission: true, + GlobalPermission: false, }, }, } From d10f87f81547c033c399a4d805a44564d0e9bd64 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Fri, 3 May 2019 11:02:03 -0500 Subject: [PATCH 107/113] chore: add osc builder commiters to CODEOWNERS file --- CODEOWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/CODEOWNERS b/CODEOWNERS index b3ecfba4d..d69a9ab9e 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -18,6 +18,7 @@ /builder/hyperone @m110 @gregorybrzeski @ad-m /builder/ucloud/ @shawnmssu /builder/yandex @GennadySpb @alexanderKhaustov @seukyaso +/builder/osc @marinsalinas # provisioners From 1b7c56f73dd350917441e386b6e6f7ed6c04bb0f Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Fri, 3 May 2019 13:10:38 -0500 Subject: [PATCH 108/113] fix: change bad artifact validation in bsu builder --- builder/osc/bsu/builder.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/osc/bsu/builder.go b/builder/osc/bsu/builder.go index 2f4ff61d5..287676d5b 100644 --- a/builder/osc/bsu/builder.go +++ b/builder/osc/bsu/builder.go @@ -204,7 +204,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack } //Build the artifact - if omis, ok := state.GetOk("omis"); !ok { + if omis, ok := state.GetOk("omis"); ok { // Build the artifact and return it artifact := &osccommon.Artifact{ Omis: omis.(map[string]string), From 7e23f14d4ebe59e2a6a78282ff35706d2a899d15 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Thu, 9 May 2019 11:50:44 -0500 Subject: [PATCH 109/113] fix: chroot builder --- builder/osc/chroot/builder.go | 19 ++- builder/osc/chroot/cleanup.go | 10 ++ builder/osc/chroot/communicator.go | 3 +- builder/osc/chroot/communicator_test.go | 15 ++ builder/osc/chroot/lockfile.go | 16 ++ builder/osc/chroot/lockfile_unix.go | 27 ++++ builder/osc/chroot/run_local_commands.go | 41 ++++++ builder/osc/chroot/step_chroot_provision.go | 37 +++++ builder/osc/chroot/step_copy_files.go | 91 ++++++++++++ builder/osc/chroot/step_copy_files_test.go | 11 ++ builder/osc/chroot/step_early_cleanup.go | 39 +++++ builder/osc/chroot/step_early_unflock.go | 30 ++++ builder/osc/chroot/step_flock.go | 74 ++++++++++ builder/osc/chroot/step_mount_device.go | 19 ++- builder/osc/chroot/step_mount_extra.go | 137 ++++++++++++++++++ .../osc/chroot/step_post_mount_commands.go | 47 ++++++ builder/osc/chroot/step_pre_mount_commands.go | 41 ++++++ 17 files changed, 644 insertions(+), 13 deletions(-) create mode 100644 builder/osc/chroot/cleanup.go create mode 100644 builder/osc/chroot/communicator_test.go create mode 100644 builder/osc/chroot/lockfile.go create mode 100644 builder/osc/chroot/lockfile_unix.go create mode 100644 builder/osc/chroot/run_local_commands.go create mode 100644 builder/osc/chroot/step_chroot_provision.go create mode 100644 builder/osc/chroot/step_copy_files.go create mode 100644 builder/osc/chroot/step_copy_files_test.go create mode 100644 builder/osc/chroot/step_early_cleanup.go create mode 100644 builder/osc/chroot/step_early_unflock.go create mode 100644 builder/osc/chroot/step_flock.go create mode 100644 builder/osc/chroot/step_mount_extra.go create mode 100644 builder/osc/chroot/step_post_mount_commands.go create mode 100644 builder/osc/chroot/step_pre_mount_commands.go diff --git a/builder/osc/chroot/builder.go b/builder/osc/chroot/builder.go index 18eb84f6f..ab52eba43 100644 --- a/builder/osc/chroot/builder.go +++ b/builder/osc/chroot/builder.go @@ -1,4 +1,4 @@ -// The chroot package is able to create an Outscale OMI without requiring +// Package chroot is able to create an Outscale OMI without requiring // the launch of a new instance for every build. It does this by attaching // and mounting the root volume of another OMI and chrooting into that // directory. It then creates an OMI from that attached drive. @@ -11,7 +11,6 @@ import ( "net/http" "runtime" - awschroot "github.com/hashicorp/packer/builder/amazon/chroot" osccommon "github.com/hashicorp/packer/builder/osc/common" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/config" @@ -238,7 +237,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack } steps = append(steps, - &awschroot.StepFlock{}, + &StepFlock{}, &StepPrepareDevice{}, &StepCreateVolume{ RootVolumeType: b.config.RootVolumeType, @@ -247,21 +246,21 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack Ctx: b.config.ctx, }, &StepLinkVolume{}, - &awschroot.StepEarlyUnflock{}, - &awschroot.StepPreMountCommands{ + &StepEarlyUnflock{}, + &StepPreMountCommands{ Commands: b.config.PreMountCommands, }, &StepMountDevice{ MountOptions: b.config.MountOptions, MountPartition: b.config.MountPartition, }, - &awschroot.StepPostMountCommands{ + &StepPostMountCommands{ Commands: b.config.PostMountCommands, }, - &awschroot.StepMountExtra{}, - &awschroot.StepCopyFiles{}, - &awschroot.StepChrootProvision{}, - &awschroot.StepEarlyCleanup{}, + &StepMountExtra{}, + &StepCopyFiles{}, + &StepChrootProvision{}, + &StepEarlyCleanup{}, &StepSnapshot{}, &osccommon.StepDeregisterOMI{ AccessConfig: &b.config.AccessConfig, diff --git a/builder/osc/chroot/cleanup.go b/builder/osc/chroot/cleanup.go new file mode 100644 index 000000000..0befac174 --- /dev/null +++ b/builder/osc/chroot/cleanup.go @@ -0,0 +1,10 @@ +package chroot + +import ( + "github.com/hashicorp/packer/helper/multistep" +) + +// Cleanup is an interface that some steps implement for early cleanup. +type Cleanup interface { + CleanupFunc(multistep.StateBag) error +} diff --git a/builder/osc/chroot/communicator.go b/builder/osc/chroot/communicator.go index 6efb6cb25..c5306fe2f 100644 --- a/builder/osc/chroot/communicator.go +++ b/builder/osc/chroot/communicator.go @@ -2,6 +2,7 @@ package chroot import ( "bytes" + "context" "fmt" "io" "log" @@ -23,7 +24,7 @@ type Communicator struct { CmdWrapper CommandWrapper } -func (c *Communicator) Start(cmd *packer.RemoteCmd) error { +func (c *Communicator) Start(ctx context.Context, cmd *packer.RemoteCmd) error { // need extra escapes for the command since we're wrapping it in quotes cmd.Command = strconv.Quote(cmd.Command) command, err := c.CmdWrapper( diff --git a/builder/osc/chroot/communicator_test.go b/builder/osc/chroot/communicator_test.go new file mode 100644 index 000000000..43995b79a --- /dev/null +++ b/builder/osc/chroot/communicator_test.go @@ -0,0 +1,15 @@ +package chroot + +import ( + "testing" + + "github.com/hashicorp/packer/packer" +) + +func TestCommunicator_ImplementsCommunicator(t *testing.T) { + var raw interface{} + raw = &Communicator{} + if _, ok := raw.(packer.Communicator); !ok { + t.Fatalf("Communicator should be a communicator") + } +} diff --git a/builder/osc/chroot/lockfile.go b/builder/osc/chroot/lockfile.go new file mode 100644 index 000000000..1ba13e04b --- /dev/null +++ b/builder/osc/chroot/lockfile.go @@ -0,0 +1,16 @@ +// +build windows + +package chroot + +import ( + "errors" + "os" +) + +func lockFile(*os.File) error { + return errors.New("not supported on Windows") +} + +func unlockFile(f *os.File) error { + return nil +} diff --git a/builder/osc/chroot/lockfile_unix.go b/builder/osc/chroot/lockfile_unix.go new file mode 100644 index 000000000..0d0f8c8f7 --- /dev/null +++ b/builder/osc/chroot/lockfile_unix.go @@ -0,0 +1,27 @@ +// +build !windows + +package chroot + +import ( + "os" + + "golang.org/x/sys/unix" +) + +// See: http://linux.die.net/include/sys/file.h +const LOCK_EX = 2 +const LOCK_NB = 4 +const LOCK_UN = 8 + +func lockFile(f *os.File) error { + err := unix.Flock(int(f.Fd()), LOCK_EX) + if err != nil { + return err + } + + return nil +} + +func unlockFile(f *os.File) error { + return unix.Flock(int(f.Fd()), LOCK_UN) +} diff --git a/builder/osc/chroot/run_local_commands.go b/builder/osc/chroot/run_local_commands.go new file mode 100644 index 000000000..9a93f8791 --- /dev/null +++ b/builder/osc/chroot/run_local_commands.go @@ -0,0 +1,41 @@ +package chroot + +import ( + "context" + "fmt" + + sl "github.com/hashicorp/packer/common/shell-local" + "github.com/hashicorp/packer/packer" + "github.com/hashicorp/packer/template/interpolate" +) + +func RunLocalCommands(commands []string, wrappedCommand CommandWrapper, ictx interpolate.Context, ui packer.Ui) error { + ctx := context.TODO() + for _, rawCmd := range commands { + intCmd, err := interpolate.Render(rawCmd, &ictx) + if err != nil { + return fmt.Errorf("Error interpolating: %s", err) + } + + command, err := wrappedCommand(intCmd) + if err != nil { + return fmt.Errorf("Error wrapping command: %s", err) + } + + ui.Say(fmt.Sprintf("Executing command: %s", command)) + comm := &sl.Communicator{ + ExecuteCommand: []string{"sh", "-c", command}, + } + cmd := &packer.RemoteCmd{Command: command} + if err := cmd.RunWithUi(ctx, comm, ui); err != nil { + return fmt.Errorf("Error executing command: %s", err) + } + if cmd.ExitStatus() != 0 { + return fmt.Errorf( + "Received non-zero exit code %d from command: %s", + cmd.ExitStatus(), + command) + } + } + return nil +} diff --git a/builder/osc/chroot/step_chroot_provision.go b/builder/osc/chroot/step_chroot_provision.go new file mode 100644 index 000000000..4545105b0 --- /dev/null +++ b/builder/osc/chroot/step_chroot_provision.go @@ -0,0 +1,37 @@ +package chroot + +import ( + "context" + "log" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" +) + +// StepChrootProvision provisions the instance within a chroot. +type StepChrootProvision struct { +} + +func (s *StepChrootProvision) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + hook := state.Get("hook").(packer.Hook) + mountPath := state.Get("mount_path").(string) + ui := state.Get("ui").(packer.Ui) + wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) + + // Create our communicator + comm := &Communicator{ + Chroot: mountPath, + CmdWrapper: wrappedCommand, + } + + // Provision + log.Println("Running the provision hook") + if err := hook.Run(ctx, packer.HookProvision, ui, comm, nil); err != nil { + state.Put("error", err) + return multistep.ActionHalt + } + + return multistep.ActionContinue +} + +func (s *StepChrootProvision) Cleanup(state multistep.StateBag) {} diff --git a/builder/osc/chroot/step_copy_files.go b/builder/osc/chroot/step_copy_files.go new file mode 100644 index 000000000..78625a8d3 --- /dev/null +++ b/builder/osc/chroot/step_copy_files.go @@ -0,0 +1,91 @@ +package chroot + +import ( + "bytes" + "context" + "fmt" + "log" + "path/filepath" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" +) + +// StepCopyFiles copies some files from the host into the chroot environment. +// +// Produces: +// copy_files_cleanup CleanupFunc - A function to clean up the copied files +// early. +type StepCopyFiles struct { + files []string +} + +func (s *StepCopyFiles) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + config := state.Get("config").(*Config) + mountPath := state.Get("mount_path").(string) + ui := state.Get("ui").(packer.Ui) + wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) + stderr := new(bytes.Buffer) + + s.files = make([]string, 0, len(config.CopyFiles)) + if len(config.CopyFiles) > 0 { + ui.Say("Copying files from host to chroot...") + for _, path := range config.CopyFiles { + ui.Message(path) + chrootPath := filepath.Join(mountPath, path) + log.Printf("Copying '%s' to '%s'", path, chrootPath) + + cmdText, err := wrappedCommand(fmt.Sprintf("cp --remove-destination %s %s", path, chrootPath)) + if err != nil { + err := fmt.Errorf("Error building copy command: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + stderr.Reset() + cmd := ShellCommand(cmdText) + cmd.Stderr = stderr + if err := cmd.Run(); err != nil { + err := fmt.Errorf( + "Error copying file: %s\nnStderr: %s", err, stderr.String()) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + s.files = append(s.files, chrootPath) + } + } + + state.Put("copy_files_cleanup", s) + return multistep.ActionContinue +} + +func (s *StepCopyFiles) Cleanup(state multistep.StateBag) { + ui := state.Get("ui").(packer.Ui) + if err := s.CleanupFunc(state); err != nil { + ui.Error(err.Error()) + } +} + +func (s *StepCopyFiles) CleanupFunc(state multistep.StateBag) error { + wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) + if s.files != nil { + for _, file := range s.files { + log.Printf("Removing: %s", file) + localCmdText, err := wrappedCommand(fmt.Sprintf("rm -f %s", file)) + if err != nil { + return err + } + + localCmd := ShellCommand(localCmdText) + if err := localCmd.Run(); err != nil { + return err + } + } + } + + s.files = nil + return nil +} diff --git a/builder/osc/chroot/step_copy_files_test.go b/builder/osc/chroot/step_copy_files_test.go new file mode 100644 index 000000000..281613e6f --- /dev/null +++ b/builder/osc/chroot/step_copy_files_test.go @@ -0,0 +1,11 @@ +package chroot + +import "testing" + +func TestCopyFilesCleanupFunc_ImplementsCleanupFunc(t *testing.T) { + var raw interface{} + raw = new(StepCopyFiles) + if _, ok := raw.(Cleanup); !ok { + t.Fatalf("cleanup func should be a CleanupFunc") + } +} diff --git a/builder/osc/chroot/step_early_cleanup.go b/builder/osc/chroot/step_early_cleanup.go new file mode 100644 index 000000000..42d7d66c5 --- /dev/null +++ b/builder/osc/chroot/step_early_cleanup.go @@ -0,0 +1,39 @@ +package chroot + +import ( + "context" + "fmt" + "log" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" +) + +// StepEarlyCleanup performs some of the cleanup steps early in order to +// prepare for snapshotting and creating an AMI. +type StepEarlyCleanup struct{} + +func (s *StepEarlyCleanup) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + ui := state.Get("ui").(packer.Ui) + cleanupKeys := []string{ + "copy_files_cleanup", + "mount_extra_cleanup", + "mount_device_cleanup", + "attach_cleanup", + } + + for _, key := range cleanupKeys { + c := state.Get(key).(Cleanup) + log.Printf("Running cleanup func: %s", key) + if err := c.CleanupFunc(state); err != nil { + err := fmt.Errorf("Error cleaning up: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + + return multistep.ActionContinue +} + +func (s *StepEarlyCleanup) Cleanup(state multistep.StateBag) {} diff --git a/builder/osc/chroot/step_early_unflock.go b/builder/osc/chroot/step_early_unflock.go new file mode 100644 index 000000000..b16becc61 --- /dev/null +++ b/builder/osc/chroot/step_early_unflock.go @@ -0,0 +1,30 @@ +package chroot + +import ( + "context" + "fmt" + "log" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" +) + +// StepEarlyUnflock unlocks the flock. +type StepEarlyUnflock struct{} + +func (s *StepEarlyUnflock) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + cleanup := state.Get("flock_cleanup").(Cleanup) + ui := state.Get("ui").(packer.Ui) + + log.Println("Unlocking file lock...") + if err := cleanup.CleanupFunc(state); err != nil { + err := fmt.Errorf("Error unlocking file lock: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + return multistep.ActionContinue +} + +func (s *StepEarlyUnflock) Cleanup(state multistep.StateBag) {} diff --git a/builder/osc/chroot/step_flock.go b/builder/osc/chroot/step_flock.go new file mode 100644 index 000000000..f3fd9d29e --- /dev/null +++ b/builder/osc/chroot/step_flock.go @@ -0,0 +1,74 @@ +package chroot + +import ( + "context" + "fmt" + "log" + "os" + "path/filepath" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" +) + +// StepFlock provisions the instance within a chroot. +// +// Produces: +// flock_cleanup Cleanup - To perform early cleanup +type StepFlock struct { + fh *os.File +} + +func (s *StepFlock) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + ui := state.Get("ui").(packer.Ui) + + lockfile := "/var/lock/packer-chroot/lock" + if err := os.MkdirAll(filepath.Dir(lockfile), 0755); err != nil { + err := fmt.Errorf("Error creating lock: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + log.Printf("Obtaining lock: %s", lockfile) + f, err := os.Create(lockfile) + if err != nil { + err := fmt.Errorf("Error creating lock: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + // LOCK! + if err := lockFile(f); err != nil { + err := fmt.Errorf("Error obtaining lock: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + // Set the file handle, we can't close it because we need to hold + // the lock. + s.fh = f + + state.Put("flock_cleanup", s) + return multistep.ActionContinue +} + +func (s *StepFlock) Cleanup(state multistep.StateBag) { + s.CleanupFunc(state) +} + +func (s *StepFlock) CleanupFunc(state multistep.StateBag) error { + if s.fh == nil { + return nil + } + + log.Printf("Unlocking: %s", s.fh.Name()) + if err := unlockFile(s.fh); err != nil { + return err + } + + s.fh = nil + return nil +} diff --git a/builder/osc/chroot/step_mount_device.go b/builder/osc/chroot/step_mount_device.go index 0b564e14e..5a27c1403 100644 --- a/builder/osc/chroot/step_mount_device.go +++ b/builder/osc/chroot/step_mount_device.go @@ -71,7 +71,8 @@ func (s *StepMountDevice) Run(_ context.Context, state multistep.StateBag) multi return multistep.ActionHalt } - log.Printf("Mount path: %s", mountPath) + log.Printf("[DEBUG] Device: %s", device) + log.Printf("[DEBUG] Mount path: %s", mountPath) if err := os.MkdirAll(mountPath, 0755); err != nil { err := fmt.Errorf("Error creating mount directory: %s", err) @@ -92,9 +93,23 @@ func (s *StepMountDevice) Run(_ context.Context, state multistep.StateBag) multi return multistep.ActionHalt } - deviceMount := fmt.Sprintf("/dev/%s", strings.Replace(string(realDeviceName), "\n", "", -1)) + log.Printf("[DEBUG] RealDeviceName: %s", realDeviceName) + + realDeviceNameSplitted := strings.Split(string(realDeviceName), "\n") + log.Printf("[DEBUG] RealDeviceName Splitted %+v", realDeviceNameSplitted) + log.Printf("[DEBUG] RealDeviceName Splitted Length %d", len(realDeviceNameSplitted)) + log.Printf("[DEBUG] RealDeviceName Splitted [0] %s", realDeviceNameSplitted[0]) + log.Printf("[DEBUG] RealDeviceName Splitted [1] %s", realDeviceNameSplitted[1]) + + realDeviceNameStr := realDeviceNameSplitted[0] + if realDeviceNameStr == "" { + realDeviceNameStr = realDeviceNameSplitted[1] + } + + deviceMount := fmt.Sprintf("/dev/%s", strings.Replace(realDeviceNameStr, "\n", "", -1)) log.Printf("[DEBUG] s.MountPartition = %s", s.MountPartition) + log.Printf("[DEBUG ] DeviceMount: %s", deviceMount) if virtualizationType == "hvm" && s.MountPartition != "0" { deviceMount = fmt.Sprintf("%s%s", deviceMount, s.MountPartition) diff --git a/builder/osc/chroot/step_mount_extra.go b/builder/osc/chroot/step_mount_extra.go new file mode 100644 index 000000000..089bf7e75 --- /dev/null +++ b/builder/osc/chroot/step_mount_extra.go @@ -0,0 +1,137 @@ +package chroot + +import ( + "bytes" + "context" + "fmt" + "os" + "os/exec" + "syscall" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" +) + +// StepMountExtra mounts the attached device. +// +// Produces: +// mount_extra_cleanup CleanupFunc - To perform early cleanup +type StepMountExtra struct { + mounts []string +} + +func (s *StepMountExtra) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + config := state.Get("config").(*Config) + mountPath := state.Get("mount_path").(string) + ui := state.Get("ui").(packer.Ui) + wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) + + s.mounts = make([]string, 0, len(config.ChrootMounts)) + + ui.Say("Mounting additional paths within the chroot...") + for _, mountInfo := range config.ChrootMounts { + innerPath := mountPath + mountInfo[2] + + if err := os.MkdirAll(innerPath, 0755); err != nil { + err := fmt.Errorf("Error creating mount directory: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + flags := "-t " + mountInfo[0] + if mountInfo[0] == "bind" { + flags = "--bind" + } + + ui.Message(fmt.Sprintf("Mounting: %s", mountInfo[2])) + stderr := new(bytes.Buffer) + mountCommand, err := wrappedCommand(fmt.Sprintf( + "mount %s %s %s", + flags, + mountInfo[1], + innerPath)) + if err != nil { + err := fmt.Errorf("Error creating mount command: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + cmd := ShellCommand(mountCommand) + cmd.Stderr = stderr + if err := cmd.Run(); err != nil { + err := fmt.Errorf( + "Error mounting: %s\nStderr: %s", err, stderr.String()) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + s.mounts = append(s.mounts, innerPath) + } + + state.Put("mount_extra_cleanup", s) + return multistep.ActionContinue +} + +func (s *StepMountExtra) Cleanup(state multistep.StateBag) { + ui := state.Get("ui").(packer.Ui) + + if err := s.CleanupFunc(state); err != nil { + ui.Error(err.Error()) + return + } +} + +func (s *StepMountExtra) CleanupFunc(state multistep.StateBag) error { + if s.mounts == nil { + return nil + } + + wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) + for len(s.mounts) > 0 { + var path string + lastIndex := len(s.mounts) - 1 + path, s.mounts = s.mounts[lastIndex], s.mounts[:lastIndex] + + grepCommand, err := wrappedCommand(fmt.Sprintf("grep %s /proc/mounts", path)) + if err != nil { + return fmt.Errorf("Error creating grep command: %s", err) + } + + // Before attempting to unmount, + // check to see if path is already unmounted + stderr := new(bytes.Buffer) + cmd := ShellCommand(grepCommand) + cmd.Stderr = stderr + if err := cmd.Run(); err != nil { + if exitError, ok := err.(*exec.ExitError); ok { + if status, ok := exitError.Sys().(syscall.WaitStatus); ok { + exitStatus := status.ExitStatus() + if exitStatus == 1 { + // path has already been unmounted + // just skip this path + continue + } + } + } + } + + unmountCommand, err := wrappedCommand(fmt.Sprintf("umount %s", path)) + if err != nil { + return fmt.Errorf("Error creating unmount command: %s", err) + } + + stderr = new(bytes.Buffer) + cmd = ShellCommand(unmountCommand) + cmd.Stderr = stderr + if err := cmd.Run(); err != nil { + return fmt.Errorf( + "Error unmounting device: %s\nStderr: %s", err, stderr.String()) + } + } + + s.mounts = nil + return nil +} diff --git a/builder/osc/chroot/step_post_mount_commands.go b/builder/osc/chroot/step_post_mount_commands.go new file mode 100644 index 000000000..704af428f --- /dev/null +++ b/builder/osc/chroot/step_post_mount_commands.go @@ -0,0 +1,47 @@ +package chroot + +import ( + "context" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" +) + +type postMountCommandsData struct { + Device string + MountPath string +} + +// StepPostMountCommands allows running arbitrary commands after mounting the +// device, but prior to the bind mount and copy steps. +type StepPostMountCommands struct { + Commands []string +} + +func (s *StepPostMountCommands) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + config := state.Get("config").(*Config) + device := state.Get("device").(string) + mountPath := state.Get("mount_path").(string) + ui := state.Get("ui").(packer.Ui) + wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) + + if len(s.Commands) == 0 { + return multistep.ActionContinue + } + + ictx := config.ctx + ictx.Data = &postMountCommandsData{ + Device: device, + MountPath: mountPath, + } + + ui.Say("Running post-mount commands...") + if err := RunLocalCommands(s.Commands, wrappedCommand, ictx, ui); err != nil { + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + return multistep.ActionContinue +} + +func (s *StepPostMountCommands) Cleanup(state multistep.StateBag) {} diff --git a/builder/osc/chroot/step_pre_mount_commands.go b/builder/osc/chroot/step_pre_mount_commands.go new file mode 100644 index 000000000..9a60256fe --- /dev/null +++ b/builder/osc/chroot/step_pre_mount_commands.go @@ -0,0 +1,41 @@ +package chroot + +import ( + "context" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" +) + +type preMountCommandsData struct { + Device string +} + +// StepPreMountCommands sets up the a new block device when building from scratch +type StepPreMountCommands struct { + Commands []string +} + +func (s *StepPreMountCommands) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + config := state.Get("config").(*Config) + device := state.Get("device").(string) + ui := state.Get("ui").(packer.Ui) + wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) + + if len(s.Commands) == 0 { + return multistep.ActionContinue + } + + ictx := config.ctx + ictx.Data = &preMountCommandsData{Device: device} + + ui.Say("Running device setup commands...") + if err := RunLocalCommands(s.Commands, wrappedCommand, ictx, ui); err != nil { + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + return multistep.ActionContinue +} + +func (s *StepPreMountCommands) Cleanup(state multistep.StateBag) {} From 73cd148e804e678862bda30988fe9eb23d3f394b Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Tue, 21 May 2019 10:56:16 -0500 Subject: [PATCH 110/113] refactor: change ebs_volume to bsu_volumeattribute in bsuvolume builder --- builder/osc/bsuvolume/builder.go | 2 +- builder/osc/bsuvolume/builder_acc_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/osc/bsuvolume/builder.go b/builder/osc/bsuvolume/builder.go index 348e9d66a..914fea983 100644 --- a/builder/osc/bsuvolume/builder.go +++ b/builder/osc/bsuvolume/builder.go @@ -26,7 +26,7 @@ type Config struct { osccommon.AccessConfig `mapstructure:",squash"` osccommon.RunConfig `mapstructure:",squash"` - VolumeMappings []BlockDevice `mapstructure:"ebs_volumes"` + VolumeMappings []BlockDevice `mapstructure:"bsu_volumes"` launchBlockDevices osccommon.BlockDevices ctx interpolate.Context diff --git a/builder/osc/bsuvolume/builder_acc_test.go b/builder/osc/bsuvolume/builder_acc_test.go index ef4e46cde..835ff9ba3 100644 --- a/builder/osc/bsuvolume/builder_acc_test.go +++ b/builder/osc/bsuvolume/builder_acc_test.go @@ -48,7 +48,7 @@ const testBuilderAccBasic = ` "vm_type": "t2.micro", "source_omi": "ami-65efcc11", "ssh_username": "outscale", - "ebs_volumes": [ + "bsu_volumes": [ { "volume_type": "gp2", "device_name": "/dev/xvdf", From 1424f1b5648e38de905d096841a7d8f39d1acb16 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Thu, 18 Jul 2019 10:46:36 -0500 Subject: [PATCH 111/113] fix: remove AWS references and unnecessary code --- builder/osc/bsusurrogate/builder_acc_test.go | 4 ---- builder/osc/common/access_config.go | 4 ++-- builder/osc/common/block_device.go | 11 ----------- builder/osc/common/omi_config.go | 20 -------------------- builder/osc/common/regions.go | 2 +- builder/osc/common/run_config_test.go | 10 +++++----- builder/osc/common/step_get_password.go | 5 ++++- 7 files changed, 12 insertions(+), 44 deletions(-) diff --git a/builder/osc/bsusurrogate/builder_acc_test.go b/builder/osc/bsusurrogate/builder_acc_test.go index 37fe057f4..243246d8f 100644 --- a/builder/osc/bsusurrogate/builder_acc_test.go +++ b/builder/osc/bsusurrogate/builder_acc_test.go @@ -1,7 +1,3 @@ -/* -Deregister the test image with -aws ec2 deregister-image --image-id $(aws ec2 describe-images --output text --filters "Name=name,Values=packer-test-packer-test-dereg" --query 'Images[*].{ID:ImageId}') -*/ package bsusurrogate import ( diff --git a/builder/osc/common/access_config.go b/builder/osc/common/access_config.go index 667c85028..c5bfabddf 100644 --- a/builder/osc/common/access_config.go +++ b/builder/osc/common/access_config.go @@ -11,7 +11,7 @@ import ( "github.com/outscale/osc-go/oapi" ) -// AccessConfig is for common configuration related to AWS access +// AccessConfig is for common configuration related to Outscale API access type AccessConfig struct { AccessKey string `mapstructure:"access_key"` CustomEndpointOAPI string `mapstructure:"custom_endpoint_oapi"` @@ -28,7 +28,7 @@ type AccessConfig struct { getOAPIConnection func() oapi.OAPIClient } -// Config returns a valid aws.Config object for access to AWS services, or +// Config returns a valid oapi.Config object for access to Outscale services, or // an error if the authentication and region couldn't be resolved func (c *AccessConfig) Config() (*oapi.Config, error) { if c.clientConfig != nil { diff --git a/builder/osc/common/block_device.go b/builder/osc/common/block_device.go index ca6b2fbf6..3f72076d5 100644 --- a/builder/osc/common/block_device.go +++ b/builder/osc/common/block_device.go @@ -20,8 +20,6 @@ type BlockDevice struct { VirtualName string `mapstructure:"virtual_name"` VolumeType string `mapstructure:"volume_type"` VolumeSize int64 `mapstructure:"volume_size"` - // Encrypted bool `mapstructure:"encrypted"` - // KmsKeyId string `mapstructure:"kms_key_id"` } type BlockDevices struct { @@ -117,10 +115,6 @@ func buildBlockDevicesVmCreation(b []BlockDevice) []oapi.BlockDeviceMappingVmCre bsu.SnapshotId = blockDevice.SnapshotId } - //missing - //BlockDevice Encrypted - //KmsKeyId - mapping.Bsu = bsu } @@ -134,11 +128,6 @@ func (b *BlockDevice) Prepare(ctx *interpolate.Context) error { return fmt.Errorf("The `device_name` must be specified " + "for every device in the block device mapping.") } - // Warn that encrypted must be true when setting kms_key_id - // if b.KmsKeyId != "" && b.Encrypted == false { - // return fmt.Errorf("The device %v, must also have `encrypted: "+ - // "true` when setting a kms_key_id.", b.DeviceName) - // } return nil } diff --git a/builder/osc/common/omi_config.go b/builder/osc/common/omi_config.go index 6ac8711b0..3cb352e65 100644 --- a/builder/osc/common/omi_config.go +++ b/builder/osc/common/omi_config.go @@ -3,7 +3,6 @@ package common import ( "fmt" "log" - "regexp" "github.com/hashicorp/packer/template/interpolate" ) @@ -90,22 +89,3 @@ func (c *OMIConfig) prepareRegions(accessConfig *AccessConfig) (errs []error) { } return errs } - -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/osc/common/regions.go b/builder/osc/common/regions.go index f52a53c3a..45a829bcf 100644 --- a/builder/osc/common/regions.go +++ b/builder/osc/common/regions.go @@ -22,7 +22,7 @@ func listOAPIRegions(oapiconn oapi.OAPIClient) ([]string, error) { return regions, nil } -// ValidateRegion returns true if the supplied region is a valid AWS +// ValidateRegion returns true if the supplied region is a valid Outscale // region and false if it's not. func (c *AccessConfig) ValidateRegion(regions ...string) error { oapiconn, err := c.NewOAPIConnection() diff --git a/builder/osc/common/run_config_test.go b/builder/osc/common/run_config_test.go index b6416d522..40b598b89 100644 --- a/builder/osc/common/run_config_test.go +++ b/builder/osc/common/run_config_test.go @@ -48,7 +48,7 @@ func TestRunConfigPrepare_VmType(t *testing.T) { c := testConfig() c.VmType = "" if err := c.Prepare(nil); len(err) != 1 { - t.Fatalf("Should error if an instance_type is not specified") + t.Fatalf("Should error if an vm_type is not specified") } } @@ -56,7 +56,7 @@ func TestRunConfigPrepare_SourceOmi(t *testing.T) { c := testConfig() c.SourceOmi = "" if err := c.Prepare(nil); len(err) != 2 { - t.Fatalf("Should error if a source_ami (or source_ami_filter) is not specified") + t.Fatalf("Should error if a source_omi (or source_omi_filter) is not specified") } } @@ -91,7 +91,7 @@ func TestRunConfigPrepare_SourceOmiFilterGood(t *testing.T) { func TestRunConfigPrepare_EnableT2UnlimitedGood(t *testing.T) { c := testConfig() - // Must have a T2 instance type if T2 Unlimited is enabled + // Must have a T2 vm type if T2 Unlimited is enabled c.VmType = "t2.micro" c.EnableT2Unlimited = true err := c.Prepare(nil) @@ -102,12 +102,12 @@ func TestRunConfigPrepare_EnableT2UnlimitedGood(t *testing.T) { func TestRunConfigPrepare_EnableT2UnlimitedBadVmType(t *testing.T) { c := testConfig() - // T2 Unlimited cannot be used with instance types other than T2 + // T2 Unlimited cannot be used with vm types other than T2 c.VmType = "m5.large" c.EnableT2Unlimited = true err := c.Prepare(nil) if len(err) != 1 { - t.Fatalf("Should error if T2 Unlimited is enabled with non-T2 instance_type") + t.Fatalf("Should error if T2 Unlimited is enabled with non-T2 vm_type") } } diff --git a/builder/osc/common/step_get_password.go b/builder/osc/common/step_get_password.go index d26b9bc2f..63ebbb288 100644 --- a/builder/osc/common/step_get_password.go +++ b/builder/osc/common/step_get_password.go @@ -96,7 +96,10 @@ WaitLoop: } // store so that we can access this later during provisioning - commonhelper.SetSharedState("winrm_password", s.Comm.WinRMPassword, s.BuildName) + err = commonhelper.SetSharedState("winrm_password", s.Comm.WinRMPassword, s.BuildName) + if err != nil { + log.Printf("[WARN] commonhelper.SetSharedState returned error: %s", err) + } packer.LogSecretFilter.Set(s.Comm.WinRMPassword) return multistep.ActionContinue From e10b9fb7081be5dd1506847c1ad41cd14af006df Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 18 Jul 2019 09:47:15 -0700 Subject: [PATCH 112/113] fix ssh interface conflict --- builder/osc/bsu/builder.go | 2 +- builder/osc/bsusurrogate/builder.go | 2 +- builder/osc/bsuvolume/builder.go | 2 +- builder/osc/common/run_config.go | 15 ++++++++------- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/builder/osc/bsu/builder.go b/builder/osc/bsu/builder.go index 287676d5b..798371723 100644 --- a/builder/osc/bsu/builder.go +++ b/builder/osc/bsu/builder.go @@ -164,7 +164,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack Config: &b.config.RunConfig.Comm, Host: osccommon.SSHHost( oapiconn, - b.config.Comm.SSHInterface), + b.config.SSHInterface), SSHConfig: b.config.RunConfig.Comm.SSHConfigFunc(), }, &common.StepProvision{}, diff --git a/builder/osc/bsusurrogate/builder.go b/builder/osc/bsusurrogate/builder.go index 3cefe9a16..1186a5bdc 100644 --- a/builder/osc/bsusurrogate/builder.go +++ b/builder/osc/bsusurrogate/builder.go @@ -187,7 +187,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack Config: &b.config.RunConfig.Comm, Host: osccommon.SSHHost( oapiconn, - b.config.Comm.SSHInterface), + b.config.SSHInterface), SSHConfig: b.config.RunConfig.Comm.SSHConfigFunc(), }, &common.StepProvision{}, diff --git a/builder/osc/bsuvolume/builder.go b/builder/osc/bsuvolume/builder.go index 914fea983..96d5531d3 100644 --- a/builder/osc/bsuvolume/builder.go +++ b/builder/osc/bsuvolume/builder.go @@ -165,7 +165,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack Config: &b.config.RunConfig.Comm, Host: osccommon.SSHHost( oapiconn, - b.config.Comm.SSHInterface), + b.config.SSHInterface), SSHConfig: b.config.RunConfig.Comm.SSHConfigFunc(), }, &common.StepProvision{}, diff --git a/builder/osc/common/run_config.go b/builder/osc/common/run_config.go index acd13ae64..1bff1772a 100644 --- a/builder/osc/common/run_config.go +++ b/builder/osc/common/run_config.go @@ -87,7 +87,8 @@ type RunConfig struct { WindowsPasswordTimeout time.Duration `mapstructure:"windows_password_timeout"` // Communicator settings - Comm communicator.Config `mapstructure:",squash"` + Comm communicator.Config `mapstructure:",squash"` + SSHInterface string `mapstructure:"ssh_interface"` } func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { @@ -113,12 +114,12 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { errs := c.Comm.Prepare(ctx) // Validating ssh_interface - if c.Comm.SSHInterface != "public_ip" && - c.Comm.SSHInterface != "private_ip" && - c.Comm.SSHInterface != "public_dns" && - c.Comm.SSHInterface != "private_dns" && - c.Comm.SSHInterface != "" { - errs = append(errs, fmt.Errorf("Unknown interface type: %s", c.Comm.SSHInterface)) + if c.SSHInterface != "public_ip" && + c.SSHInterface != "private_ip" && + c.SSHInterface != "public_dns" && + c.SSHInterface != "private_dns" && + c.SSHInterface != "" { + errs = append(errs, fmt.Errorf("Unknown interface type: %s", c.SSHInterface)) } if c.Comm.SSHKeyPairName != "" { From e634caee0a09365b277c30ca41391d22727f13c9 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Thu, 18 Jul 2019 12:07:08 -0500 Subject: [PATCH 113/113] remove chroot acc test --- builder/osc/chroot/builder_acc_test.go | 31 -------------------------- 1 file changed, 31 deletions(-) delete mode 100644 builder/osc/chroot/builder_acc_test.go diff --git a/builder/osc/chroot/builder_acc_test.go b/builder/osc/chroot/builder_acc_test.go deleted file mode 100644 index f194dd49c..000000000 --- a/builder/osc/chroot/builder_acc_test.go +++ /dev/null @@ -1,31 +0,0 @@ -package chroot - -import ( - "testing" - - builderT "github.com/hashicorp/packer/helper/builder/testing" -) - -func TestBuilderAcc_basic(t *testing.T) { - builderT.Test(t, builderT.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Builder: &Builder{}, - Template: testBuilderAccBasic, - SkipArtifactTeardown: true, - }) -} - -func testAccPreCheck(t *testing.T) { -} - -const testBuilderAccBasic = ` -{ - "builders": [{ - "type": "test", - "region": "eu-west-2", - "source_omi": "ami-65efcc11", - "omi_name": "packer-test-{{timestamp}}", - "omi_virtualization_type": "hvm" - }] -} -`