Merge pull request #69042 from rramkumar1/fake-gce-1
Expose public function to init fake GCECloud + add common hooks
This commit is contained in:
commit
f0311b52b3
@ -20,6 +20,7 @@ go_library(
|
||||
"gce_clusterid.go",
|
||||
"gce_clusters.go",
|
||||
"gce_disks.go",
|
||||
"gce_fake.go",
|
||||
"gce_firewall.go",
|
||||
"gce_forwardingrule.go",
|
||||
"gce_healthchecks.go",
|
||||
@ -50,6 +51,7 @@ go_library(
|
||||
"//pkg/cloudprovider/providers/gce/cloud:go_default_library",
|
||||
"//pkg/cloudprovider/providers/gce/cloud/filter:go_default_library",
|
||||
"//pkg/cloudprovider/providers/gce/cloud/meta:go_default_library",
|
||||
"//pkg/cloudprovider/providers/gce/cloud/mock:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/features:go_default_library",
|
||||
"//pkg/kubelet/apis:go_default_library",
|
||||
@ -120,7 +122,6 @@ go_test(
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/tools/cache:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/tools/record:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/require:go_default_library",
|
||||
|
@ -44,6 +44,8 @@ var (
|
||||
InUseError = &googleapi.Error{Code: http.StatusBadRequest, Message: "It's being used by god."}
|
||||
// InternalServerError is shared variable with error code StatusInternalServerError for error verification.
|
||||
InternalServerError = &googleapi.Error{Code: http.StatusInternalServerError}
|
||||
// UnauthorizedErr wraps a Google API error with code StatusForbidden.
|
||||
UnauthorizedErr = &googleapi.Error{Code: http.StatusForbidden}
|
||||
)
|
||||
|
||||
// gceObject is an abstraction of all GCE API object in go client
|
||||
@ -436,6 +438,63 @@ func UpdateRegionBackendServiceHook(ctx context.Context, key *meta.Key, obj *ga.
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateBackendServiceHook defines the hook for updating a BackendService.
|
||||
// It replaces the object with the same key in the mock with the updated object.
|
||||
func UpdateBackendServiceHook(ctx context.Context, key *meta.Key, obj *ga.BackendService, m *cloud.MockBackendServices) error {
|
||||
_, err := m.Get(ctx, key)
|
||||
if err != nil {
|
||||
return &googleapi.Error{
|
||||
Code: http.StatusNotFound,
|
||||
Message: fmt.Sprintf("Key: %s was not found in BackendServices", key.String()),
|
||||
}
|
||||
}
|
||||
|
||||
obj.Name = key.Name
|
||||
projectID := m.ProjectRouter.ProjectID(ctx, "ga", "backendServices")
|
||||
obj.SelfLink = cloud.SelfLink(meta.VersionGA, projectID, "backendServices", key)
|
||||
|
||||
m.Objects[*key] = &cloud.MockBackendServicesObj{Obj: obj}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateAlphaBackendServiceHook defines the hook for updating an alpha BackendService.
|
||||
// It replaces the object with the same key in the mock with the updated object.
|
||||
func UpdateAlphaBackendServiceHook(ctx context.Context, key *meta.Key, obj *alpha.BackendService, m *cloud.MockAlphaBackendServices) error {
|
||||
_, err := m.Get(ctx, key)
|
||||
if err != nil {
|
||||
return &googleapi.Error{
|
||||
Code: http.StatusNotFound,
|
||||
Message: fmt.Sprintf("Key: %s was not found in BackendServices", key.String()),
|
||||
}
|
||||
}
|
||||
|
||||
obj.Name = key.Name
|
||||
projectID := m.ProjectRouter.ProjectID(ctx, "alpha", "backendServices")
|
||||
obj.SelfLink = cloud.SelfLink(meta.VersionAlpha, projectID, "backendServices", key)
|
||||
|
||||
m.Objects[*key] = &cloud.MockBackendServicesObj{Obj: obj}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateURLMapHook defines the hook for updating a UrlMap.
|
||||
// It replaces the object with the same key in the mock with the updated object.
|
||||
func UpdateURLMapHook(ctx context.Context, key *meta.Key, obj *ga.UrlMap, m *cloud.MockUrlMaps) error {
|
||||
_, err := m.Get(ctx, key)
|
||||
if err != nil {
|
||||
return &googleapi.Error{
|
||||
Code: http.StatusNotFound,
|
||||
Message: fmt.Sprintf("Key: %s was not found in UrlMaps", key.String()),
|
||||
}
|
||||
}
|
||||
|
||||
obj.Name = key.Name
|
||||
projectID := m.ProjectRouter.ProjectID(ctx, "ga", "urlMaps")
|
||||
obj.SelfLink = cloud.SelfLink(meta.VersionGA, projectID, "urlMaps", key)
|
||||
|
||||
m.Objects[*key] = &cloud.MockUrlMapsObj{Obj: obj}
|
||||
return nil
|
||||
}
|
||||
|
||||
// InsertFirewallsUnauthorizedErrHook mocks firewall insertion. A forbidden error will be thrown as return.
|
||||
func InsertFirewallsUnauthorizedErrHook(ctx context.Context, key *meta.Key, obj *ga.Firewall, m *cloud.MockFirewalls) (bool, error) {
|
||||
return true, &googleapi.Error{Code: http.StatusForbidden}
|
||||
@ -496,6 +555,16 @@ func DeleteAddressesInternalErrHook(ctx context.Context, key *meta.Key, m *cloud
|
||||
return true, InternalServerError
|
||||
}
|
||||
|
||||
// InsertAlphaBackendServiceUnauthorizedErrHook mocks inserting an alpha BackendService and returns a forbidden error.
|
||||
func InsertAlphaBackendServiceUnauthorizedErrHook(ctx context.Context, key *meta.Key, obj *alpha.BackendService, m *cloud.MockAlphaBackendServices) (bool, error) {
|
||||
return true, UnauthorizedErr
|
||||
}
|
||||
|
||||
// UpdateAlphaBackendServiceUnauthorizedErrHook mocks updating an alpha BackendService and returns a forbidden error.
|
||||
func UpdateAlphaBackendServiceUnauthorizedErrHook(ctx context.Context, key *meta.Key, obj *alpha.BackendService, m *cloud.MockAlphaBackendServices) error {
|
||||
return UnauthorizedErr
|
||||
}
|
||||
|
||||
// GetRegionBackendServicesErrHook mocks getting region backend service and returns an internal server error.
|
||||
func GetRegionBackendServicesErrHook(ctx context.Context, key *meta.Key, m *cloud.MockRegionBackendServices) (bool, *ga.BackendService, error) {
|
||||
return true, nil, InternalServerError
|
||||
|
83
pkg/cloudprovider/providers/gce/gce_fake.go
Normal file
83
pkg/cloudprovider/providers/gce/gce_fake.go
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
Copyright 2018 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 (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
compute "google.golang.org/api/compute/v1"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/kubernetes/pkg/cloudprovider/providers/gce/cloud"
|
||||
)
|
||||
|
||||
type TestClusterValues struct {
|
||||
ProjectID string
|
||||
Region string
|
||||
ZoneName string
|
||||
SecondaryZoneName string
|
||||
ClusterID string
|
||||
ClusterName string
|
||||
}
|
||||
|
||||
func DefaultTestClusterValues() TestClusterValues {
|
||||
return TestClusterValues{
|
||||
ProjectID: "test-project",
|
||||
Region: "us-central1",
|
||||
ZoneName: "us-central1-b",
|
||||
SecondaryZoneName: "us-central1-c",
|
||||
ClusterID: "test-cluster-id",
|
||||
ClusterName: "Test Cluster Name",
|
||||
}
|
||||
}
|
||||
|
||||
func FakeGCECloud(vals TestClusterValues) *GCECloud {
|
||||
return simpleFakeGCECloud(vals)
|
||||
}
|
||||
|
||||
type fakeRoundTripper struct{}
|
||||
|
||||
func (*fakeRoundTripper) RoundTrip(*http.Request) (*http.Response, error) {
|
||||
return nil, fmt.Errorf("err: test used fake http client")
|
||||
}
|
||||
|
||||
// Stubs ClusterID so that ClusterID.getOrInitialize() does not require calling
|
||||
// gce.Initialize()
|
||||
func fakeClusterID(clusterID string) ClusterID {
|
||||
return ClusterID{
|
||||
clusterID: &clusterID,
|
||||
store: cache.NewStore(func(obj interface{}) (string, error) {
|
||||
return "", nil
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
func simpleFakeGCECloud(vals TestClusterValues) *GCECloud {
|
||||
client := &http.Client{Transport: &fakeRoundTripper{}}
|
||||
service, _ := compute.New(client)
|
||||
gce := &GCECloud{
|
||||
region: vals.Region,
|
||||
service: service,
|
||||
managedZones: []string{vals.ZoneName},
|
||||
projectID: vals.ProjectID,
|
||||
networkProjectID: vals.ProjectID,
|
||||
ClusterID: fakeClusterID(vals.ClusterID),
|
||||
}
|
||||
c := cloud.NewMockGCE(&gceProjectRouter{gce})
|
||||
gce.c = c
|
||||
return gce
|
||||
}
|
@ -23,9 +23,7 @@ package gce
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -35,12 +33,9 @@ import (
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/tools/record"
|
||||
v1_service "k8s.io/kubernetes/pkg/api/v1/service"
|
||||
"k8s.io/kubernetes/pkg/cloudprovider/providers/gce/cloud"
|
||||
"k8s.io/kubernetes/pkg/cloudprovider/providers/gce/cloud/meta"
|
||||
"k8s.io/kubernetes/pkg/cloudprovider/providers/gce/cloud/mock"
|
||||
kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
|
||||
)
|
||||
|
||||
@ -54,26 +49,6 @@ const (
|
||||
errStrUnsupportedTier = "unsupported network tier: \"" + wrongTier + "\""
|
||||
)
|
||||
|
||||
type TestClusterValues struct {
|
||||
ProjectID string
|
||||
Region string
|
||||
ZoneName string
|
||||
SecondaryZoneName string
|
||||
ClusterID string
|
||||
ClusterName string
|
||||
}
|
||||
|
||||
func DefaultTestClusterValues() TestClusterValues {
|
||||
return TestClusterValues{
|
||||
ProjectID: "test-project",
|
||||
Region: "us-central1",
|
||||
ZoneName: "us-central1-b",
|
||||
SecondaryZoneName: "us-central1-c",
|
||||
ClusterID: "test-cluster-id",
|
||||
ClusterName: "Test Cluster Name",
|
||||
}
|
||||
}
|
||||
|
||||
func fakeLoadbalancerService(lbType string) *v1.Service {
|
||||
return &v1.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
@ -92,73 +67,6 @@ var (
|
||||
FilewallChangeMsg = fmt.Sprintf("%s %s %s", v1.EventTypeNormal, eventReasonManualChange, eventMsgFirewallChange)
|
||||
)
|
||||
|
||||
type fakeRoundTripper struct{}
|
||||
|
||||
func (*fakeRoundTripper) RoundTrip(*http.Request) (*http.Response, error) {
|
||||
return nil, fmt.Errorf("err: test used fake http client")
|
||||
}
|
||||
|
||||
func fakeGCECloud(vals TestClusterValues) (*GCECloud, error) {
|
||||
client := &http.Client{Transport: &fakeRoundTripper{}}
|
||||
|
||||
service, err := compute.New(client)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Used in disk unit tests
|
||||
fakeManager := newFakeManager(vals.ProjectID, vals.Region)
|
||||
zonesWithNodes := createNodeZones([]string{vals.ZoneName})
|
||||
|
||||
alphaFeatureGate := NewAlphaFeatureGate([]string{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
gce := &GCECloud{
|
||||
region: vals.Region,
|
||||
service: service,
|
||||
manager: fakeManager,
|
||||
managedZones: []string{vals.ZoneName},
|
||||
projectID: vals.ProjectID,
|
||||
networkProjectID: vals.ProjectID,
|
||||
AlphaFeatureGate: alphaFeatureGate,
|
||||
nodeZones: zonesWithNodes,
|
||||
nodeInformerSynced: func() bool { return true },
|
||||
ClusterID: fakeClusterID(vals.ClusterID),
|
||||
}
|
||||
|
||||
c := cloud.NewMockGCE(&gceProjectRouter{gce})
|
||||
c.MockTargetPools.AddInstanceHook = mock.AddInstanceHook
|
||||
c.MockTargetPools.RemoveInstanceHook = mock.RemoveInstanceHook
|
||||
c.MockForwardingRules.InsertHook = mock.InsertFwdRuleHook
|
||||
c.MockAddresses.InsertHook = mock.InsertAddressHook
|
||||
c.MockAlphaAddresses.InsertHook = mock.InsertAlphaAddressHook
|
||||
c.MockAlphaAddresses.X = mock.AddressAttributes{}
|
||||
c.MockAddresses.X = mock.AddressAttributes{}
|
||||
|
||||
c.MockInstanceGroups.X = mock.InstanceGroupAttributes{
|
||||
InstanceMap: make(map[meta.Key]map[string]*compute.InstanceWithNamedPorts),
|
||||
Lock: &sync.Mutex{},
|
||||
}
|
||||
c.MockInstanceGroups.AddInstancesHook = mock.AddInstancesHook
|
||||
c.MockInstanceGroups.RemoveInstancesHook = mock.RemoveInstancesHook
|
||||
c.MockInstanceGroups.ListInstancesHook = mock.ListInstancesHook
|
||||
|
||||
c.MockRegionBackendServices.UpdateHook = mock.UpdateRegionBackendServiceHook
|
||||
c.MockHealthChecks.UpdateHook = mock.UpdateHealthCheckHook
|
||||
c.MockFirewalls.UpdateHook = mock.UpdateFirewallHook
|
||||
|
||||
keyGA := meta.GlobalKey("key-ga")
|
||||
c.MockZones.Objects[*keyGA] = &cloud.MockZonesObj{
|
||||
Obj: &compute.Zone{Name: vals.ZoneName, Region: gce.getRegionLink(vals.Region)},
|
||||
}
|
||||
|
||||
gce.c = c
|
||||
|
||||
return gce, nil
|
||||
}
|
||||
|
||||
func createAndInsertNodes(gce *GCECloud, nodeNames []string, zoneName string) ([]*v1.Node, error) {
|
||||
nodes := []*v1.Node{}
|
||||
|
||||
@ -208,17 +116,6 @@ func createAndInsertNodes(gce *GCECloud, nodeNames []string, zoneName string) ([
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
// Stubs ClusterID so that ClusterID.getOrInitialize() does not require calling
|
||||
// gce.Initialize()
|
||||
func fakeClusterID(clusterID string) ClusterID {
|
||||
return ClusterID{
|
||||
clusterID: &clusterID,
|
||||
store: cache.NewStore(func(obj interface{}) (string, error) {
|
||||
return "", nil
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
func assertExternalLbResources(t *testing.T, gce *GCECloud, apiService *v1.Service, vals TestClusterValues, nodeNames []string) {
|
||||
lbName := gce.GetLoadBalancerName(context.TODO(), "", apiService)
|
||||
hcName := MakeNodesHealthCheckName(vals.ClusterID)
|
||||
|
@ -24,17 +24,55 @@ import (
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/kubernetes/pkg/cloudprovider/providers/gce/cloud"
|
||||
"k8s.io/kubernetes/pkg/cloudprovider/providers/gce/cloud/meta"
|
||||
"k8s.io/kubernetes/pkg/cloudprovider/providers/gce/cloud/mock"
|
||||
|
||||
"cloud.google.com/go/compute/metadata"
|
||||
compute "google.golang.org/api/compute/v1"
|
||||
"google.golang.org/api/googleapi"
|
||||
)
|
||||
|
||||
func fakeGCECloud(vals TestClusterValues) (*GCECloud, error) {
|
||||
gce := simpleFakeGCECloud(vals)
|
||||
|
||||
gce.AlphaFeatureGate = NewAlphaFeatureGate([]string{})
|
||||
gce.nodeInformerSynced = func() bool { return true }
|
||||
|
||||
mockGCE := gce.c.(*cloud.MockGCE)
|
||||
mockGCE.MockTargetPools.AddInstanceHook = mock.AddInstanceHook
|
||||
mockGCE.MockTargetPools.RemoveInstanceHook = mock.RemoveInstanceHook
|
||||
mockGCE.MockForwardingRules.InsertHook = mock.InsertFwdRuleHook
|
||||
mockGCE.MockAddresses.InsertHook = mock.InsertAddressHook
|
||||
mockGCE.MockAlphaAddresses.InsertHook = mock.InsertAlphaAddressHook
|
||||
mockGCE.MockAlphaAddresses.X = mock.AddressAttributes{}
|
||||
mockGCE.MockAddresses.X = mock.AddressAttributes{}
|
||||
|
||||
mockGCE.MockInstanceGroups.X = mock.InstanceGroupAttributes{
|
||||
InstanceMap: make(map[meta.Key]map[string]*compute.InstanceWithNamedPorts),
|
||||
Lock: &sync.Mutex{},
|
||||
}
|
||||
mockGCE.MockInstanceGroups.AddInstancesHook = mock.AddInstancesHook
|
||||
mockGCE.MockInstanceGroups.RemoveInstancesHook = mock.RemoveInstancesHook
|
||||
mockGCE.MockInstanceGroups.ListInstancesHook = mock.ListInstancesHook
|
||||
|
||||
mockGCE.MockRegionBackendServices.UpdateHook = mock.UpdateRegionBackendServiceHook
|
||||
mockGCE.MockHealthChecks.UpdateHook = mock.UpdateHealthCheckHook
|
||||
mockGCE.MockFirewalls.UpdateHook = mock.UpdateFirewallHook
|
||||
|
||||
keyGA := meta.GlobalKey("key-ga")
|
||||
mockGCE.MockZones.Objects[*keyGA] = &cloud.MockZonesObj{
|
||||
Obj: &compute.Zone{Name: vals.ZoneName, Region: gce.getRegionLink(vals.Region)},
|
||||
}
|
||||
|
||||
return gce, nil
|
||||
}
|
||||
|
||||
type gceInstance struct {
|
||||
Zone string
|
||||
Name string
|
||||
|
Loading…
Reference in New Issue
Block a user