Add PodCIDRs API for GCE (Google cloud alpha feature)

pull/6/head
Bowei Du 2017-03-27 13:31:09 -07:00
parent f51b26e502
commit f5be63e0f7
3 changed files with 89 additions and 45 deletions

View File

@ -46,6 +46,7 @@ go_library(
"//vendor:golang.org/x/net/context", "//vendor:golang.org/x/net/context",
"//vendor:golang.org/x/oauth2", "//vendor:golang.org/x/oauth2",
"//vendor:golang.org/x/oauth2/google", "//vendor:golang.org/x/oauth2/google",
"//vendor:google.golang.org/api/compute/v0.alpha",
"//vendor:google.golang.org/api/compute/v1", "//vendor:google.golang.org/api/compute/v1",
"//vendor:google.golang.org/api/container/v1", "//vendor:google.golang.org/api/container/v1",
"//vendor:google.golang.org/api/gensupport", "//vendor:google.golang.org/api/gensupport",

View File

@ -36,6 +36,7 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
"golang.org/x/oauth2" "golang.org/x/oauth2"
"golang.org/x/oauth2/google" "golang.org/x/oauth2/google"
computealpha "google.golang.org/api/compute/v0.alpha"
compute "google.golang.org/api/compute/v1" compute "google.golang.org/api/compute/v1"
container "google.golang.org/api/container/v1" container "google.golang.org/api/container/v1"
"google.golang.org/api/gensupport" "google.golang.org/api/gensupport"
@ -77,6 +78,7 @@ const (
// GCECloud is an implementation of Interface, LoadBalancer and Instances for Google Compute Engine. // GCECloud is an implementation of Interface, LoadBalancer and Instances for Google Compute Engine.
type GCECloud struct { type GCECloud struct {
service *compute.Service service *compute.Service
serviceAlpha *computealpha.Service
containerService *container.Service containerService *container.Service
projectID string projectID string
region string region string
@ -211,43 +213,29 @@ func newGCECloud(config io.Reader) (*GCECloud, error) {
func CreateGCECloud(projectID, region, zone string, managedZones []string, networkURL string, nodeTags []string, func CreateGCECloud(projectID, region, zone string, managedZones []string, networkURL string, nodeTags []string,
nodeInstancePrefix string, tokenSource oauth2.TokenSource, useMetadataServer bool) (*GCECloud, error) { nodeInstancePrefix string, tokenSource oauth2.TokenSource, useMetadataServer bool) (*GCECloud, error) {
if tokenSource == nil { client, err := newOauthClient(tokenSource)
var err error
tokenSource, err = google.DefaultTokenSource(
oauth2.NoContext,
compute.CloudPlatformScope,
compute.ComputeScope)
glog.Infof("Using DefaultTokenSource %#v", tokenSource)
if err != nil {
return nil, err
}
} else {
glog.Infof("Using existing Token Source %#v", tokenSource)
}
if err := wait.PollImmediate(5*time.Second, 30*time.Second, func() (bool, error) {
if _, err := tokenSource.Token(); err != nil {
glog.Errorf("error fetching initial token: %v", err)
return false, nil
}
return true, nil
}); err != nil {
return nil, err
}
client := oauth2.NewClient(oauth2.NoContext, tokenSource)
svc, err := compute.New(client)
if err != nil { if err != nil {
return nil, err return nil, err
} }
containerSvc, err := container.New(client) service, err := compute.New(client)
if err != nil {
return nil, err
}
client, err = newOauthClient(tokenSource)
serviceAlpha, err := computealpha.New(client)
if err != nil {
return nil, err
}
containerService, err := container.New(client)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if networkURL == "" { if networkURL == "" {
networkName, err := getNetworkNameViaAPICall(svc, projectID) networkName, err := getNetworkNameViaAPICall(service, projectID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -255,7 +243,7 @@ func CreateGCECloud(projectID, region, zone string, managedZones []string, netwo
} }
if len(managedZones) == 0 { if len(managedZones) == 0 {
managedZones, err = getZonesForRegion(svc, projectID, region) managedZones, err = getZonesForRegion(service, projectID, region)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -267,8 +255,9 @@ func CreateGCECloud(projectID, region, zone string, managedZones []string, netwo
operationPollRateLimiter := flowcontrol.NewTokenBucketRateLimiter(10, 100) // 10 qps, 100 bucket size. operationPollRateLimiter := flowcontrol.NewTokenBucketRateLimiter(10, 100) // 10 qps, 100 bucket size.
return &GCECloud{ return &GCECloud{
service: svc, service: service,
containerService: containerSvc, serviceAlpha: serviceAlpha,
containerService: containerService,
projectID: projectID, projectID: projectID,
region: region, region: region,
localZone: zone, localZone: zone,
@ -378,3 +367,31 @@ func getZonesForRegion(svc *compute.Service, projectID, region string) ([]string
} }
return zones, nil return zones, nil
} }
func newOauthClient(tokenSource oauth2.TokenSource) (*http.Client, error) {
if tokenSource == nil {
var err error
tokenSource, err = google.DefaultTokenSource(
oauth2.NoContext,
compute.CloudPlatformScope,
compute.ComputeScope)
glog.Infof("Using DefaultTokenSource %#v", tokenSource)
if err != nil {
return nil, err
}
} else {
glog.Infof("Using existing Token Source %#v", tokenSource)
}
if err := wait.PollImmediate(5*time.Second, 30*time.Second, func() (bool, error) {
if _, err := tokenSource.Token(); err != nil {
glog.Errorf("error fetching initial token: %v", err)
return false, nil
}
return true, nil
}); err != nil {
return nil, err
}
return oauth2.NewClient(oauth2.NoContext, tokenSource), nil
}

View File

@ -26,6 +26,7 @@ import (
"cloud.google.com/go/compute/metadata" "cloud.google.com/go/compute/metadata"
"github.com/golang/glog" "github.com/golang/glog"
computealpha "google.golang.org/api/compute/v0.alpha"
compute "google.golang.org/api/compute/v1" compute "google.golang.org/api/compute/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
@ -51,6 +52,20 @@ func (gce *GCECloud) NodeAddresses(_ types.NodeName) ([]v1.NodeAddress, error) {
}, nil }, nil
} }
// This method will not be called from the node that is requesting this ID.
// i.e. metadata service and other local methods cannot be used here
func (gce *GCECloud) NodeAddressesByProviderID(providerID string) ([]v1.NodeAddress, error) {
return []v1.NodeAddress{}, errors.New("unimplemented")
}
// InstanceTypeByProviderID returns the cloudprovider instance type of the node
// with the specified unique providerID This method will not be called from the
// node that is requesting this ID. i.e. metadata service and other local
// methods cannot be used here
func (gce *GCECloud) InstanceTypeByProviderID(providerID string) (string, error) {
return "", errors.New("unimplemented")
}
// ExternalID returns the cloud provider ID of the node with the specified NodeName (deprecated). // ExternalID returns the cloud provider ID of the node with the specified NodeName (deprecated).
func (gce *GCECloud) ExternalID(nodeName types.NodeName) (string, error) { func (gce *GCECloud) ExternalID(nodeName types.NodeName) (string, error) {
instanceName := mapNodeNameToInstanceName(nodeName) instanceName := mapNodeNameToInstanceName(nodeName)
@ -202,6 +217,31 @@ func (gce *GCECloud) CurrentNodeName(hostname string) (types.NodeName, error) {
return types.NodeName(hostname), nil return types.NodeName(hostname), nil
} }
// PodCIDRs returns a list of CIDR ranges that are assigned to the
// `node` for allocation to pods. Returns a list of the form
// "<ip>/<netmask>".
func (gce *GCECloud) PodCIDRs(nodeName types.NodeName) (cidrs []string, err error) {
var instance *gceInstance
instance, err = gce.getInstanceByName(mapNodeNameToInstanceName(nodeName))
if err != nil {
return
}
var res *computealpha.Instance
res, err = gce.serviceAlpha.Instances.Get(
gce.projectID, instance.Zone, instance.Name).Do()
if err != nil {
return
}
for _, networkInterface := range res.NetworkInterfaces {
for _, aliasIpRange := range networkInterface.AliasIpRanges {
cidrs = append(cidrs, aliasIpRange.IpCidrRange)
}
}
return
}
// Gets the named instances, returning cloudprovider.InstanceNotFound if any instance is not found // Gets the named instances, returning cloudprovider.InstanceNotFound if any instance is not found
func (gce *GCECloud) getInstancesByNames(names []string) ([]*gceInstance, error) { func (gce *GCECloud) getInstancesByNames(names []string) ([]*gceInstance, error) {
instances := make(map[string]*gceInstance) instances := make(map[string]*gceInstance)
@ -351,17 +391,3 @@ func (gce *GCECloud) isCurrentInstance(instanceID string) bool {
return currentInstanceID == canonicalizeInstanceName(instanceID) return currentInstanceID == canonicalizeInstanceName(instanceID)
} }
// NodeAddressesByProviderID returns the node addresses of an instances with the specified unique providerID
// This method will not be called from the node that is requesting this ID. i.e. metadata service
// and other local methods cannot be used here
func (gce *GCECloud) NodeAddressesByProviderID(providerID string) ([]v1.NodeAddress, error) {
return []v1.NodeAddress{}, errors.New("unimplemented")
}
// InstanceTypeByProviderID returns the cloudprovider instance type of the node with the specified unique providerID
// This method will not be called from the node that is requesting this ID. i.e. metadata service
// and other local methods cannot be used here
func (gce *GCECloud) InstanceTypeByProviderID(providerID string) (string, error) {
return "", errors.New("unimplemented")
}