add neg to gce cloud provider

This commit is contained in:
Minhan Xia 2017-08-21 18:12:27 -07:00
parent 43d2da04f9
commit 039ac28f02
6 changed files with 182 additions and 17 deletions

View File

@ -32,6 +32,7 @@ go_library(
"gce_loadbalancer_external.go", "gce_loadbalancer_external.go",
"gce_loadbalancer_internal.go", "gce_loadbalancer_internal.go",
"gce_loadbalancer_naming.go", "gce_loadbalancer_naming.go",
"gce_networkendpointgroup.go",
"gce_op.go", "gce_op.go",
"gce_routes.go", "gce_routes.go",
"gce_targetpool.go", "gce_targetpool.go",

View File

@ -29,13 +29,16 @@ const (
// tier to use. Currently supports "Standard" and "Premium" (default). // tier to use. Currently supports "Standard" and "Premium" (default).
AlphaFeatureNetworkTiers = "NetworkTiers" AlphaFeatureNetworkTiers = "NetworkTiers"
GCEDiskAlphaFeatureGate = "DiskAlphaAPI" AlphaFeatureGCEDisk = "DiskAlphaAPI"
AlphaFeatureNetworkEndpointGroup = "NetworkEndpointGroup"
) )
// All known alpha features // All known alpha features
var knownAlphaFeatures = map[string]bool{ var knownAlphaFeatures = map[string]bool{
AlphaFeatureNetworkTiers: true, AlphaFeatureNetworkTiers: true,
GCEDiskAlphaFeatureGate: true, AlphaFeatureGCEDisk: true,
AlphaFeatureNetworkEndpointGroup: true,
} }
type AlphaFeatureGate struct { type AlphaFeatureGate struct {
@ -58,3 +61,10 @@ func NewAlphaFeatureGate(features []string) (*AlphaFeatureGate, error) {
} }
return &AlphaFeatureGate{featureMap}, utilerrors.NewAggregate(errList) return &AlphaFeatureGate{featureMap}, utilerrors.NewAggregate(errList)
} }
func (gce *GCECloud) alphaFeatureEnabled(feature string) error {
if !gce.AlphaFeatureGate.Enabled(feature) {
return fmt.Errorf("alpha feature %q is not enabled.", feature)
}
return nil
}

View File

