From 0ec1ead1231be80051ddcc27c4961fc04f74b356 Mon Sep 17 00:00:00 2001 From: Jiafeng Liao Date: Wed, 2 Nov 2022 18:05:51 -0700 Subject: [PATCH] [pwx-27619] Add options for selected cloudops APIs --- .gitignore | 1 + Makefile | 5 +- aws/aws.go | 51 +- azure/azure.go | 22 +- backoff/exponential.go | 36 +- cloudops.go | 21 +- gce/gce.go | 20 +- go.mod | 1 + mock/cloud_storage_management.mock.go | 23 +- mock/cloudops.mock.go | 298 +++++++---- oracle/oracle.go | 20 +- test/cloudops.go | 22 +- tools.go | 9 + unsupported/unsupported.go | 18 +- .../golang/mock/mockgen/model/model.go | 470 ++++++++++++++++++ vendor/modules.txt | 1 + vsphere/vsphere.go | 47 +- 17 files changed, 843 insertions(+), 222 deletions(-) create mode 100644 tools.go create mode 100644 vendor/github.com/golang/mock/mockgen/model/model.go diff --git a/.gitignore b/.gitignore index c57100a59..7595b5c67 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ coverage.txt +.idea/ diff --git a/Makefile b/Makefile index df44fb9d2..0b56354bb 100644 --- a/Makefile +++ b/Makefile @@ -40,8 +40,9 @@ vendor-tidy: vendor: go mod vendor -lint: - (mkdir -p tools && cd tools && GO111MODULE=off && go get -v golang.org/x/lint/golint) +$(GOPATH)/bin/golint: + GO111MODULE=off go get -u golang.org/x/lint/golint +lint: $(GOPATH)/bin/golint for file in $$(find . -name '*.go' | grep -v vendor | \ grep -v '\.pb\.go' | \ grep -v '\.pb\.gw\.go' | \ diff --git a/aws/aws.go b/aws/aws.go index b9e47eea4..2371ad783 100644 --- a/aws/aws.go +++ b/aws/aws.go @@ -322,19 +322,21 @@ func (s *awsOps) InspectInstanceGroupForInstance(instanceID string) (*cloudops.I return nil, &cloudops.ErrNoInstanceGroup{} } -func (s *awsOps) ApplyTags(volumeID string, labels map[string]string) error { +func (s *awsOps) ApplyTags(volumeID string, labels map[string]string, options map[string]string) error { req := &ec2.CreateTagsInput{ Resources: []*string{&volumeID}, Tags: s.tags(labels), + DryRun: dryRun(options), } _, err := s.ec2.CreateTags(req) return err } -func (s *awsOps) RemoveTags(volumeID string, labels map[string]string) error { +func (s *awsOps) RemoveTags(volumeID string, labels map[string]string, options map[string]string) error { req := &ec2.DeleteTagsInput{ Resources: []*string{&volumeID}, Tags: s.tags(labels), + DryRun: dryRun(options), } _, err := s.ec2.DeleteTags(req) return err @@ -660,7 +662,7 @@ func (s *awsOps) FreeDevices( func (s *awsOps) rollbackCreate(id string, createErr error) error { logrus.Warnf("Rollback create volume %v, Error %v", id, createErr) - err := s.Delete(id) + err := s.Delete(id, nil) if err != nil { logrus.Warnf("Rollback failed volume %v, Error %v", id, err) } @@ -668,7 +670,7 @@ func (s *awsOps) rollbackCreate(id string, createErr error) error { } func (s *awsOps) refreshVol(id *string) (*ec2.Volume, error) { - vols, err := s.Inspect([]*string{id}) + vols, err := s.Inspect([]*string{id}, nil) if err != nil { return nil, err } @@ -707,8 +709,11 @@ func (s *awsOps) GetDeviceID(vol interface{}) (string, error) { } } -func (s *awsOps) Inspect(volumeIds []*string) ([]interface{}, error) { - req := &ec2.DescribeVolumesInput{VolumeIds: volumeIds} +func (s *awsOps) Inspect(volumeIds []*string, options map[string]string) ([]interface{}, error) { + req := &ec2.DescribeVolumesInput{ + VolumeIds: volumeIds, + DryRun: dryRun(options), + } resp, err := s.ec2.DescribeVolumes(req) if err != nil { return nil, err @@ -739,6 +744,7 @@ func (s *awsOps) Enumerate( volumeIds []*string, labels map[string]string, setIdentifier string, + ) (map[string][]interface{}, error) { sets := make(map[string][]interface{}) @@ -778,6 +784,7 @@ func (s *awsOps) Enumerate( func (s *awsOps) Create( v interface{}, labels map[string]string, + options map[string]string, ) (interface{}, error) { vol, ok := v.(*ec2.Volume) if !ok { @@ -797,6 +804,7 @@ func (s *awsOps) Create( VolumeType: vol.VolumeType, SnapshotId: vol.SnapshotId, Throughput: vol.Throughput, + DryRun: dryRun(options), } if len(s.outpostARN) > 0 { @@ -846,11 +854,14 @@ func (s *awsOps) Create( } func (s *awsOps) DeleteFrom(id, _ string) error { - return s.Delete(id) + return s.Delete(id, nil) } -func (s *awsOps) Delete(id string) error { - req := &ec2.DeleteVolumeInput{VolumeId: &id} +func (s *awsOps) Delete(id string, options map[string]string) error { + req := &ec2.DeleteVolumeInput{ + VolumeId: &id, + DryRun: dryRun(options), + } _, err := s.ec2.DeleteVolume(req) return err } @@ -879,6 +890,7 @@ func (s *awsOps) Attach(volumeID string, options map[string]string) (string, err Device: &device, InstanceId: &s.instance, VolumeId: &volumeID, + DryRun: dryRun(options), } if _, err := s.ec2.AttachVolume(req); err != nil { if strings.Contains(err.Error(), "is already in use") { @@ -904,20 +916,21 @@ func (s *awsOps) Attach(volumeID string, options map[string]string) (string, err return "", fmt.Errorf("failed to attach any of the free devices. Attempted: %v", devices) } -func (s *awsOps) Detach(volumeID string) error { - return s.detachInternal(volumeID, s.instance) +func (s *awsOps) Detach(volumeID string, options map[string]string) error { + return s.detachInternal(volumeID, s.instance, options) } func (s *awsOps) DetachFrom(volumeID, instanceName string) error { - return s.detachInternal(volumeID, instanceName) + return s.detachInternal(volumeID, instanceName, nil) } -func (s *awsOps) detachInternal(volumeID, instanceName string) error { +func (s *awsOps) detachInternal(volumeID, instanceName string, options map[string]string) error { force := false req := &ec2.DetachVolumeInput{ InstanceId: &instanceName, VolumeId: &volumeID, Force: &force, + DryRun: dryRun(options), } if _, err := s.ec2.DetachVolume(req); err != nil { return err @@ -932,6 +945,7 @@ func (s *awsOps) detachInternal(volumeID, instanceName string) error { func (s *awsOps) Expand( volumeID string, newSizeInGiB uint64, + options map[string]string, ) (uint64, error) { vol, err := s.refreshVol(&volumeID) if err != nil { @@ -948,6 +962,7 @@ func (s *awsOps) Expand( request := &ec2.ModifyVolumeInput{ VolumeId: vol.VolumeId, Size: &newSizeInGiBInt64, + DryRun: dryRun(options), } output, err := s.ec2.ModifyVolume(request) if err != nil { @@ -995,16 +1010,19 @@ func (s *awsOps) Expand( func (s *awsOps) Snapshot( volumeID string, readonly bool, + options map[string]string, ) (interface{}, error) { request := &ec2.CreateSnapshotInput{ VolumeId: &volumeID, + DryRun: dryRun(options), } return s.ec2.CreateSnapshot(request) } -func (s *awsOps) SnapshotDelete(snapID string) error { +func (s *awsOps) SnapshotDelete(snapID string, options map[string]string) error { request := &ec2.DeleteSnapshotInput{ SnapshotId: &snapID, + DryRun: dryRun(options), } _, err := s.ec2.DeleteSnapshot(request) @@ -1201,3 +1219,8 @@ func reverse(a []string) []string { return reversed } + +func dryRun(options map[string]string) *bool { + _, ok := options[cloudops.DryRunOption] + return &ok +} diff --git a/azure/azure.go b/azure/azure.go index 4b81d4ca6..24337592b 100644 --- a/azure/azure.go +++ b/azure/azure.go @@ -346,7 +346,7 @@ func (a *azureOps) SetInstanceGroupSize(instanceGroupID string, instanceGroupSize := int32(count) agentPoolProperties := containerservice.ManagedClusterAgentPoolProfileProperties{ - Count: &instanceGroupSize, + Count: &instanceGroupSize, OsType: containerservice.Linux, } @@ -368,6 +368,7 @@ func (a *azureOps) SetInstanceGroupSize(instanceGroupID string, func (a *azureOps) Create( template interface{}, labels map[string]string, + options map[string]string, ) (interface{}, error) { d, ok := template.(*compute.Disk) if !ok { @@ -494,7 +495,7 @@ func (a *azureOps) handleAttachError(err error) error { // but did not succeed. We need to explicitly remove it to proceed. matches := attachFailureMessageRegex.FindStringSubmatch(re.ServiceError.Message) if len(matches) == 2 { - detachErr := a.Detach(matches[1]) + detachErr := a.Detach(matches[1], nil) if detachErr != nil { logrus.Warnf("Failed to detach disk %v: %v", matches[1], detachErr) } @@ -504,7 +505,7 @@ func (a *azureOps) handleAttachError(err error) error { return err } -func (a *azureOps) Detach(diskName string) error { +func (a *azureOps) Detach(diskName string, options map[string]string) error { return a.detachInternal(diskName, a.instance) } @@ -559,7 +560,7 @@ func (a *azureOps) detachInternal(diskName, instance string) error { return a.waitForDetach(diskName, instance) } -func (a *azureOps) Delete(diskName string) error { +func (a *azureOps) Delete(diskName string, options map[string]string) error { ctx := context.Background() future, err := a.disksClient.Delete(ctx, a.resourceGroupName, diskName) if err != nil { @@ -576,12 +577,13 @@ func (a *azureOps) Delete(diskName string) error { } func (a *azureOps) DeleteFrom(diskName, _ string) error { - return a.Delete(diskName) + return a.Delete(diskName, nil) } func (a *azureOps) Expand( diskName string, newSizeInGiB uint64, + options map[string]string, ) (uint64, error) { disk, err := a.disksClient.Get( context.Background(), @@ -644,7 +646,7 @@ func (a *azureOps) FreeDevices( } } -func (a *azureOps) Inspect(diskNames []*string) ([]interface{}, error) { +func (a *azureOps) Inspect(diskNames []*string, options map[string]string) ([]interface{}, error) { var disks []interface{} for _, diskName := range diskNames { @@ -823,7 +825,7 @@ func (a *azureOps) devicePath(diskName string) (string, error) { ) } -func (a *azureOps) Snapshot(diskName string, readonly bool) (interface{}, error) { +func (a *azureOps) Snapshot(diskName string, readonly bool, options map[string]string) (interface{}, error) { if !readonly { return nil, fmt.Errorf("read-write snapshots are not supported in Azure") } @@ -861,7 +863,7 @@ func (a *azureOps) Snapshot(diskName string, readonly bool) (interface{}, error) return &snap, err } -func (a *azureOps) SnapshotDelete(snapName string) error { +func (a *azureOps) SnapshotDelete(snapName string, options map[string]string) error { ctx := context.Background() future, err := a.snapshotsClient.Delete(ctx, a.resourceGroupName, snapName) if err != nil { @@ -877,7 +879,7 @@ func (a *azureOps) SnapshotDelete(snapName string) error { return err } -func (a *azureOps) ApplyTags(diskName string, labels map[string]string) error { +func (a *azureOps) ApplyTags(diskName string, labels map[string]string, options map[string]string) error { if len(labels) == 0 { return nil } @@ -921,7 +923,7 @@ func (a *azureOps) ApplyTags(diskName string, labels map[string]string) error { return err } -func (a *azureOps) RemoveTags(diskName string, labels map[string]string) error { +func (a *azureOps) RemoveTags(diskName string, labels map[string]string, options map[string]string) error { if len(labels) == 0 { return nil } diff --git a/backoff/exponential.go b/backoff/exponential.go index c8a2bb502..bc168fe36 100644 --- a/backoff/exponential.go +++ b/backoff/exponential.go @@ -209,13 +209,13 @@ func (e *exponentialBackoff) DeleteInstance(instanceID string, zone string, time } // Create volume based on input template volume and also apply given labels. -func (e *exponentialBackoff) Create(template interface{}, labels map[string]string) (interface{}, error) { +func (e *exponentialBackoff) Create(template interface{}, labels map[string]string, options map[string]string) (interface{}, error) { var ( drive interface{} origErr error ) conditionFn := func() (bool, error) { - drive, origErr = e.cloudOps.Create(template, labels) + drive, origErr = e.cloudOps.Create(template, labels, options) msg := fmt.Sprintf("Failed to create drive.") return e.handleError(origErr, msg) } @@ -252,12 +252,12 @@ func (e *exponentialBackoff) Attach(volumeID string, options map[string]string) } // Detach volumeID. -func (e *exponentialBackoff) Detach(volumeID string) error { +func (e *exponentialBackoff) Detach(volumeID string, options map[string]string) error { var ( origErr error ) conditionFn := func() (bool, error) { - origErr = e.cloudOps.Detach(volumeID) + origErr = e.cloudOps.Detach(volumeID, options) msg := fmt.Sprintf("Failed to detach drive (%v).", volumeID) return e.handleError(origErr, msg) } @@ -286,12 +286,12 @@ func (e *exponentialBackoff) DetachFrom(volumeID, instanceID string) error { } // Delete volumeID. -func (e *exponentialBackoff) Delete(volumeID string) error { +func (e *exponentialBackoff) Delete(volumeID string, options map[string]string) error { var ( origErr error ) conditionFn := func() (bool, error) { - origErr = e.cloudOps.Delete(volumeID) + origErr = e.cloudOps.Delete(volumeID, options) msg := fmt.Sprintf("Failed to delete drive (%v).", volumeID) return e.handleError(origErr, msg) } @@ -345,13 +345,13 @@ func (e *exponentialBackoff) FreeDevices(blockDeviceMappings []interface{}, root } // Inspect volumes specified by volumeID -func (e *exponentialBackoff) Inspect(volumeIds []*string) ([]interface{}, error) { +func (e *exponentialBackoff) Inspect(volumeIds []*string, options map[string]string) ([]interface{}, error) { var ( volumes []interface{} origErr error ) conditionFn := func() (bool, error) { - volumes, origErr = e.cloudOps.Inspect(volumeIds) + volumes, origErr = e.cloudOps.Inspect(volumeIds, options) msg := fmt.Sprintf("Failed to inspect drives (%v).", volumeIds) return e.handleError(origErr, msg) } @@ -436,13 +436,13 @@ func (e *exponentialBackoff) DevicePath(volumeID string) (string, error) { return devicePath, origErr } -func (e *exponentialBackoff) Expand(volumeID string, targetSize uint64) (uint64, error) { +func (e *exponentialBackoff) Expand(volumeID string, targetSize uint64, options map[string]string) (uint64, error) { var ( actualSize uint64 origErr error ) conditionFn := func() (bool, error) { - actualSize, origErr = e.cloudOps.Expand(volumeID, targetSize) + actualSize, origErr = e.cloudOps.Expand(volumeID, targetSize, options) msg := fmt.Sprintf("Failed to get device path for drive (%v).", volumeID) return e.handleError(origErr, msg) } @@ -454,13 +454,13 @@ func (e *exponentialBackoff) Expand(volumeID string, targetSize uint64) (uint64, } // Snapshot the volume with given volumeID -func (e *exponentialBackoff) Snapshot(volumeID string, readonly bool) (interface{}, error) { +func (e *exponentialBackoff) Snapshot(volumeID string, readonly bool, options map[string]string) (interface{}, error) { var ( snapshot interface{} origErr error ) conditionFn := func() (bool, error) { - snapshot, origErr = e.cloudOps.Snapshot(volumeID, readonly) + snapshot, origErr = e.cloudOps.Snapshot(volumeID, readonly, options) msg := fmt.Sprintf("Failed to snapshot drive (%v).", volumeID) return e.handleError(origErr, msg) } @@ -472,12 +472,12 @@ func (e *exponentialBackoff) Snapshot(volumeID string, readonly bool) (interface } // SnapshotDelete deletes the snapshot with given ID -func (e *exponentialBackoff) SnapshotDelete(snapID string) error { +func (e *exponentialBackoff) SnapshotDelete(snapID string, options map[string]string) error { var ( origErr error ) conditionFn := func() (bool, error) { - origErr = e.cloudOps.SnapshotDelete(snapID) + origErr = e.cloudOps.SnapshotDelete(snapID, options) msg := fmt.Sprintf("Failed to delete snapshot (%v).", snapID) return e.handleError(origErr, msg) } @@ -489,12 +489,12 @@ func (e *exponentialBackoff) SnapshotDelete(snapID string) error { } // ApplyTags will apply given labels/tags on the given volume -func (e *exponentialBackoff) ApplyTags(volumeID string, labels map[string]string) error { +func (e *exponentialBackoff) ApplyTags(volumeID string, labels map[string]string, options map[string]string) error { var ( origErr error ) conditionFn := func() (bool, error) { - origErr = e.cloudOps.ApplyTags(volumeID, labels) + origErr = e.cloudOps.ApplyTags(volumeID, labels, options) msg := fmt.Sprintf("Failed to apply tags on drive (%v).", volumeID) return e.handleError(origErr, msg) } @@ -506,12 +506,12 @@ func (e *exponentialBackoff) ApplyTags(volumeID string, labels map[string]string } // RemoveTags removes labels/tags from the given volume -func (e *exponentialBackoff) RemoveTags(volumeID string, labels map[string]string) error { +func (e *exponentialBackoff) RemoveTags(volumeID string, labels map[string]string, options map[string]string) error { var ( origErr error ) conditionFn := func() (bool, error) { - origErr = e.cloudOps.RemoveTags(volumeID, labels) + origErr = e.cloudOps.RemoveTags(volumeID, labels, options) msg := fmt.Sprintf("Failed to remove tags from drive (%v).", volumeID) return e.handleError(origErr, msg) } diff --git a/cloudops.go b/cloudops.go index 04d82aa57..ad938190d 100644 --- a/cloudops.go +++ b/cloudops.go @@ -32,6 +32,9 @@ const ( Pure = "pure" // Oracle provider Oracle = "oracle" + + // DryRunOption is the key to tell if dry run the request + DryRunOption = "dry-run" ) // CloudResourceInfo provides metadata information on a cloud resource. @@ -120,7 +123,7 @@ type Compute interface { // Storage interface to manage storage operations. type Storage interface { // Create volume based on input template volume and also apply given labels. - Create(template interface{}, labels map[string]string) (interface{}, error) + Create(template interface{}, labels map[string]string, options map[string]string) (interface{}, error) // GetDeviceID returns ID/Name of the given device/disk or snapshot GetDeviceID(template interface{}) (string, error) // Attach volumeID, accepts attachoOptions as opaque data @@ -130,13 +133,13 @@ type Storage interface { // It returns the new size of the device. It is a blocking API where it will // only return once the requested size is validated with the cloud provider or // the number of retries prescribed by the cloud provider are exhausted. - Expand(volumeID string, newSizeInGiB uint64) (uint64, error) + Expand(volumeID string, newSizeInGiB uint64, options map[string]string) (uint64, error) // Detach volumeID. - Detach(volumeID string) error + Detach(volumeID string, options map[string]string) error // DetachFrom detaches the disk/volume with given ID from the given instance ID DetachFrom(volumeID, instanceID string) error // Delete volumeID. - Delete(volumeID string) error + Delete(volumeID string, options map[string]string) error // DeleteFrom deletes the given volume/disk from the given instanceID DeleteFrom(volumeID, instanceID string) error // Desribe an instance @@ -146,7 +149,7 @@ type Storage interface { // the instance and where they are mapped to FreeDevices(blockDeviceMappings []interface{}, rootDeviceName string) ([]string, error) // Inspect volumes specified by volumeID - Inspect(volumeIds []*string) ([]interface{}, error) + Inspect(volumeIds []*string, options map[string]string) ([]interface{}, error) // DeviceMappings returns map[local_attached_volume_path]->volume ID/NAME DeviceMappings() (map[string]string, error) // Enumerate volumes that match given filters. Organize them into @@ -159,13 +162,13 @@ type Storage interface { // DevicePath for the given volume i.e path where it's attached DevicePath(volumeID string) (string, error) // Snapshot the volume with given volumeID - Snapshot(volumeID string, readonly bool) (interface{}, error) + Snapshot(volumeID string, readonly bool, options map[string]string) (interface{}, error) // SnapshotDelete deletes the snapshot with given ID - SnapshotDelete(snapID string) error + SnapshotDelete(snapID string, options map[string]string) error // ApplyTags will apply given labels/tags on the given volume - ApplyTags(volumeID string, labels map[string]string) error + ApplyTags(volumeID string, labels map[string]string, options map[string]string) error // RemoveTags removes labels/tags from the given volume - RemoveTags(volumeID string, labels map[string]string) error + RemoveTags(volumeID string, labels map[string]string, options map[string]string) error // Tags will list the existing labels/tags on the given volume Tags(volumeID string) (map[string]string, error) } diff --git a/gce/gce.go b/gce/gce.go index 58f8acf36..569bbdab7 100644 --- a/gce/gce.go +++ b/gce/gce.go @@ -301,7 +301,9 @@ func (s *gceOps) InspectInstanceGroupForInstance(instanceID string) (*cloudops.I func (s *gceOps) ApplyTags( diskName string, - labels map[string]string) error { + labels map[string]string, + options map[string]string, +) error { d, err := s.computeService.Disks.Get(s.inst.project, s.inst.zone, diskName).Do() if err != nil { return err @@ -374,6 +376,7 @@ func (s *gceOps) Attach(diskName string, options map[string]string) (string, err func (s *gceOps) Create( template interface{}, labels map[string]string, + options map[string]string, ) (interface{}, error) { v, ok := template.(*compute.Disk) if !ok { @@ -420,7 +423,7 @@ func (s *gceOps) Create( } func (s *gceOps) DeleteFrom(id, _ string) error { - return s.Delete(id) + return s.Delete(id, nil) } func (s *gceOps) DeleteInstance(instanceID string, zone string, timeout time.Duration) error { @@ -457,7 +460,7 @@ func (s *gceOps) DeleteInstance(instanceID string, zone string, timeout time.Dur return nil } -func (s *gceOps) Delete(id string) error { +func (s *gceOps) Delete(id string, options map[string]string) error { ctx := context.Background() found := false req := s.computeService.Disks.AggregatedList(s.inst.project) @@ -487,7 +490,7 @@ func (s *gceOps) Delete(id string) error { return nil } -func (s *gceOps) Detach(devicePath string) error { +func (s *gceOps) Detach(devicePath string, options map[string]string) error { return s.detachInternal(devicePath, s.inst.name) } @@ -664,6 +667,7 @@ func (s *gceOps) GetDeviceID(disk interface{}) (string, error) { func (s *gceOps) Expand( volumeID string, newSizeInGiB uint64, + options map[string]string, ) (uint64, error) { vol, err := s.computeService.Disks.Get(s.inst.project, s.inst.zone, volumeID).Do() @@ -709,7 +713,7 @@ func (s *gceOps) Expand( return newSizeInGiB, waitWithErr } -func (s *gceOps) Inspect(diskNames []*string) ([]interface{}, error) { +func (s *gceOps) Inspect(diskNames []*string, options map[string]string) ([]interface{}, error) { allDisks, err := s.getDisksFromAllZones(nil) if err != nil { return nil, err @@ -729,6 +733,7 @@ func (s *gceOps) Inspect(diskNames []*string) ([]interface{}, error) { func (s *gceOps) RemoveTags( diskName string, labels map[string]string, + options map[string]string, ) error { d, err := s.computeService.Disks.Get(s.inst.project, s.inst.zone, diskName).Do() if err != nil { @@ -1070,6 +1075,7 @@ func (s *gceOps) getClusterName() (string, error) { func (s *gceOps) Snapshot( disk string, readonly bool, + options map[string]string, ) (interface{}, error) { rb := &compute.Snapshot{ Name: fmt.Sprintf("snap-%d%02d%02d", time.Now().Year(), time.Now().Month(), time.Now().Day()), @@ -1096,7 +1102,7 @@ func (s *gceOps) Snapshot( return snap, err } -func (s *gceOps) SnapshotDelete(snapID string) error { +func (s *gceOps) SnapshotDelete(snapID string, options map[string]string) error { operation, err := s.computeService.Snapshots.Delete(s.inst.project, snapID).Do() if err != nil { return err @@ -1278,7 +1284,7 @@ func gceInfoFromEnv(inst *instance) error { func (s *gceOps) rollbackCreate(id string, createErr error) error { logrus.Warnf("Rollback create volume %v, Error %v", id, createErr) - err := s.Delete(id) + err := s.Delete(id, nil) if err != nil { logrus.Warnf("Rollback failed volume %v, Error %v", id, err) } diff --git a/go.mod b/go.mod index 70c8f2c3f..803615df2 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( github.com/aws/aws-sdk-go v1.40.39 github.com/codeskyblue/go-sh v0.0.0-20170112005953-b097669b1569 github.com/golang/mock v1.4.4 + github.com/google/uuid v1.1.2 github.com/hashicorp/go-version v1.2.1 github.com/libopenstorage/openstorage v8.0.1-0.20210603043922-faf638fed3e5+incompatible github.com/libopenstorage/secrets v0.0.0-20210908194121-a1d19aa9713a diff --git a/mock/cloud_storage_management.mock.go b/mock/cloud_storage_management.mock.go index 0186ba936..256593d06 100644 --- a/mock/cloud_storage_management.mock.go +++ b/mock/cloud_storage_management.mock.go @@ -5,56 +5,61 @@ package mock import ( + reflect "reflect" + gomock "github.com/golang/mock/gomock" cloudops "github.com/libopenstorage/cloudops" - reflect "reflect" ) -// MockStorageManager is a mock of StorageManager interface +// MockStorageManager is a mock of StorageManager interface. type MockStorageManager struct { ctrl *gomock.Controller recorder *MockStorageManagerMockRecorder } -// MockStorageManagerMockRecorder is the mock recorder for MockStorageManager +// MockStorageManagerMockRecorder is the mock recorder for MockStorageManager. type MockStorageManagerMockRecorder struct { mock *MockStorageManager } -// NewMockStorageManager creates a new mock instance +// NewMockStorageManager creates a new mock instance. func NewMockStorageManager(ctrl *gomock.Controller) *MockStorageManager { mock := &MockStorageManager{ctrl: ctrl} mock.recorder = &MockStorageManagerMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockStorageManager) EXPECT() *MockStorageManagerMockRecorder { return m.recorder } -// GetStorageDistribution mocks base method +// GetStorageDistribution mocks base method. func (m *MockStorageManager) GetStorageDistribution(arg0 *cloudops.StorageDistributionRequest) (*cloudops.StorageDistributionResponse, error) { + m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetStorageDistribution", arg0) ret0, _ := ret[0].(*cloudops.StorageDistributionResponse) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetStorageDistribution indicates an expected call of GetStorageDistribution +// GetStorageDistribution indicates an expected call of GetStorageDistribution. func (mr *MockStorageManagerMockRecorder) GetStorageDistribution(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorageDistribution", reflect.TypeOf((*MockStorageManager)(nil).GetStorageDistribution), arg0) } -// RecommendStoragePoolUpdate mocks base method +// RecommendStoragePoolUpdate mocks base method. func (m *MockStorageManager) RecommendStoragePoolUpdate(arg0 *cloudops.StoragePoolUpdateRequest) (*cloudops.StoragePoolUpdateResponse, error) { + m.ctrl.T.Helper() ret := m.ctrl.Call(m, "RecommendStoragePoolUpdate", arg0) ret0, _ := ret[0].(*cloudops.StoragePoolUpdateResponse) ret1, _ := ret[1].(error) return ret0, ret1 } -// RecommendStoragePoolUpdate indicates an expected call of RecommendStoragePoolUpdate +// RecommendStoragePoolUpdate indicates an expected call of RecommendStoragePoolUpdate. func (mr *MockStorageManagerMockRecorder) RecommendStoragePoolUpdate(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecommendStoragePoolUpdate", reflect.TypeOf((*MockStorageManager)(nil).RecommendStoragePoolUpdate), arg0) } diff --git a/mock/cloudops.mock.go b/mock/cloudops.mock.go index e3cf7af5f..2a69c5242 100644 --- a/mock/cloudops.mock.go +++ b/mock/cloudops.mock.go @@ -5,371 +5,469 @@ package mock import ( - gomock "github.com/golang/mock/gomock" - cloudops "github.com/libopenstorage/cloudops" reflect "reflect" time "time" + + gomock "github.com/golang/mock/gomock" + cloudops "github.com/libopenstorage/cloudops" ) -// MockOps is a mock of Ops interface +// MockOps is a mock of Ops interface. type MockOps struct { ctrl *gomock.Controller recorder *MockOpsMockRecorder } -// MockOpsMockRecorder is the mock recorder for MockOps +// MockOpsMockRecorder is the mock recorder for MockOps. type MockOpsMockRecorder struct { mock *MockOps } -// NewMockOps creates a new mock instance +// NewMockOps creates a new mock instance. func NewMockOps(ctrl *gomock.Controller) *MockOps { mock := &MockOps{ctrl: ctrl} mock.recorder = &MockOpsMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockOps) EXPECT() *MockOpsMockRecorder { return m.recorder } -// ApplyTags mocks base method -func (m *MockOps) ApplyTags(arg0 string, arg1 map[string]string) error { - ret := m.ctrl.Call(m, "ApplyTags", arg0, arg1) +// ApplyTags mocks base method. +func (m *MockOps) ApplyTags(arg0 string, arg1, arg2 map[string]string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ApplyTags", arg0, arg1, arg2) ret0, _ := ret[0].(error) return ret0 } -// ApplyTags indicates an expected call of ApplyTags -func (mr *MockOpsMockRecorder) ApplyTags(arg0, arg1 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ApplyTags", reflect.TypeOf((*MockOps)(nil).ApplyTags), arg0, arg1) +// ApplyTags indicates an expected call of ApplyTags. +func (mr *MockOpsMockRecorder) ApplyTags(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ApplyTags", reflect.TypeOf((*MockOps)(nil).ApplyTags), arg0, arg1, arg2) } -// Attach mocks base method -func (m *MockOps) Attach(arg0 string) (string, error) { - ret := m.ctrl.Call(m, "Attach", arg0) +// Attach mocks base method. +func (m *MockOps) Attach(arg0 string, arg1 map[string]string) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Attach", arg0, arg1) ret0, _ := ret[0].(string) ret1, _ := ret[1].(error) return ret0, ret1 } -// Attach indicates an expected call of Attach -func (mr *MockOpsMockRecorder) Attach(arg0 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Attach", reflect.TypeOf((*MockOps)(nil).Attach), arg0) +// Attach indicates an expected call of Attach. +func (mr *MockOpsMockRecorder) Attach(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Attach", reflect.TypeOf((*MockOps)(nil).Attach), arg0, arg1) } -// Create mocks base method -func (m *MockOps) Create(arg0 interface{}, arg1 map[string]string) (interface{}, error) { - ret := m.ctrl.Call(m, "Create", arg0, arg1) +// Create mocks base method. +func (m *MockOps) Create(arg0 interface{}, arg1, arg2 map[string]string) (interface{}, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Create", arg0, arg1, arg2) ret0, _ := ret[0].(interface{}) ret1, _ := ret[1].(error) return ret0, ret1 } -// Create indicates an expected call of Create -func (mr *MockOpsMockRecorder) Create(arg0, arg1 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockOps)(nil).Create), arg0, arg1) +// Create indicates an expected call of Create. +func (mr *MockOpsMockRecorder) Create(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockOps)(nil).Create), arg0, arg1, arg2) } -// Delete mocks base method -func (m *MockOps) Delete(arg0 string) error { - ret := m.ctrl.Call(m, "Delete", arg0) +// Delete mocks base method. +func (m *MockOps) Delete(arg0 string, arg1 map[string]string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Delete", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } -// Delete indicates an expected call of Delete -func (mr *MockOpsMockRecorder) Delete(arg0 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockOps)(nil).Delete), arg0) +// Delete indicates an expected call of Delete. +func (mr *MockOpsMockRecorder) Delete(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockOps)(nil).Delete), arg0, arg1) } -// DeleteFrom mocks base method +// DeleteFrom mocks base method. func (m *MockOps) DeleteFrom(arg0, arg1 string) error { + m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DeleteFrom", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } -// DeleteFrom indicates an expected call of DeleteFrom +// DeleteFrom indicates an expected call of DeleteFrom. func (mr *MockOpsMockRecorder) DeleteFrom(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteFrom", reflect.TypeOf((*MockOps)(nil).DeleteFrom), arg0, arg1) } -// DeleteInstance mocks base method +// DeleteInstance mocks base method. func (m *MockOps) DeleteInstance(arg0, arg1 string, arg2 time.Duration) error { + m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DeleteInstance", arg0, arg1, arg2) ret0, _ := ret[0].(error) return ret0 } -// DeleteInstance indicates an expected call of DeleteInstance +// DeleteInstance indicates an expected call of DeleteInstance. func (mr *MockOpsMockRecorder) DeleteInstance(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteInstance", reflect.TypeOf((*MockOps)(nil).DeleteInstance), arg0, arg1, arg2) } -// Describe mocks base method +// Describe mocks base method. func (m *MockOps) Describe() (interface{}, error) { + m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Describe") ret0, _ := ret[0].(interface{}) ret1, _ := ret[1].(error) return ret0, ret1 } -// Describe indicates an expected call of Describe +// Describe indicates an expected call of Describe. func (mr *MockOpsMockRecorder) Describe() *gomock.Call { + mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Describe", reflect.TypeOf((*MockOps)(nil).Describe)) } -// Detach mocks base method -func (m *MockOps) Detach(arg0 string) error { - ret := m.ctrl.Call(m, "Detach", arg0) +// Detach mocks base method. +func (m *MockOps) Detach(arg0 string, arg1 map[string]string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Detach", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } -// Detach indicates an expected call of Detach -func (mr *MockOpsMockRecorder) Detach(arg0 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Detach", reflect.TypeOf((*MockOps)(nil).Detach), arg0) +// Detach indicates an expected call of Detach. +func (mr *MockOpsMockRecorder) Detach(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Detach", reflect.TypeOf((*MockOps)(nil).Detach), arg0, arg1) } -// DetachFrom mocks base method +// DetachFrom mocks base method. func (m *MockOps) DetachFrom(arg0, arg1 string) error { + m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DetachFrom", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } -// DetachFrom indicates an expected call of DetachFrom +// DetachFrom indicates an expected call of DetachFrom. func (mr *MockOpsMockRecorder) DetachFrom(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DetachFrom", reflect.TypeOf((*MockOps)(nil).DetachFrom), arg0, arg1) } -// DeviceMappings mocks base method +// DeviceMappings mocks base method. func (m *MockOps) DeviceMappings() (map[string]string, error) { + m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DeviceMappings") ret0, _ := ret[0].(map[string]string) ret1, _ := ret[1].(error) return ret0, ret1 } -// DeviceMappings indicates an expected call of DeviceMappings +// DeviceMappings indicates an expected call of DeviceMappings. func (mr *MockOpsMockRecorder) DeviceMappings() *gomock.Call { + mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeviceMappings", reflect.TypeOf((*MockOps)(nil).DeviceMappings)) } -// DevicePath mocks base method +// DevicePath mocks base method. func (m *MockOps) DevicePath(arg0 string) (string, error) { + m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DevicePath", arg0) ret0, _ := ret[0].(string) ret1, _ := ret[1].(error) return ret0, ret1 } -// DevicePath indicates an expected call of DevicePath +// DevicePath indicates an expected call of DevicePath. func (mr *MockOpsMockRecorder) DevicePath(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DevicePath", reflect.TypeOf((*MockOps)(nil).DevicePath), arg0) } -// Enumerate mocks base method +// Enumerate mocks base method. func (m *MockOps) Enumerate(arg0 []*string, arg1 map[string]string, arg2 string) (map[string][]interface{}, error) { + m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Enumerate", arg0, arg1, arg2) ret0, _ := ret[0].(map[string][]interface{}) ret1, _ := ret[1].(error) return ret0, ret1 } -// Enumerate indicates an expected call of Enumerate +// Enumerate indicates an expected call of Enumerate. func (mr *MockOpsMockRecorder) Enumerate(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Enumerate", reflect.TypeOf((*MockOps)(nil).Enumerate), arg0, arg1, arg2) } -// Expand mocks base method -func (m *MockOps) Expand(arg0 string, arg1 uint64) (uint64, error) { - ret := m.ctrl.Call(m, "Expand", arg0, arg1) +// Expand mocks base method. +func (m *MockOps) Expand(arg0 string, arg1 uint64, arg2 map[string]string) (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Expand", arg0, arg1, arg2) ret0, _ := ret[0].(uint64) ret1, _ := ret[1].(error) return ret0, ret1 } -// Expand indicates an expected call of Expand -func (mr *MockOpsMockRecorder) Expand(arg0, arg1 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Expand", reflect.TypeOf((*MockOps)(nil).Expand), arg0, arg1) +// Expand indicates an expected call of Expand. +func (mr *MockOpsMockRecorder) Expand(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Expand", reflect.TypeOf((*MockOps)(nil).Expand), arg0, arg1, arg2) } -// FreeDevices mocks base method +// FreeDevices mocks base method. func (m *MockOps) FreeDevices(arg0 []interface{}, arg1 string) ([]string, error) { + m.ctrl.T.Helper() ret := m.ctrl.Call(m, "FreeDevices", arg0, arg1) ret0, _ := ret[0].([]string) ret1, _ := ret[1].(error) return ret0, ret1 } -// FreeDevices indicates an expected call of FreeDevices +// FreeDevices indicates an expected call of FreeDevices. func (mr *MockOpsMockRecorder) FreeDevices(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FreeDevices", reflect.TypeOf((*MockOps)(nil).FreeDevices), arg0, arg1) } -// GetClusterSizeForInstance mocks base method +// GetClusterSizeForInstance mocks base method. func (m *MockOps) GetClusterSizeForInstance(arg0 string) (int64, error) { + m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetClusterSizeForInstance", arg0) ret0, _ := ret[0].(int64) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetClusterSizeForInstance indicates an expected call of GetClusterSizeForInstance +// GetClusterSizeForInstance indicates an expected call of GetClusterSizeForInstance. func (mr *MockOpsMockRecorder) GetClusterSizeForInstance(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetClusterSizeForInstance", reflect.TypeOf((*MockOps)(nil).GetClusterSizeForInstance), arg0) } -// GetDeviceID mocks base method +// GetDeviceID mocks base method. func (m *MockOps) GetDeviceID(arg0 interface{}) (string, error) { + m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetDeviceID", arg0) ret0, _ := ret[0].(string) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetDeviceID indicates an expected call of GetDeviceID +// GetDeviceID indicates an expected call of GetDeviceID. func (mr *MockOpsMockRecorder) GetDeviceID(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeviceID", reflect.TypeOf((*MockOps)(nil).GetDeviceID), arg0) } -// GetInstanceGroupSize mocks base method +// GetInstance mocks base method. +func (m *MockOps) GetInstance(arg0 string) (interface{}, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetInstance", arg0) + ret0, _ := ret[0].(interface{}) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetInstance indicates an expected call of GetInstance. +func (mr *MockOpsMockRecorder) GetInstance(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetInstance", reflect.TypeOf((*MockOps)(nil).GetInstance), arg0) +} + +// GetInstanceGroupSize mocks base method. func (m *MockOps) GetInstanceGroupSize(arg0 string) (int64, error) { + m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetInstanceGroupSize", arg0) ret0, _ := ret[0].(int64) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetInstanceGroupSize indicates an expected call of GetInstanceGroupSize +// GetInstanceGroupSize indicates an expected call of GetInstanceGroupSize. func (mr *MockOpsMockRecorder) GetInstanceGroupSize(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetInstanceGroupSize", reflect.TypeOf((*MockOps)(nil).GetInstanceGroupSize), arg0) } -// Inspect mocks base method -func (m *MockOps) Inspect(arg0 []*string) ([]interface{}, error) { - ret := m.ctrl.Call(m, "Inspect", arg0) +// Inspect mocks base method. +func (m *MockOps) Inspect(arg0 []*string, arg1 map[string]string) ([]interface{}, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Inspect", arg0, arg1) ret0, _ := ret[0].([]interface{}) ret1, _ := ret[1].(error) return ret0, ret1 } -// Inspect indicates an expected call of Inspect -func (mr *MockOpsMockRecorder) Inspect(arg0 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Inspect", reflect.TypeOf((*MockOps)(nil).Inspect), arg0) +// Inspect indicates an expected call of Inspect. +func (mr *MockOpsMockRecorder) Inspect(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Inspect", reflect.TypeOf((*MockOps)(nil).Inspect), arg0, arg1) } -// InspectInstance mocks base method +// InspectInstance mocks base method. func (m *MockOps) InspectInstance(arg0 string) (*cloudops.InstanceInfo, error) { + m.ctrl.T.Helper() ret := m.ctrl.Call(m, "InspectInstance", arg0) ret0, _ := ret[0].(*cloudops.InstanceInfo) ret1, _ := ret[1].(error) return ret0, ret1 } -// InspectInstance indicates an expected call of InspectInstance +// InspectInstance indicates an expected call of InspectInstance. func (mr *MockOpsMockRecorder) InspectInstance(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InspectInstance", reflect.TypeOf((*MockOps)(nil).InspectInstance), arg0) } -// InspectInstanceGroupForInstance mocks base method +// InspectInstanceGroupForInstance mocks base method. func (m *MockOps) InspectInstanceGroupForInstance(arg0 string) (*cloudops.InstanceGroupInfo, error) { + m.ctrl.T.Helper() ret := m.ctrl.Call(m, "InspectInstanceGroupForInstance", arg0) ret0, _ := ret[0].(*cloudops.InstanceGroupInfo) ret1, _ := ret[1].(error) return ret0, ret1 } -// InspectInstanceGroupForInstance indicates an expected call of InspectInstanceGroupForInstance +// InspectInstanceGroupForInstance indicates an expected call of InspectInstanceGroupForInstance. func (mr *MockOpsMockRecorder) InspectInstanceGroupForInstance(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InspectInstanceGroupForInstance", reflect.TypeOf((*MockOps)(nil).InspectInstanceGroupForInstance), arg0) } -// InstanceID mocks base method +// InstanceID mocks base method. func (m *MockOps) InstanceID() string { + m.ctrl.T.Helper() ret := m.ctrl.Call(m, "InstanceID") ret0, _ := ret[0].(string) return ret0 } -// InstanceID indicates an expected call of InstanceID +// InstanceID indicates an expected call of InstanceID. func (mr *MockOpsMockRecorder) InstanceID() *gomock.Call { + mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InstanceID", reflect.TypeOf((*MockOps)(nil).InstanceID)) } -// Name mocks base method +// Name mocks base method. func (m *MockOps) Name() string { + m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Name") ret0, _ := ret[0].(string) return ret0 } -// Name indicates an expected call of Name +// Name indicates an expected call of Name. func (mr *MockOpsMockRecorder) Name() *gomock.Call { + mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockOps)(nil).Name)) } -// RemoveTags mocks base method -func (m *MockOps) RemoveTags(arg0 string, arg1 map[string]string) error { - ret := m.ctrl.Call(m, "RemoveTags", arg0, arg1) +// RemoveTags mocks base method. +func (m *MockOps) RemoveTags(arg0 string, arg1, arg2 map[string]string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RemoveTags", arg0, arg1, arg2) ret0, _ := ret[0].(error) return ret0 } -// RemoveTags indicates an expected call of RemoveTags -func (mr *MockOpsMockRecorder) RemoveTags(arg0, arg1 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveTags", reflect.TypeOf((*MockOps)(nil).RemoveTags), arg0, arg1) +// RemoveTags indicates an expected call of RemoveTags. +func (mr *MockOpsMockRecorder) RemoveTags(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveTags", reflect.TypeOf((*MockOps)(nil).RemoveTags), arg0, arg1, arg2) } -// SetInstanceGroupSize mocks base method +// SetClusterVersion mocks base method. +func (m *MockOps) SetClusterVersion(arg0 string, arg1 time.Duration) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetClusterVersion", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetClusterVersion indicates an expected call of SetClusterVersion. +func (mr *MockOpsMockRecorder) SetClusterVersion(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetClusterVersion", reflect.TypeOf((*MockOps)(nil).SetClusterVersion), arg0, arg1) +} + +// SetInstanceGroupSize mocks base method. func (m *MockOps) SetInstanceGroupSize(arg0 string, arg1 int64, arg2 time.Duration) error { + m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SetInstanceGroupSize", arg0, arg1, arg2) ret0, _ := ret[0].(error) return ret0 } -// SetInstanceGroupSize indicates an expected call of SetInstanceGroupSize +// SetInstanceGroupSize indicates an expected call of SetInstanceGroupSize. func (mr *MockOpsMockRecorder) SetInstanceGroupSize(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetInstanceGroupSize", reflect.TypeOf((*MockOps)(nil).SetInstanceGroupSize), arg0, arg1, arg2) } -// Snapshot mocks base method -func (m *MockOps) Snapshot(arg0 string, arg1 bool) (interface{}, error) { - ret := m.ctrl.Call(m, "Snapshot", arg0, arg1) +// SetInstanceGroupVersion mocks base method. +func (m *MockOps) SetInstanceGroupVersion(arg0, arg1 string, arg2 time.Duration) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetInstanceGroupVersion", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetInstanceGroupVersion indicates an expected call of SetInstanceGroupVersion. +func (mr *MockOpsMockRecorder) SetInstanceGroupVersion(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetInstanceGroupVersion", reflect.TypeOf((*MockOps)(nil).SetInstanceGroupVersion), arg0, arg1, arg2) +} + +// Snapshot mocks base method. +func (m *MockOps) Snapshot(arg0 string, arg1 bool, arg2 map[string]string) (interface{}, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Snapshot", arg0, arg1, arg2) ret0, _ := ret[0].(interface{}) ret1, _ := ret[1].(error) return ret0, ret1 } -// Snapshot indicates an expected call of Snapshot -func (mr *MockOpsMockRecorder) Snapshot(arg0, arg1 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Snapshot", reflect.TypeOf((*MockOps)(nil).Snapshot), arg0, arg1) +// Snapshot indicates an expected call of Snapshot. +func (mr *MockOpsMockRecorder) Snapshot(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Snapshot", reflect.TypeOf((*MockOps)(nil).Snapshot), arg0, arg1, arg2) } -// SnapshotDelete mocks base method -func (m *MockOps) SnapshotDelete(arg0 string) error { - ret := m.ctrl.Call(m, "SnapshotDelete", arg0) +// SnapshotDelete mocks base method. +func (m *MockOps) SnapshotDelete(arg0 string, arg1 map[string]string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SnapshotDelete", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } -// SnapshotDelete indicates an expected call of SnapshotDelete -func (mr *MockOpsMockRecorder) SnapshotDelete(arg0 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SnapshotDelete", reflect.TypeOf((*MockOps)(nil).SnapshotDelete), arg0) +// SnapshotDelete indicates an expected call of SnapshotDelete. +func (mr *MockOpsMockRecorder) SnapshotDelete(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SnapshotDelete", reflect.TypeOf((*MockOps)(nil).SnapshotDelete), arg0, arg1) } -// Tags mocks base method +// Tags mocks base method. func (m *MockOps) Tags(arg0 string) (map[string]string, error) { + m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Tags", arg0) ret0, _ := ret[0].(map[string]string) ret1, _ := ret[1].(error) return ret0, ret1 } -// Tags indicates an expected call of Tags +// Tags indicates an expected call of Tags. func (mr *MockOpsMockRecorder) Tags(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Tags", reflect.TypeOf((*MockOps)(nil).Tags), arg0) } diff --git a/oracle/oracle.go b/oracle/oracle.go index b424a426a..56fc4e8aa 100644 --- a/oracle/oracle.go +++ b/oracle/oracle.go @@ -409,7 +409,7 @@ func (o *oracleOps) DevicePath(volumeID string) (string, error) { } // Inspect volumes specified by volumeID -func (o *oracleOps) Inspect(volumeIds []*string) ([]interface{}, error) { +func (o *oracleOps) Inspect(volumeIds []*string, options map[string]string) ([]interface{}, error) { oracleVols := []interface{}{} for _, volID := range volumeIds { getVolReq := core.GetVolumeRequest{ @@ -425,7 +425,7 @@ func (o *oracleOps) Inspect(volumeIds []*string) ([]interface{}, error) { } // Create volume based on input template volume and also apply given labels. -func (o *oracleOps) Create(template interface{}, labels map[string]string) (interface{}, error) { +func (o *oracleOps) Create(template interface{}, labels map[string]string, options map[string]string) (interface{}, error) { vol, ok := template.(*core.Volume) if !ok { return nil, cloudops.NewStorageError(cloudops.ErrVolInval, @@ -480,7 +480,7 @@ func (o *oracleOps) waitVolumeStatus(volID string, desiredStatus core.VolumeLife func (o *oracleOps) rollbackCreate(id string, createErr error) error { logrus.Warnf("Rollback create volume %v, Error %v", id, createErr) - err := o.Delete(id) + err := o.Delete(id, nil) if err != nil { logrus.Warnf("Rollback failed volume %v, Error %v", id, err) } @@ -488,7 +488,7 @@ func (o *oracleOps) rollbackCreate(id string, createErr error) error { } // Delete volumeID. -func (o *oracleOps) Delete(volumeID string) error { +func (o *oracleOps) Delete(volumeID string, options map[string]string) error { delVolReq := core.DeleteVolumeRequest{ VolumeId: &volumeID, } @@ -687,7 +687,7 @@ func (o *oracleOps) waitVolumeAttachmentStatus(volumeAttachmentID *string, desir } // Detach volumeID. -func (o *oracleOps) Detach(volumeID string) error { +func (o *oracleOps) Detach(volumeID string, options map[string]string) error { return o.detachInternal(volumeID, o.instance) } @@ -829,7 +829,7 @@ func nodePoolContainsNode(s []containerengine.Node, e string) bool { return false } -func (o *oracleOps) Expand(volumeID string, newSizeInGiB uint64) (uint64, error) { +func (o *oracleOps) Expand(volumeID string, newSizeInGiB uint64, options map[string]string) (uint64, error) { logrus.Debug("Expand volume to size ", newSizeInGiB, " GiB") volume, err := o.storage.GetVolume(context.Background(), core.GetVolumeRequest{VolumeId: &volumeID}) @@ -1045,7 +1045,7 @@ func (o *oracleOps) deleted(v core.Volume) bool { } // ApplyTags will overwrite the existing tags with newly provided tags -func (o *oracleOps) ApplyTags(volumeID string, labels map[string]string) error { +func (o *oracleOps) ApplyTags(volumeID string, labels map[string]string, options map[string]string) error { req := core.UpdateVolumeRequest{ VolumeId: common.String(volumeID), UpdateVolumeDetails: core.UpdateVolumeDetails{ @@ -1061,7 +1061,7 @@ func (o *oracleOps) ApplyTags(volumeID string, labels map[string]string) error { // Tags will list the existing labels/tags on the given volume func (o *oracleOps) Tags(volumeID string) (map[string]string, error) { - vols, err := o.Inspect([]*string{&volumeID}) + vols, err := o.Inspect([]*string{&volumeID}, nil) if err != nil { return nil, err } @@ -1077,7 +1077,7 @@ func (o *oracleOps) Tags(volumeID string) (map[string]string, error) { } // RemoveTags removes labels/tags from the given volume -func (o *oracleOps) RemoveTags(volumeID string, labels map[string]string) error { +func (o *oracleOps) RemoveTags(volumeID string, labels map[string]string, options map[string]string) error { currentTags, err := o.Tags(volumeID) if err != nil { return nil @@ -1085,5 +1085,5 @@ func (o *oracleOps) RemoveTags(volumeID string, labels map[string]string) error for key := range labels { delete(currentTags, key) } - return o.ApplyTags(volumeID, currentTags) + return o.ApplyTags(volumeID, currentTags, options) } diff --git a/test/cloudops.go b/test/cloudops.go index 0fc9137ca..77f3cacc4 100644 --- a/test/cloudops.go +++ b/test/cloudops.go @@ -181,7 +181,7 @@ func compute(t *testing.T, driver cloudops.Ops) { } func create(t *testing.T, driver cloudops.Ops, template interface{}) interface{} { - d, err := driver.Create(template, nil) + d, err := driver.Create(template, nil, nil) require.NoError(t, err, "failed to create disk") require.NotNil(t, d, "got nil disk from create api") @@ -196,7 +196,7 @@ func id(t *testing.T, driver cloudops.Ops, disk interface{}) string { } func snapshot(t *testing.T, driver cloudops.Ops, diskName string) { - snap, err := driver.Snapshot(diskName, true) + snap, err := driver.Snapshot(diskName, true, nil) if _, typeOk := err.(*cloudops.ErrNotSupported); typeOk { return } @@ -208,12 +208,12 @@ func snapshot(t *testing.T, driver cloudops.Ops, diskName string) { require.NoError(t, err, "failed to get snapshot ID") require.NotEmpty(t, snapID, "got empty snapshot name/ID") - err = driver.SnapshotDelete(snapID) + err = driver.SnapshotDelete(snapID, nil) require.NoError(t, err, "failed to delete snapshot") } func tags(t *testing.T, driver cloudops.Ops, diskName string) { - err := driver.ApplyTags(diskName, diskLabels) + err := driver.ApplyTags(diskName, diskLabels, nil) if _, typeOk := err.(*cloudops.ErrNotSupported); typeOk { return } @@ -224,14 +224,14 @@ func tags(t *testing.T, driver cloudops.Ops, diskName string) { require.NoError(t, err, "failed to get tags for disk") require.Len(t, tags, 3, "invalid number of labels found on disk") - err = driver.RemoveTags(diskName, diskLabels) + err = driver.RemoveTags(diskName, diskLabels, nil) require.NoError(t, err, "failed to remove tags from disk") tags, err = driver.Tags(diskName) require.NoError(t, err, "failed to get tags for disk") require.Len(t, tags, 0, "invalid number of labels found on disk") - err = driver.ApplyTags(diskName, diskLabels) + err = driver.ApplyTags(diskName, diskLabels, nil) require.NoError(t, err, "failed to apply tags to disk") } @@ -257,7 +257,7 @@ func enumerate(t *testing.T, driver cloudops.Ops, diskName string) { } func inspect(t *testing.T, driver cloudops.Ops, diskName string) { - disks, err := driver.Inspect([]*string{&diskName}) + disks, err := driver.Inspect([]*string{&diskName}, nil) if _, typeOk := err.(*cloudops.ErrNotSupported); typeOk { return } @@ -267,7 +267,7 @@ func inspect(t *testing.T, driver cloudops.Ops, diskName string) { } func expand(t *testing.T, driver cloudops.Ops, diskName string, sizeCheck SizeCheck) { - newSize, err := driver.Expand(diskName, targetDiskSizeInGiB) + newSize, err := driver.Expand(diskName, targetDiskSizeInGiB, nil) if _, typeOk := err.(*cloudops.ErrNotSupported); typeOk { return } @@ -275,7 +275,7 @@ func expand(t *testing.T, driver cloudops.Ops, diskName string, sizeCheck SizeCh require.NoError(t, err, "unexpected error on expand") require.Equal(t, newSize, uint64(targetDiskSizeInGiB), "unexpected size returned on expand") - disks, err := driver.Inspect([]*string{&diskName}) + disks, err := driver.Inspect([]*string{&diskName}, nil) if _, typeOk := err.(*cloudops.ErrNotSupported); typeOk { return // cannot check if cloud provider doesn't support inspect } @@ -337,12 +337,12 @@ func devicePath(t *testing.T, driver cloudops.Ops, diskName string) { } func teardown(t *testing.T, driver cloudops.Ops, diskID string) { - err := driver.Detach(diskID) + err := driver.Detach(diskID, nil) require.NoError(t, err, "disk detach returned error") time.Sleep(3 * time.Second) - err = driver.Delete(diskID) + err = driver.Delete(diskID, nil) require.NoError(t, err, "failed to delete disk") } diff --git a/tools.go b/tools.go new file mode 100644 index 000000000..a54e53fc1 --- /dev/null +++ b/tools.go @@ -0,0 +1,9 @@ +//go:build tools +// +build tools + +package tools + +import ( + // Needed because of https://github.com/golang/mock/tree/v1.6.0#reflect-vendoring-error + _ "github.com/golang/mock/mockgen/model" +) diff --git a/unsupported/unsupported.go b/unsupported/unsupported.go index 3bf9c8812..253f91d01 100644 --- a/unsupported/unsupported.go +++ b/unsupported/unsupported.go @@ -83,7 +83,7 @@ func NewUnsupportedStorage() cloudops.Storage { return &unsupportedStorage{} } -func (u *unsupportedStorage) Create(template interface{}, labels map[string]string) (interface{}, error) { +func (u *unsupportedStorage) Create(template interface{}, labels map[string]string, options map[string]string) (interface{}, error) { return nil, &cloudops.ErrNotSupported{ Operation: "Create", } @@ -99,12 +99,12 @@ func (u *unsupportedStorage) Attach(volumeID string, options map[string]string) Operation: "Attach", } } -func (u *unsupportedStorage) Expand(volumeID string, newSizeInGiB uint64) (uint64, error) { +func (u *unsupportedStorage) Expand(volumeID string, newSizeInGiB uint64, options map[string]string) (uint64, error) { return 0, &cloudops.ErrNotSupported{ Operation: "Expand", } } -func (u *unsupportedStorage) Detach(volumeID string) error { +func (u *unsupportedStorage) Detach(volumeID string, options map[string]string) error { return &cloudops.ErrNotSupported{ Operation: "Detach", } @@ -114,7 +114,7 @@ func (u *unsupportedStorage) DetachFrom(volumeID, instanceID string) error { Operation: "DetachFrom", } } -func (u *unsupportedStorage) Delete(volumeID string) error { +func (u *unsupportedStorage) Delete(volumeID string, options map[string]string) error { return &cloudops.ErrNotSupported{ Operation: "Delete", } @@ -135,7 +135,7 @@ func (u *unsupportedStorage) FreeDevices(blockDeviceMappings []interface{}, root Operation: "FreeDevices", } } -func (u *unsupportedStorage) Inspect(volumeIds []*string) ([]interface{}, error) { +func (u *unsupportedStorage) Inspect(volumeIds []*string, options map[string]string) ([]interface{}, error) { return nil, &cloudops.ErrNotSupported{ Operation: "Inspect", } @@ -158,25 +158,25 @@ func (u *unsupportedStorage) DevicePath(volumeID string) (string, error) { Operation: "DevicePath", } } -func (u *unsupportedStorage) Snapshot(volumeID string, readonly bool) (interface{}, error) { +func (u *unsupportedStorage) Snapshot(volumeID string, readonly bool, options map[string]string) (interface{}, error) { return nil, &cloudops.ErrNotSupported{ Operation: "Snapshot", } } -func (u *unsupportedStorage) SnapshotDelete(snapID string) error { +func (u *unsupportedStorage) SnapshotDelete(snapID string, options map[string]string) error { return &cloudops.ErrNotSupported{ Operation: "SnapshotDelete", } } -func (u *unsupportedStorage) ApplyTags(volumeID string, labels map[string]string) error { +func (u *unsupportedStorage) ApplyTags(volumeID string, labels map[string]string, options map[string]string) error { return &cloudops.ErrNotSupported{ Operation: "ApplyTags", } } -func (u *unsupportedStorage) RemoveTags(volumeID string, labels map[string]string) error { +func (u *unsupportedStorage) RemoveTags(volumeID string, labels map[string]string, options map[string]string) error { return &cloudops.ErrNotSupported{ Operation: "RemoveTags", } diff --git a/vendor/github.com/golang/mock/mockgen/model/model.go b/vendor/github.com/golang/mock/mockgen/model/model.go new file mode 100644 index 000000000..88783cfdf --- /dev/null +++ b/vendor/github.com/golang/mock/mockgen/model/model.go @@ -0,0 +1,470 @@ +// Copyright 2012 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package model contains the data model necessary for generating mock implementations. +package model + +import ( + "encoding/gob" + "fmt" + "io" + "reflect" + "strings" +) + +// pkgPath is the importable path for package model +const pkgPath = "github.com/golang/mock/mockgen/model" + +// Package is a Go package. It may be a subset. +type Package struct { + Name string + PkgPath string + Interfaces []*Interface + DotImports []string +} + +// Print writes the package name and its exported interfaces. +func (pkg *Package) Print(w io.Writer) { + _, _ = fmt.Fprintf(w, "package %s\n", pkg.Name) + for _, intf := range pkg.Interfaces { + intf.Print(w) + } +} + +// Imports returns the imports needed by the Package as a set of import paths. +func (pkg *Package) Imports() map[string]bool { + im := make(map[string]bool) + for _, intf := range pkg.Interfaces { + intf.addImports(im) + } + return im +} + +// Interface is a Go interface. +type Interface struct { + Name string + Methods []*Method +} + +// Print writes the interface name and its methods. +func (intf *Interface) Print(w io.Writer) { + _, _ = fmt.Fprintf(w, "interface %s\n", intf.Name) + for _, m := range intf.Methods { + m.Print(w) + } +} + +func (intf *Interface) addImports(im map[string]bool) { + for _, m := range intf.Methods { + m.addImports(im) + } +} + +// Method is a single method of an interface. +type Method struct { + Name string + In, Out []*Parameter + Variadic *Parameter // may be nil +} + +// Print writes the method name and its signature. +func (m *Method) Print(w io.Writer) { + _, _ = fmt.Fprintf(w, " - method %s\n", m.Name) + if len(m.In) > 0 { + _, _ = fmt.Fprintf(w, " in:\n") + for _, p := range m.In { + p.Print(w) + } + } + if m.Variadic != nil { + _, _ = fmt.Fprintf(w, " ...:\n") + m.Variadic.Print(w) + } + if len(m.Out) > 0 { + _, _ = fmt.Fprintf(w, " out:\n") + for _, p := range m.Out { + p.Print(w) + } + } +} + +func (m *Method) addImports(im map[string]bool) { + for _, p := range m.In { + p.Type.addImports(im) + } + if m.Variadic != nil { + m.Variadic.Type.addImports(im) + } + for _, p := range m.Out { + p.Type.addImports(im) + } +} + +// Parameter is an argument or return parameter of a method. +type Parameter struct { + Name string // may be empty + Type Type +} + +// Print writes a method parameter. +func (p *Parameter) Print(w io.Writer) { + n := p.Name + if n == "" { + n = `""` + } + _, _ = fmt.Fprintf(w, " - %v: %v\n", n, p.Type.String(nil, "")) +} + +// Type is a Go type. +type Type interface { + String(pm map[string]string, pkgOverride string) string + addImports(im map[string]bool) +} + +func init() { + gob.Register(&ArrayType{}) + gob.Register(&ChanType{}) + gob.Register(&FuncType{}) + gob.Register(&MapType{}) + gob.Register(&NamedType{}) + gob.Register(&PointerType{}) + + // Call gob.RegisterName to make sure it has the consistent name registered + // for both gob decoder and encoder. + // + // For a non-pointer type, gob.Register will try to get package full path by + // calling rt.PkgPath() for a name to register. If your project has vendor + // directory, it is possible that PkgPath will get a path like this: + // ../../../vendor/github.com/golang/mock/mockgen/model + gob.RegisterName(pkgPath+".PredeclaredType", PredeclaredType("")) +} + +// ArrayType is an array or slice type. +type ArrayType struct { + Len int // -1 for slices, >= 0 for arrays + Type Type +} + +func (at *ArrayType) String(pm map[string]string, pkgOverride string) string { + s := "[]" + if at.Len > -1 { + s = fmt.Sprintf("[%d]", at.Len) + } + return s + at.Type.String(pm, pkgOverride) +} + +func (at *ArrayType) addImports(im map[string]bool) { at.Type.addImports(im) } + +// ChanType is a channel type. +type ChanType struct { + Dir ChanDir // 0, 1 or 2 + Type Type +} + +func (ct *ChanType) String(pm map[string]string, pkgOverride string) string { + s := ct.Type.String(pm, pkgOverride) + if ct.Dir == RecvDir { + return "<-chan " + s + } + if ct.Dir == SendDir { + return "chan<- " + s + } + return "chan " + s +} + +func (ct *ChanType) addImports(im map[string]bool) { ct.Type.addImports(im) } + +// ChanDir is a channel direction. +type ChanDir int + +// Constants for channel directions. +const ( + RecvDir ChanDir = 1 + SendDir ChanDir = 2 +) + +// FuncType is a function type. +type FuncType struct { + In, Out []*Parameter + Variadic *Parameter // may be nil +} + +func (ft *FuncType) String(pm map[string]string, pkgOverride string) string { + args := make([]string, len(ft.In)) + for i, p := range ft.In { + args[i] = p.Type.String(pm, pkgOverride) + } + if ft.Variadic != nil { + args = append(args, "..."+ft.Variadic.Type.String(pm, pkgOverride)) + } + rets := make([]string, len(ft.Out)) + for i, p := range ft.Out { + rets[i] = p.Type.String(pm, pkgOverride) + } + retString := strings.Join(rets, ", ") + if nOut := len(ft.Out); nOut == 1 { + retString = " " + retString + } else if nOut > 1 { + retString = " (" + retString + ")" + } + return "func(" + strings.Join(args, ", ") + ")" + retString +} + +func (ft *FuncType) addImports(im map[string]bool) { + for _, p := range ft.In { + p.Type.addImports(im) + } + if ft.Variadic != nil { + ft.Variadic.Type.addImports(im) + } + for _, p := range ft.Out { + p.Type.addImports(im) + } +} + +// MapType is a map type. +type MapType struct { + Key, Value Type +} + +func (mt *MapType) String(pm map[string]string, pkgOverride string) string { + return "map[" + mt.Key.String(pm, pkgOverride) + "]" + mt.Value.String(pm, pkgOverride) +} + +func (mt *MapType) addImports(im map[string]bool) { + mt.Key.addImports(im) + mt.Value.addImports(im) +} + +// NamedType is an exported type in a package. +type NamedType struct { + Package string // may be empty + Type string // TODO: should this be typed Type? +} + +func (nt *NamedType) String(pm map[string]string, pkgOverride string) string { + // TODO: is this right? + if pkgOverride == nt.Package { + return nt.Type + } + prefix := pm[nt.Package] + if prefix != "" { + return prefix + "." + nt.Type + } + + return nt.Type +} + +func (nt *NamedType) addImports(im map[string]bool) { + if nt.Package != "" { + im[nt.Package] = true + } +} + +// PointerType is a pointer to another type. +type PointerType struct { + Type Type +} + +func (pt *PointerType) String(pm map[string]string, pkgOverride string) string { + return "*" + pt.Type.String(pm, pkgOverride) +} +func (pt *PointerType) addImports(im map[string]bool) { pt.Type.addImports(im) } + +// PredeclaredType is a predeclared type such as "int". +type PredeclaredType string + +func (pt PredeclaredType) String(map[string]string, string) string { return string(pt) } +func (pt PredeclaredType) addImports(map[string]bool) {} + +// The following code is intended to be called by the program generated by ../reflect.go. + +// InterfaceFromInterfaceType returns a pointer to an interface for the +// given reflection interface type. +func InterfaceFromInterfaceType(it reflect.Type) (*Interface, error) { + if it.Kind() != reflect.Interface { + return nil, fmt.Errorf("%v is not an interface", it) + } + intf := &Interface{} + + for i := 0; i < it.NumMethod(); i++ { + mt := it.Method(i) + // TODO: need to skip unexported methods? or just raise an error? + m := &Method{ + Name: mt.Name, + } + + var err error + m.In, m.Variadic, m.Out, err = funcArgsFromType(mt.Type) + if err != nil { + return nil, err + } + + intf.Methods = append(intf.Methods, m) + } + + return intf, nil +} + +// t's Kind must be a reflect.Func. +func funcArgsFromType(t reflect.Type) (in []*Parameter, variadic *Parameter, out []*Parameter, err error) { + nin := t.NumIn() + if t.IsVariadic() { + nin-- + } + var p *Parameter + for i := 0; i < nin; i++ { + p, err = parameterFromType(t.In(i)) + if err != nil { + return + } + in = append(in, p) + } + if t.IsVariadic() { + p, err = parameterFromType(t.In(nin).Elem()) + if err != nil { + return + } + variadic = p + } + for i := 0; i < t.NumOut(); i++ { + p, err = parameterFromType(t.Out(i)) + if err != nil { + return + } + out = append(out, p) + } + return +} + +func parameterFromType(t reflect.Type) (*Parameter, error) { + tt, err := typeFromType(t) + if err != nil { + return nil, err + } + return &Parameter{Type: tt}, nil +} + +var errorType = reflect.TypeOf((*error)(nil)).Elem() + +var byteType = reflect.TypeOf(byte(0)) + +func typeFromType(t reflect.Type) (Type, error) { + // Hack workaround for https://golang.org/issue/3853. + // This explicit check should not be necessary. + if t == byteType { + return PredeclaredType("byte"), nil + } + + if imp := t.PkgPath(); imp != "" { + return &NamedType{ + Package: impPath(imp), + Type: t.Name(), + }, nil + } + + // only unnamed or predeclared types after here + + // Lots of types have element types. Let's do the parsing and error checking for all of them. + var elemType Type + switch t.Kind() { + case reflect.Array, reflect.Chan, reflect.Map, reflect.Ptr, reflect.Slice: + var err error + elemType, err = typeFromType(t.Elem()) + if err != nil { + return nil, err + } + } + + switch t.Kind() { + case reflect.Array: + return &ArrayType{ + Len: t.Len(), + Type: elemType, + }, nil + case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, + reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128, reflect.String: + return PredeclaredType(t.Kind().String()), nil + case reflect.Chan: + var dir ChanDir + switch t.ChanDir() { + case reflect.RecvDir: + dir = RecvDir + case reflect.SendDir: + dir = SendDir + } + return &ChanType{ + Dir: dir, + Type: elemType, + }, nil + case reflect.Func: + in, variadic, out, err := funcArgsFromType(t) + if err != nil { + return nil, err + } + return &FuncType{ + In: in, + Out: out, + Variadic: variadic, + }, nil + case reflect.Interface: + // Two special interfaces. + if t.NumMethod() == 0 { + return PredeclaredType("interface{}"), nil + } + if t == errorType { + return PredeclaredType("error"), nil + } + case reflect.Map: + kt, err := typeFromType(t.Key()) + if err != nil { + return nil, err + } + return &MapType{ + Key: kt, + Value: elemType, + }, nil + case reflect.Ptr: + return &PointerType{ + Type: elemType, + }, nil + case reflect.Slice: + return &ArrayType{ + Len: -1, + Type: elemType, + }, nil + case reflect.Struct: + if t.NumField() == 0 { + return PredeclaredType("struct{}"), nil + } + } + + // TODO: Struct, UnsafePointer + return nil, fmt.Errorf("can't yet turn %v (%v) into a model.Type", t, t.Kind()) +} + +// impPath sanitizes the package path returned by `PkgPath` method of a reflect Type so that +// it is importable. PkgPath might return a path that includes "vendor". These paths do not +// compile, so we need to remove everything up to and including "/vendor/". +// See https://github.com/golang/go/issues/12019. +func impPath(imp string) string { + if strings.HasPrefix(imp, "vendor/") { + imp = "/" + imp + } + if i := strings.LastIndex(imp, "/vendor/"); i != -1 { + imp = imp[i+len("/vendor/"):] + } + return imp +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 6666baae5..58de5224f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -117,6 +117,7 @@ github.com/gogo/protobuf/sortkeys github.com/golang/groupcache/lru # github.com/golang/mock v1.4.4 github.com/golang/mock/gomock +github.com/golang/mock/mockgen/model # github.com/golang/protobuf v1.5.2 github.com/golang/protobuf/descriptor github.com/golang/protobuf/jsonpb diff --git a/vsphere/vsphere.go b/vsphere/vsphere.go index fea06479b..e124e07ac 100644 --- a/vsphere/vsphere.go +++ b/vsphere/vsphere.go @@ -106,7 +106,7 @@ func (ops *vsphereOps) Name() string { return string(cloudops.Vsphere) } func (ops *vsphereOps) InstanceID() string { return ops.cfg.VMUUID } -func (ops *vsphereOps) Create(opts interface{}, labels map[string]string) (interface{}, error) { +func (ops *vsphereOps) Create(opts interface{}, labels map[string]string, options map[string]string) (interface{}, error) { volumeOptions, ok := opts.(*vclib.VolumeOptions) if !ok { return nil, fmt.Errorf("invalid volume options specified to create: %v", opts) @@ -316,7 +316,7 @@ func (ops *vsphereOps) Attach(diskPath string, options map[string]string) (strin return path.Join(diskByIDPath, diskSCSIPrefix+diskUUID), nil } -func (ops *vsphereOps) Detach(diskPath string) error { +func (ops *vsphereOps) Detach(diskPath string, options map[string]string) error { return ops.detachInternal(diskPath, ops.cfg.VMUUID) } @@ -351,7 +351,7 @@ func (ops *vsphereOps) detachInternal(diskPath, instanceID string) error { } // Delete virtual disk at given path -func (ops *vsphereOps) Delete(diskPath string) error { +func (ops *vsphereOps) Delete(diskPath string, options map[string]string) error { return ops.deleteInternal(diskPath, ops.cfg.VMUUID) } @@ -406,7 +406,7 @@ func (ops *vsphereOps) FreeDevices(blockDeviceMappings []interface{}, rootDevice } } -func (ops *vsphereOps) Inspect(vmdksWithDS []*string) ([]interface{}, error) { +func (ops *vsphereOps) Inspect(vmdksWithDS []*string, options map[string]string) ([]interface{}, error) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -530,6 +530,7 @@ func (ops *vsphereOps) Enumerate(volumeIds []*string, func (ops *vsphereOps) Expand( vmdkPath string, newSizeInGiB uint64, + options map[string]string, ) (uint64, error) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -608,28 +609,28 @@ func (ops *vsphereOps) Expand( } // Snapshot the volume with given volumeID -func (ops *vsphereOps) Snapshot(volumeID string, readonly bool) (interface{}, error) { +func (ops *vsphereOps) Snapshot(volumeID string, readonly bool, options map[string]string) (interface{}, error) { return nil, &cloudops.ErrNotSupported{ Operation: "Snapshot", } } // SnapshotDelete deletes the snapshot with given ID -func (ops *vsphereOps) SnapshotDelete(snapID string) error { +func (ops *vsphereOps) SnapshotDelete(snapID string, options map[string]string) error { return &cloudops.ErrNotSupported{ Operation: "SnapshotDelete", } } // ApplyTags will apply given labels/tags on the given volume -func (ops *vsphereOps) ApplyTags(volumeID string, labels map[string]string) error { +func (ops *vsphereOps) ApplyTags(volumeID string, labels map[string]string, options map[string]string) error { return &cloudops.ErrNotSupported{ Operation: "ApplyTags", } } // RemoveTags removes labels/tags from the given volume -func (ops *vsphereOps) RemoveTags(volumeID string, labels map[string]string) error { +func (ops *vsphereOps) RemoveTags(volumeID string, labels map[string]string, options map[string]string) error { return &cloudops.ErrNotSupported{ Operation: "RemoveTags", } @@ -830,21 +831,21 @@ func recommendDatastore( var ds types.ManagedObjectReference /* - recs are the recommendations made by vSphere. There will be multiple datastore recommendations made by vSphere - and it's expected for us to select one manually based on any of the parameters given to us. The below code picks - the best datastore based on two factors: - 1. Rating: Valid values range from 1 (lowest confidence) to 5 (highest confidence). - 2. Space Utilization after virtual disk placement: It's percentage value - If there is a higher rating recommendation with the best space utilization, we'll select that. - Many recommendations will be made with the same rating. In those cases we'll pick the one with lease space util. - What is interesting will be when a lower recommendation has very less space util than a higher rating one. In order - to consider those cases, let's assign a 9% value for each rating and decide which one to pick. Let's consider some examples: - 1. Rating 5, Util 41.00 vs Rating 4, Util 30.0000 -> We'll pick the second one since it's atleast 10% less utilized - 2. Rating 5, Util 50.000 vs Rating 3, Util 20.000 -> We'll pick the second one again for the same reason + recs are the recommendations made by vSphere. There will be multiple datastore recommendations made by vSphere + and it's expected for us to select one manually based on any of the parameters given to us. The below code picks + the best datastore based on two factors: + 1. Rating: Valid values range from 1 (lowest confidence) to 5 (highest confidence). + 2. Space Utilization after virtual disk placement: It's percentage value + If there is a higher rating recommendation with the best space utilization, we'll select that. + Many recommendations will be made with the same rating. In those cases we'll pick the one with lease space util. + What is interesting will be when a lower recommendation has very less space util than a higher rating one. In order + to consider those cases, let's assign a 9% value for each rating and decide which one to pick. Let's consider some examples: + 1. Rating 5, Util 41.00 vs Rating 4, Util 30.0000 -> We'll pick the second one since it's atleast 10% less utilized + 2. Rating 5, Util 50.000 vs Rating 3, Util 20.000 -> We'll pick the second one again for the same reason */ minSpaceUtilization := float32(200) const ( - maxRating = int32(5) + maxRating = int32(5) normalizationPercent = float32(9) ) for i, r := range recs { @@ -852,10 +853,10 @@ func recommendDatastore( for _, a := range r.Action { action := a.(*types.StoragePlacementAction) logrus.Infof("vsphere recommendation action %v", action) - normalizedUtilization := (float32(maxRating - r.Rating) * normalizationPercent) + action.SpaceUtilAfter + normalizedUtilization := (float32(maxRating-r.Rating) * normalizationPercent) + action.SpaceUtilAfter if normalizedUtilization < minSpaceUtilization { - minSpaceUtilization = normalizedUtilization - ds = action.Destination + minSpaceUtilization = normalizedUtilization + ds = action.Destination } } }