From 4ca1dbc5891132d72927f64ead4bd4a7fc792045 Mon Sep 17 00:00:00 2001 From: saadali Date: Tue, 29 Aug 2017 09:39:45 -0700 Subject: [PATCH] Enable switching to alpha GCE disk API --- pkg/cloudprovider/providers/gce/gce.go | 133 ++++++++- pkg/cloudprovider/providers/gce/gce_alpha.go | 8 +- pkg/cloudprovider/providers/gce/gce_disks.go | 47 +-- .../providers/gce/gce_disks_test.go | 278 +++++++++++++++--- test/e2e/e2e.go | 8 +- 5 files changed, 390 insertions(+), 84 deletions(-) diff --git a/pkg/cloudprovider/providers/gce/gce.go b/pkg/cloudprovider/providers/gce/gce.go index 0decfcaa254..b28f61c6bcc 100644 --- a/pkg/cloudprovider/providers/gce/gce.go +++ b/pkg/cloudprovider/providers/gce/gce.go @@ -131,16 +131,36 @@ type GCECloud struct { type ServiceManager interface { // Creates a new persistent disk on GCE with the given disk spec. - CreateDisk(project string, zone string, disk *compute.Disk) (*compute.Operation, error) + CreateDisk( + name string, + sizeGb int64, + tagsStr string, + diskTypeURI string, + zone string) (gceObject, error) + + // Attach a persistent disk on GCE with the given disk spec to the specified instance. + AttachDisk(diskName string, + diskKind string, + diskZone string, + readWrite string, + source string, + diskType string, + instanceName string) (gceObject, error) + + // Detach a persistent disk on GCE with the given disk spec from the specified instance. + DetachDisk( + instanceZone string, + instanceName string, + devicePath string) (gceObject, error) // Gets the persistent disk from GCE with the given diskName. - GetDisk(project string, zone string, diskName string) (*compute.Disk, error) + GetDisk(project string, zone string, diskName string) (*GCEDisk, error) // Deletes the persistent disk from GCE with the given diskName. - DeleteDisk(project string, zone string, disk string) (*compute.Operation, error) + DeleteDisk(project string, zone string, disk string) (gceObject, error) // Waits until GCE reports the given operation in the given zone as done. - WaitForZoneOp(op *compute.Operation, zone string, mc *metricContext) error + WaitForZoneOp(op gceObject, zone string, mc *metricContext) error } type GCEServiceManager struct { @@ -717,29 +737,118 @@ func newOauthClient(tokenSource oauth2.TokenSource) (*http.Client, error) { } func (manager *GCEServiceManager) CreateDisk( - project string, - zone string, - disk *compute.Disk) (*compute.Operation, error) { + name string, + sizeGb int64, + tagsStr string, + diskTypeURI string, + zone string) (gceObject, error) { + if manager.gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) { + diskToCreateAlpha := &computealpha.Disk{ + Name: name, + SizeGb: sizeGb, + Description: tagsStr, + Type: diskTypeURI, + } + return manager.gce.serviceAlpha.Disks.Insert(manager.gce.projectID, zone, diskToCreateAlpha).Do() + } - return manager.gce.service.Disks.Insert(project, zone, disk).Do() + diskToCreateV1 := &compute.Disk{ + Name: name, + SizeGb: sizeGb, + Description: tagsStr, + Type: diskTypeURI, + } + return manager.gce.service.Disks.Insert(manager.gce.projectID, zone, diskToCreateV1).Do() +} + +func (manager *GCEServiceManager) AttachDisk( + diskName string, + diskKind string, + diskZone string, + readWrite string, + source string, + diskType string, + instanceName string) (gceObject, error) { + if manager.gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) { + attachedDiskAlpha := &computealpha.AttachedDisk{ + DeviceName: diskName, + Kind: diskKind, + Mode: readWrite, + Source: source, + Type: diskType, + } + return manager.gce.serviceAlpha.Instances.AttachDisk( + manager.gce.projectID, diskZone, instanceName, attachedDiskAlpha).Do() + } + + attachedDiskV1 := &compute.AttachedDisk{ + DeviceName: diskName, + Kind: diskKind, + Mode: readWrite, + Source: source, + Type: diskType, + } + return manager.gce.service.Instances.AttachDisk( + manager.gce.projectID, diskZone, instanceName, attachedDiskV1).Do() +} + +func (manager *GCEServiceManager) DetachDisk( + instanceZone string, + instanceName string, + devicePath string) (gceObject, error) { + if manager.gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) { + manager.gce.serviceAlpha.Instances.DetachDisk( + manager.gce.projectID, instanceZone, instanceName, devicePath).Do() + } + + return manager.gce.service.Instances.DetachDisk( + manager.gce.projectID, instanceZone, instanceName, devicePath).Do() } func (manager *GCEServiceManager) GetDisk( project string, zone string, - diskName string) (*compute.Disk, error) { + diskName string) (*GCEDisk, error) { - return manager.gce.service.Disks.Get(project, zone, diskName).Do() + if manager.gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) { + diskAlpha, err := manager.gce.serviceAlpha.Disks.Get(project, zone, diskName).Do() + if err != nil { + return nil, err + } + + return &GCEDisk{ + Zone: lastComponent(diskAlpha.Zone), + Name: diskAlpha.Name, + Kind: diskAlpha.Kind, + Type: diskAlpha.Type, + }, nil + } + + diskStable, err := manager.gce.service.Disks.Get(project, zone, diskName).Do() + if err != nil { + return nil, err + } + + return &GCEDisk{ + Zone: lastComponent(diskStable.Zone), + Name: diskStable.Name, + Kind: diskStable.Kind, + Type: diskStable.Type, + }, nil } func (manager *GCEServiceManager) DeleteDisk( project string, zone string, - diskName string) (*compute.Operation, error) { + diskName string) (gceObject, error) { + + if manager.gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) { + return manager.gce.serviceAlpha.Disks.Delete(project, zone, diskName).Do() + } return manager.gce.service.Disks.Delete(project, zone, diskName).Do() } -func (manager *GCEServiceManager) WaitForZoneOp(op *compute.Operation, zone string, mc *metricContext) error { +func (manager *GCEServiceManager) WaitForZoneOp(op gceObject, zone string, mc *metricContext) error { return manager.gce.waitForZoneOp(op, zone, mc) } diff --git a/pkg/cloudprovider/providers/gce/gce_alpha.go b/pkg/cloudprovider/providers/gce/gce_alpha.go index fb659c9391e..bd629769ba3 100644 --- a/pkg/cloudprovider/providers/gce/gce_alpha.go +++ b/pkg/cloudprovider/providers/gce/gce_alpha.go @@ -23,7 +23,13 @@ import ( ) // All known alpha features -var knownAlphaFeatures = map[string]bool{} +var knownAlphaFeatures = map[string]bool{ + GCEDiskAlphaFeatureGate: true, +} + +const ( + GCEDiskAlphaFeatureGate = "GCEDiskAlphaAPI" +) type AlphaFeatureGate struct { features map[string]bool diff --git a/pkg/cloudprovider/providers/gce/gce_disks.go b/pkg/cloudprovider/providers/gce/gce_disks.go index 57ca223da73..bdc126c3048 100644 --- a/pkg/cloudprovider/providers/gce/gce_disks.go +++ b/pkg/cloudprovider/providers/gce/gce_disks.go @@ -28,7 +28,6 @@ import ( "k8s.io/kubernetes/pkg/volume" "github.com/golang/glog" - compute "google.golang.org/api/compute/v1" "google.golang.org/api/googleapi" ) @@ -40,6 +39,7 @@ const ( diskTypeDefault = DiskTypeStandard diskTypeUriTemplate = "%s/zones/%s/diskTypes/%s" + diskTypePersistent = "PERSISTENT" ) // Disks is interface for manipulation with GCE PDs. @@ -101,17 +101,18 @@ func (gce *GCECloud) AttachDisk(diskName string, nodeName types.NodeName, readOn if readOnly { readWrite = "READ_ONLY" } - attachedDisk := gce.convertDiskToAttachedDisk(disk, readWrite) mc := newDiskMetricContext("attach", instance.Zone) - attachOp, err := gce.service.Instances.AttachDisk( - gce.projectID, disk.Zone, instance.Name, attachedDisk).Do() + source := gce.service.BasePath + strings.Join([]string{ + gce.projectID, "zones", disk.Zone, "disks", disk.Name}, "/") + attachOp, err := gce.manager.AttachDisk( + disk.Name, disk.Kind, disk.Zone, readWrite, source, diskTypePersistent, instance.Name) if err != nil { return mc.Observe(err) } - return gce.waitForZoneOp(attachOp, disk.Zone, mc) + return gce.manager.WaitForZoneOp(attachOp, disk.Zone, mc) } func (gce *GCECloud) DetachDisk(devicePath string, nodeName types.NodeName) error { @@ -131,12 +132,12 @@ func (gce *GCECloud) DetachDisk(devicePath string, nodeName types.NodeName) erro } mc := newDiskMetricContext("detach", inst.Zone) - detachOp, err := gce.service.Instances.DetachDisk(gce.projectID, inst.Zone, inst.Name, devicePath).Do() + detachOp, err := gce.manager.DetachDisk(inst.Zone, inst.Name, devicePath) if err != nil { return mc.Observe(err) } - return gce.waitForZoneOp(detachOp, inst.Zone, mc) + return gce.manager.WaitForZoneOp(detachOp, inst.Zone, mc) } func (gce *GCECloud) DiskIsAttached(diskName string, nodeName types.NodeName) (bool, error) { @@ -236,15 +237,11 @@ func (gce *GCECloud) CreateDisk( } diskTypeUri := projectsApiEndpoint + fmt.Sprintf(diskTypeUriTemplate, gce.projectID, zone, diskType) - diskToCreate := &compute.Disk{ - Name: name, - SizeGb: sizeGb, - Description: tagsStr, - Type: diskTypeUri, - } - mc := newDiskMetricContext("create", zone) - createOp, err := gce.manager.CreateDisk(gce.projectID, zone, diskToCreate) + + createOp, err := gce.manager.CreateDisk( + name, sizeGb, tagsStr, diskTypeUri, zone) + if isGCEError(err, "alreadyExists") { glog.Warningf("GCE PD %q already exists, reusing", name) return nil @@ -325,13 +322,7 @@ func (gce *GCECloud) findDiskByName(diskName string, zone string) (*GCEDisk, err mc := newDiskMetricContext("get", zone) disk, err := gce.manager.GetDisk(gce.projectID, zone, diskName) if err == nil { - d := &GCEDisk{ - Zone: lastComponent(disk.Zone), - Name: disk.Name, - Kind: disk.Kind, - Type: disk.Type, - } - return d, mc.Observe(nil) + return disk, mc.Observe(nil) } if !isHTTPErrorCode(err, http.StatusNotFound) { return nil, mc.Observe(err) @@ -418,18 +409,6 @@ func (gce *GCECloud) doDeleteDisk(diskToDelete string) error { return gce.manager.WaitForZoneOp(deleteOp, disk.Zone, mc) } -// Converts a Disk resource to an AttachedDisk resource. -func (gce *GCECloud) convertDiskToAttachedDisk(disk *GCEDisk, readWrite string) *compute.AttachedDisk { - return &compute.AttachedDisk{ - DeviceName: disk.Name, - Kind: disk.Kind, - Mode: readWrite, - Source: gce.service.BasePath + strings.Join([]string{ - gce.projectID, "zones", disk.Zone, "disks", disk.Name}, "/"), - Type: "PERSISTENT", - } -} - // isGCEError returns true if given error is a googleapi.Error with given // reason (e.g. "resourceInUseByAnotherResource") func isGCEError(err error, reason string) bool { diff --git a/pkg/cloudprovider/providers/gce/gce_disks_test.go b/pkg/cloudprovider/providers/gce/gce_disks_test.go index 5ff88d65c0b..8eb960a1f72 100644 --- a/pkg/cloudprovider/providers/gce/gce_disks_test.go +++ b/pkg/cloudprovider/providers/gce/gce_disks_test.go @@ -20,6 +20,9 @@ import ( "testing" "fmt" + + computealpha "google.golang.org/api/compute/v0.alpha" + computebeta "google.golang.org/api/compute/v0.beta" compute "google.golang.org/api/compute/v1" "google.golang.org/api/googleapi" "k8s.io/kubernetes/pkg/cloudprovider" @@ -30,10 +33,15 @@ func TestCreateDisk_Basic(t *testing.T) { /* Arrange */ fakeManager := newFakeManager() projectId := "test-project" + alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{}) + if featureGateErr != nil { + t.Error(featureGateErr) + } gce := GCECloud{ - manager: fakeManager, - managedZones: []string{"zone1"}, - projectID: projectId, + manager: fakeManager, + managedZones: []string{"zone1"}, + projectID: projectId, + AlphaFeatureGate: alphaFeatureGate, } diskName := "disk" @@ -61,7 +69,7 @@ func TestCreateDisk_Basic(t *testing.T) { } // Partial check of equality between disk description sent to GCE and parameters of method. - diskToCreate := fakeManager.diskToCreate + diskToCreate := fakeManager.diskToCreateStable if diskToCreate.Name != diskName { t.Errorf("Expected disk name: %s; Actual: %s", diskName, diskToCreate.Name) } @@ -80,7 +88,15 @@ func TestCreateDisk_Basic(t *testing.T) { func TestCreateDisk_DiskAlreadyExists(t *testing.T) { /* Arrange */ fakeManager := newFakeManager() - gce := GCECloud{manager: fakeManager, managedZones: []string{"zone1"}} + alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{}) + if featureGateErr != nil { + t.Error(featureGateErr) + } + gce := GCECloud{ + manager: fakeManager, + managedZones: []string{"zone1"}, + AlphaFeatureGate: alphaFeatureGate, + } // Inject disk AlreadyExists error. alreadyExistsError := googleapi.ErrorItem{Reason: "alreadyExists"} @@ -156,7 +172,15 @@ func TestCreateDisk_BadDiskType(t *testing.T) { func TestCreateDisk_MultiZone(t *testing.T) { /* Arrange */ fakeManager := newFakeManager() - gce := GCECloud{manager: fakeManager, managedZones: []string{"zone1", "zone2", "zone3"}} + alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{}) + if featureGateErr != nil { + t.Error(featureGateErr) + } + gce := GCECloud{ + manager: fakeManager, + managedZones: []string{"zone1", "zone2", "zone3"}, + AlphaFeatureGate: alphaFeatureGate, + } diskName := "disk" diskType := DiskTypeStandard @@ -175,7 +199,15 @@ func TestCreateDisk_MultiZone(t *testing.T) { func TestDeleteDisk_Basic(t *testing.T) { /* Arrange */ fakeManager := newFakeManager() - gce := GCECloud{manager: fakeManager, managedZones: []string{"zone1"}} + alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{}) + if featureGateErr != nil { + t.Error(featureGateErr) + } + gce := GCECloud{ + manager: fakeManager, + managedZones: []string{"zone1"}, + AlphaFeatureGate: alphaFeatureGate, + } diskName := "disk" diskType := DiskTypeSSD zone := "zone1" @@ -217,7 +249,15 @@ func TestDeleteDisk_NotFound(t *testing.T) { func TestDeleteDisk_ResourceBeingUsed(t *testing.T) { /* Arrange */ fakeManager := newFakeManager() - gce := GCECloud{manager: fakeManager, managedZones: []string{"zone1"}} + alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{}) + if featureGateErr != nil { + t.Error(featureGateErr) + } + gce := GCECloud{ + manager: fakeManager, + managedZones: []string{"zone1"}, + AlphaFeatureGate: alphaFeatureGate, + } diskName := "disk" diskType := DiskTypeSSD zone := "zone1" @@ -238,7 +278,15 @@ func TestDeleteDisk_ResourceBeingUsed(t *testing.T) { func TestDeleteDisk_SameDiskMultiZone(t *testing.T) { /* Assert */ fakeManager := newFakeManager() - gce := GCECloud{manager: fakeManager, managedZones: []string{"zone1", "zone2", "zone3"}} + alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{}) + if featureGateErr != nil { + t.Error(featureGateErr) + } + gce := GCECloud{ + manager: fakeManager, + managedZones: []string{"zone1", "zone2", "zone3"}, + AlphaFeatureGate: alphaFeatureGate, + } diskName := "disk" diskType := DiskTypeSSD const sizeGb int64 = 128 @@ -262,7 +310,15 @@ func TestDeleteDisk_SameDiskMultiZone(t *testing.T) { func TestDeleteDisk_DiffDiskMultiZone(t *testing.T) { /* Arrange */ fakeManager := newFakeManager() - gce := GCECloud{manager: fakeManager, managedZones: []string{"zone1"}} + alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{}) + if featureGateErr != nil { + t.Error(featureGateErr) + } + gce := GCECloud{ + manager: fakeManager, + managedZones: []string{"zone1"}, + AlphaFeatureGate: alphaFeatureGate, + } diskName := "disk" diskType := DiskTypeSSD const sizeGb int64 = 128 @@ -290,7 +346,15 @@ func TestGetAutoLabelsForPD_Basic(t *testing.T) { diskType := DiskTypeSSD zone := "us-central1-c" const sizeGb int64 = 128 - gce := GCECloud{manager: fakeManager, managedZones: []string{zone}} + alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{}) + if featureGateErr != nil { + t.Error(featureGateErr) + } + gce := GCECloud{ + manager: fakeManager, + managedZones: []string{zone}, + AlphaFeatureGate: alphaFeatureGate, + } gce.CreateDisk(diskName, diskType, zone, sizeGb, nil) @@ -317,7 +381,15 @@ func TestGetAutoLabelsForPD_NoZone(t *testing.T) { diskType := DiskTypeStandard zone := "europe-west1-d" const sizeGb int64 = 128 - gce := GCECloud{manager: fakeManager, managedZones: []string{zone}} + alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{}) + if featureGateErr != nil { + t.Error(featureGateErr) + } + gce := GCECloud{ + manager: fakeManager, + managedZones: []string{zone}, + AlphaFeatureGate: alphaFeatureGate, + } gce.CreateDisk(diskName, diskType, zone, sizeGb, nil) /* Act */ @@ -375,7 +447,15 @@ func TestGetAutoLabelsForPD_DupDisk(t *testing.T) { zone := "us-west1-b" const sizeGb int64 = 128 - gce := GCECloud{manager: fakeManager, managedZones: []string{"us-west1-b", "asia-southeast1-a"}} + alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{}) + if featureGateErr != nil { + t.Error(featureGateErr) + } + gce := GCECloud{ + manager: fakeManager, + managedZones: []string{"us-west1-b", "asia-southeast1-a"}, + AlphaFeatureGate: alphaFeatureGate, + } for _, zone := range gce.managedZones { gce.CreateDisk(diskName, diskType, zone, sizeGb, nil) } @@ -403,7 +483,15 @@ func TestGetAutoLabelsForPD_DupDiskNoZone(t *testing.T) { diskType := DiskTypeStandard const sizeGb int64 = 128 - gce := GCECloud{manager: fakeManager, managedZones: []string{"us-west1-b", "asia-southeast1-a"}} + alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{}) + if featureGateErr != nil { + t.Error(featureGateErr) + } + gce := GCECloud{ + manager: fakeManager, + managedZones: []string{"us-west1-b", "asia-southeast1-a"}, + AlphaFeatureGate: alphaFeatureGate, + } for _, zone := range gce.managedZones { gce.CreateDisk(diskName, diskType, zone, sizeGb, nil) } @@ -417,16 +505,29 @@ func TestGetAutoLabelsForPD_DupDiskNoZone(t *testing.T) { } } +type targetClientAPI int + +const ( + targetStable targetClientAPI = iota + targetBeta + targetAlpha +) + type FakeServiceManager struct { // Common fields shared among tests - op *compute.Operation // Mocks an operation returned by GCE API calls + targetAPI targetClientAPI + opAlpha *computealpha.Operation // Mocks an operation returned by GCE API calls + opBeta *computebeta.Operation // Mocks an operation returned by GCE API calls + opStable *compute.Operation // Mocks an operation returned by GCE API calls doesOpMatch bool disks map[string]string // zone: diskName waitForZoneOpError error // Error to be returned by WaitForZoneOp // Fields for TestCreateDisk - createDiskCalled bool - diskToCreate *compute.Disk + createDiskCalled bool + diskToCreateAlpha *computealpha.Disk + diskToCreateBeta *computebeta.Disk + diskToCreateStable *compute.Disk // Fields for TestDeleteDisk deleteDiskCalled bool @@ -442,16 +543,93 @@ func newFakeManager() *FakeServiceManager { * to be used by other tested methods. */ func (manager *FakeServiceManager) CreateDisk( - project string, - zone string, - disk *compute.Disk) (*compute.Operation, error) { - + name string, + sizeGb int64, + tagsStr string, + diskTypeURI string, + zone string) (gceObject, error) { manager.createDiskCalled = true - op := &compute.Operation{} - manager.op = op - manager.diskToCreate = disk - manager.disks[zone] = disk.Name - return op, nil + + switch t := manager.targetAPI; t { + case targetStable: + manager.opStable = &compute.Operation{} + diskToCreateV1 := &compute.Disk{ + Name: name, + SizeGb: sizeGb, + Description: tagsStr, + Type: diskTypeURI, + } + manager.diskToCreateStable = diskToCreateV1 + manager.disks[zone] = diskToCreateV1.Name + return manager.opStable, nil + case targetBeta: + manager.opBeta = &computebeta.Operation{} + diskToCreateBeta := &computebeta.Disk{ + Name: name, + SizeGb: sizeGb, + Description: tagsStr, + Type: diskTypeURI, + } + manager.diskToCreateBeta = diskToCreateBeta + manager.disks[zone] = diskToCreateBeta.Name + return manager.opBeta, nil + case targetAlpha: + manager.opAlpha = &computealpha.Operation{} + diskToCreateAlpha := &computealpha.Disk{ + Name: name, + SizeGb: sizeGb, + Description: tagsStr, + Type: diskTypeURI, + } + manager.diskToCreateAlpha = diskToCreateAlpha + manager.disks[zone] = diskToCreateAlpha.Name + return manager.opAlpha, nil + default: + return nil, fmt.Errorf("unexpected type: %T", t) + } +} + +func (manager *FakeServiceManager) AttachDisk( + diskName string, + diskKind string, + diskZone string, + readWrite string, + source string, + diskType string, + instanceName string) (gceObject, error) { + + switch t := manager.targetAPI; t { + case targetStable: + manager.opStable = &compute.Operation{} + return manager.opStable, nil + case targetBeta: + manager.opBeta = &computebeta.Operation{} + return manager.opBeta, nil + case targetAlpha: + manager.opAlpha = &computealpha.Operation{} + return manager.opAlpha, nil + default: + return nil, fmt.Errorf("unexpected type: %T", t) + } +} + +func (manager *FakeServiceManager) DetachDisk( + instanceZone string, + instanceName string, + devicePath string) (gceObject, error) { + switch t := manager.targetAPI; t { + case targetStable: + manager.opStable = &compute.Operation{} + return manager.opStable, nil + case targetBeta: + manager.opBeta = &computebeta.Operation{} + return manager.opBeta, nil + case targetAlpha: + manager.opAlpha = &computealpha.Operation{} + return manager.opAlpha, nil + default: + return nil, fmt.Errorf("unexpected type: %T", t) + } } /** @@ -460,7 +638,7 @@ func (manager *FakeServiceManager) CreateDisk( func (manager *FakeServiceManager) GetDisk( project string, zone string, - diskName string) (*compute.Disk, error) { + diskName string) (*GCEDisk, error) { if manager.disks[zone] == "" { return nil, cloudprovider.DiskNotFound @@ -472,8 +650,12 @@ func (manager *FakeServiceManager) GetDisk( return nil, err } - disk := &compute.Disk{Name: diskName, Zone: zone, Kind: "compute#disk"} - return disk, nil + return &GCEDisk{ + Zone: lastComponent(zone), + Name: diskName, + Kind: "compute#disk", + Type: "type", + }, nil } /** @@ -482,21 +664,45 @@ func (manager *FakeServiceManager) GetDisk( func (manager *FakeServiceManager) DeleteDisk( project string, zone string, - disk string) (*compute.Operation, error) { + disk string) (gceObject, error) { manager.deleteDiskCalled = true - op := &compute.Operation{} - manager.op = op manager.disks[zone] = "" - return op, nil + + switch t := manager.targetAPI; t { + case targetStable: + manager.opStable = &compute.Operation{} + return manager.opStable, nil + case targetBeta: + manager.opBeta = &computebeta.Operation{} + return manager.opBeta, nil + case targetAlpha: + manager.opAlpha = &computealpha.Operation{} + return manager.opAlpha, nil + default: + return nil, fmt.Errorf("unexpected type: %T", t) + } } func (manager *FakeServiceManager) WaitForZoneOp( - op *compute.Operation, + op gceObject, zone string, mc *metricContext) error { - if op == manager.op { - manager.doesOpMatch = true + switch v := op.(type) { + case *computealpha.Operation: + if op.(*computealpha.Operation) == manager.opAlpha { + manager.doesOpMatch = true + } + case *computebeta.Operation: + if op.(*computebeta.Operation) == manager.opBeta { + manager.doesOpMatch = true + } + case *compute.Operation: + if op.(*compute.Operation) == manager.opStable { + manager.doesOpMatch = true + } + default: + return fmt.Errorf("unexpected type: %T", v) } return manager.waitForZoneOpError } diff --git a/test/e2e/e2e.go b/test/e2e/e2e.go index d25f664a819..1a0cbb3f76b 100644 --- a/test/e2e/e2e.go +++ b/test/e2e/e2e.go @@ -78,6 +78,11 @@ func setupProviderConfig() error { managedZones = []string{zone} } + gceAlphaFeatureGate, err := gcecloud.NewAlphaFeatureGate([]string{}) + if err != nil { + glog.Errorf("Encountered error for creating alpha feature gate: %v", err) + } + gceCloud, err := gcecloud.CreateGCECloud(&gcecloud.CloudConfig{ ApiEndpoint: framework.TestContext.CloudConfig.ApiEndpoint, ProjectID: framework.TestContext.CloudConfig.ProjectID, @@ -89,7 +94,8 @@ func setupProviderConfig() error { NodeTags: nil, NodeInstancePrefix: "", TokenSource: nil, - UseMetadataServer: false}) + UseMetadataServer: false, + AlphaFeatureGate: gceAlphaFeatureGate}) if err != nil { return fmt.Errorf("Error building GCE/GKE provider: %v", err)