add neg to gce cloud provider

pull/6/head
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_internal.go",
"gce_loadbalancer_naming.go",
"gce_networkendpointgroup.go",
"gce_op.go",
"gce_routes.go",
"gce_targetpool.go",

View File

@ -29,13 +29,16 @@ const (
// tier to use. Currently supports "Standard" and "Premium" (default).
AlphaFeatureNetworkTiers = "NetworkTiers"
GCEDiskAlphaFeatureGate = "DiskAlphaAPI"
AlphaFeatureGCEDisk = "DiskAlphaAPI"
AlphaFeatureNetworkEndpointGroup = "NetworkEndpointGroup"
)
// All known alpha features
var knownAlphaFeatures = map[string]bool{
AlphaFeatureNetworkTiers: true,
GCEDiskAlphaFeatureGate: true,
AlphaFeatureNetworkTiers: true,
AlphaFeatureGCEDisk: true,
AlphaFeatureNetworkEndpointGroup: true,
}
type AlphaFeatureGate struct {
@ -58,3 +61,10 @@ func NewAlphaFeatureGate(features []string) (*AlphaFeatureGate, error) {
}
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
}
if manager.gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) {
if manager.gce.AlphaFeatureGate.Enabled(AlphaFeatureGCEDisk) {
diskToCreateAlpha := &computealpha.Disk{
Name: name,
SizeGb: sizeGb,
@ -157,7 +157,7 @@ func (manager *gceServiceManager) CreateRegionalDiskOnCloudProvider(
fullyQualifiedReplicaZones = append(
fullyQualifiedReplicaZones, manager.getReplicaZoneURI(replicaZone))
}
if manager.gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) {
if manager.gce.AlphaFeatureGate.Enabled(AlphaFeatureGCEDisk) {
diskToCreateAlpha := &computealpha.Disk{
Name: name,
SizeGb: sizeGb,
@ -182,7 +182,7 @@ func (manager *gceServiceManager) AttachDiskOnCloudProvider(
return nil, err
}
if manager.gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) {
if manager.gce.AlphaFeatureGate.Enabled(AlphaFeatureGCEDisk) {
attachedDiskAlpha := &computealpha.AttachedDisk{
DeviceName: disk.Name,
Kind: disk.Kind,
@ -209,7 +209,7 @@ func (manager *gceServiceManager) DetachDiskOnCloudProvider(
instanceZone string,
instanceName string,
devicePath string) (gceObject, error) {
if manager.gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) {
if manager.gce.AlphaFeatureGate.Enabled(AlphaFeatureGCEDisk) {
manager.gce.serviceAlpha.Instances.DetachDisk(
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)
}
if manager.gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) {
if manager.gce.AlphaFeatureGate.Enabled(AlphaFeatureGCEDisk) {
diskAlpha, err := manager.gce.serviceAlpha.Disks.Get(
manager.gce.projectID, zone, diskName).Do()
if err != nil {
@ -295,7 +295,7 @@ func (manager *gceServiceManager) GetDiskFromCloudProvider(
func (manager *gceServiceManager) GetRegionalDiskFromCloudProvider(
diskName string) (*GCEDisk, error) {
if manager.gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) {
if manager.gce.AlphaFeatureGate.Enabled(AlphaFeatureGCEDisk) {
diskAlpha, err := manager.gce.serviceAlpha.RegionDisks.Get(
manager.gce.projectID, manager.gce.region, diskName).Do()
if err != nil {
@ -323,7 +323,7 @@ func (manager *gceServiceManager) DeleteDiskOnCloudProvider(
zone string,
diskName string) (gceObject, error) {
if manager.gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) {
if manager.gce.AlphaFeatureGate.Enabled(AlphaFeatureGCEDisk) {
return manager.gce.serviceAlpha.Disks.Delete(
manager.gce.projectID, zone, diskName).Do()
}
@ -334,7 +334,7 @@ func (manager *gceServiceManager) DeleteDiskOnCloudProvider(
func (manager *gceServiceManager) DeleteRegionalDiskOnCloudProvider(
diskName string) (gceObject, error) {
if manager.gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) {
if manager.gce.AlphaFeatureGate.Enabled(AlphaFeatureGCEDisk) {
return manager.gce.serviceAlpha.RegionDisks.Delete(
manager.gce.projectID, manager.gce.region, diskName).Do()
}
@ -354,7 +354,7 @@ func (manager *gceServiceManager) WaitForRegionalOp(
func (manager *gceServiceManager) getDiskSourceURI(disk *GCEDisk) (string, error) {
getProjectsAPIEndpoint := manager.getProjectsAPIEndpoint()
if manager.gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) {
if manager.gce.AlphaFeatureGate.Enabled(AlphaFeatureGCEDisk) {
getProjectsAPIEndpoint = manager.getProjectsAPIEndpointAlpha()
}
@ -392,7 +392,7 @@ func (manager *gceServiceManager) getDiskSourceURI(disk *GCEDisk) (string, error
func (manager *gceServiceManager) getDiskTypeURI(
diskRegion string, diskZoneInfo zoneType, diskType string) (string, error) {
getProjectsAPIEndpoint := manager.getProjectsAPIEndpoint()
if manager.gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) {
if manager.gce.AlphaFeatureGate.Enabled(AlphaFeatureGCEDisk) {
getProjectsAPIEndpoint = manager.getProjectsAPIEndpointAlpha()
}
@ -425,7 +425,7 @@ func (manager *gceServiceManager) getDiskTypeURI(
func (manager *gceServiceManager) getReplicaZoneURI(zone string) string {
getProjectsAPIEndpoint := manager.getProjectsAPIEndpoint()
if manager.gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) {
if manager.gce.AlphaFeatureGate.Enabled(AlphaFeatureGCEDisk) {
getProjectsAPIEndpoint = manager.getProjectsAPIEndpointAlpha()
}
@ -569,7 +569,7 @@ func (gce *GCECloud) AttachDisk(diskName string, nodeName types.NodeName, readOn
// Try fetching as regional PD
var disk *GCEDisk
var mc *metricContext
if gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) {
if gce.AlphaFeatureGate.Enabled(AlphaFeatureGCEDisk) {
disk, err = gce.getRegionalDiskByName(diskName)
if err != nil {
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
// Return cloudprovider.DiskNotFound if the given disk cannot be found in any zone
func (gce *GCECloud) GetDiskByNameUnknownZone(diskName string) (*GCEDisk, error) {
if gce.AlphaFeatureGate.Enabled(GCEDiskAlphaFeatureGate) {
if gce.AlphaFeatureGate.Enabled(AlphaFeatureGCEDisk) {
regionalDisk, err := gce.getRegionalDiskByName(diskName)
if err == nil {
return regionalDisk, err

View File

@ -96,7 +96,7 @@ func TestCreateRegionalDisk_Basic(t *testing.T) {
gceProjectId := "test-project"
gceRegion := "fake-region"
fakeManager := newFakeManager(gceProjectId, gceRegion)
alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{GCEDiskAlphaFeatureGate})
alphaFeatureGate, featureGateErr := NewAlphaFeatureGate([]string{AlphaFeatureGCEDisk})
if featureGateErr != nil {
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 {
if len(zone) == 0 {
zone = unusedMetricLabel
}
if len(region) == 0 {
region = unusedMetricLabel
}
return &metricContext{
start: time.Now(),
attributes: []string{prefix + "_" + request, region, zone, version},