@ -119,7 +119,7 @@ func (manager *gceServiceManager) CreateDiskOnCloudProvider(
return nil, err return nil, err
} }
if manager.gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) { if manager.gce.AlphaFeatureGate.Enabled(AlphaFeatureGCEDisk) {
diskToCreateAlpha := &computealpha.Disk{ diskToCreateAlpha := &computealpha.Disk{
Name: name, Name: name,
SizeGb: sizeGb, SizeGb: sizeGb,
@ -157,7 +157,7 @@ func (manager *gceServiceManager) CreateRegionalDiskOnCloudProvider(
fullyQualifiedReplicaZones = append( fullyQualifiedReplicaZones = append(
fullyQualifiedReplicaZones, manager.getReplicaZoneURI(replicaZone)) fullyQualifiedReplicaZones, manager.getReplicaZoneURI(replicaZone))
} }
if manager.gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) { if manager.gce.AlphaFeatureGate.Enabled(AlphaFeatureGCEDisk) {
diskToCreateAlpha := &computealpha.Disk{ diskToCreateAlpha := &computealpha.Disk{
Name: name, Name: name,
SizeGb: sizeGb, SizeGb: sizeGb,
@ -182,7 +182,7 @@ func (manager *gceServiceManager) AttachDiskOnCloudProvider(
return nil, err return nil, err
} }
if manager.gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) { if manager.gce.AlphaFeatureGate.Enabled(AlphaFeatureGCEDisk) {
attachedDiskAlpha := &computealpha.AttachedDisk{ attachedDiskAlpha := &computealpha.AttachedDisk{
DeviceName: disk.Name, DeviceName: disk.Name,
Kind: disk.Kind, Kind: disk.Kind,
@ -209,7 +209,7 @@ func (manager *gceServiceManager) DetachDiskOnCloudProvider(
instanceZone string, instanceZone string,
instanceName string, instanceName string,
devicePath string) (gceObject, error) { devicePath string) (gceObject, error) {
if manager.gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) { if manager.gce.AlphaFeatureGate.Enabled(AlphaFeatureGCEDisk) {
manager.gce.serviceAlpha.Instances.DetachDisk( manager.gce.serviceAlpha.Instances.DetachDisk(
manager.gce.projectID, instanceZone, instanceName, devicePath).Do() manager.gce.projectID, instanceZone, instanceName, devicePath).Do()
} }
@ -229,7 +229,7 @@ func (manager *gceServiceManager) GetDiskFromCloudProvider(
return nil, fmt.Errorf("Can not fetch disk. Zone is specified (%q). But disk name is empty.", zone) return nil, fmt.Errorf("Can not fetch disk. Zone is specified (%q). But disk name is empty.", zone)
} }
if manager.gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) { if manager.gce.AlphaFeatureGate.Enabled(AlphaFeatureGCEDisk) {
diskAlpha, err := manager.gce.serviceAlpha.Disks.Get( diskAlpha, err := manager.gce.serviceAlpha.Disks.Get(
manager.gce.projectID, zone, diskName).Do() manager.gce.projectID, zone, diskName).Do()
if err != nil { if err != nil {
@ -295,7 +295,7 @@ func (manager *gceServiceManager) GetDiskFromCloudProvider(
func (manager *gceServiceManager) GetRegionalDiskFromCloudProvider( func (manager *gceServiceManager) GetRegionalDiskFromCloudProvider(
diskName string) (*GCEDisk, error) { diskName string) (*GCEDisk, error) {
if manager.gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) { if manager.gce.AlphaFeatureGate.Enabled(AlphaFeatureGCEDisk) {
diskAlpha, err := manager.gce.serviceAlpha.RegionDisks.Get( diskAlpha, err := manager.gce.serviceAlpha.RegionDisks.Get(
manager.gce.projectID, manager.gce.region, diskName).Do() manager.gce.projectID, manager.gce.region, diskName).Do()
if err != nil { if err != nil {
@ -323,7 +323,7 @@ func (manager *gceServiceManager) DeleteDiskOnCloudProvider(
zone string, zone string,
diskName string) (gceObject, error) { diskName string) (gceObject, error) {
if manager.gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) { if manager.gce.AlphaFeatureGate.Enabled(AlphaFeatureGCEDisk) {
return manager.gce.serviceAlpha.Disks.Delete( return manager.gce.serviceAlpha.Disks.Delete(
manager.gce.projectID, zone, diskName).Do() manager.gce.projectID, zone, diskName).Do()
} }
@ -334,7 +334,7 @@ func (manager *gceServiceManager) DeleteDiskOnCloudProvider(
func (manager *gceServiceManager) DeleteRegionalDiskOnCloudProvider( func (manager *gceServiceManager) DeleteRegionalDiskOnCloudProvider(
diskName string) (gceObject, error) { diskName string) (gceObject, error) {
if manager.gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) { if manager.gce.AlphaFeatureGate.Enabled(AlphaFeatureGCEDisk) {
return manager.gce.serviceAlpha.RegionDisks.Delete( return manager.gce.serviceAlpha.RegionDisks.Delete(
manager.gce.projectID, manager.gce.region, diskName).Do() manager.gce.projectID, manager.gce.region, diskName).Do()
} }
@ -354,7 +354,7 @@ func (manager *gceServiceManager) WaitForRegionalOp(
func (manager *gceServiceManager) getDiskSourceURI(disk *GCEDisk) (string, error) { func (manager *gceServiceManager) getDiskSourceURI(disk *GCEDisk) (string, error) {
getProjectsAPIEndpoint := manager.getProjectsAPIEndpoint() getProjectsAPIEndpoint := manager.getProjectsAPIEndpoint()
if manager.gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) { if manager.gce.AlphaFeatureGate.Enabled(AlphaFeatureGCEDisk) {
getProjectsAPIEndpoint = manager.getProjectsAPIEndpointAlpha() getProjectsAPIEndpoint = manager.getProjectsAPIEndpointAlpha()
} }
@ -392,7 +392,7 @@ func (manager *gceServiceManager) getDiskSourceURI(disk *GCEDisk) (string, error
func (manager *gceServiceManager) getDiskTypeURI( func (manager *gceServiceManager) getDiskTypeURI(
diskRegion string, diskZoneInfo zoneType, diskType string) (string, error) { diskRegion string, diskZoneInfo zoneType, diskType string) (string, error) {
getProjectsAPIEndpoint := manager.getProjectsAPIEndpoint() getProjectsAPIEndpoint := manager.getProjectsAPIEndpoint()
if manager.gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) { if manager.gce.AlphaFeatureGate.Enabled(AlphaFeatureGCEDisk) {
getProjectsAPIEndpoint = manager.getProjectsAPIEndpointAlpha() getProjectsAPIEndpoint = manager.getProjectsAPIEndpointAlpha()
} }
@ -425,7 +425,7 @@ func (manager *gceServiceManager) getDiskTypeURI(
func (manager *gceServiceManager) getReplicaZoneURI(zone string) string { func (manager *gceServiceManager) getReplicaZoneURI(zone string) string {
getProjectsAPIEndpoint := manager.getProjectsAPIEndpoint() getProjectsAPIEndpoint := manager.getProjectsAPIEndpoint()
if manager.gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) { if manager.gce.AlphaFeatureGate.Enabled(AlphaFeatureGCEDisk) {
getProjectsAPIEndpoint = manager.getProjectsAPIEndpointAlpha() getProjectsAPIEndpoint = manager.getProjectsAPIEndpointAlpha()
} }
@ -569,7 +569,7 @@ func (gce *GCECloud) AttachDisk(diskName string, nodeName types.NodeName, readOn
// Try fetching as regional PD // Try fetching as regional PD
var disk *GCEDisk var disk *GCEDisk
var mc *metricContext var mc *metricContext
if gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) { if gce.AlphaFeatureGate.Enabled(AlphaFeatureGCEDisk) {
disk, err = gce.getRegionalDiskByName(diskName) disk, err = gce.getRegionalDiskByName(diskName)
if err != nil { if err != nil {
glog.V(5).Infof("Could not find regional PD named %q to Attach. Will look for a zonal PD", diskName) glog.V(5).Infof("Could not find regional PD named %q to Attach. Will look for a zonal PD", diskName)
@ -932,7 +932,7 @@ func (gce *GCECloud) getRegionalDiskByName(diskName string) (*GCEDisk, error) {
// Prefer getDiskByName, if the zone can be established // Prefer getDiskByName, if the zone can be established
// Return cloudprovider.DiskNotFound if the given disk cannot be found in any zone // Return cloudprovider.DiskNotFound if the given disk cannot be found in any zone
func (gce *GCECloud) GetDiskByNameUnknownZone(diskName string) (*GCEDisk, error) { func (gce *GCECloud) GetDiskByNameUnknownZone(diskName string) (*GCEDisk, error) {
if gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) { if gce.AlphaFeatureGate.Enabled(AlphaFeatureGCEDisk) {
regionalDisk, err := gce.getRegionalDiskByName(diskName) regionalDisk, err := gce.getRegionalDiskByName(diskName)
if err == nil { if err == nil {
return regionalDisk, err return regionalDisk, err

View File

@ -96,7 +96,7 @@ func TestCreateRegionalDisk_Basic(t *testing.T) {
gceProjectId := "test-project" gceProjectId := "test-project"
gceRegion := "fake-region" gceRegion := "fake-region"
fakeManager := newFakeManager(gceProjectId, gceRegion) fakeManager := newFakeManager(gceProjectId, gceRegion)
alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{GCEDiskAlphaFeatureGate}) alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{AlphaFeatureGCEDisk})
if featureGateErr != nil { if featureGateErr != nil {
t.Error(featureGateErr) t.Error(featureGateErr)
} }

View File

@ -0,0 +1,148 @@
/*
Copyright 2017 The Kubernetes Authors.
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 gce
import (
"context"
computealpha "google.golang.org/api/compute/v0.alpha"
"strings"
)
const (
NEGLoadBalancerType = "LOAD_BALANCING"
NEGIPPortNetworkEndpointType = "GCE_VM_IP_PORT"
)
func newNetworkEndpointGroupMetricContext(request string, zone string) *metricContext {
return newGenericMetricContext("networkendpointgroup_", request, unusedMetricLabel, zone, computeAlphaVersion)
}
func (gce *GCECloud) GetNetworkEndpointGroup(name string, zone string) (*computealpha.NetworkEndpointGroup, error) {
if err := gce.alphaFeatureEnabled(AlphaFeatureNetworkEndpointGroup); err != nil {
return nil, err
}
mc := newNetworkEndpointGroupMetricContext("get", zone)
v, err := gce.serviceAlpha.NetworkEndpointGroups.Get(gce.ProjectID(), zone, name).Do()
return v, mc.Observe(err)
}
func (gce *GCECloud) ListNetworkEndpointGroup(zone string) ([]*computealpha.NetworkEndpointGroup, error) {
if err := gce.alphaFeatureEnabled(AlphaFeatureNetworkEndpointGroup); err != nil {
return nil, err
}
mc := newNetworkEndpointGroupMetricContext("list", zone)
networkEndpointGroups := []*computealpha.NetworkEndpointGroup{}
err := gce.serviceAlpha.NetworkEndpointGroups.List(gce.ProjectID(), zone).Pages(context.Background(), func(res *computealpha.NetworkEndpointGroupList) error {
networkEndpointGroups = append(networkEndpointGroups, res.Items...)
return nil
})
return networkEndpointGroups, mc.Observe(err)
}
func (gce *GCECloud) AggregatedListNetworkEndpointGroup() (map[string][]*computealpha.NetworkEndpointGroup, error) {
if err := gce.alphaFeatureEnabled(AlphaFeatureNetworkEndpointGroup); err != nil {
return nil, err
}
mc := newNetworkEndpointGroupMetricContext("aggregated_list", "")
zoneNetworkEndpointGroupMap := map[string][]*computealpha.NetworkEndpointGroup{}
err := gce.serviceAlpha.NetworkEndpointGroups.AggregatedList(gce.ProjectID()).Pages(context.Background(), func(res *computealpha.NetworkEndpointGroupAggregatedList) error {
for key, negs := range res.Items {
if len(negs.NetworkEndpointGroups) == 0 {
continue
}
// key has the format of "zones/${zone_name}"
zone := strings.Split(key, "/")[1]
if _, ok := zoneNetworkEndpointGroupMap[zone]; !ok {
zoneNetworkEndpointGroupMap[zone] = []*computealpha.NetworkEndpointGroup{}
}
zoneNetworkEndpointGroupMap[zone] = append(zoneNetworkEndpointGroupMap[zone], negs.NetworkEndpointGroups...)
}
return nil
})
return zoneNetworkEndpointGroupMap, mc.Observe(err)
}
func (gce *GCECloud) CreateNetworkEndpointGroup(neg *computealpha.NetworkEndpointGroup, zone string) error {
if err := gce.alphaFeatureEnabled(AlphaFeatureNetworkEndpointGroup); err != nil {
return err
}
mc := newNetworkEndpointGroupMetricContext("create", zone)
op, err := gce.serviceAlpha.NetworkEndpointGroups.Insert(gce.ProjectID(), zone, neg).Do()
if err != nil {
return mc.Observe(err)
}
return gce.waitForZoneOp(op, zone, mc)
}
func (gce *GCECloud) DeleteNetworkEndpointGroup(name string, zone string) error {
if err := gce.alphaFeatureEnabled(AlphaFeatureNetworkEndpointGroup); err != nil {
return err
}
mc := newNetworkEndpointGroupMetricContext("delete", zone)
op, err := gce.serviceAlpha.NetworkEndpointGroups.Delete(gce.ProjectID(), zone, name).Do()
if err != nil {
return mc.Observe(err)
}
return gce.waitForZoneOp(op, zone, mc)
}
func (gce *GCECloud) AttachNetworkEndpoints(name, zone string, endpoints []*computealpha.NetworkEndpoint) error {
if err := gce.alphaFeatureEnabled(AlphaFeatureNetworkEndpointGroup); err != nil {
return err
}
mc := newNetworkEndpointGroupMetricContext("attach", zone)
op, err := gce.serviceAlpha.NetworkEndpointGroups.AttachNetworkEndpoints(gce.ProjectID(), zone, name, &computealpha.NetworkEndpointGroupsAttachEndpointsRequest{
NetworkEndpoints: endpoints,
}).Do()
if err != nil {
return mc.Observe(err)
}
return gce.waitForZoneOp(op, zone, mc)
}
func (gce *GCECloud) DetachNetworkEndpoints(name, zone string, endpoints []*computealpha.NetworkEndpoint) error {
if err := gce.alphaFeatureEnabled(AlphaFeatureNetworkEndpointGroup); err != nil {
return err
}
mc := newNetworkEndpointGroupMetricContext("detach", zone)
op, err := gce.serviceAlpha.NetworkEndpointGroups.DetachNetworkEndpoints(gce.ProjectID(), zone, name, &computealpha.NetworkEndpointGroupsDetachEndpointsRequest{
NetworkEndpoints: endpoints,
}).Do()
if err != nil {
return mc.Observe(err)
}
return gce.waitForZoneOp(op, zone, mc)
}
func (gce *GCECloud) ListNetworkEndpoints(name, zone string, showHealthStatus bool) ([]*computealpha.NetworkEndpointWithHealthStatus, error) {
if err := gce.alphaFeatureEnabled(AlphaFeatureNetworkEndpointGroup); err != nil {
return nil, err
}
healthStatus := "SKIP"
if showHealthStatus {
healthStatus = "SHOW"
}
mc := newNetworkEndpointGroupMetricContext("list_networkendpoints", zone)
networkEndpoints := []*computealpha.NetworkEndpointWithHealthStatus{}
err := gce.serviceAlpha.NetworkEndpointGroups.ListNetworkEndpoints(gce.ProjectID(), zone, name, &computealpha.NetworkEndpointGroupsListEndpointsRequest{
HealthStatus: healthStatus,
}).Pages(context.Background(), func(res *computealpha.NetworkEndpointGroupsListNetworkEndpoints) error {
networkEndpoints = append(networkEndpoints, res.Items...)
return nil
})
return networkEndpoints, mc.Observe(err)
}

View File

@ -67,6 +67,12 @@ func (mc *metricContext) Observe(err error) error {
} }
func newGenericMetricContext(prefix, request, region, zone, version string) *metricContext { func newGenericMetricContext(prefix, request, region, zone, version string) *metricContext {
if len(zone) == 0 {
zone = unusedMetricLabel
}
if len(region) == 0 {
region = unusedMetricLabel
}
return &metricContext{ return &metricContext{
start: time.Now(), start: time.Now(),
attributes: []string{prefix + "_" + request, region, zone, version}, attributes: []string{prefix + "_" + request, region, zone, version},