Skip to content

Commit 08e6cdd

Browse files
committed
Handle Multiple Projects For MIG Cache
1 parent 45d513d commit 08e6cdd

File tree

3 files changed

+51
-6
lines changed

3 files changed

+51
-6
lines changed

cluster-autoscaler/cloudprovider/gce/gce_manager_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ const listInstanceGroupManagerResponsePartTemplate = `
253253
}
254254
}
255255
],
256-
"instanceGroup": "https://www.googleapis.com/compute/v1/projects/lukaszos-gke-dev2/zones/%v/instanceGroups/%v",
256+
"instanceGroup": "https://www.googleapis.com/compute/v1/projects/project1/zones/%v/instanceGroups/%v",
257257
"baseInstanceName": "%s",
258258
"fingerprint": "ASJwTpesjDI=",
259259
"currentActions": {
@@ -271,7 +271,7 @@ const listInstanceGroupManagerResponsePartTemplate = `
271271
"isStable": true
272272
},
273273
"targetSize": %v,
274-
"selfLink": "https://www.googleapis.com/compute/v1/projects/lukaszos-gke-dev2/zones/us-west1-b/instanceGroupManagers/gke-blah-default-pool-67b773a0-grp",
274+
"selfLink": "https://www.googleapis.com/compute/v1/projects/project1/zones/us-west1-b/instanceGroupManagers/gke-blah-default-pool-67b773a0-grp",
275275
"updatePolicy": {
276276
"type": "OPPORTUNISTIC",
277277
"minimalAction": "REPLACE",

cluster-autoscaler/cloudprovider/gce/mig_info_provider.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"fmt"
2222
"net/url"
2323
"path"
24+
"regexp"
2425
"strings"
2526
"sync"
2627
"time"
@@ -62,6 +63,11 @@ type timeProvider interface {
6263
Now() time.Time
6364
}
6465

66+
var (
67+
// Compile a regular expression to find the text between "projects/" and the next "/".
68+
migProjectSelfLinkRe = regexp.MustCompile(`projects/([^/]+)`)
69+
)
70+
6571
type cachingMigInfoProvider struct {
6672
migInfoMutex sync.Mutex
6773
cache *GceCache
@@ -479,8 +485,13 @@ func (c *cachingMigInfoProvider) fillMigInfoCache() error {
479485

480486
for idx, zone := range zones {
481487
for _, zoneMig := range migs[idx] {
488+
projectId, err := extractProjectWithRegex(zoneMig.SelfLink)
489+
if err != nil {
490+
klog.Errorf("Unable to extract projectID from MIG self link: %s, err: %v", zoneMig.SelfLink, err)
491+
projectId = c.projectId
492+
}
482493
zoneMigRef := GceRef{
483-
c.projectId,
494+
projectId,
484495
zone,
485496
zoneMig.Name,
486497
}
@@ -508,6 +519,19 @@ func (c *cachingMigInfoProvider) fillMigInfoCache() error {
508519
return nil
509520
}
510521

522+
// extractProjectWithRegex uses a regular expression to find and return the project name
523+
// from the selfLink of a MIG.
524+
func extractProjectWithRegex(selflink string) (string, error) {
525+
// FindStringSubmatch returns an array with the full match and all captured groups.
526+
// matches[0] will be the full matched string (e.g., "/projects/some-project").
527+
// matches[1] will be the content of the first capturing group (e.g., "some-project").
528+
matches := migProjectSelfLinkRe.FindStringSubmatch(selflink)
529+
if len(matches) < 2 {
530+
return "", fmt.Errorf("could not find project name in self link: %s", selflink)
531+
}
532+
return matches[1], nil
533+
}
534+
511535
func (c *cachingMigInfoProvider) getRegisteredMigRefs() map[GceRef]bool {
512536
migRefs := make(map[GceRef]bool)
513537
for _, mig := range c.migLister.GetMigs() {

cluster-autoscaler/cloudprovider/gce/mig_info_provider_test.go

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -787,11 +787,19 @@ func TestGetMigTargetSize(t *testing.T) {
787787
Zone: mig.GceRef().Zone,
788788
Name: mig.GceRef().Name,
789789
TargetSize: targetSize,
790+
SelfLink: fmt.Sprintf("projects/%s/zones/%s/instanceGroups/%s", mig.GceRef().Project, mig.GceRef().Zone, mig.GceRef().Name),
791+
}
792+
instanceGroupManager1 := &gce.InstanceGroupManager{
793+
Zone: mig1.GceRef().Zone,
794+
Name: mig1.GceRef().Name,
795+
TargetSize: targetSize,
796+
SelfLink: fmt.Sprintf("projects/%s/zones/%s/instanceGroups/%s", mig1.GceRef().Project, mig1.GceRef().Zone, mig1.GceRef().Name),
790797
}
791798

792799
testCases := []struct {
793800
name string
794801
cache *GceCache
802+
migQuery *gceMig
795803
fetchMigs func(string) ([]*gce.InstanceGroupManager, error)
796804
fetchMigTargetSize func(GceRef) (int64, error)
797805
expectedTargetSize int64
@@ -804,40 +812,53 @@ func TestGetMigTargetSize(t *testing.T) {
804812
migTargetSizeCache: map[GceRef]int64{mig.GceRef(): targetSize},
805813
},
806814
expectedTargetSize: targetSize,
815+
migQuery: mig,
807816
},
808817
{
809818
name: "target size from cache fill",
810819
cache: emptyCache(),
811820
fetchMigs: fetchMigsConst([]*gce.InstanceGroupManager{instanceGroupManager}),
812821
expectedTargetSize: targetSize,
822+
migQuery: mig,
823+
},
824+
{
825+
name: "target size from cache fill, multiple MIG projects",
826+
cache: emptyCache(),
827+
fetchMigs: fetchMigsConst([]*gce.InstanceGroupManager{instanceGroupManager, instanceGroupManager1}),
828+
expectedTargetSize: targetSize,
829+
migQuery: mig1,
813830
},
814831
{
815832
name: "cache fill without mig, fallback success",
816833
cache: emptyCache(),
817834
fetchMigs: fetchMigsConst([]*gce.InstanceGroupManager{}),
818835
fetchMigTargetSize: fetchMigTargetSizeConst(targetSize),
819836
expectedTargetSize: targetSize,
837+
migQuery: mig,
820838
},
821839
{
822840
name: "cache fill failure, fallback success",
823841
cache: emptyCache(),
824842
fetchMigs: fetchMigsFail,
825843
fetchMigTargetSize: fetchMigTargetSizeConst(targetSize),
826844
expectedTargetSize: targetSize,
845+
migQuery: mig,
827846
},
828847
{
829848
name: "cache fill without mig, fallback failure",
830849
cache: emptyCache(),
831850
fetchMigs: fetchMigsConst([]*gce.InstanceGroupManager{}),
832851
fetchMigTargetSize: fetchMigTargetSizeFail,
833852
expectedErr: errFetchMigTargetSize,
853+
migQuery: mig,
834854
},
835855
{
836856
name: "cache fill failure, fallback failure",
837857
cache: emptyCache(),
838858
fetchMigs: fetchMigsFail,
839859
fetchMigTargetSize: fetchMigTargetSizeFail,
840860
expectedErr: errFetchMigTargetSize,
861+
migQuery: mig,
841862
},
842863
}
843864

@@ -850,8 +871,8 @@ func TestGetMigTargetSize(t *testing.T) {
850871
migLister := NewMigLister(tc.cache)
851872
provider := NewCachingMigInfoProvider(tc.cache, migLister, client, mig.GceRef().Project, 1, 0*time.Second, false)
852873

853-
targetSize, err := provider.GetMigTargetSize(mig.GceRef())
854-
cachedTargetSize, found := tc.cache.GetMigTargetSize(mig.GceRef())
874+
targetSize, err := provider.GetMigTargetSize(tc.migQuery.GceRef())
875+
cachedTargetSize, found := tc.cache.GetMigTargetSize(tc.migQuery.GceRef())
855876

856877
assert.Equal(t, tc.expectedErr, err)
857878
assert.Equal(t, tc.expectedErr == nil, found)
@@ -1916,7 +1937,7 @@ func (f *fakeTime) Now() time.Time {
19161937

19171938
func emptyCache() *GceCache {
19181939
return &GceCache{
1919-
migs: map[GceRef]Mig{mig.GceRef(): mig},
1940+
migs: map[GceRef]Mig{mig.GceRef(): mig, mig1.GceRef(): mig1},
19201941
instances: make(map[GceRef][]GceInstance),
19211942
instancesUpdateTime: make(map[GceRef]time.Time),
19221943
migTargetSizeCache: make(map[GceRef]int64),

0 commit comments

Comments
 (0)